コード例 #1
0
  private static void qualify(PsiMember member, PsiElement renamed, String name) {
    if (!(renamed instanceof GrReferenceExpression)) return;

    final PsiClass clazz = member.getContainingClass();
    if (clazz == null) return;

    final GrReferenceExpression refExpr = (GrReferenceExpression) renamed;
    final PsiElement replaced;
    if (member.hasModifierProperty(GrModifier.STATIC)) {
      final GrReferenceExpression newRefExpr =
          GroovyPsiElementFactory.getInstance(member.getProject())
              .createReferenceExpressionFromText(clazz.getQualifiedName() + "." + name);
      replaced = refExpr.replace(newRefExpr);
    } else {
      final PsiClass containingClass = PsiTreeUtil.getParentOfType(renamed, PsiClass.class);
      if (member.getManager().areElementsEquivalent(containingClass, clazz)) {
        final GrReferenceExpression newRefExpr =
            GroovyPsiElementFactory.getInstance(member.getProject())
                .createReferenceExpressionFromText("this." + name);
        replaced = refExpr.replace(newRefExpr);
      } else {
        final GrReferenceExpression newRefExpr =
            GroovyPsiElementFactory.getInstance(member.getProject())
                .createReferenceExpressionFromText(clazz.getQualifiedName() + ".this." + name);
        replaced = refExpr.replace(newRefExpr);
      }
    }
    PsiUtil.shortenReferences((GroovyPsiElement) replaced);
  }
 @Override
 public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
   if (FileTypeUtils.isInServerPageFile(expression)) {
     // disable for jsp files IDEADEV-12957
     return;
   }
   super.visitReferenceExpression(expression);
   if (expression.getQualifierExpression() == null) {
     return;
   }
   final PsiElement referenceNameElement = expression.getReferenceNameElement();
   if (referenceNameElement == null) {
     return;
   }
   final PsiElement containingClass = getContainingContextClass(expression);
   if (containingClass == null) {
     return;
   }
   final PsiElement element = expression.resolve();
   if (!(element instanceof PsiMethod || element instanceof PsiField)) {
     return;
   }
   final PsiMember member = (PsiMember) element;
   if (!member.hasModifierProperty(PsiModifier.PRIVATE)) {
     return;
   }
   final PsiClass memberClass = ClassUtils.getContainingClass(member);
   if (memberClass == null) {
     return;
   }
   if (memberClass.equals(containingClass)) {
     return;
   }
   registerError(referenceNameElement, memberClass, member);
 }
 @Override
 public void visitAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
   if (anonymousClass instanceof PsiEnumConstantInitializer) {
     return;
   }
   final PsiMember containingMember =
       PsiTreeUtil.getParentOfType(anonymousClass, PsiMember.class);
   if (containingMember == null || containingMember.hasModifierProperty(PsiModifier.STATIC)) {
     return;
   }
   final PsiJavaCodeReferenceElement reference = anonymousClass.getBaseClassReference();
   if (reference.resolve() == null) {
     // don't warn on broken code
     return;
   }
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(anonymousClass, PsiClass.class);
   if (containingClass == null) {
     return;
   }
   if (containingClass.getContainingClass() != null
       && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
     // strictly speaking can be named static inner class but not when part of the current
     // containing class
     return;
   }
   final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass);
   anonymousClass.accept(visitor);
   if (!visitor.canInnerClassBeStatic()) {
     return;
   }
   if (hasReferenceToLocalClass(anonymousClass)) {
     return;
   }
   registerClassError(anonymousClass);
 }
コード例 #4
0
  private static boolean processInstanceMember(
      boolean shouldProcessInstance, @NotNull PsiMember member) {
    if (shouldProcessInstance) return true;

    if (member instanceof GrReflectedMethod) {
      return ((GrReflectedMethod) member).getBaseMethod().hasModifierProperty(PsiModifier.STATIC);
    } else {
      return member.hasModifierProperty(PsiModifier.STATIC);
    }
  }
