コード例 #1
0
 private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) {
   PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
   PsiClass aClass = (PsiClass) info.getMember();
   if (Boolean.FALSE.equals(info.getOverrides())) {
     final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
     LOG.assertTrue(sourceReferenceList != null);
     PsiJavaCodeReferenceElement ref =
         mySourceClass.equals(sourceReferenceList.getParent())
             ? RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass)
             : RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
     if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
       RefactoringUtil.replaceMovedMemberTypeParameters(
           ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
       final PsiReferenceList referenceList =
           myIsTargetInterface
               ? myTargetSuperClass.getExtendsList()
               : myTargetSuperClass.getImplementsList();
       assert referenceList != null;
       referenceList.add(ref);
     }
   } else {
     RefactoringUtil.replaceMovedMemberTypeParameters(
         aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
     fixReferencesToStatic(aClass);
     final PsiMember movedElement =
         (PsiMember)
             myTargetSuperClass.add(
                 convertClassToLanguage(aClass, myTargetSuperClass.getLanguage()));
     myMembersAfterMove.add(movedElement);
     aClass.delete();
   }
 }
コード例 #2
0
  private static void findClassUsages(
      final PsiClass psiClass,
      final PsiElement[] allElementsToDelete,
      final List<UsageInfo> usages) {
    final boolean justPrivates = containsOnlyPrivates(psiClass);
    final String qualifiedName = psiClass.getQualifiedName();
    final boolean annotationType = psiClass.isAnnotationType() && qualifiedName != null;

    ReferencesSearch.search(psiClass)
        .forEach(
            reference -> {
              final PsiElement element = reference.getElement();

              if (!isInside(element, allElementsToDelete)) {
                PsiElement parent = element.getParent();
                if (parent instanceof PsiReferenceList) {
                  final PsiElement pparent = parent.getParent();
                  if (pparent instanceof PsiClass
                      && element instanceof PsiJavaCodeReferenceElement) {
                    final PsiClass inheritor = (PsiClass) pparent;
                    // If psiClass contains only private members, then it is safe to remove it and
                    // change inheritor's extends/implements accordingly
                    if (justPrivates) {
                      if (parent.equals(inheritor.getExtendsList())
                          || parent.equals(inheritor.getImplementsList())) {
                        usages.add(
                            new SafeDeleteExtendsClassUsageInfo(
                                (PsiJavaCodeReferenceElement) element, psiClass, inheritor));
                        return true;
                      }
                    }
                  }
                }
                LOG.assertTrue(element.getTextRange() != null);
                final PsiFile containingFile = psiClass.getContainingFile();
                boolean sameFileWithSingleClass = false;
                if (containingFile instanceof PsiClassOwner) {
                  final PsiClass[] classes = ((PsiClassOwner) containingFile).getClasses();
                  sameFileWithSingleClass =
                      classes.length == 1
                          && classes[0] == psiClass
                          && element.getContainingFile() == containingFile;
                }

                final boolean safeDelete = sameFileWithSingleClass || isInNonStaticImport(element);
                if (annotationType && parent instanceof PsiAnnotation) {
                  usages.add(
                      new SafeDeleteAnnotation((PsiAnnotation) parent, psiClass, safeDelete));
                } else {
                  usages.add(
                      new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass, safeDelete));
                }
              }
              return true;
            });
  }
