/** signature should be changed for methods with type parameters */
 private void prepareMethodsChangeSignature(
     final PsiClass currentClass,
     final PsiElement memberToChangeSignature,
     final PsiType memberType) {
   if (memberToChangeSignature instanceof PsiMethod) {
     final PsiMethod method =
         MethodSignatureUtil.findMethodBySuperMethod(
             currentClass, (PsiMethod) memberToChangeSignature, true);
     if (method != null && method.getContainingClass() == currentClass) {
       myLabeler.addRoot(new TypeMigrationUsageInfo(method), memberType, method, false);
     }
   } else if (memberToChangeSignature instanceof PsiParameter
       && ((PsiParameter) memberToChangeSignature).getDeclarationScope() instanceof PsiMethod) {
     final PsiMethod superMethod =
         (PsiMethod) ((PsiParameter) memberToChangeSignature).getDeclarationScope();
     final int parameterIndex =
         superMethod.getParameterList().getParameterIndex((PsiParameter) memberToChangeSignature);
     final PsiMethod method =
         MethodSignatureUtil.findMethodBySuperMethod(currentClass, superMethod, true);
     if (method != null && method.getContainingClass() == currentClass) {
       final PsiParameter parameter = method.getParameterList().getParameters()[parameterIndex];
       if (!parameter.getType().equals(memberType)) {
         myLabeler.addRoot(new TypeMigrationUsageInfo(parameter), memberType, parameter, false);
       }
     }
   }
 }
Exemple #2
0
    private void processListenerProperties(@NotNull PsiMethod method) {
      if (!method.getName().startsWith("add")
          || method.getParameterList().getParametersCount() != 1) return;

      final PsiParameter parameter = method.getParameterList().getParameters()[0];
      final PsiType type = parameter.getType();
      if (!(type instanceof PsiClassType)) return;

      final PsiClassType classType = (PsiClassType) type;
      final PsiClass listenerClass = classType.resolve();
      if (listenerClass == null) return;

      final PsiMethod[] listenerMethods = listenerClass.getMethods();
      if (!InheritanceUtil.isInheritorOrSelf(listenerClass, myEventListener, true)) return;

      for (PsiMethod listenerMethod : listenerMethods) {
        final String name = listenerMethod.getName();
        if (myPropertyNames.add(name)) {
          LookupElementBuilder builder =
              LookupElementBuilder.create(
                      generatePropertyResolveResult(name, listenerMethod, null, null), name)
                  .withIcon(JetgroovyIcons.Groovy.Property);
          myConsumer.consume(builder);
        }
      }
    }
Exemple #3
0
  @NotNull
  public List<String> createConversions(@NotNull PsiCallExpression expression) {
    PsiExpressionList argumentList = expression.getArgumentList();
    PsiExpression[] arguments =
        argumentList != null ? argumentList.getExpressions() : new PsiExpression[] {};
    List<String> conversions = new LinkedList<String>();
    //noinspection UnusedDeclaration
    for (PsiExpression a : arguments) {
      conversions.add("");
    }

    PsiMethod resolve = expression.resolveMethod();
    if (resolve != null) {
      List<PsiType> expectedTypes = new LinkedList<PsiType>();
      List<PsiType> actualTypes = new LinkedList<PsiType>();

      for (PsiParameter p : resolve.getParameterList().getParameters())
        expectedTypes.add(p.getType());

      for (PsiExpression e : arguments) actualTypes.add(e.getType());

      if (conversions.size() == actualTypes.size() && actualTypes.size() == expectedTypes.size()) {
        for (int i = 0; i < actualTypes.size(); i++)
          conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));
      }
    }
    return conversions;
  }
Exemple #4
0
 @NotNull
 public Parameter parameterToParameter(@NotNull PsiParameter parameter) {
   return new Parameter(
       new IdentifierImpl(parameter.getName()),
       typeToType(
           parameter.getType(), ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())));
 }
