Пример #1
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;
  }
Пример #2
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;
  }
Пример #3
0
 public static int getLambdaIdx(PsiExpressionList expressionList, final PsiElement element) {
   PsiExpression[] expressions = expressionList.getExpressions();
   for (int i = 0; i < expressions.length; i++) {
     PsiExpression expression = expressions[i];
     if (PsiTreeUtil.isAncestor(expression, element, false)) {
       return i;
     }
   }
   return -1;
 }
 @Nullable
 private static InferenceSession startTopLevelInference(
     final PsiCall topLevelCall, final ParameterTypeInferencePolicy policy) {
   final JavaResolveResult result = topLevelCall.resolveMethodGenerics();
   if (result instanceof MethodCandidateInfo) {
     final PsiMethod method = ((MethodCandidateInfo) result).getElement();
     final PsiParameter[] topLevelParameters = method.getParameterList().getParameters();
     final PsiExpressionList topLevelCallArgumentList = topLevelCall.getArgumentList();
     LOG.assertTrue(topLevelCallArgumentList != null, topLevelCall);
     final PsiExpression[] topLevelArguments = topLevelCallArgumentList.getExpressions();
     return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(
         topLevelCall,
         true,
         new Computable<InferenceSession>() {
           @Override
           public InferenceSession compute() {
             final InferenceSession topLevelSession =
                 new InferenceSession(
                     method.getTypeParameters(),
                     ((MethodCandidateInfo) result).getSiteSubstitutor(),
                     topLevelCall.getManager(),
                     topLevelCall,
                     policy);
             topLevelSession.initExpressionConstraints(
                 topLevelParameters,
                 topLevelArguments,
                 topLevelCall,
                 method,
                 ((MethodCandidateInfo) result).isVarargs());
             topLevelSession.infer(
                 topLevelParameters,
                 topLevelArguments,
                 topLevelCall,
                 ((MethodCandidateInfo) result).createProperties());
             return topLevelSession;
           }
         });
   }
   return null;
 }