コード例 #3
0
  private boolean isAccessibleFrom(RefElement from, RefJavaElement to, String accessModifier) {
    if (accessModifier == PsiModifier.PUBLIC) return true;

    final RefJavaUtil refUtil = RefJavaUtil.getInstance();
    if (accessModifier == PsiModifier.PACKAGE_LOCAL) {
      return RefJavaUtil.getPackage(from) == RefJavaUtil.getPackage(to);
    }

    RefClass fromTopLevel = refUtil.getTopLevelClass(from);
    RefClass toTopLevel = refUtil.getTopLevelClass(to);
    RefClass fromOwner = refUtil.getOwnerClass(from);
    RefClass toOwner = refUtil.getOwnerClass(to);

    if (accessModifier == PsiModifier.PROTECTED) {
      if (SUGGEST_PRIVATE_FOR_INNERS) {
        return refUtil.isInheritor(fromTopLevel, toOwner)
            || fromOwner != null && refUtil.isInheritor(fromOwner, toTopLevel)
            || toOwner != null && refUtil.getOwnerClass(toOwner) == from;
      }

      return refUtil.isInheritor(fromTopLevel, toOwner);
    }

    if (accessModifier == PsiModifier.PRIVATE) {
      if (SUGGEST_PRIVATE_FOR_INNERS) {
        if (isInExtendsList(to, fromTopLevel.getElement().getExtendsList())) return false;
        if (isInExtendsList(to, fromTopLevel.getElement().getImplementsList())) return false;
        if (isInAnnotations(to, fromTopLevel)) return false;
        return fromTopLevel == toOwner
            || fromOwner == toTopLevel
            || toOwner != null && refUtil.getOwnerClass(toOwner) == from;
      }

      if (fromOwner != null
          && fromOwner.isStatic()
          && !to.isStatic()
          && refUtil.isInheritor(fromOwner, toOwner)) return false;

      if (fromTopLevel == toOwner) {
        if (from instanceof RefClass && to instanceof RefClass) {
          final PsiClass fromClass = ((RefClass) from).getElement();
          LOG.assertTrue(fromClass != null);
          if (isInExtendsList(to, fromClass.getExtendsList())) return false;
          if (isInExtendsList(to, fromClass.getImplementsList())) return false;
        }

        return true;
      }
    }

    return false;
  }
コード例 #4
0
 @Nullable
 private PsiType extractListTypeFromContainingClass(
   PsiElement element) {
   PsiClass listClass = PsiTreeUtil.getParentOfType(element,
                                                    PsiClass.class);
   if (listClass == null) {
     return null;
   }
   final PsiMethod[] getMethods =
     listClass.findMethodsByName("get", true);
   if (getMethods.length == 0) {
     return null;
   }
   final PsiType type = getMethods[0].getReturnType();
   if (!(type instanceof PsiClassType)) {
     return null;
   }
   final PsiClassType classType = (PsiClassType)type;
   final PsiClass parameterClass = classType.resolve();
   if (parameterClass == null) {
     return null;
   }
   PsiClass subClass = null;
   while (listClass != null && !listClass.hasTypeParameters()) {
     subClass = listClass;
     listClass = listClass.getSuperClass();
   }
   if (listClass == null || subClass == null) {
     return TypeUtils.getObjectType(element);
   }
   final PsiTypeParameter[] typeParameters =
     listClass.getTypeParameters();
   if (!parameterClass.equals(typeParameters[0])) {
     return TypeUtils.getObjectType(element);
   }
   final PsiReferenceList extendsList = subClass.getExtendsList();
   if (extendsList == null) {
     return null;
   }
   final PsiJavaCodeReferenceElement[] referenceElements =
     extendsList.getReferenceElements();
   if (referenceElements.length == 0) {
     return null;
   }
   final PsiType[] types =
     referenceElements[0].getTypeParameters();
   if (types.length == 0) {
     return TypeUtils.getObjectType(element);
   }
   return types[0];
 }
コード例 #5
0
 public void testReferenceElement() throws Exception {
   final JavaPsiFacade manager = getJavaFacade();
   final PsiClass classA =
       manager
           .getElementFactory()
           .createClassFromText("class A extends List<String>{}", null)
           .getInnerClasses()[0];
   final PsiClass classTestList =
       manager.findClass(
           "test.List", GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule));
   assertNotNull(classTestList);
   classA.getExtendsList().getReferenceElements()[0].bindToElement(classTestList);
   assertEquals("class A extends test.List<String>{}", classA.getText());
 }