コード例 #5
0
 @Override
 public boolean isAbstractWhenDisabled(MemberInfo member) {
   PsiClass currentSuperClass = getSuperClass();
   if (currentSuperClass == null) return false;
   if (currentSuperClass.isInterface()) {
     final PsiMember psiMember = member.getMember();
     if (psiMember instanceof PsiMethod) {
       return !psiMember.hasModifierProperty(PsiModifier.STATIC);
     }
   }
   return false;
 }
コード例 #6
0
 @Override
 protected void visitClassMemberReferenceElement(
     PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
   if (classMember != null && !willBeMoved(classMember, myMovedMembers)) {
     final PsiClass containingClass = classMember.getContainingClass();
     if (containingClass != null) {
       if (!PsiUtil.isAccessibleFromPackage(classMember, myTargetPackage)) {
         if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
           myConflicts.putValue(
               myMember,
               RefactoringUIUtil.getDescription(classMember, true) + " won't be accessible");
         } else if (classMember.hasModifierProperty(PsiModifier.PROTECTED)
             && !mySubClass.isInheritor(containingClass, true)) {
           myConflicts.putValue(
               myMember,
               RefactoringUIUtil.getDescription(classMember, true) + " won't be accessible");
         }
       }
     }
   }
 }
コード例 #7
0
 protected void visitClassMemberReferenceElement(
     PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
   if (classMember != null
       && RefactoringHierarchyUtil.isMemberBetween(mySuperClass, mySubclass, classMember)) {
     if (classMember.hasModifierProperty(PsiModifier.STATIC)
         && !willBeMoved(classMember, myMovedMembers)) {
       final boolean isAccessible;
       if (mySuperClass != null) {
         isAccessible = PsiUtil.isAccessible(classMember, mySuperClass, null);
       } else if (myTargetPackage != null) {
         isAccessible = PsiUtil.isAccessibleFromPackage(classMember, myTargetPackage);
       } else {
         isAccessible = classMember.hasModifierProperty(PsiModifier.PUBLIC);
       }
       if (!isAccessible) {
         String message =
             RefactoringBundle.message(
                 "0.uses.1.which.is.not.accessible.from.the.superclass",
                 RefactoringUIUtil.getDescription(myScope, false),
                 RefactoringUIUtil.getDescription(classMember, true));
         message = CommonRefactoringUtil.capitalize(message);
         myConflictsList.putValue(classMember, message);
       }
       return;
     }
     if (!myAbstractMethods.contains(classMember) && !willBeMoved(classMember, myMovedMembers)) {
       if (!existsInSuperClass(classMember)) {
         String message =
             RefactoringBundle.message(
                 "0.uses.1.which.is.not.moved.to.the.superclass",
                 RefactoringUIUtil.getDescription(myScope, false),
                 RefactoringUIUtil.getDescription(classMember, true));
         message = CommonRefactoringUtil.capitalize(message);
         myConflictsList.putValue(classMember, message);
       }
     }
   }
 }
コード例 #8
0
  @NotNull
  public static SearchScope getMemberUseScope(@NotNull PsiMember member) {
    final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(member);
    PsiFile file = member.getContainingFile();
    if (isInServerPage(file)) return maximalUseScope;

    PsiClass aClass = member.getContainingClass();
    if (aClass instanceof PsiAnonymousClass) {
      // member from anonymous class can be called from outside the class
      PsiElement methodCallExpr =
          PsiTreeUtil.getParentOfType(aClass, PsiMethodCallExpression.class);
      return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass);
    }

    if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
      return maximalUseScope; // class use scope doesn't matter, since another very visible class
      // can inherit from aClass
    } else if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
      return maximalUseScope; // class use scope doesn't matter, since another very visible class
      // can inherit from aClass
    } else if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
      PsiClass topClass = PsiUtil.getTopLevelClass(member);
      return topClass != null ? new LocalSearchScope(topClass) : new LocalSearchScope(file);
    } else {
      if (file instanceof PsiJavaFile) {
        PsiPackage aPackage =
            JavaPsiFacade.getInstance(member.getProject())
                .findPackage(((PsiJavaFile) file).getPackageName());
        if (aPackage != null) {
          SearchScope scope = PackageScope.packageScope(aPackage, false);
          scope = scope.intersectWith(maximalUseScope);
          return scope;
        }
      }

      return maximalUseScope;
    }
  }