Пример #5
0
  private NamesByExprInfo suggestVariableNameByExpressionPlace(
      PsiExpression expr, final VariableKind variableKind, boolean correctKeywords) {
    if (expr.getParent() instanceof PsiExpressionList) {
      PsiExpressionList list = (PsiExpressionList) expr.getParent();
      PsiElement listParent = list.getParent();
      PsiSubstitutor subst = PsiSubstitutor.EMPTY;
      PsiMethod method = null;
      if (listParent instanceof PsiMethodCallExpression) {
        final JavaResolveResult resolveResult =
            ((PsiMethodCallExpression) listParent).getMethodExpression().advancedResolve(false);
        method = (PsiMethod) resolveResult.getElement();
        subst = resolveResult.getSubstitutor();
      } else {
        if (listParent instanceof PsiAnonymousClass) {
          listParent = listParent.getParent();
        }
        if (listParent instanceof PsiNewExpression) {
          method = ((PsiNewExpression) listParent).resolveConstructor();
        }
      }

      if (method != null) {
        final PsiElement navElement = method.getNavigationElement();
        if (navElement instanceof PsiMethod) {
          method = (PsiMethod) navElement;
        }
        PsiExpression[] expressions = list.getExpressions();
        int index = -1;
        for (int i = 0; i < expressions.length; i++) {
          if (expressions[i] == expr) {
            index = i;
            break;
          }
        }
        PsiParameter[] parameters = method.getParameterList().getParameters();
        if (index < parameters.length) {
          String name = parameters[index].getName();
          if (name != null
              && TypeConversionUtil.areTypesAssignmentCompatible(
                  subst.substitute(parameters[index].getType()), expr)) {
            name = variableNameToPropertyName(name, VariableKind.PARAMETER);
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            if (expressions.length == 1) {
              final String methodName = method.getName();
              String[] words = NameUtil.nameToWords(methodName);
              if (words.length > 0) {
                final String firstWord = words[0];
                if (SET_PREFIX.equals(firstWord)) {
                  final String propertyName = methodName.substring(firstWord.length());
                  final String[] setterNames =
                      getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
                  names = ArrayUtil.mergeArrays(names, setterNames);
                }
              }
            }
            return new NamesByExprInfo(name, names);
          }
        }
      }
    } else if (expr.getParent() instanceof PsiAssignmentExpression
        && variableKind == VariableKind.PARAMETER) {
      final PsiAssignmentExpression assignmentExpression =
          (PsiAssignmentExpression) expr.getParent();
      if (expr == assignmentExpression.getRExpression()) {
        final PsiExpression leftExpression = assignmentExpression.getLExpression();
        if (leftExpression instanceof PsiReferenceExpression
            && ((PsiReferenceExpression) leftExpression).getQualifier() == null) {
          String name = leftExpression.getText();
          if (name != null) {
            final PsiElement resolve = ((PsiReferenceExpression) leftExpression).resolve();
            if (resolve instanceof PsiVariable) {
              name = variableNameToPropertyName(name, getVariableKind((PsiVariable) resolve));
            }
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            return new NamesByExprInfo(name, names);
          }
        }
      }
    }

    return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY);
  }
  // This methods works equally well for primary usages as well as for propagated callers' usages
  private static void fixActualArgumentsList(
      PsiExpressionList list,
      JavaChangeInfo changeInfo,
      boolean toInsertDefaultValue,
      PsiSubstitutor substitutor)
      throws IncorrectOperationException {
    final PsiElementFactory factory =
        JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
    if (changeInfo.isParameterSetOrOrderChanged()) {
      if (changeInfo instanceof JavaChangeInfoImpl
          && ((JavaChangeInfoImpl) changeInfo).isPropagationEnabled) {
        final ParameterInfoImpl[] createdParmsInfo =
            ((JavaChangeInfoImpl) changeInfo).getCreatedParmsInfoWithoutVarargs();
        for (ParameterInfoImpl info : createdParmsInfo) {
          PsiExpression newArg;
          if (toInsertDefaultValue) {
            newArg = createDefaultValue(changeInfo, factory, info, list);
          } else {
            newArg = factory.createExpressionFromText(info.getName(), list);
          }
          JavaCodeStyleManager.getInstance(list.getProject())
              .shortenClassReferences(list.add(newArg));
        }
      } else {
        final PsiExpression[] args = list.getExpressions();
        final int nonVarargCount = getNonVarargCount(changeInfo, args);
        final int varargCount = args.length - nonVarargCount;
        if (varargCount < 0) return;
        PsiExpression[] newVarargInitializers = null;

        final int newArgsLength;
        final int newNonVarargCount;
        final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
        if (changeInfo.isArrayToVarargs()) {
          newNonVarargCount = newParms.length - 1;
          final JavaParameterInfo lastNewParm = newParms[newParms.length - 1];
          final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()];
          if (arrayToConvert instanceof PsiNewExpression) {
            final PsiNewExpression expression = (PsiNewExpression) arrayToConvert;
            final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
            if (arrayInitializer != null) {
              newVarargInitializers = arrayInitializer.getInitializers();
            }
          }
          newArgsLength =
              newVarargInitializers == null
                  ? newParms.length
                  : newNonVarargCount + newVarargInitializers.length;
        } else if (changeInfo.isRetainsVarargs()) {
          newNonVarargCount = newParms.length - 1;
          newArgsLength = newNonVarargCount + varargCount;
        } else if (changeInfo.isObtainsVarags()) {
          newNonVarargCount = newParms.length - 1;
          newArgsLength = newNonVarargCount;
        } else {
          newNonVarargCount = newParms.length;
          newArgsLength = newParms.length;
        }

        String[] oldVarargs = null;
        if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) {
          oldVarargs = new String[varargCount];
          for (int i = nonVarargCount; i < args.length; i++) {
            oldVarargs[i - nonVarargCount] = args[i].getText();
          }
        }

        final PsiExpression[] newArgs = new PsiExpression[newArgsLength];
        for (int i = 0; i < newNonVarargCount; i++) {
          if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) {
            PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager());
            if (type instanceof PsiArrayType) {
              type = substitutor.substitute(type);
              type = TypeConversionUtil.erasure(type);
              String typeText = type.getCanonicalText();
              if (type instanceof PsiEllipsisType) {
                typeText = typeText.replace("...", "[]");
              }
              String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}";
              newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod());
              continue;
            }
          }
          newArgs[i] =
              createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
        }
        if (changeInfo.isArrayToVarargs()) {
          if (newVarargInitializers == null) {
            newArgs[newNonVarargCount] =
                createActualArgument(
                    changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
          } else {
            System.arraycopy(
                newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
          }
        } else {
          final int newVarargCount = newArgsLength - newNonVarargCount;
          LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount);
          for (int i = newNonVarargCount; i < newArgsLength; i++) {
            final int oldIndex = newParms[newNonVarargCount].getOldIndex();
            if (oldIndex >= 0 && oldIndex != nonVarargCount) {
              newArgs[i] =
                  createActualArgument(
                      changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
            } else {
              System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount);
              break;
            }
          }
        }
        ChangeSignatureUtil.synchronizeList(
            list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm());
      }
    }
  }
 public List<PsiExpression> getChildren(PsiExpressionList psiExpressionList) {
   return Arrays.asList(psiExpressionList.getExpressions());
 }
  private void addTypesByVariable(
      HashSet<PsiType> typesSet,
      PsiVariable var,
      PsiFile scopeFile,
      HashSet<PsiVariable> checkedVariables,
      int flags,
      TextRange rangeToIgnore) {
    if (!checkedVariables.add(var)) return;
    // System.out.println("analyzing usages of " + var + " in file " + scopeFile);
    SearchScope searchScope = new LocalSearchScope(scopeFile);

    if (BitUtil.isSet(flags, CHECK_USAGE) || BitUtil.isSet(flags, CHECK_DOWN)) {
      for (PsiReference varRef : ReferencesSearch.search(var, searchScope, false)) {
        PsiElement ref = varRef.getElement();

        if (BitUtil.isSet(flags, CHECK_USAGE)) {
          PsiType type = guessElementTypeFromReference(myMethodPatternMap, ref, rangeToIgnore);
          if (type != null && !(type instanceof PsiPrimitiveType)) {
            typesSet.add(type);
          }
        }

        if (BitUtil.isSet(flags, CHECK_DOWN)) {
          if (ref.getParent() instanceof PsiExpressionList
              && ref.getParent().getParent() instanceof PsiMethodCallExpression) { // TODO : new
            PsiExpressionList list = (PsiExpressionList) ref.getParent();
            PsiExpression[] args = list.getExpressions();
            int argIndex = -1;
            for (int j = 0; j < args.length; j++) {
              PsiExpression arg = args[j];
              if (arg.equals(ref)) {
                argIndex = j;
                break;
              }
            }

            PsiMethodCallExpression methodCall = (PsiMethodCallExpression) list.getParent();
            PsiMethod method = (PsiMethod) methodCall.getMethodExpression().resolve();
            if (method != null) {
              PsiParameter[] parameters = method.getParameterList().getParameters();
              if (argIndex < parameters.length) {
                addTypesByVariable(
                    typesSet,
                    parameters[argIndex],
                    method.getContainingFile(),
                    checkedVariables,
                    flags | CHECK_USAGE,
                    rangeToIgnore);
              }
            }
          }
        }
      }
    }

    if (BitUtil.isSet(flags, CHECK_UP)) {
      if (var instanceof PsiParameter
          && var.getParent() instanceof PsiParameterList
          && var.getParent().getParent() instanceof PsiMethod) {
        PsiParameterList list = (PsiParameterList) var.getParent();
        PsiParameter[] parameters = list.getParameters();
        int argIndex = -1;
        for (int i = 0; i < parameters.length; i++) {
          PsiParameter parameter = parameters[i];
          if (parameter.equals(var)) {
            argIndex = i;
            break;
          }
        }

        PsiMethod method = (PsiMethod) var.getParent().getParent();
        // System.out.println("analyzing usages of " + method + " in file " + scopeFile);
        for (PsiReference methodRef : ReferencesSearch.search(method, searchScope, false)) {
          PsiElement ref = methodRef.getElement();
          if (ref.getParent() instanceof PsiMethodCallExpression) {
            PsiMethodCallExpression methodCall = (PsiMethodCallExpression) ref.getParent();
            PsiExpression[] args = methodCall.getArgumentList().getExpressions();
            if (args.length <= argIndex) continue;
            PsiExpression arg = args[argIndex];
            if (arg instanceof PsiReferenceExpression) {
              PsiElement refElement = ((PsiReferenceExpression) arg).resolve();
              if (refElement instanceof PsiVariable) {
                addTypesByVariable(
                    typesSet,
                    (PsiVariable) refElement,
                    scopeFile,
                    checkedVariables,
                    flags | CHECK_USAGE,
                    rangeToIgnore);
              }
            }
            // TODO : constructor
          }
        }
      }
    }
  }