コード例 #6
0
  private static void addSuperClass(PsiClass targetClass, Project project, String superClassName)
      throws IncorrectOperationException {
    if (superClassName == null) return;

    PsiElementFactory ef = JavaPsiFacade.getInstance(project).getElementFactory();
    PsiJavaCodeReferenceElement superClassRef;

    PsiClass superClass = findClass(project, superClassName);
    if (superClass != null) {
      superClassRef = ef.createClassReferenceElement(superClass);
    } else {
      superClassRef =
          ef.createFQClassNameReferenceElement(superClassName, GlobalSearchScope.allScope(project));
    }
    targetClass.getExtendsList().add(superClassRef);
  }
コード例 #7
0
 public void testClassTypeParamsPresentation() throws Exception {
   PsiClass psiClass = getTestClass();
   final PsiReferenceList extendsList = psiClass.getExtendsList();
   final PsiJavaCodeReferenceElement referenceElement = extendsList.getReferenceElements()[0];
   final PsiClass superClass = extendsList.getReferencedTypes()[0].resolve();
   final File htmlPath =
       new File(
           JavaTestUtil.getJavaTestDataPath()
               + "/codeInsight/javadocIG/"
               + getTestName(true)
               + ".html");
   String htmlText = FileUtil.loadFile(htmlPath);
   String docInfo =
       new JavaDocumentationProvider().getQuickNavigateInfo(superClass, referenceElement);
   assertNotNull(docInfo);
   assertEquals(
       StringUtil.convertLineSeparators(htmlText.trim()),
       StringUtil.convertLineSeparators(docInfo.trim()));
 }
コード例 #8
0
 static PsiClass extractInterface(
     PsiDirectory targetDir,
     PsiClass aClass,
     String interfaceName,
     MemberInfo[] selectedMembers,
     DocCommentPolicy javaDocPolicy)
     throws IncorrectOperationException {
   PsiClass anInterface =
       JavaDirectoryService.getInstance().createInterface(targetDir, interfaceName);
   PsiJavaCodeReferenceElement ref =
       ExtractSuperClassUtil.createExtendingReference(anInterface, aClass, selectedMembers);
   final PsiReferenceList referenceList =
       aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList();
   assert referenceList != null;
   referenceList.add(ref);
   PullUpHelper pullUpHelper =
       new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy);
   pullUpHelper.moveMembersToBase();
   return anInterface;
 }
コード例 #9
0
 @NotNull
 public static PsiClassType[] getExtendsListTypes(@NotNull PsiClass psiClass) {
   if (psiClass.isEnum()) {
     PsiClassType enumSuperType =
         getEnumSuperType(
             psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory());
     return enumSuperType == null ? PsiClassType.EMPTY_ARRAY : new PsiClassType[] {enumSuperType};
   }
   if (psiClass.isAnnotationType()) {
     return new PsiClassType[] {
       getAnnotationSuperType(
           psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())
     };
   }
   final PsiReferenceList extendsList = psiClass.getExtendsList();
   if (extendsList != null) {
     return extendsList.getReferencedTypes();
   }
   return PsiClassType.EMPTY_ARRAY;
 }
コード例 #10
0
 @Nullable
 private static PsiReferenceParameterList findTypeArgumentsList(
     final PsiClass superClass, final PsiClass derivedClass) {
   PsiReferenceParameterList referenceParameterList = null;
   if (derivedClass instanceof PsiAnonymousClass) {
     referenceParameterList =
         ((PsiAnonymousClass) derivedClass).getBaseClassReference().getParameterList();
   } else {
     final PsiReferenceList implementsList = derivedClass.getImplementsList();
     if (implementsList != null) {
       referenceParameterList = extractReferenceParameterList(superClass, implementsList);
     }
     if (referenceParameterList == null) {
       final PsiReferenceList extendsList = derivedClass.getExtendsList();
       if (extendsList != null) {
         referenceParameterList = extractReferenceParameterList(superClass, extendsList);
       }
     }
   }
   return referenceParameterList;
 }