Exemple #5
0
  private static boolean isParameterUsedRecursively(
      @NotNull PsiElement element, @NotNull List<PsiReference> array) {
    if (!(element instanceof PsiParameter)) return false;
    PsiParameter parameter = (PsiParameter) element;
    PsiElement scope = parameter.getDeclarationScope();
    if (!(scope instanceof PsiMethod)) return false;
    PsiMethod method = (PsiMethod) scope;
    int paramIndex = ArrayUtilRt.find(method.getParameterList().getParameters(), parameter);

    for (PsiReference reference : array) {
      if (!(reference instanceof PsiElement)) return false;
      PsiElement argument = (PsiElement) reference;

      PsiMethodCallExpression methodCallExpression =
          (PsiMethodCallExpression)
              new PsiMatcherImpl(argument)
                  .dot(PsiMatchers.hasClass(PsiReferenceExpression.class))
                  .parent(PsiMatchers.hasClass(PsiExpressionList.class))
                  .parent(PsiMatchers.hasClass(PsiMethodCallExpression.class))
                  .getElement();
      if (methodCallExpression == null) return false;
      PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
      if (method != methodExpression.resolve()) return false;
      PsiExpressionList argumentList = methodCallExpression.getArgumentList();
      PsiExpression[] arguments = argumentList.getExpressions();
      int argumentIndex = ArrayUtilRt.find(arguments, argument);
      if (paramIndex != argumentIndex) return false;
    }

    return true;
  }
 private static boolean isUnique(
     PsiParameter[] params, String newName, HashMap<PsiField, String> usedNames) {
   if (usedNames.containsValue(newName)) return false;
   for (PsiParameter parameter : params) {
     if (Comparing.strEqual(parameter.getName(), newName)) {
       return false;
     }
   }
   return true;
 }
  protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final UsageInfo[] usages = refUsages.get();
    MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
    final Set<PsiMember> members = new HashSet<PsiMember>();
    members.add(myMethod);
    if (myTargetVariable instanceof PsiField) members.add((PsiMember) myTargetVariable);
    if (!myTargetClass.isInterface()) {
      RefactoringConflictsUtil.analyzeAccessibilityConflicts(
          members, myTargetClass, conflicts, myNewVisibility);
    } else {
      for (final UsageInfo usage : usages) {
        if (usage instanceof InheritorUsageInfo) {
          RefactoringConflictsUtil.analyzeAccessibilityConflicts(
              members, ((InheritorUsageInfo) usage).getInheritor(), conflicts, myNewVisibility);
        }
      }
    }

    if (myTargetVariable instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter) myTargetVariable;
      for (final UsageInfo usageInfo : usages) {
        if (usageInfo instanceof MethodCallUsageInfo) {
          final PsiElement methodCall = ((MethodCallUsageInfo) usageInfo).getMethodCallExpression();
          if (methodCall instanceof PsiMethodCallExpression) {
            final PsiExpression[] expressions =
                ((PsiMethodCallExpression) methodCall).getArgumentList().getExpressions();
            final int index = myMethod.getParameterList().getParameterIndex(parameter);
            if (index < expressions.length) {
              PsiExpression instanceValue = expressions[index];
              instanceValue = RefactoringUtil.unparenthesizeExpression(instanceValue);
              if (instanceValue instanceof PsiLiteralExpression
                  && ((PsiLiteralExpression) instanceValue).getValue() == null) {
                String message =
                    RefactoringBundle.message(
                        "0.contains.call.with.null.argument.for.parameter.1",
                        RefactoringUIUtil.getDescription(
                            ConflictsUtil.getContainer(methodCall), true),
                        CommonRefactoringUtil.htmlEmphasize(parameter.getName()));
                conflicts.putValue(instanceValue, message);
              }
            }
          } else if (methodCall instanceof PsiMethodReferenceExpression) {
            conflicts.putValue(methodCall, "Method reference would be broken after move");
          }
        }
      }
    }

    try {
      ConflictsUtil.checkMethodConflicts(myTargetClass, myMethod, getPatternMethod(), conflicts);
    } catch (IncorrectOperationException e) {
    }

    return showConflicts(conflicts, usages);
  }