コード例 #9
0
 @Override
 @NotNull
 protected UsageInfo[] findUsages() {
   final List<UsageInfo> result = new ArrayList<>();
   for (MemberInfo memberInfo : myMembersToMove) {
     final PsiMember member = memberInfo.getMember();
     if (member.hasModifierProperty(PsiModifier.STATIC)) {
       for (PsiReference reference : ReferencesSearch.search(member)) {
         result.add(new UsageInfo(reference));
       }
     }
   }
   return result.isEmpty() ? UsageInfo.EMPTY_ARRAY : result.toArray(new UsageInfo[result.size()]);
 }
コード例 #10
0
 @Override
 public int checkForProblems(@NotNull MemberInfo member) {
   if (member.isChecked()) return OK;
   PsiClass currentSuperClass = getSuperClass();
   if (currentSuperClass != null && currentSuperClass.isInterface()) {
     PsiMember element = member.getMember();
     if (element.hasModifierProperty(PsiModifier.STATIC)) {
       return super.checkForProblems(member);
     }
     return OK;
   } else {
     return super.checkForProblems(member);
   }
 }
コード例 #11
0
  @NotNull
  @Override
  protected UsageInfo[] findUsages() {
    final List<UsageInfo> result = new ArrayList<UsageInfo>();
    for (GrMemberInfo info : myMembersToMove) {
      final PsiMember member = info.getMember();
      if (member.hasModifierProperty(PsiModifier.STATIC)) {
        for (PsiReference reference : ReferencesSearch.search(member)) {
          result.add(new UsageInfo(reference));
        }
      }
    }

    return DefaultGroovyMethods.asType(result, UsageInfo[].class);
  }
コード例 #12
0
  @NotNull
  public static SearchScope getMemberUseScope(@NotNull PsiMember member) {
    PsiFile file = member.getContainingFile();
    PsiElement topElement = file == null ? member : file;
    Project project = topElement.getProject();
    final GlobalSearchScope maximalUseScope =
        ResolveScopeManager.getInstance(project).getUseScope(topElement);
    if (isInServerPage(file)) return maximalUseScope;

    PsiClass aClass = member.getContainingClass();
    if (aClass instanceof PsiAnonymousClass
        && !(aClass instanceof PsiEnumConstantInitializer
            && member instanceof PsiMethod
            && member.hasModifierProperty(PsiModifier.PUBLIC)
            && ((PsiMethod) member).findSuperMethods().length > 0)) {
      // member from anonymous class can be called from outside the class
      PsiElement methodCallExpr =
          PsiUtil.isLanguageLevel8OrHigher(aClass)
              ? PsiTreeUtil.getTopmostParentOfType(aClass, PsiStatement.class)
              : PsiTreeUtil.getParentOfType(aClass, PsiMethodCallExpression.class);
      return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass);
    }

    PsiModifierList modifierList = member.getModifierList();
    int accessLevel =
        modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList);
    if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC
        || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) {
      return maximalUseScope; // class use scope doesn't matter, since another very visible class
      // can inherit from aClass
    }
    if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) {
      PsiClass topClass = PsiUtil.getTopLevelClass(member);
      return topClass != null
          ? new LocalSearchScope(topClass)
          : file == null ? maximalUseScope : new LocalSearchScope(file);
    }
    if (file instanceof PsiJavaFile) {
      PsiPackage aPackage =
          JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile) file).getPackageName());
      if (aPackage != null) {
        SearchScope scope = PackageScope.packageScope(aPackage, false);
        return scope.intersectWith(maximalUseScope);
      }
    }
    return maximalUseScope;
  }
