Ejemplo n.º 1
0
 @Nullable
 PsiElement findMatchingElement(@Nullable PsiElement element, Editor editor) {
   while (element != null) {
     if (!JavaLanguage.INSTANCE.equals(element.getLanguage())) {
       break;
     }
     if (predicate instanceof PsiElementEditorPredicate) {
       if (((PsiElementEditorPredicate) predicate).satisfiedBy(element, editor)) {
         return element;
       }
     } else if (predicate.satisfiedBy(element)) {
       return element;
     }
     element = element.getParent();
     if (element instanceof PsiFile) {
       break;
     }
   }
   return null;
 }
  private void findParametersUsage(
      final PsiMethod method, ArrayList<UsageInfo> result, PsiMethod[] overriders) {
    if (JavaLanguage.INSTANCE.equals(myChangeInfo.getLanguage())) {
      PsiParameter[] parameters = method.getParameterList().getParameters();
      for (ParameterInfo info : myChangeInfo.getNewParameters()) {
        if (info.getOldIndex() >= 0) {
          PsiParameter parameter = parameters[info.getOldIndex()];
          if (!info.getName().equals(parameter.getName())) {
            addParameterUsages(parameter, result, info);

            for (PsiMethod overrider : overriders) {
              PsiParameter parameter1 =
                  overrider.getParameterList().getParameters()[info.getOldIndex()];
              if (parameter1 != null
                  && Comparing.strEqual(parameter.getName(), parameter1.getName())) {
                addParameterUsages(parameter1, result, info);
              }
            }
          }
        }
      }
    }
  }
  private void detectLocalsCollisionsInMethod(
      final PsiMethod method, final ArrayList<UsageInfo> result, boolean isOriginal) {
    if (!JavaLanguage.INSTANCE.equals(method.getLanguage())) return;

    final PsiParameter[] parameters = method.getParameterList().getParameters();
    final Set<PsiParameter> deletedOrRenamedParameters = new HashSet<PsiParameter>();
    if (isOriginal) {
      ContainerUtil.addAll(deletedOrRenamedParameters, parameters);
      for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
        if (parameterInfo.getOldIndex() >= 0 && parameterInfo.getOldIndex() < parameters.length) {
          final PsiParameter parameter = parameters[parameterInfo.getOldIndex()];
          if (parameterInfo.getName().equals(parameter.getName())) {
            deletedOrRenamedParameters.remove(parameter);
          }
        }
      }
    }

    for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
      final int oldParameterIndex = parameterInfo.getOldIndex();
      final String newName = parameterInfo.getName();
      if (oldParameterIndex >= 0) {
        if (isOriginal
            && oldParameterIndex < parameters.length
            && !newName.equals(myChangeInfo.getOldParameterNames()[oldParameterIndex])) {
          // Name changes take place only in primary method when name was actually changed
          final PsiParameter parameter = parameters[oldParameterIndex];
          if (!newName.equals(parameter.getName())) {
            JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
                parameter,
                newName,
                method.getBody(),
                null,
                new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
                  public void visitCollidingElement(final PsiVariable collidingVariable) {
                    if (!deletedOrRenamedParameters.contains(collidingVariable)) {
                      result.add(
                          new RenamedParameterCollidesWithLocalUsageInfo(
                              parameter, collidingVariable, method));
                    }
                  }
                });
          }
        }
      } else {
        JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
            method,
            newName,
            method.getBody(),
            null,
            new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
              public void visitCollidingElement(PsiVariable collidingVariable) {
                if (!deletedOrRenamedParameters.contains(collidingVariable)) {
                  result.add(
                      new NewParameterCollidesWithLocalUsageInfo(
                          collidingVariable, collidingVariable, method));
                }
              }
            });
      }
    }
  }
  private PsiMethod[] findSimpleUsagesWithoutParameters(
      final PsiMethod method,
      final ArrayList<UsageInfo> result,
      boolean isToModifyArgs,
      boolean isToThrowExceptions,
      boolean isOriginal) {

    GlobalSearchScope projectScope = GlobalSearchScope.projectScope(method.getProject());
    PsiMethod[] overridingMethods =
        OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY);

    for (PsiMethod overridingMethod : overridingMethods) {
      result.add(
          new OverriderUsageInfo(
              overridingMethod, method, isOriginal, isToModifyArgs, isToThrowExceptions));
    }

    boolean needToChangeCalls =
        !myChangeInfo.isGenerateDelegate()
            && (myChangeInfo.isNameChanged()
                || myChangeInfo.isParameterSetOrOrderChanged()
                || myChangeInfo.isExceptionSetOrOrderChanged()
                || myChangeInfo.isVisibilityChanged() /*for checking inaccessible*/);
    if (needToChangeCalls) {
      int parameterCount = method.getParameterList().getParametersCount();

      PsiReference[] refs =
          MethodReferencesSearch.search(method, projectScope, true)
              .toArray(PsiReference.EMPTY_ARRAY);
      for (PsiReference ref : refs) {
        PsiElement element = ref.getElement();

        boolean isToCatchExceptions =
            isToThrowExceptions
                && needToCatchExceptions(RefactoringUtil.getEnclosingMethod(element));
        if (!isToCatchExceptions) {
          if (RefactoringUtil.isMethodUsage(element)) {
            PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element);
            if (list == null
                || !method.isVarArgs() && list.getExpressions().length != parameterCount) continue;
          }
        }
        if (RefactoringUtil.isMethodUsage(element)) {
          result.add(new MethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions));
        } else if (element instanceof PsiDocTagValue) {
          result.add(new UsageInfo(element));
        } else if (element instanceof PsiMethod && ((PsiMethod) element).isConstructor()) {
          if (JavaLanguage.INSTANCE.equals(element.getLanguage())) {
            DefaultConstructorImplicitUsageInfo implicitUsageInfo =
                new DefaultConstructorImplicitUsageInfo(
                    (PsiMethod) element, ((PsiMethod) element).getContainingClass(), method);
            result.add(implicitUsageInfo);
          }
        } else if (element instanceof PsiClass) {
          LOG.assertTrue(method.isConstructor());
          final PsiClass psiClass = (PsiClass) element;
          if (JavaLanguage.INSTANCE.equals(psiClass.getLanguage())) {
            if (myChangeInfo instanceof JavaChangeInfo) {
              if (shouldPropagateToNonPhysicalMethod(
                  method,
                  result,
                  psiClass,
                  ((JavaChangeInfo) myChangeInfo).getMethodsToPropagateParameters())) {
                continue;
              }
            }
            result.add(new NoConstructorClassUsageInfo(psiClass));
          }
        } else if (ref instanceof PsiCallReference) {
          result.add(new CallReferenceUsageInfo((PsiCallReference) ref));
        } else {
          result.add(new MoveRenameUsageInfo(element, ref, method));
        }
      }

      // if (method.isConstructor() && parameterCount == 0) {
      //    RefactoringUtil.visitImplicitConstructorUsages(method.getContainingClass(),
      //                                                   new
      // DefaultConstructorUsageCollector(result));
      // }
    } else if (myChangeInfo.isParameterTypesChanged()) {
      PsiReference[] refs =
          MethodReferencesSearch.search(method, projectScope, true)
              .toArray(PsiReference.EMPTY_ARRAY);
      for (PsiReference reference : refs) {
        final PsiElement element = reference.getElement();
        if (element instanceof PsiDocTagValue) {
          result.add(new UsageInfo(reference));
        } else if (element instanceof XmlElement) {
          result.add(new MoveRenameUsageInfo(reference, method));
        } else if (element instanceof PsiMethodReferenceExpression) {
          result.add(new UsageInfo(reference));
        }
      }
    }

    // Conflicts
    detectLocalsCollisionsInMethod(method, result, isOriginal);
    for (final PsiMethod overridingMethod : overridingMethods) {
      detectLocalsCollisionsInMethod(overridingMethod, result, isOriginal);
    }

    return overridingMethods;
  }