Exemple #8
0
 @NotNull
 private ParameterList createFunctionParameters(@NotNull PsiMethod method) {
   List<Parameter> result = new LinkedList<Parameter>();
   for (PsiParameter parameter : method.getParameterList().getParameters()) {
     result.add(
         new Parameter(
             new IdentifierImpl(parameter.getName()),
             typeToType(
                 parameter.getType(),
                 ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())),
             ConverterUtil.isReadOnly(parameter, method.getBody())));
   }
   return new ParameterList(result);
 }
  public static PsiType getLambdaParameterType(PsiParameter param) {
    final PsiElement paramParent = param.getParent();
    if (paramParent instanceof PsiParameterList) {
      final int parameterIndex = ((PsiParameterList) paramParent).getParameterIndex(param);
      if (parameterIndex > -1) {
        final PsiLambdaExpression lambdaExpression =
            PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class);
        if (lambdaExpression != null) {

          PsiType type = getFunctionalInterfaceType(lambdaExpression, true, parameterIndex);
          if (type == null) {
            type = getFunctionalInterfaceType(lambdaExpression, false);
          }
          if (type instanceof PsiIntersectionType) {
            final PsiType[] conjuncts = ((PsiIntersectionType) type).getConjuncts();
            for (PsiType conjunct : conjuncts) {
              final PsiType lambdaParameterFromType =
                  getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct);
              if (lambdaParameterFromType != null) return lambdaParameterFromType;
            }
          } else {
            final PsiType lambdaParameterFromType =
                getLambdaParameterFromType(parameterIndex, lambdaExpression, type);
            if (lambdaParameterFromType != null) {
              return lambdaParameterFromType;
            }
          }
        }
      }
    }
    return new PsiLambdaParameterType(param);
  }
 private static PsiType getNormalizedType(PsiParameter parameter) {
   final PsiType type = parameter.getType();
   if (type instanceof PsiEllipsisType) {
     return ((PsiEllipsisType) type).getComponentType();
   }
   return type;
 }
  private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions)
      throws IncorrectOperationException {
    // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions
    newExceptions = filterCheckedExceptions(newExceptions);

    PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class);
    if (context instanceof PsiTryStatement) {
      PsiTryStatement tryStatement = (PsiTryStatement) context;
      PsiCodeBlock tryBlock = tryStatement.getTryBlock();

      // Remove unused catches
      Collection<PsiClassType> classes =
          ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock);
      PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters();
      for (PsiParameter parameter : catchParameters) {
        final PsiType caughtType = parameter.getType();

        if (!(caughtType instanceof PsiClassType)) continue;
        if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue;

        if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue;
        parameter.getParent().delete(); // delete catch section
      }

      PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock);
      addExceptions(exceptionsToAdd, tryStatement);

      adjustPossibleEmptyTryStatement(tryStatement);
    } else {
      newExceptions = filterUnhandledExceptions(newExceptions, ref);
      if (newExceptions.length > 0) {
        // Add new try statement
        PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject());
        PsiTryStatement tryStatement =
            (PsiTryStatement)
                elementFactory.createStatementFromText("try {} catch (Exception e) {}", null);
        PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
        LOG.assertTrue(anchor != null);
        tryStatement.getTryBlock().add(anchor);
        tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor);

        addExceptions(newExceptions, tryStatement);
        anchor.delete();
        tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section
      }
    }
  }
 private static void notNull(Project project, PsiField field, PsiParameter parameter) {
   final String notNull = NullableNotNullManager.getInstance(field.getProject()).getNotNull(field);
   if (notNull != null) {
     final PsiAnnotation annotation =
         JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@" + notNull, field);
     parameter.getModifierList().addBefore(annotation, null);
   }
 }
 private static void resolveParameterVsFieldsConflicts(
     final PsiParameter[] newParms,
     final PsiMethod method,
     final PsiParameterList list,
     boolean[] toRemoveParm)
     throws IncorrectOperationException {
   List<FieldConflictsResolver> conflictResolvers = new ArrayList<FieldConflictsResolver>();
   for (PsiParameter parameter : newParms) {
     conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody()));
   }
   ChangeSignatureUtil.synchronizeList(
       list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm);
   JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list);
   for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) {
     fieldConflictsResolver.fix();
   }
 }
  public static boolean isMethodParameterAnnotatedWith(
      final PsiMethod method,
      final int idx,
      @Nullable Collection<PsiMethod> processed,
      final String annFqn,
      @Nullable Map<String, Object> annotationAttributeValues,
      @Nullable final Set<PsiModifierListOwner> nonNlsTargets) {
    if (processed != null) {
      if (processed.contains(method)) return false;
    } else {
      processed = new THashSet<PsiMethod>();
    }
    processed.add(method);

    final PsiParameter[] params = method.getParameterList().getParameters();
    PsiParameter param;
    if (idx >= params.length) {
      if (params.length == 0) {
        return false;
      }
      PsiParameter lastParam = params[params.length - 1];
      if (lastParam.isVarArgs()) {
        param = lastParam;
      } else {
        return false;
      }
    } else {
      param = params[idx];
    }
    final PsiAnnotation annotation = AnnotationUtil.findAnnotation(param, annFqn);
    if (annotation != null) {
      return processAnnotationAttributes(annotationAttributeValues, annotation);
    }
    if (nonNlsTargets != null) {
      nonNlsTargets.add(param);
    }

    final PsiMethod[] superMethods = method.findSuperMethods();
    for (PsiMethod superMethod : superMethods) {
      if (isMethodParameterAnnotatedWith(
          superMethod, idx, processed, annFqn, annotationAttributeValues, null)) return true;
    }

    return false;
  }
  private static void checkCall(
      @NotNull PsiCallExpression methodCall, @NotNull ProblemsHolder holder) {
    PsiMethod method = methodCall.resolveMethod();
    if (method == null) return;
    PsiParameter[] parameters = method.getParameterList().getParameters();
    PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
    for (int i = 0; i < parameters.length; i++) {
      PsiParameter parameter = parameters[i];
      AllowedValues values = getAllowedValues(parameter, parameter.getType(), null);
      if (values == null) continue;
      if (i >= arguments.length) break;
      PsiExpression argument = arguments[i];
      argument = PsiUtil.deparenthesizeExpression(argument);
      if (argument == null) continue;

      checkMagicParameterArgument(parameter, argument, values, holder);
    }
  }
  private static void checkMagicParameterArgument(
      @NotNull PsiParameter parameter,
      PsiExpression argument,
      @NotNull AllowedValues allowedValues,
      @NotNull ProblemsHolder holder) {
    final PsiManager manager = PsiManager.getInstance(holder.getProject());

    if (!argument.getTextRange().isEmpty()
        && !isAllowed(parameter.getDeclarationScope(), argument, allowedValues, manager)) {
      registerProblem(argument, allowedValues, holder);
    }
  }
 @Nullable
 private static String getCannotInlineMessage(
     final PsiParameter psiParameter, final PsiMethod method) {
   if (psiParameter.isVarArgs()) {
     return RefactoringBundle.message("inline.parameter.error.varargs");
   }
   if (method.findSuperMethods().length > 0
       || OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY).length > 0) {
     return RefactoringBundle.message("inline.parameter.error.hierarchy");
   }
   return null;
 }
 private static boolean askWhetherShouldSearchForParameterInOverridingMethods(
     final PsiElement psiElement, final PsiParameter parameter) {
   return Messages.showOkCancelDialog(
           psiElement.getProject(),
           FindBundle.message(
               "find.parameter.usages.in.overriding.methods.prompt", parameter.getName()),
           FindBundle.message("find.parameter.usages.in.overriding.methods.title"),
           CommonBundle.getYesButtonText(),
           CommonBundle.getNoButtonText(),
           Messages.getQuestionIcon())
       == 0;
 }
 @Nullable
 private static PsiParameter findParamByName(
     String newName,
     PsiType type,
     PsiParameter[] newParameters,
     ParameterInfoImpl[] parameterInfos) {
   for (PsiParameter newParameter : newParameters) {
     if (Comparing.strEqual(newName, newParameter.getName())) {
       return newParameter;
     }
   }
   for (int i = 0; i < newParameters.length; i++) {
     if (parameterInfos[i].getOldIndex() == -1) {
       final PsiParameter parameter = newParameters[i];
       final PsiType paramType =
           parameterInfos[i].getTypeWrapper().getType(parameter, parameter.getManager());
       if (type.isAssignableFrom(paramType)) {
         return parameter;
       }
     }
   }
   return null;
 }
  @Override
  @NotNull
  public PsiElement[] getPrimaryElements() {
    final PsiElement element = getPsiElement();
    if (element instanceof PsiParameter) {
      final PsiParameter parameter = (PsiParameter) element;
      final PsiElement scope = parameter.getDeclarationScope();
      if (scope instanceof PsiMethod) {
        final PsiMethod method = (PsiMethod) scope;
        if (PsiUtil.canBeOverriden(method)) {
          final PsiClass aClass = method.getContainingClass();
          LOG.assertTrue(aClass != null); // Otherwise can not be overriden

          boolean hasOverridden = OverridingMethodsSearch.search(method).findFirst() != null;
          if (hasOverridden
              && askWhetherShouldSearchForParameterInOverridingMethods(element, parameter)) {
            return getParameterElementsToSearch(parameter);
          }
        }
      }
    }
    return myElementsToSearch.length == 0 ? new PsiElement[] {element} : myElementsToSearch;
  }
 static boolean isArgumentInVarargPosition(
     PsiExpression[] expressions, int ei, PsiParameter varargParam, PsiSubstitutor substitutor) {
   if (varargParam == null) return false;
   final PsiExpression expression = expressions[ei];
   if (expression == null
       || TypeConversionUtil.areTypesAssignmentCompatible(
           substitutor.substitute(((PsiEllipsisType) varargParam.getType()).getComponentType()),
           expression)) {
     final int lastExprIdx = expressions.length - 1;
     if (ei == lastExprIdx) return true;
     return expressions[lastExprIdx].getType() != PsiType.NULL;
   }
   return false;
 }
  private static void modifySuperCall(
      final PsiMethod subConstructor, final Set<PsiParameter> parametersToPassToSuper) {
    final PsiCodeBlock body = subConstructor.getBody();
    if (body != null) {
      PsiMethodCallExpression superCall = null;
      final PsiStatement[] statements = body.getStatements();
      if (statements.length > 0) {
        if (statements[0] instanceof PsiExpressionStatement) {
          final PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression();
          if (expression instanceof PsiMethodCallExpression) {
            final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
            if ("super".equals(methodCall.getMethodExpression().getText())) {
              superCall = methodCall;
            }
          }
        }
      }

      final PsiElementFactory factory =
          JavaPsiFacade.getInstance(subConstructor.getProject()).getElementFactory();
      try {
        if (superCall == null) {
          PsiExpressionStatement statement =
              (PsiExpressionStatement) factory.createStatementFromText("super();", null);
          statement = (PsiExpressionStatement) body.addAfter(statement, null);
          superCall = (PsiMethodCallExpression) statement.getExpression();
        }

        final PsiExpressionList argList = superCall.getArgumentList();
        for (final PsiParameter parameter : parametersToPassToSuper) {
          argList.add(factory.createExpressionFromText(parameter.getName(), null));
        }
      } catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }
  }
  public static boolean isMethodEquivalentTo(@NotNull PsiMethod method1, PsiElement another) {
    if (method1 == another) return true;
    if (!(another instanceof PsiMethod)) return false;
    PsiMethod method2 = (PsiMethod) another;
    if (!another.isValid()) return false;
    if (!method1.getName().equals(method2.getName())) return false;
    PsiClass aClass1 = method1.getContainingClass();
    PsiClass aClass2 = method2.getContainingClass();
    PsiManager manager = method1.getManager();
    if (!(aClass1 != null && aClass2 != null && manager.areElementsEquivalent(aClass1, aClass2)))
      return false;

    PsiParameter[] parameters1 = method1.getParameterList().getParameters();
    PsiParameter[] parameters2 = method2.getParameterList().getParameters();
    if (parameters1.length != parameters2.length) return false;
    for (int i = 0; i < parameters1.length; i++) {
      PsiParameter parameter1 = parameters1[i];
      PsiParameter parameter2 = parameters2[i];
      PsiType type1 = parameter1.getType();
      PsiType type2 = parameter2.getType();
      if (!compareParamTypes(manager, type1, type2)) return false;
    }
    return true;
  }
 private static PsiElement[] getParameterElementsToSearch(final PsiParameter parameter) {
   final PsiMethod method = (PsiMethod) parameter.getDeclarationScope();
   PsiMethod[] overrides =
       OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY);
   for (int i = 0; i < overrides.length; i++) {
     overrides[i] = (PsiMethod) overrides[i].getNavigationElement();
   }
   List<PsiElement> elementsToSearch = new ArrayList<PsiElement>(overrides.length + 1);
   elementsToSearch.add(parameter);
   int idx = method.getParameterList().getParameterIndex(parameter);
   for (PsiMethod override : overrides) {
     final PsiParameter[] parameters = override.getParameterList().getParameters();
     if (idx < parameters.length) {
       elementsToSearch.add(parameters[idx]);
     }
   }
   return elementsToSearch.toArray(new PsiElement[elementsToSearch.size()]);
 }
  private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) {
    PsiMethod method = null;
    if (owner instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter) owner;
      PsiElement scope = parameter.getDeclarationScope();
      if (!(scope instanceof PsiMethod)) return null;
      PsiElement nav = scope.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
      if (method.isConstructor()) {
        // not a property, try the @ConstructorProperties({"prop"})
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties");
        if (annotation == null) return null;
        PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
        if (!(value instanceof PsiArrayInitializerMemberValue)) return null;
        PsiAnnotationMemberValue[] initializers =
            ((PsiArrayInitializerMemberValue) value).getInitializers();
        PsiElement parent = parameter.getParent();
        if (!(parent instanceof PsiParameterList)) return null;
        int index = ((PsiParameterList) parent).getParameterIndex(parameter);
        if (index >= initializers.length) return null;
        PsiAnnotationMemberValue initializer = initializers[index];
        if (!(initializer instanceof PsiLiteralExpression)) return null;
        Object val = ((PsiLiteralExpression) initializer).getValue();
        if (!(val instanceof String)) return null;
        PsiMethod setter =
            PropertyUtil.findPropertySetter(
                method.getContainingClass(), (String) val, false, false);
        if (setter == null) return null;
        // try the @beaninfo of the corresponding setter
        method = (PsiMethod) setter.getNavigationElement();
      }
    } else if (owner instanceof PsiMethod) {
      PsiElement nav = owner.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
    }
    if (method == null) return null;

    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    if (PropertyUtil.isSimplePropertyGetter(method)) {
      List<PsiMethod> setters =
          PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
      if (setters.size() != 1) return null;
      method = setters.get(0);
    }
    if (!PropertyUtil.isSimplePropertySetter(method)) return null;
    PsiDocComment doc = method.getDocComment();
    if (doc == null) return null;
    PsiDocTag beaninfo = doc.findTagByName("beaninfo");
    if (beaninfo == null) return null;
    String data =
        StringUtil.join(
            beaninfo.getDataElements(),
            new Function<PsiElement, String>() {
              @Override
              public String fun(PsiElement element) {
                return element.getText();
              }
            },
            "\n");
    int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:");
    if (enumIndex == -1) return null;
    data = data.substring(enumIndex);
    int colon = data.indexOf(":");
    int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n");
    data = data.substring(0, last);

    List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>();
    for (String line : StringUtil.splitByLines(data)) {
      List<String> words = StringUtil.split(line, " ", true, true);
      if (words.size() != 2) continue;
      String ref = words.get(1);
      PsiExpression constRef =
          JavaPsiFacade.getElementFactory(aClass.getProject())
              .createExpressionFromText(ref, aClass);
      if (!(constRef instanceof PsiReferenceExpression)) continue;
      PsiReferenceExpression expr = (PsiReferenceExpression) constRef;
      values.add(expr);
    }
    if (values.isEmpty()) return null;
    PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]);
    return new AllowedValues(array, false);
  }
 protected boolean findNewParamsPlace(
     PsiExpression[] expressions,
     PsiMethod targetMethod,
     PsiSubstitutor substitutor,
     StringBuilder buf,
     HashSet<ParameterInfoImpl> newParams,
     PsiParameter[] parameters,
     List<ParameterInfoImpl> result) {
   // find which parameters to introduce and where
   Set<String> existingNames = new HashSet<String>();
   for (PsiParameter parameter : parameters) {
     existingNames.add(parameter.getName());
   }
   int ei = 0;
   int pi = 0;
   PsiParameter varargParam = targetMethod.isVarArgs() ? parameters[parameters.length - 1] : null;
   while (ei < expressions.length || pi < parameters.length) {
     if (buf.length() > 0) buf.append(", ");
     PsiExpression expression = ei < expressions.length ? expressions[ei] : null;
     PsiParameter parameter = pi < parameters.length ? parameters[pi] : null;
     PsiType paramType = parameter == null ? null : substitutor.substitute(parameter.getType());
     boolean parameterAssignable =
         paramType != null
             && (expression == null
                 || TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression));
     if (parameterAssignable) {
       final PsiType type = parameter.getType();
       result.add(new ParameterInfoImpl(pi, parameter.getName(), type));
       buf.append(escapePresentableType(type));
       pi++;
       ei++;
     } else if (isArgumentInVarargPosition(expressions, ei, varargParam, substitutor)) {
       if (pi == parameters.length - 1) {
         assert varargParam != null;
         final PsiType type = varargParam.getType();
         result.add(new ParameterInfoImpl(pi, varargParam.getName(), type));
         buf.append(escapePresentableType(type));
       }
       pi++;
       ei++;
     } else if (expression != null) {
       if (varargParam != null && pi >= parameters.length) return false;
       if (PsiPolyExpressionUtil.isPolyExpression(expression)) return false;
       PsiType exprType = RefactoringUtil.getTypeByExpression(expression);
       if (exprType == null) return false;
       if (exprType instanceof PsiDisjunctionType) {
         exprType = ((PsiDisjunctionType) exprType).getLeastUpperBound();
       }
       JavaCodeStyleManager codeStyleManager =
           JavaCodeStyleManager.getInstance(expression.getProject());
       String name =
           suggestUniqueParameterName(codeStyleManager, expression, exprType, existingNames);
       final ParameterInfoImpl newParameterInfo =
           new ParameterInfoImpl(-1, name, exprType, expression.getText().replace('\n', ' '));
       result.add(newParameterInfo);
       newParams.add(newParameterInfo);
       buf.append("<b>").append(escapePresentableType(exprType)).append("</b>");
       ei++;
     }
   }
   if (result.size() != expressions.length && varargParam == null) return false;
   return true;
 }
  public static void visitRefInDocTag(
      final PsiDocTag tag,
      final JavadocManager manager,
      final PsiElement context,
      final ArrayList<ProblemDescriptor> problems,
      final InspectionManager inspectionManager,
      final boolean onTheFly) {
    final String tagName = tag.getName();
    final PsiDocTagValue value = tag.getValueElement();
    if (value == null) return;
    final JavadocTagInfo info = manager.getTagInfo(tagName);
    if (info != null && !info.isValidInContext(context)) return;
    final String message = info == null || !info.isInline() ? null : info.checkTagValue(value);
    if (message != null) {
      problems.add(createDescriptor(value, message, inspectionManager, onTheFly));
    }

    final PsiReference reference = value.getReference();
    if (reference == null) return;
    final PsiElement element = reference.resolve();
    if (element != null) return;
    final int textOffset = value.getTextOffset();
    if (textOffset == value.getTextRange().getEndOffset()) return;
    final PsiDocTagValue valueElement = tag.getValueElement();
    if (valueElement == null) return;

    final CharSequence paramName =
        value
            .getContainingFile()
            .getViewProvider()
            .getContents()
            .subSequence(textOffset, value.getTextRange().getEndOffset());
    final String params = "<code>" + paramName + "</code>";
    final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
    if (onTheFly && "param".equals(tagName)) {
      final PsiDocCommentOwner commentOwner =
          PsiTreeUtil.getParentOfType(tag, PsiDocCommentOwner.class);
      if (commentOwner instanceof PsiMethod) {
        final PsiMethod method = (PsiMethod) commentOwner;
        final PsiParameter[] parameters = method.getParameterList().getParameters();
        final PsiDocTag[] tags = tag.getContainingComment().getTags();
        final Set<String> unboundParams = new HashSet<String>();
        for (PsiParameter parameter : parameters) {
          if (!JavaDocLocalInspection.isFound(tags, parameter)) {
            unboundParams.add(parameter.getName());
          }
        }
        if (!unboundParams.isEmpty()) {
          fixes.add(new RenameReferenceQuickFix(unboundParams));
        }
      }
    }
    fixes.add(new RemoveTagFix(tagName, paramName));

    problems.add(
        inspectionManager.createProblemDescriptor(
            valueElement,
            reference.getRangeInElement(),
            cannotResolveSymbolMessage(params),
            ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
            onTheFly,
            fixes.toArray(new LocalQuickFix[fixes.size()])));
  }
  private ParameterInfoImpl[] getNewParametersInfo(
      PsiExpression[] expressions,
      PsiMethod targetMethod,
      PsiSubstitutor substitutor,
      final StringBuilder buf,
      final HashSet<ParameterInfoImpl> newParams,
      final HashSet<ParameterInfoImpl> removedParams,
      final HashSet<ParameterInfoImpl> changedParams) {
    PsiParameter[] parameters = targetMethod.getParameterList().getParameters();
    List<ParameterInfoImpl> result = new ArrayList<ParameterInfoImpl>();
    if (expressions.length < parameters.length) {
      // find which parameters to remove
      int ei = 0;
      int pi = 0;

      while (ei < expressions.length && pi < parameters.length) {
        PsiExpression expression = expressions[ei];
        PsiParameter parameter = parameters[pi];
        PsiType paramType = substitutor.substitute(parameter.getType());
        if (buf.length() > 0) buf.append(", ");
        final PsiType parameterType = PsiUtil.convertAnonymousToBaseType(paramType);
        final String presentableText = escapePresentableType(parameterType);
        final ParameterInfoImpl parameterInfo =
            new ParameterInfoImpl(pi, parameter.getName(), parameter.getType());
        if (TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression)) {
          buf.append(presentableText);
          result.add(parameterInfo);
          pi++;
          ei++;
        } else {
          buf.append("<s>").append(presentableText).append("</s>");
          removedParams.add(parameterInfo);
          pi++;
        }
      }
      if (result.size() != expressions.length) return null;
      for (int i = pi; i < parameters.length; i++) {
        if (buf.length() > 0) buf.append(", ");
        buf.append("<s>").append(escapePresentableType(parameters[i].getType())).append("</s>");
        final ParameterInfoImpl parameterInfo =
            new ParameterInfoImpl(pi, parameters[i].getName(), parameters[i].getType());
        removedParams.add(parameterInfo);
      }
    } else if (expressions.length > parameters.length) {
      if (!findNewParamsPlace(
          expressions, targetMethod, substitutor, buf, newParams, parameters, result)) return null;
    } else {
      // parameter type changed
      for (int i = 0; i < parameters.length; i++) {
        if (buf.length() > 0) buf.append(", ");
        PsiParameter parameter = parameters[i];
        PsiExpression expression = expressions[i];
        PsiType paramType = substitutor.substitute(parameter.getType());
        final String presentableText = escapePresentableType(paramType);
        if (TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression)) {
          result.add(new ParameterInfoImpl(i, parameter.getName(), paramType));
          buf.append(presentableText);
        } else {
          if (PsiPolyExpressionUtil.isPolyExpression(expression)) return null;
          PsiType exprType = RefactoringUtil.getTypeByExpression(expression);
          if (exprType == null) return null;
          if (exprType instanceof PsiDisjunctionType) {
            exprType = ((PsiDisjunctionType) exprType).getLeastUpperBound();
          }
          final ParameterInfoImpl changedParameterInfo =
              new ParameterInfoImpl(i, parameter.getName(), exprType);
          result.add(changedParameterInfo);
          changedParams.add(changedParameterInfo);
          buf.append("<s>")
              .append(presentableText)
              .append("</s> <b>")
              .append(escapePresentableType(exprType))
              .append("</b>");
        }
      }
      // do not perform silly refactorings
      boolean isSilly = true;
      for (int i = 0; i < result.size(); i++) {
        PsiParameter parameter = parameters[i];
        PsiType paramType = substitutor.substitute(parameter.getType());
        ParameterInfoImpl parameterInfo = result.get(i);
        String typeText = parameterInfo.getTypeText();
        if (!paramType.equalsToText(typeText) && !paramType.getPresentableText().equals(typeText)) {
          isSilly = false;
          break;
        }
      }
      if (isSilly) return null;
    }
    return result.toArray(new ParameterInfoImpl[result.size()]);
  }
  private static void findParameterUsages(
      final PsiParameter parameter, final List<UsageInfo> usages) {
    final PsiMethod method = (PsiMethod) parameter.getDeclarationScope();
    final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
    // search for refs to current method only, do not search for refs to overriding methods, they'll
    // be searched separately
    ReferencesSearch.search(method)
        .forEach(
            reference -> {
              PsiElement element = reference.getElement();
              if (element != null) {
                final JavaSafeDeleteDelegate safeDeleteDelegate =
                    JavaSafeDeleteDelegate.EP.forLanguage(element.getLanguage());
                if (safeDeleteDelegate != null) {
                  safeDeleteDelegate.createUsageInfoForParameter(
                      reference, usages, parameter, method);
                }
                if (!parameter.isVarArgs()
                    && !RefactoringChangeUtil.isSuperMethodCall(element.getParent())) {
                  final PsiParameter paramInCaller =
                      SafeDeleteJavaCallerChooser.isTheOnlyOneParameterUsage(
                          element.getParent(), parameterIndex, method);
                  if (paramInCaller != null) {
                    final PsiMethod callerMethod = (PsiMethod) paramInCaller.getDeclarationScope();
                    if (ApplicationManager.getApplication().isUnitTestMode()) {
                      usages.add(
                          new SafeDeleteParameterCallHierarchyUsageInfo(
                              callerMethod, paramInCaller, callerMethod));
                    } else {
                      usages.add(
                          new SafeDeleteParameterCallHierarchyUsageInfo(
                              method, parameter, callerMethod));
                    }
                  }
                }
              }
              return true;
            });

    ReferencesSearch.search(parameter)
        .forEach(
            reference -> {
              PsiElement element = reference.getElement();
              final PsiDocTag docTag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);
              if (docTag != null) {
                usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(docTag, parameter, true));
                return true;
              }

              boolean isSafeDelete = false;
              if (element.getParent().getParent() instanceof PsiMethodCallExpression) {
                PsiMethodCallExpression call =
                    (PsiMethodCallExpression) element.getParent().getParent();
                PsiReferenceExpression methodExpression = call.getMethodExpression();
                if (methodExpression.getText().equals(PsiKeyword.SUPER)) {
                  isSafeDelete = true;
                } else if (methodExpression.getQualifierExpression()
                    instanceof PsiSuperExpression) {
                  final PsiMethod superMethod = call.resolveMethod();
                  if (superMethod != null
                      && MethodSignatureUtil.isSuperMethod(superMethod, method)) {
                    isSafeDelete = true;
                  }
                }
              }

              usages.add(
                  new SafeDeleteReferenceJavaDeleteUsageInfo(element, parameter, isSafeDelete));
              return true;
            });

    findFunctionalExpressions(usages, method);
  }
  private static void processPrimaryMethod(
      JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal)
      throws IncorrectOperationException {
    PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();

    if (changeInfo.isVisibilityChanged()) {
      PsiModifierList modifierList = method.getModifierList();
      final String highestVisibility =
          isOriginal
              ? changeInfo.getNewVisibility()
              : VisibilityUtil.getHighestVisibility(
                  changeInfo.getNewVisibility(),
                  VisibilityUtil.getVisibilityModifier(modifierList));
      VisibilityUtil.setVisibility(modifierList, highestVisibility);
    }

    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());

      if (newName != null && !newName.equals(method.getName())) {
        final PsiIdentifier nameId = method.getNameIdentifier();
        assert nameId != null;
        nameId.replace(
            JavaPsiFacade.getInstance(method.getProject())
                .getElementFactory()
                .createIdentifier(newName));
      }
    }

    final PsiSubstitutor substitutor =
        baseMethod == null
            ? PsiSubstitutor.EMPTY
            : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod);

    if (changeInfo.isReturnTypeChanged()) {
      PsiType newTypeElement =
          changeInfo
              .getNewReturnType()
              .getType(changeInfo.getMethod().getParameterList(), method.getManager());
      final PsiType returnType = substitutor.substitute(newTypeElement);
      // don't modify return type for non-Java overriders (EJB)
      if (method.getName().equals(changeInfo.getNewName())) {
        final PsiTypeElement typeElement = method.getReturnTypeElement();
        if (typeElement != null) {
          typeElement.replace(factory.createTypeElement(returnType));
        }
      }
    }

    PsiParameterList list = method.getParameterList();
    PsiParameter[] parameters = list.getParameters();

    final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
    final int delta =
        baseMethod != null
            ? baseMethod.getParameterList().getParametersCount()
                - method.getParameterList().getParametersCount()
            : 0;
    PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)];
    final String[] oldParameterNames = changeInfo.getOldParameterNames();
    final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
    for (int i = 0; i < newParms.length; i++) {
      JavaParameterInfo info = parameterInfos[i];
      int index = info.getOldIndex();
      if (index >= 0) {
        PsiParameter parameter = parameters[index];
        newParms[i] = parameter;

        String oldName = oldParameterNames[index];
        if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) {
          PsiIdentifier newIdentifier = factory.createIdentifier(info.getName());
          parameter.getNameIdentifier().replace(newIdentifier);
        }

        String oldType = oldParameterTypes[index];
        if (!oldType.equals(info.getTypeText())) {
          parameter.normalizeDeclaration();
          PsiType newType =
              substitutor.substitute(
                  info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));

          parameter.getTypeElement().replace(factory.createTypeElement(newType));
        }
      } else {
        newParms[i] = createNewParameter(changeInfo, info, substitutor);
      }
    }

    resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
    fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
      fixPrimaryThrowsLists(method, newExceptions);
    }
  }