コード例 #13
0
 protected void visitClassMemberReferenceElement(
     PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
   if (classMember.hasModifierProperty(PsiModifier.STATIC)) {
     if (!myMembersToMove.contains(classMember)
         && RefactoringHierarchyUtil.isMemberBetween(
             myTargetSuperClass, mySourceClass, classMember)) {
       myReferences.add(classMemberReference);
       myReferees.add(classMember);
       myRefereeClasses.add(classMember.getContainingClass());
     } else if (myMembersToMove.contains(classMember)
         || myMembersAfterMove.contains(classMember)) {
       myReferences.add(classMemberReference);
       myReferees.add(classMember);
       myRefereeClasses.add(myTargetSuperClass);
     }
   }
 }
コード例 #14
0
  public static boolean isInExcludedPackage(
      @NotNull final PsiMember member, boolean allowInstanceInnerClasses) {
    final String name = PsiUtil.getMemberQualifiedName(member);
    if (name == null) return false;

    if (!member.hasModifierProperty(PsiModifier.STATIC)) {
      if (member instanceof PsiMethod || member instanceof PsiField) {
        return false;
      }
      if (allowInstanceInnerClasses
          && member instanceof PsiClass
          && member.getContainingClass() != null) {
        return false;
      }
    }

    return ProjectCodeInsightSettings.getSettings(member.getProject()).isExcluded(name);
  }
コード例 #15
0
 private static boolean referenceExpressionsAreEquivalent(
     PsiReferenceExpression referenceExpression1, PsiReferenceExpression referenceExpression2) {
   final PsiElement element1 = referenceExpression1.resolve();
   final PsiElement element2 = referenceExpression2.resolve();
   if (element1 != null) {
     if (!element1.equals(element2)) {
       return false;
     }
   } else {
     return element2 == null;
   }
   if (element1 instanceof PsiMember) {
     final PsiMember member1 = (PsiMember) element1;
     if (member1.hasModifierProperty(PsiModifier.STATIC)) {
       return true;
     } else if (member1 instanceof PsiClass) {
       return true;
     }
   } else {
     return true;
   }
   final PsiExpression qualifier1 = referenceExpression1.getQualifierExpression();
   final PsiExpression qualifier2 = referenceExpression2.getQualifierExpression();
   if (qualifier1 != null
       && !(qualifier1 instanceof PsiThisExpression || qualifier1 instanceof PsiSuperExpression)) {
     if (qualifier2 == null) {
       return false;
     } else if (!expressionsAreEquivalent(qualifier1, qualifier2)) {
       return false;
     }
   } else {
     if (qualifier2 != null
         && !(qualifier2 instanceof PsiThisExpression
             || qualifier2 instanceof PsiSuperExpression)) {
       return false;
     }
   }
   final String text1 = referenceExpression1.getText();
   final String text2 = referenceExpression2.getText();
   return text1.equals(text2);
 }