コード例 #11
0
  private static List<PsiClassType> getSuperTypes(PsiClass clazz) {
    if (clazz instanceof GrTypeDefinition) {
      final GrExtendsClause elist = ((GrTypeDefinition) clazz).getExtendsClause();
      final GrImplementsClause ilist = ((GrTypeDefinition) clazz).getImplementsClause();

      if (elist == null && ilist == null) return ContainerUtil.emptyList();

      final ArrayList<PsiClassType> types = new ArrayList<PsiClassType>();
      if (elist != null) ContainerUtil.addAll(types, elist.getReferencedTypes());
      if (ilist != null) ContainerUtil.addAll(types, ilist.getReferencedTypes());
      return types;
    } else {
      final PsiReferenceList elist = clazz.getExtendsList();
      final PsiReferenceList ilist = clazz.getImplementsList();

      if (elist == null && ilist == null) return ContainerUtil.emptyList();

      final ArrayList<PsiClassType> types = new ArrayList<PsiClassType>();
      if (elist != null) ContainerUtil.addAll(types, elist.getReferencedTypes());
      if (ilist != null) ContainerUtil.addAll(types, ilist.getReferencedTypes());
      return types;
    }
  }
コード例 #12
0
  public void replace(final ReplacementInfo info, ReplaceOptions options) {
    PsiElement elementToReplace = info.getMatch(0);
    PsiElement elementParent = elementToReplace.getParent();
    String replacementToMake = info.getReplacement();
    Project project = myContext.getProject();
    PsiElement el = findRealSubstitutionElement(elementToReplace);
    boolean listContext = isListContext(el);

    if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) {
      replacementToMake = "@" + replacementToMake;
    }

    PsiElement[] statements =
        ReplacerUtil.createTreeForReplacement(
            replacementToMake,
            el instanceof PsiMember && !isSymbolReplacement(el)
                ? PatternTreeContext.Class
                : PatternTreeContext.Block,
            myContext);

    if (listContext) {
      if (statements.length > 1) {
        elementParent.addRangeBefore(
            statements[0], statements[statements.length - 1], elementToReplace);
      } else if (statements.length == 1) {
        PsiElement replacement = getMatchExpr(statements[0], elementToReplace);

        handleModifierList(el, replacement);
        replacement = handleSymbolReplacement(replacement, el);

        if (replacement instanceof PsiTryStatement) {
          final List<PsiCatchSection> unmatchedCatchSections =
              el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
          final PsiCatchSection[] catches = ((PsiTryStatement) replacement).getCatchSections();

          if (unmatchedCatchSections != null) {
            for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
              final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter();
              final PsiElementFactory elementFactory =
                  JavaPsiFacade.getInstance(project).getElementFactory();
              final PsiCatchSection catchSection =
                  elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null);

              catchSection.getCatchBlock().replace(unmatchedCatchSections.get(i).getCatchBlock());
              replacement.addAfter(catchSection, catches[catches.length - 1]);
              replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild());
            }
          }
        }

        try {
          final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace);

          if (replacement instanceof PsiComment
              && (elementParent instanceof PsiIfStatement
                  || elementParent instanceof PsiLoopStatement)) {
            elementParent.addAfter(createSemicolon(replacement), inserted);
          }
        } catch (IncorrectOperationException e) {
          elementToReplace.replace(replacement);
        }
      }
    } else if (statements.length > 0) {
      PsiElement replacement =
          ReplacerUtil.copySpacesAndCommentsBefore(
              elementToReplace, statements, replacementToMake, elementParent);

      replacement = getMatchExpr(replacement, elementToReplace);

      if (replacement instanceof PsiStatement
          && !(replacement.getLastChild() instanceof PsiJavaToken)
          && !(replacement.getLastChild() instanceof PsiComment)) {
        // assert w/o ;
        final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling();

        if (prevLastChildInParent != null) {
          elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el);
        } else {
          elementParent.addBefore(replacement.getFirstChild(), el);
        }

        el.getNode().getTreeParent().removeChild(el.getNode());
      } else {
        // preserve comments
        handleModifierList(el, replacement);

        if (replacement instanceof PsiClass) {
          // modifier list
          final PsiStatement[] searchStatements = getCodeBlock().getStatements();
          if (searchStatements.length > 0
              && searchStatements[0] instanceof PsiDeclarationStatement
              && ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0]
                  instanceof PsiClass) {
            final PsiClass replaceClazz = (PsiClass) replacement;
            final PsiClass queryClazz =
                (PsiClass) ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0];
            final PsiClass clazz = (PsiClass) el;

            if (replaceClazz.getExtendsList().getTextLength() == 0
                && queryClazz.getExtendsList().getTextLength() == 0
                && clazz.getExtendsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getExtendsList().getPrevSibling(),
                  replaceClazz.getExtendsList()); // whitespace
              replaceClazz
                  .getExtendsList()
                  .addRange(
                      clazz.getExtendsList().getFirstChild(),
                      clazz.getExtendsList().getLastChild());
            }

            if (replaceClazz.getImplementsList().getTextLength() == 0
                && queryClazz.getImplementsList().getTextLength() == 0
                && clazz.getImplementsList().getTextLength() != 0) {
              replaceClazz.addBefore(
                  clazz.getImplementsList().getPrevSibling(),
                  replaceClazz.getImplementsList()); // whitespace
              replaceClazz
                  .getImplementsList()
                  .addRange(
                      clazz.getImplementsList().getFirstChild(),
                      clazz.getImplementsList().getLastChild());
            }

            if (replaceClazz.getTypeParameterList().getTextLength() == 0
                && queryClazz.getTypeParameterList().getTextLength() == 0
                && clazz.getTypeParameterList().getTextLength() != 0) {
              // skip < and >
              replaceClazz.getTypeParameterList().replace(clazz.getTypeParameterList());
            }
          }
        }

        replacement = handleSymbolReplacement(replacement, el);

        el.replace(replacement);
      }
    } else {
      final PsiElement nextSibling = el.getNextSibling();
      el.delete();
      if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) {
        nextSibling.delete();
      }
    }

    if (listContext) {
      final int matchSize = info.getMatchesCount();

      for (int i = 0; i < matchSize; ++i) {
        PsiElement matchElement = info.getMatch(i);
        PsiElement element = findRealSubstitutionElement(matchElement);

        if (element == null) continue;
        PsiElement firstToDelete = element;
        PsiElement lastToDelete = element;
        PsiElement prevSibling = element.getPrevSibling();
        PsiElement nextSibling = element.getNextSibling();

        if (prevSibling instanceof PsiWhiteSpace) {
          firstToDelete = prevSibling;
          prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null;
        } else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
          lastToDelete = nextSibling;
        }

        if (nextSibling instanceof XmlText && i + 1 < matchSize) {
          final PsiElement next = info.getMatch(i + 1);
          if (next != null && next == nextSibling.getNextSibling()) {
            lastToDelete = nextSibling;
          }
        }

        if (element instanceof PsiExpression) {
          final PsiElement parent = element.getParent().getParent();
          if ((parent instanceof PsiCall || parent instanceof PsiAnonymousClass)
              && prevSibling instanceof PsiJavaToken
              && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
            firstToDelete = prevSibling;
          }
        } else if (element instanceof PsiParameter
            && prevSibling instanceof PsiJavaToken
            && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) {
          firstToDelete = prevSibling;
        }

        element.getParent().deleteChildRange(firstToDelete, lastToDelete);
      }
    }
  }