コード例 #16
0
    private void checkMember(@NotNull final PsiMember member) {
      if (member.hasModifierProperty(PsiModifier.PRIVATE)
          || member.hasModifierProperty(PsiModifier.NATIVE)) return;
      if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical())
        return;

      if (member instanceof PsiMethod) {
        PsiMethod method = (PsiMethod) member;
        if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) {
          log(member.getName() + " overrides");
          return; // overrides
        }
        if (MethodUtils.isOverridden(method)) {
          log(member.getName() + " overridden");
          return;
        }
      }
      if (member instanceof PsiEnumConstant) return;
      if (member instanceof PsiClass
          && (member instanceof PsiAnonymousClass
              || member instanceof PsiTypeParameter
              || member instanceof PsiSyntheticClass
              || PsiUtil.isLocalClass((PsiClass) member))) {
        return;
      }
      final PsiClass memberClass = member.getContainingClass();
      if (memberClass != null
          && (memberClass.isInterface()
              || memberClass.isEnum()
              || memberClass.isAnnotationType()
              || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) {
        return;
      }
      final PsiFile memberFile = member.getContainingFile();
      Project project = memberFile.getProject();

      if (myDeadCodeInspection.isEntryPoint(member)) {
        log(member.getName() + " is entry point");
        return;
      }

      PsiModifierList memberModifierList = member.getModifierList();
      if (memberModifierList == null) return;
      final int currentLevel = PsiUtil.getAccessLevel(memberModifierList);
      final AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE);
      final AtomicBoolean foundUsage = new AtomicBoolean();
      PsiDirectory memberDirectory = memberFile.getContainingDirectory();
      final PsiPackage memberPackage =
          memberDirectory == null
              ? null
              : JavaDirectoryService.getInstance().getPackage(memberDirectory);
      log(member.getName() + ": checking effective level for " + member);
      boolean result =
          UnusedSymbolUtil.processUsages(
              project,
              memberFile,
              member,
              new EmptyProgressIndicator(),
              null,
              new Processor<UsageInfo>() {
                @Override
                public boolean process(UsageInfo info) {
                  foundUsage.set(true);
                  PsiFile psiFile = info.getFile();
                  if (psiFile == null) return true;
                  if (!(psiFile instanceof PsiJavaFile)) {
                    log("     refd from " + psiFile.getName() + "; set to public");
                    maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
                    if (memberClass != null) {
                      childMembersAreUsedOutsideMyPackage.add(memberClass);
                    }
                    return false; // referenced from XML, has to be public
                  }
                  // int offset = info.getNavigationOffset();
                  // if (offset == -1) return true;
                  PsiElement element = info.getElement();
                  if (element == null) return true;
                  @PsiUtil.AccessLevel
                  int level =
                      getEffectiveLevel(element, psiFile, memberFile, memberClass, memberPackage);
                  log(
                      "    ref in file "
                          + psiFile.getName()
                          + "; level = "
                          + PsiUtil.getAccessModifier(level)
                          + "; ("
                          + element
                          + ")");
                  while (true) {
                    int oldLevel = maxLevel.get();
                    if (level <= oldLevel || maxLevel.compareAndSet(oldLevel, level)) break;
                  }
                  if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
                    childMembersAreUsedOutsideMyPackage.add(memberClass);
                  }

                  return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
                }
              });

      if (!foundUsage.get()) {
        log(member.getName() + " unused; ignore");
        return; // do not propose private for unused method
      }
      int max = maxLevel.get();
      if (max == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) {
        max = PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
      }

      log(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(max) + "'");

      if (max < currentLevel) {
        if (max == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
            && member instanceof PsiClass
            && childMembersAreUsedOutsideMyPackage.contains(member)) {
          log(member.getName() + "  children used outside my package; ignore");
          return; // e.g. some public method is used outside my package (without importing class)
        }
        PsiElement toHighlight =
            currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
                ? ((PsiNameIdentifierOwner) member).getNameIdentifier()
                : ContainerUtil.find(
                    memberModifierList.getChildren(),
                    new Condition<PsiElement>() {
                      @Override
                      public boolean value(PsiElement element) {
                        return element instanceof PsiKeyword
                            && element.getText().equals(PsiUtil.getAccessModifier(currentLevel));
                      }
                    });
        assert toHighlight != null
            : member
                + " ; "
                + ((PsiNameIdentifierOwner) member).getNameIdentifier()
                + "; "
                + memberModifierList.getText();
        myHolder.registerProblem(
            toHighlight,
            "Access can be " + PsiUtil.getAccessModifier(max),
            new ChangeModifierFix(PsiUtil.getAccessModifier(max)));
      }
    }
コード例 #17
0
 protected void visitClassMemberReferenceElement(
     PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
   if (!classMember.hasModifierProperty(PsiModifier.STATIC)) {
     myElementReference = classMemberReference;
   }
 }