protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    checkExistingMethods(conflicts, true);
    checkExistingMethods(conflicts, false);
    final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll();
    for (FieldDescriptor fieldDescriptor : myFieldDescriptors) {
      final Set<PsiMethod> setters = new HashSet<PsiMethod>();
      final Set<PsiMethod> getters = new HashSet<PsiMethod>();

      for (PsiClass aClass : classes) {
        final PsiMethod getterOverrider =
            myDescriptor.isToEncapsulateGet()
                ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false)
                : null;
        if (getterOverrider != null) {
          getters.add(getterOverrider);
        }
        final PsiMethod setterOverrider =
            myDescriptor.isToEncapsulateSet()
                ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false)
                : null;
        if (setterOverrider != null) {
          setters.add(setterOverrider);
        }
      }
      if (!getters.isEmpty() || !setters.isEmpty()) {
        final PsiField field = fieldDescriptor.getField();
        for (PsiReference reference : ReferencesSearch.search(field)) {
          final PsiElement place = reference.getElement();
          if (place instanceof PsiReferenceExpression) {
            final PsiExpression qualifierExpression =
                ((PsiReferenceExpression) place).getQualifierExpression();
            final PsiClass ancestor;
            if (qualifierExpression == null) {
              ancestor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
            } else {
              ancestor = PsiUtil.resolveClassInType(qualifierExpression.getType());
            }

            final boolean isGetter = !PsiUtil.isAccessedForWriting((PsiExpression) place);
            for (PsiMethod overridden : isGetter ? getters : setters) {
              if (InheritanceUtil.isInheritorOrSelf(myClass, ancestor, true)) {
                conflicts.putValue(
                    overridden,
                    "There is already a "
                        + RefactoringUIUtil.getDescription(overridden, true)
                        + " which would hide generated "
                        + (isGetter ? "getter" : "setter")
                        + " for "
                        + place.getText());
                break;
              }
            }
          }
        }
      }
    }
    return showConflicts(conflicts, refUsages.get());
  }
 private static String createInitializerReplacementText(
     PsiType varType, PsiExpression initializer) {
   final PsiType initializerType = initializer.getType();
   final PsiClassType rawType =
       initializerType instanceof PsiClassType
           ? ((PsiClassType) initializerType).rawType()
           : null;
   final PsiClassType rawVarType =
       varType instanceof PsiClassType ? ((PsiClassType) varType).rawType() : null;
   if (rawType != null
       && rawVarType != null
       && rawType.equalsToText(CommonClassNames.JAVA_UTIL_ARRAY_LIST)
       && rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_LIST)) {
     return "toList()";
   } else if (rawType != null
       && rawVarType != null
       && rawType.equalsToText(CommonClassNames.JAVA_UTIL_HASH_SET)
       && rawVarType.equalsToText(CommonClassNames.JAVA_UTIL_SET)) {
     return "toSet()";
   } else if (rawType != null) {
     return "toCollection(" + rawType.getClassName() + "::new)";
   } else {
     return "toCollection(() -> " + initializer.getText() + ")";
   }
 }
Ejemplo n.º 3
0
 public static boolean isValidPropertyReference(
     @NotNull Project project,
     @NotNull PsiLiteralExpression expression,
     @NotNull String key,
     @NotNull Ref<String> outResourceBundle) {
   final HashMap<String, Object> annotationAttributeValues = new HashMap<String, Object>();
   annotationAttributeValues.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null);
   if (mustBePropertyKey(project, expression, annotationAttributeValues)) {
     final Object resourceBundleName =
         annotationAttributeValues.get(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER);
     if (!(resourceBundleName instanceof PsiExpression)) {
       return false;
     }
     PsiExpression expr = (PsiExpression) resourceBundleName;
     final Object value =
         JavaPsiFacade.getInstance(expr.getProject())
             .getConstantEvaluationHelper()
             .computeConstantExpression(expr);
     if (value == null) {
       return false;
     }
     String bundleName = value.toString();
     outResourceBundle.set(bundleName);
     return isPropertyRef(expression, key, bundleName);
   }
   return true;
 }
Ejemplo n.º 4
0
 private static boolean checkRawAcceptable(
     PsiLambdaExpression expression, PsiType functionalInterfaceType) {
   PsiElement parent = expression.getParent();
   while (parent instanceof PsiParenthesizedExpression) {
     parent = parent.getParent();
   }
   if (parent instanceof PsiExpressionList) {
     final PsiElement gParent = parent.getParent();
     if (gParent instanceof PsiMethodCallExpression) {
       final PsiExpression qualifierExpression =
           ((PsiMethodCallExpression) gParent).getMethodExpression().getQualifierExpression();
       final PsiType type = qualifierExpression != null ? qualifierExpression.getType() : null;
       if (type instanceof PsiClassType && ((PsiClassType) type).isRaw()) {
         return true;
       }
       final PsiMethod method = ((PsiMethodCallExpression) gParent).resolveMethod();
       if (method != null) {
         int lambdaIdx = getLambdaIdx((PsiExpressionList) parent, expression);
         final PsiParameter[] parameters = method.getParameterList().getParameters();
         final PsiType normalizedType =
             getNormalizedType(parameters[adjustLambdaIdx(lambdaIdx, method, parameters)]);
         if (normalizedType instanceof PsiClassType && ((PsiClassType) normalizedType).isRaw())
           return true;
       }
     }
     if (functionalInterfaceType instanceof PsiClassType
         && ((PsiClassType) functionalInterfaceType).isRaw()) {
       return false;
     }
   }
   return true;
 }
  private static boolean isCollectCall(PsiStatement body, final PsiParameter parameter) {
    PsiIfStatement ifStatement = extractIfStatement(body);
    final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement);
    if (methodCallExpression != null) {
      final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
      final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
      PsiClass qualifierClass = null;
      if (qualifierExpression instanceof PsiReferenceExpression) {
        if (ReferencesSearch.search(parameter, new LocalSearchScope(qualifierExpression))
                .findFirst()
            != null) {
          return false;
        }
        final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve();
        if (resolve instanceof PsiVariable) {
          if (ReferencesSearch.search(
                      resolve, new LocalSearchScope(methodCallExpression.getArgumentList()))
                  .findFirst()
              != null) {
            return false;
          }
        }
        qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
      } else if (qualifierExpression == null) {
        final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class);
        if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) {
          qualifierClass = enclosingClass;
        }
      }

      if (qualifierClass != null
          && InheritanceUtil.isInheritor(
              qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) {

        while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) {
          final PsiExpression condition = ifStatement.getCondition();
          if (condition != null
              && isConditionDependsOnUpdatedCollections(condition, qualifierExpression))
            return false;
          ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class);
        }

        final PsiElement resolve = methodExpression.resolve();
        if (resolve instanceof PsiMethod
            && "add".equals(((PsiMethod) resolve).getName())
            && ((PsiMethod) resolve).getParameterList().getParametersCount() == 1) {
          final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
          if (args.length == 1) {
            if (args[0] instanceof PsiCallExpression) {
              final PsiMethod method = ((PsiCallExpression) args[0]).resolveMethod();
              return method != null && !method.hasTypeParameters() && !isThrowsCompatible(method);
            }
            return true;
          }
        }
      }
    }
    return false;
  }
 private static String getIteratedValueText(PsiExpression iteratedValue) {
   return iteratedValue instanceof PsiCallExpression
           || iteratedValue instanceof PsiReferenceExpression
           || iteratedValue instanceof PsiQualifiedExpression
           || iteratedValue instanceof PsiParenthesizedExpression
       ? iteratedValue.getText()
       : "(" + iteratedValue.getText() + ")";
 }
Ejemplo n.º 7
0
  @Nullable
  private String[] suggestVariableNameFromLiterals(
      PsiExpression expr, VariableKind variableKind, boolean correctKeywords) {
    final PsiElement[] literals =
        PsiTreeUtil.collectElements(
            expr,
            new PsiElementFilter() {
              @Override
              public boolean isAccepted(PsiElement element) {
                if (isStringPsiLiteral(element)
                    && StringUtil.isJavaIdentifier(StringUtil.unquoteString(element.getText()))) {
                  final PsiElement exprList = element.getParent();
                  if (exprList instanceof PsiExpressionList) {
                    final PsiElement call = exprList.getParent();
                    if (call instanceof PsiNewExpression) {
                      return true;
                    } else if (call instanceof PsiMethodCallExpression) {
                      // TODO: exclude or not getA().getB("name").getC(); or
                      // getA(getB("name").getC()); It works fine for now in the most cases
                      return true;
                    }
                  }
                }
                return false;
              }
            });

    if (literals.length == 1) {
      final String text = StringUtil.unquoteString(literals[0].getText());
      return getSuggestionsByName(
          text, variableKind, expr.getType() instanceof PsiArrayType, correctKeywords);
    }
    return null;
  }
 private static String compoundLambdaOrMethodReference(
     PsiParameter parameter,
     PsiExpression expression,
     String samQualifiedName,
     PsiType[] samParamTypes) {
   String result = "";
   final Project project = parameter.getProject();
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass functionClass =
       psiFacade.findClass(samQualifiedName, GlobalSearchScope.allScope(project));
   for (int i = 0; i < samParamTypes.length; i++) {
     if (samParamTypes[i] instanceof PsiPrimitiveType) {
       samParamTypes[i] = ((PsiPrimitiveType) samParamTypes[i]).getBoxedType(expression);
     }
   }
   final PsiClassType functionalInterfaceType =
       functionClass != null
           ? psiFacade.getElementFactory().createType(functionClass, samParamTypes)
           : null;
   final PsiParameter[] parameters = {parameter};
   final String methodReferenceText =
       LambdaCanBeMethodReferenceInspection.convertToMethodReference(
           expression, parameters, functionalInterfaceType, null);
   if (methodReferenceText != null) {
     LOG.assertTrue(functionalInterfaceType != null);
     result += "(" + functionalInterfaceType.getCanonicalText() + ")" + methodReferenceText;
   } else {
     result += parameter.getName() + " -> " + expression.getText();
   }
   return result;
 }
Ejemplo n.º 9
0
  private NamesByExprInfo suggestVariableNameByExpression(
      PsiExpression expr, VariableKind variableKind, boolean correctKeywords) {

    final LinkedHashSet<String> names = new LinkedHashSet<String>();
    final String[] fromLiterals =
        suggestVariableNameFromLiterals(expr, variableKind, correctKeywords);
    if (fromLiterals != null) {
      ContainerUtil.addAll(names, fromLiterals);
    }

    ContainerUtil.addAll(
        names,
        suggestVariableNameByExpressionOnly(expr, variableKind, correctKeywords, false).names);
    ContainerUtil.addAll(
        names, suggestVariableNameByExpressionPlace(expr, variableKind, correctKeywords).names);

    PsiType type = expr.getType();
    if (type != null) {
      ContainerUtil.addAll(names, suggestVariableNameByType(type, variableKind, correctKeywords));
    }
    ContainerUtil.addAll(
        names,
        suggestVariableNameByExpressionOnly(expr, variableKind, correctKeywords, true).names);

    String[] namesArray = ArrayUtil.toStringArray(names);
    String propertyName =
        suggestVariableNameByExpressionOnly(expr, variableKind, correctKeywords, false).propertyName
                != null
            ? suggestVariableNameByExpressionOnly(expr, variableKind, correctKeywords, false)
                .propertyName
            : suggestVariableNameByExpressionPlace(expr, variableKind, correctKeywords)
                .propertyName;
    return new NamesByExprInfo(propertyName, namesArray);
  }
  private static boolean isGoodExpression(
      PsiExpression expression,
      @NotNull AllowedValues allowedValues,
      @NotNull PsiElement scope,
      @NotNull PsiManager manager) {
    expression = PsiUtil.deparenthesizeExpression(expression);
    if (expression == null) return true;
    if (expression instanceof PsiConditionalExpression) {
      PsiExpression thenExpression = ((PsiConditionalExpression) expression).getThenExpression();
      boolean thenAllowed =
          thenExpression == null || isAllowed(scope, thenExpression, allowedValues, manager);
      if (!thenAllowed) return false;
      PsiExpression elseExpression = ((PsiConditionalExpression) expression).getElseExpression();
      return elseExpression == null || isAllowed(scope, elseExpression, allowedValues, manager);
    }

    if (isOneOf(expression, allowedValues, manager)) return true;

    if (allowedValues.canBeOred) {
      PsiExpression zero = getLiteralExpression(expression, manager, "0");
      if (same(expression, zero, manager)) return true;
      PsiExpression mOne = getLiteralExpression(expression, manager, "-1");
      if (same(expression, mOne, manager)) return true;
      if (expression instanceof PsiPolyadicExpression) {
        IElementType tokenType = ((PsiPolyadicExpression) expression).getOperationTokenType();
        if (JavaTokenType.OR.equals(tokenType) || JavaTokenType.AND.equals(tokenType)) {
          for (PsiExpression operand : ((PsiPolyadicExpression) expression).getOperands()) {
            if (!isAllowed(scope, operand, allowedValues, manager)) return false;
          }
          return true;
        }
      }
      if (expression instanceof PsiPrefixExpression
          && JavaTokenType.TILDE.equals(
              ((PsiPrefixExpression) expression).getOperationTokenType())) {
        PsiExpression operand = ((PsiPrefixExpression) expression).getOperand();
        return operand == null || isAllowed(scope, operand, allowedValues, manager);
      }
    }

    PsiElement resolved = null;
    if (expression instanceof PsiReference) {
      resolved = ((PsiReference) expression).resolve();
    } else if (expression instanceof PsiCallExpression) {
      resolved = ((PsiCallExpression) expression).resolveMethod();
    }

    AllowedValues allowedForRef;
    if (resolved instanceof PsiModifierListOwner
        && (allowedForRef =
                getAllowedValues(
                    (PsiModifierListOwner) resolved,
                    getType((PsiModifierListOwner) resolved),
                    null))
            != null
        && allowedForRef.isSubsetOf(allowedValues, manager)) return true;

    return PsiType.NULL.equals(expression.getType());
  }
Ejemplo n.º 11
0
  @Override
  public SuggestedNameInfo suggestVariableName(
      @NotNull final VariableKind kind,
      @Nullable final String propertyName,
      @Nullable final PsiExpression expr,
      @Nullable PsiType type,
      final boolean correctKeywords) {
    LinkedHashSet<String> names = new LinkedHashSet<String>();

    if (expr != null && type == null) {
      type = expr.getType();
    }

    if (propertyName != null) {
      String[] namesByName = getSuggestionsByName(propertyName, kind, false, correctKeywords);
      sortVariableNameSuggestions(namesByName, kind, propertyName, null);
      ContainerUtil.addAll(names, namesByName);
    }

    final NamesByExprInfo namesByExpr;
    if (expr != null) {
      namesByExpr = suggestVariableNameByExpression(expr, kind, correctKeywords);
      if (namesByExpr.propertyName != null) {
        sortVariableNameSuggestions(namesByExpr.names, kind, namesByExpr.propertyName, null);
      }
      ContainerUtil.addAll(names, namesByExpr.names);
    } else {
      namesByExpr = null;
    }

    if (type != null) {
      String[] namesByType = suggestVariableNameByType(type, kind, correctKeywords);
      sortVariableNameSuggestions(namesByType, kind, null, type);
      ContainerUtil.addAll(names, namesByType);
    }

    final String _propertyName;
    if (propertyName != null) {
      _propertyName = propertyName;
    } else {
      _propertyName = namesByExpr != null ? namesByExpr.propertyName : null;
    }

    addNamesFromStatistics(names, kind, _propertyName, type);

    String[] namesArray = ArrayUtil.toStringArray(names);
    sortVariableNameSuggestions(namesArray, kind, _propertyName, type);

    final PsiType _type = type;
    return new SuggestedNameInfo(namesArray) {
      @Override
      public void nameChosen(String name) {
        if (_propertyName != null || _type != null && _type.isValid()) {
          JavaStatisticsManager.incVariableNameUseCount(name, kind, _propertyName, _type);
        }
      }
    };
  }
 private static void checkExpression(
     PsiExpression expression, PsiModifierListOwner owner, PsiType type, ProblemsHolder holder) {
   AllowedValues allowed = getAllowedValues(owner, type, null);
   if (allowed == null) return;
   PsiElement scope = PsiUtil.getTopLevelEnclosingCodeBlock(expression, null);
   if (scope == null) scope = expression;
   if (!isAllowed(scope, expression, allowed, expression.getManager())) {
     registerProblem(expression, allowed, holder);
   }
 }
Ejemplo n.º 13
0
  public static Set<String> suggestExpressionOfType(
      final PsiClassType type, final PsiLiteralExpression context) {
    PsiVariable[] variables = MacroUtil.getVariablesVisibleAt(context, "");
    Set<String> result = new LinkedHashSet<String>();
    for (PsiVariable var : variables) {
      PsiType varType = var.getType();
      if (type == null || type.isAssignableFrom(varType)) {
        result.add(var.getNameIdentifier().getText());
      }
    }

    PsiExpression[] expressions = MacroUtil.getStandardExpressionsOfType(context, type);
    for (PsiExpression expression : expressions) {
      result.add(expression.getText());
    }
    if (type != null) {
      addAvailableMethodsOfType(type, context, result);
    }
    return result;
  }
Ejemplo n.º 14
0
 @NotNull
 private static PsiExpression getTopLevel(Project project, @NotNull PsiExpression expression) {
   int i = 0;
   while (expression.getParent() instanceof PsiExpression) {
     i++;
     final PsiExpression parent = (PsiExpression) expression.getParent();
     if (parent instanceof PsiConditionalExpression
         && ((PsiConditionalExpression) parent).getCondition() == expression) break;
     expression = parent;
     if (expression instanceof PsiAssignmentExpression) break;
     if (i > 10 && expression instanceof PsiBinaryExpression) {
       ParameterizedCachedValue<PsiExpression, Pair<Project, PsiExpression>> value =
           expression.getUserData(TOP_LEVEL_EXPRESSION);
       if (value != null && value.hasUpToDateValue()) {
         return getToplevelExpression(
             project, expression); // optimization: use caching for big hierarchies
       }
     }
   }
   return expression;
 }
  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 PsiType getQualifierCastType(
     PsiJavaReference javaReference, CompletionParameters parameters) {
   if (javaReference instanceof PsiReferenceExpression) {
     final PsiReferenceExpression refExpr = (PsiReferenceExpression) javaReference;
     final PsiExpression qualifier = refExpr.getQualifierExpression();
     if (qualifier != null) {
       final Project project = qualifier.getProject();
       PsiType type = null;
       final PairFunction<PsiExpression, CompletionParameters, PsiType> evaluator =
           refExpr.getContainingFile().getCopyableUserData(DYNAMIC_TYPE_EVALUATOR);
       if (evaluator != null) {
         type = evaluator.fun(qualifier, parameters);
       }
       if (type == null) {
         type = GuessManager.getInstance(project).getControlFlowExpressionType(qualifier);
       }
       return type;
     }
   }
   return null;
 }
Ejemplo n.º 17
0
 @Override
 public CachedValueProvider.Result<PsiExpression> compute(
     Pair<Project, PsiExpression> pair) {
   PsiExpression param = pair.second;
   Project project = pair.first;
   PsiExpression topLevel = getTopLevel(project, param);
   ParameterizedCachedValue<PsiExpression, Pair<Project, PsiExpression>> cachedValue =
       param.getUserData(TOP_LEVEL_EXPRESSION);
   assert cachedValue != null;
   int i = 0;
   for (PsiElement element = param;
       element != topLevel;
       element = element.getParent(), i++) {
     if (i % 10
         == 0) { // optimization: store up link to the top level expression in each 10nth
                 // element
       element.putUserData(TOP_LEVEL_EXPRESSION, cachedValue);
     }
   }
   return CachedValueProvider.Result.create(
       topLevel, PsiManager.getInstance(project).getModificationTracker());
 }
  private void checkForSuperCall(PsiMethod method) {
    if (isConstructor()) {
      PsiCodeBlock body = method.getBody();
      if (body == null) return;
      PsiStatement[] statements = body.getStatements();
      boolean isBaseExplicitlyCalled = false;
      if (statements.length > 0) {
        PsiStatement first = statements[0];
        if (first instanceof PsiExpressionStatement) {
          PsiExpression firstExpression = ((PsiExpressionStatement) first).getExpression();
          if (firstExpression instanceof PsiMethodCallExpression) {
            PsiExpression qualifierExpression =
                ((PsiMethodCallExpression) firstExpression)
                    .getMethodExpression()
                    .getQualifierExpression();
            if (qualifierExpression instanceof PsiReferenceExpression) {
              @NonNls String text = qualifierExpression.getText();
              if ("super".equals(text) || text.equals("this")) {
                isBaseExplicitlyCalled = true;
              }
            }
          }
        }
      }

      if (!isBaseExplicitlyCalled) {
        for (RefClass superClass : getOwnerClass().getBaseClasses()) {
          RefMethodImpl superDefaultConstructor =
              (RefMethodImpl) superClass.getDefaultConstructor();

          if (superDefaultConstructor != null) {
            superDefaultConstructor.addInReference(this);
            addOutReference(superDefaultConstructor);
          }
        }
      }
    }
  }
Ejemplo n.º 19
0
 @NotNull
 public static PsiExpression getToplevelExpression(
     @NotNull final Project project, @NotNull final PsiExpression expression) {
   if (expression instanceof PsiBinaryExpression
       || expression.getParent() instanceof PsiBinaryExpression) { // can be large, cache
     return CachedValuesManager.getManager(project)
         .getParameterizedCachedValue(
             expression,
             TOP_LEVEL_EXPRESSION,
             TOP_LEVEL_PROVIDER,
             true,
             Pair.create(project, expression));
   }
   return getTopLevel(project, expression);
 }
 private static String createMapperFunctionalExpressionText(
     PsiParameter parameter, PsiExpression expression) {
   String iteration = "";
   if (!isIdentityMapping(parameter, expression)) {
     iteration += ".map(";
     iteration +=
         compoundLambdaOrMethodReference(
             parameter,
             expression,
             "java.util.function.Function",
             new PsiType[] {parameter.getType(), expression.getType()});
     iteration += ")";
   }
   return iteration;
 }
 @NotNull
 public static QualifierResolveResult getQualifierResolveResult(
     @NotNull PsiMethodReferenceExpression methodReferenceExpression) {
   PsiClass containingClass = null;
   PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
   final PsiExpression expression = methodReferenceExpression.getQualifierExpression();
   if (expression != null) {
     final PsiType expressionType = getExpandedType(expression.getType(), expression);
     PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType);
     containingClass = result.getElement();
     if (containingClass != null) {
       substitutor = result.getSubstitutor();
     }
     if (containingClass == null && expression instanceof PsiReferenceExpression) {
       final JavaResolveResult resolveResult =
           ((PsiReferenceExpression) expression).advancedResolve(false);
       final PsiElement resolve = resolveResult.getElement();
       if (resolve instanceof PsiClass) {
         containingClass = (PsiClass) resolve;
         substitutor = resolveResult.getSubstitutor();
         return new QualifierResolveResult(containingClass, substitutor, true);
       }
     }
   } else {
     final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType();
     if (typeElement != null) {
       PsiType type = getExpandedType(typeElement.getType(), typeElement);
       PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type);
       containingClass = result.getElement();
       if (containingClass != null) {
         return new QualifierResolveResult(containingClass, result.getSubstitutor(), true);
       }
     }
   }
   return new QualifierResolveResult(containingClass, substitutor, false);
 }
  private static boolean isConditionDependsOnUpdatedCollections(
      PsiExpression condition, PsiExpression qualifierExpression) {
    final PsiElement collection =
        qualifierExpression instanceof PsiReferenceExpression
            ? ((PsiReferenceExpression) qualifierExpression).resolve()
            : null;
    if (collection != null) {
      return ReferencesSearch.search(collection, new LocalSearchScope(condition)).findFirst()
          != null;
    }

    final boolean[] dependsOnCollection = {false};
    condition.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitMethodCallExpression(PsiMethodCallExpression expression) {
            super.visitMethodCallExpression(expression);
            final PsiExpression callQualifier =
                expression.getMethodExpression().getQualifierExpression();
            if (callQualifier == null
                || callQualifier instanceof PsiThisExpression
                    && ((PsiThisExpression) callQualifier).getQualifier() == null
                || callQualifier instanceof PsiSuperExpression
                    && ((PsiSuperExpression) callQualifier).getQualifier() == null) {
              dependsOnCollection[0] = true;
            }
          }

          @Override
          public void visitThisExpression(PsiThisExpression expression) {
            super.visitThisExpression(expression);
            if (expression.getQualifier() == null
                && expression.getParent() instanceof PsiExpressionList) {
              dependsOnCollection[0] = true;
            }
          }

          @Override
          public void visitClass(PsiClass aClass) {}

          @Override
          public void visitLambdaExpression(PsiLambdaExpression expression) {}
        });

    return dependsOnCollection[0];
  }
Ejemplo n.º 23
0
  public static boolean isPassedToAnnotatedParam(
      @NotNull Project project,
      @NotNull PsiExpression expression,
      final String annFqn,
      @Nullable Map<String, Object> annotationAttributeValues,
      @Nullable final Set<PsiModifierListOwner> nonNlsTargets) {
    expression = getToplevelExpression(project, expression);
    final PsiElement parent = expression.getParent();

    if (!(parent instanceof PsiExpressionList)) return false;
    int idx = -1;
    final PsiExpression[] args = ((PsiExpressionList) parent).getExpressions();
    for (int i = 0; i < args.length; i++) {
      PsiExpression arg = args[i];
      if (PsiTreeUtil.isAncestor(arg, expression, false)) {
        idx = i;
        break;
      }
    }
    if (idx == -1) return false;

    PsiElement grParent = parent.getParent();

    if (grParent instanceof PsiAnonymousClass) {
      grParent = grParent.getParent();
    }

    if (grParent instanceof PsiCall) {
      PsiMethod method = ((PsiCall) grParent).resolveMethod();
      if (method != null
          && isMethodParameterAnnotatedWith(
              method, idx, null, annFqn, annotationAttributeValues, nonNlsTargets)) {
        return true;
      }
    }

    return false;
  }
  private static boolean processValuesFlownTo(
      @NotNull final PsiExpression argument,
      PsiElement scope,
      @NotNull final Processor<PsiExpression> processor) {
    SliceAnalysisParams params = new SliceAnalysisParams();
    params.dataFlowToThis = true;
    params.scope = new AnalysisScope(new LocalSearchScope(scope), argument.getProject());

    SliceRootNode rootNode =
        new SliceRootNode(
            scope.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params));

    Collection<? extends AbstractTreeNode> children =
        rootNode.getChildren().iterator().next().getChildren();
    for (AbstractTreeNode child : children) {
      SliceUsage usage = (SliceUsage) child.getValue();
      PsiElement element = usage.getElement();
      if (element instanceof PsiExpression && !processor.process((PsiExpression) element))
        return false;
    }

    return !children.isEmpty();
  }
  protected void checkSameSignatures(@NotNull List<CandidateInfo> conflicts) {
    // candidates should go in order of class hierarchy traversal
    // in order for this to work
    Map<MethodSignature, CandidateInfo> signatures =
        new THashMap<MethodSignature, CandidateInfo>(conflicts.size());
    Set<PsiMethod> superMethods = new HashSet<PsiMethod>();
    for (CandidateInfo conflict : conflicts) {
      final PsiMethod method = ((MethodCandidateInfo) conflict).getElement();
      for (HierarchicalMethodSignature methodSignature :
          method.getHierarchicalMethodSignature().getSuperSignatures()) {
        final PsiMethod superMethod = methodSignature.getMethod();
        final PsiClass aClass = superMethod.getContainingClass();
        if (aClass != null
            && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) {
          superMethods.add(superMethod);
        }
      }
    }
    nextConflict:
    for (int i = 0; i < conflicts.size(); i++) {
      ProgressManager.checkCanceled();
      CandidateInfo info = conflicts.get(i);
      PsiMethod method = (PsiMethod) info.getElement();

      if (!method.hasModifierProperty(PsiModifier.STATIC) && superMethods.contains(method)) {
        conflicts.remove(i);
        i--;
        continue;
      }

      PsiClass class1 = method.getContainingClass();
      PsiSubstitutor infoSubstitutor = ((MethodCandidateInfo) info).getSubstitutor(false);
      MethodSignature signature = method.getSignature(infoSubstitutor);
      CandidateInfo existing = signatures.get(signature);

      if (existing == null) {
        signatures.put(signature, info);
        continue;
      }
      PsiMethod existingMethod = (PsiMethod) existing.getElement();
      PsiClass existingClass = existingMethod.getContainingClass();
      if (class1 != null
          && existingClass != null) { // prefer interface methods to methods from Object
        if (class1.isInterface()
            && CommonClassNames.JAVA_LANG_OBJECT.equals(existingClass.getQualifiedName())) {
          signatures.put(signature, info);
          continue;
        } else if (existingClass.isInterface()
            && CommonClassNames.JAVA_LANG_OBJECT.equals(class1.getQualifiedName())) {
          conflicts.remove(info);
          i--;
          continue;
        }
      }
      if (method == existingMethod) {
        PsiElement scope1 = info.getCurrentFileResolveScope();
        PsiElement scope2 = existing.getCurrentFileResolveScope();
        if (scope1 instanceof PsiClass
            && scope2 instanceof PsiClass
            && PsiTreeUtil.isAncestor(scope1, scope2, true)
            && !existing
                .isAccessible()) { // prefer methods from outer class to inaccessible base class
                                   // methods
          signatures.put(signature, info);
          continue;
        }
      }

      // filter out methods with incorrect inferred bounds (for unrelated methods only)
      boolean existingTypeParamAgree = areTypeParametersAgree(existing);
      boolean infoTypeParamAgree = areTypeParametersAgree(info);
      if (existingTypeParamAgree
          && !infoTypeParamAgree
          && !PsiSuperMethodImplUtil.isSuperMethodSmart(method, existingMethod)) {
        conflicts.remove(i);
        i--;
        continue;
      }
      if (!existingTypeParamAgree
          && infoTypeParamAgree
          && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
        signatures.put(signature, info);
        int index = conflicts.indexOf(existing);
        conflicts.remove(index);
        i--;
        continue;
      }

      if (InheritanceUtil.isInheritorOrSelf(class1, existingClass, true)
          || InheritanceUtil.isInheritorOrSelf(existingClass, class1, true)) {
        PsiParameter[] parameters = method.getParameterList().getParameters();
        final PsiParameter[] existingParameters = existingMethod.getParameterList().getParameters();
        for (int i1 = 0, parametersLength = parameters.length; i1 < parametersLength; i1++) {
          if (parameters[i1].getType() instanceof PsiArrayType
              && !(existingParameters[i1].getType()
                  instanceof PsiArrayType)) { // prefer more specific type
            signatures.put(signature, info);
            continue nextConflict;
          }
        }
        PsiType returnType1 = method.getReturnType();
        PsiType returnType2 = existingMethod.getReturnType();
        if (returnType1 != null && returnType2 != null) {
          returnType1 = infoSubstitutor.substitute(returnType1);
          returnType2 =
              ((MethodCandidateInfo) existing).getSubstitutor(false).substitute(returnType2);
          if (!returnType1.equals(returnType2) && returnType1.isAssignableFrom(returnType2)) {
            conflicts.remove(i);
            i--;
            continue;
          }
        }

        // prefer derived class
        signatures.put(signature, info);
      } else {
        final PsiMethodCallExpression methodCallExpression =
            PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class);
        if (methodCallExpression != null) {
          final PsiReferenceExpression expression = methodCallExpression.getMethodExpression();
          final PsiExpression qualifierExpression = expression.getQualifierExpression();
          PsiClass currentClass;
          if (qualifierExpression != null) {
            currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
          } else {
            currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
          }

          if (currentClass != null && existingClass != null && class1 != null) {
            final PsiSubstitutor eSubstitutor =
                TypeConversionUtil.getMaybeSuperClassSubstitutor(
                    existingClass, currentClass, PsiSubstitutor.EMPTY, null);
            final PsiSubstitutor cSubstitutor =
                TypeConversionUtil.getMaybeSuperClassSubstitutor(
                    class1, currentClass, PsiSubstitutor.EMPTY, null);
            if (eSubstitutor != null
                && cSubstitutor != null
                && MethodSignatureUtil.areSignaturesEqual(
                    existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) {
              final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType());
              final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType());
              if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) {
                if (TypeConversionUtil.isAssignable(returnType, returnType1, false)) {
                  if (class1.isInterface() && !existingClass.isInterface()) continue;
                  conflicts.remove(existing);
                } else {
                  if (!TypeConversionUtil.isAssignable(returnType1, returnType, false)) continue;
                  conflicts.remove(i);
                }
                i--;
                break;
              }
            }
          }
        }
      }
    }
  }
    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiForeachStatement foreachStatement =
          PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class);
      if (foreachStatement != null) {
        if (!FileModificationService.getInstance().preparePsiElementForWrite(foreachStatement))
          return;
        final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
        PsiStatement body = foreachStatement.getBody();
        final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
        if (body != null && iteratedValue != null) {
          final PsiParameter parameter = foreachStatement.getIterationParameter();
          final PsiIfStatement ifStatement = extractIfStatement(body);
          final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement);

          if (methodCallExpression == null) return;

          if (isAddAllCall(foreachStatement, body)) {
            restoreComments(foreachStatement, body);
            final PsiExpression qualifierExpression =
                methodCallExpression.getMethodExpression().getQualifierExpression();
            final String qualifierText =
                qualifierExpression != null ? qualifierExpression.getText() : "";
            final String callText =
                StringUtil.getQualifiedName(
                    qualifierText, "addAll(" + getIteratedValueText(iteratedValue) + ");");
            PsiElement result =
                foreachStatement.replace(
                    elementFactory.createStatementFromText(callText, foreachStatement));
            reformatWhenNeeded(project, result);
            return;
          }
          final StringBuilder builder =
              new StringBuilder(getIteratedValueText(iteratedValue) + ".stream()");

          builder.append(createFiltersChainText(body, parameter, ifStatement));
          builder.append(
              createMapperFunctionalExpressionText(
                  parameter, methodCallExpression.getArgumentList().getExpressions()[0]));

          builder.append(".collect(java.util.stream.Collectors.");
          PsiElement result = null;
          try {
            final PsiExpression qualifierExpression =
                methodCallExpression.getMethodExpression().getQualifierExpression();
            if (qualifierExpression instanceof PsiReferenceExpression) {
              final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve();
              if (resolve instanceof PsiVariable) {
                if (resolve instanceof PsiLocalVariable
                    && foreachStatement.equals(
                        PsiTreeUtil.skipSiblingsForward(
                            resolve.getParent(), PsiWhiteSpace.class))) {
                  final PsiExpression initializer = ((PsiVariable) resolve).getInitializer();
                  if (initializer instanceof PsiNewExpression) {
                    final PsiExpressionList argumentList =
                        ((PsiNewExpression) initializer).getArgumentList();
                    if (argumentList != null && argumentList.getExpressions().length == 0) {
                      restoreComments(foreachStatement, body);
                      final String callText =
                          builder.toString()
                              + createInitializerReplacementText(
                                  ((PsiVariable) resolve).getType(), initializer)
                              + ")";
                      result =
                          initializer.replace(
                              elementFactory.createExpressionFromText(callText, null));
                      simplifyRedundantCast(result);
                      foreachStatement.delete();
                      return;
                    }
                  }
                }
              }
            }
            restoreComments(foreachStatement, body);
            final String qualifierText =
                qualifierExpression != null ? qualifierExpression.getText() : "";
            final String callText =
                StringUtil.getQualifiedName(
                    qualifierText, "addAll(" + builder.toString() + "toList()));");
            result =
                foreachStatement.replace(
                    elementFactory.createStatementFromText(callText, foreachStatement));
            simplifyRedundantCast(result);
          } finally {
            reformatWhenNeeded(project, result);
          }
        }
      }
    }
Ejemplo n.º 27
0
  private NamesByExprInfo suggestVariableNameByExpressionOnly(
      PsiExpression expr,
      final VariableKind variableKind,
      boolean correctKeywords,
      boolean useAllMethodNames) {
    if (expr instanceof PsiMethodCallExpression) {
      PsiReferenceExpression methodExpr = ((PsiMethodCallExpression) expr).getMethodExpression();
      String methodName = methodExpr.getReferenceName();
      if (methodName != null) {
        if ("of".equals(methodName) || "ofNullable".equals(methodName)) {
          if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) {
            PsiExpression[] expressions =
                ((PsiMethodCallExpression) expr).getArgumentList().getExpressions();
            if (expressions.length > 0) {
              return suggestVariableNameByExpressionOnly(
                  expressions[0], variableKind, correctKeywords, useAllMethodNames);
            }
          }
        }
        if ("map".equals(methodName)
            || "flatMap".equals(methodName)
            || "filter".equals(methodName)) {
          if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) {
            return new NamesByExprInfo(null);
          }
        }

        String[] words = NameUtil.nameToWords(methodName);
        if (words.length > 0) {
          final String firstWord = words[0];
          if (GET_PREFIX.equals(firstWord)
              || IS_PREFIX.equals(firstWord)
              || FIND_PREFIX.equals(firstWord)
              || CREATE_PREFIX.equals(firstWord)) {
            if (words.length > 1) {
              final String propertyName = methodName.substring(firstWord.length());
              String[] names =
                  getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
              final PsiExpression qualifierExpression = methodExpr.getQualifierExpression();
              if (qualifierExpression instanceof PsiReferenceExpression
                  && ((PsiReferenceExpression) qualifierExpression).resolve()
                      instanceof PsiVariable) {
                names =
                    ArrayUtil.append(
                        names,
                        StringUtil.sanitizeJavaIdentifier(
                            changeIfNotIdentifier(
                                qualifierExpression.getText()
                                    + StringUtil.capitalize(propertyName))));
              }
              return new NamesByExprInfo(propertyName, names);
            }
          } else if (words.length == 1 || useAllMethodNames) {
            return new NamesByExprInfo(
                methodName, getSuggestionsByName(methodName, variableKind, false, correctKeywords));
          }
        }
      }
    } else if (expr instanceof PsiReferenceExpression) {
      String propertyName = ((PsiReferenceExpression) expr).getReferenceName();
      PsiElement refElement = ((PsiReferenceExpression) expr).resolve();
      if (refElement instanceof PsiVariable) {
        VariableKind refVariableKind = getVariableKind((PsiVariable) refElement);
        propertyName = variableNameToPropertyName(propertyName, refVariableKind);
      }
      if (refElement != null && propertyName != null) {
        String[] names = getSuggestionsByName(propertyName, variableKind, false, correctKeywords);
        return new NamesByExprInfo(propertyName, names);
      }
    } else if (expr instanceof PsiArrayAccessExpression) {
      PsiExpression arrayExpr = ((PsiArrayAccessExpression) expr).getArrayExpression();
      if (arrayExpr instanceof PsiReferenceExpression) {
        String arrayName = ((PsiReferenceExpression) arrayExpr).getReferenceName();
        PsiElement refElement = ((PsiReferenceExpression) arrayExpr).resolve();
        if (refElement instanceof PsiVariable) {
          VariableKind refVariableKind = getVariableKind((PsiVariable) refElement);
          arrayName = variableNameToPropertyName(arrayName, refVariableKind);
        }

        if (arrayName != null) {
          String name = StringUtil.unpluralize(arrayName);
          if (name != null) {
            String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords);
            return new NamesByExprInfo(name, names);
          }
        }
      }
    } else if (expr instanceof PsiLiteralExpression
        && variableKind == VariableKind.STATIC_FINAL_FIELD) {
      final PsiLiteralExpression literalExpression = (PsiLiteralExpression) expr;
      final Object value = literalExpression.getValue();
      if (value instanceof String) {
        final String stringValue = (String) value;
        String[] names = getSuggestionsByValue(stringValue);
        if (names.length > 0) {
          return new NamesByExprInfo(null, constantValueToConstantName(names));
        }
      }
    } else if (expr instanceof PsiParenthesizedExpression) {
      return suggestVariableNameByExpressionOnly(
          ((PsiParenthesizedExpression) expr).getExpression(),
          variableKind,
          correctKeywords,
          useAllMethodNames);
    } else if (expr instanceof PsiTypeCastExpression) {
      return suggestVariableNameByExpressionOnly(
          ((PsiTypeCastExpression) expr).getOperand(),
          variableKind,
          correctKeywords,
          useAllMethodNames);
    } else if (expr instanceof PsiLiteralExpression) {
      final String text = StringUtil.stripQuotesAroundValue(expr.getText());
      if (isIdentifier(text)) {
        return new NamesByExprInfo(
            text, getSuggestionsByName(text, variableKind, false, correctKeywords));
      }
    }

    return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY);
  }
  @Nullable
  public static String getSuspiciousMethodCallMessage(
      @NotNull PsiMethodCallExpression methodCall,
      PsiType argType,
      boolean reportConvertibleMethodCalls,
      @NotNull List<PsiMethod> patternMethods,
      @NotNull IntArrayList indices) {
    final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
    final PsiExpression qualifier = methodExpression.getQualifierExpression();
    if (qualifier == null
        || qualifier instanceof PsiThisExpression
        || qualifier instanceof PsiSuperExpression) return null;
    if (argType instanceof PsiPrimitiveType) {
      argType = ((PsiPrimitiveType) argType).getBoxedType(methodCall);
    }

    if (!(argType instanceof PsiClassType)) return null;

    final JavaResolveResult resolveResult = methodExpression.advancedResolve(false);
    PsiMethod calleeMethod = (PsiMethod) resolveResult.getElement();
    if (calleeMethod == null) return null;
    PsiMethod contextMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class);

    //noinspection SynchronizationOnLocalVariableOrMethodParameter
    synchronized (patternMethods) {
      if (patternMethods.isEmpty()) {
        setupPatternMethods(
            methodCall.getManager(), methodCall.getResolveScope(), patternMethods, indices);
      }
    }

    for (int i = 0; i < patternMethods.size(); i++) {
      PsiMethod patternMethod = patternMethods.get(i);
      if (!patternMethod.getName().equals(methodExpression.getReferenceName())) continue;
      int index = indices.get(i);

      // we are in collections method implementation
      if (contextMethod != null && isInheritorOrSelf(contextMethod, patternMethod)) return null;

      final PsiClass calleeClass = calleeMethod.getContainingClass();
      PsiSubstitutor substitutor = resolveResult.getSubstitutor();
      final PsiClass patternClass = patternMethod.getContainingClass();
      assert patternClass != null;
      assert calleeClass != null;
      substitutor = TypeConversionUtil.getClassSubstitutor(patternClass, calleeClass, substitutor);
      if (substitutor == null) continue;

      if (!patternMethod
          .getSignature(substitutor)
          .equals(calleeMethod.getSignature(PsiSubstitutor.EMPTY))) continue;

      PsiTypeParameter[] typeParameters = patternClass.getTypeParameters();
      if (typeParameters.length <= index) return null;
      final PsiTypeParameter typeParameter = typeParameters[index];
      PsiType typeParamMapping = substitutor.substitute(typeParameter);
      if (typeParamMapping == null) return null;

      PsiParameter[] parameters = patternMethod.getParameterList().getParameters();
      if (parameters.length == 1 && "removeAll".equals(patternMethod.getName())) {
        PsiType paramType = parameters[0].getType();
        if (InheritanceUtil.isInheritor(paramType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
          PsiType qualifierType = qualifier.getType();
          if (qualifierType != null) {
            final PsiType itemType =
                JavaGenericsUtil.getCollectionItemType(argType, calleeMethod.getResolveScope());
            final PsiType qualifierItemType =
                JavaGenericsUtil.getCollectionItemType(
                    qualifierType, calleeMethod.getResolveScope());
            if (qualifierItemType != null
                && itemType != null
                && !qualifierItemType.isAssignableFrom(itemType)) {
              return InspectionsBundle.message(
                  "inspection.suspicious.collections.method.calls.problem.descriptor",
                  PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
                  PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
            }
          }
          return null;
        }
      }

      String message = null;
      if (typeParamMapping instanceof PsiCapturedWildcardType) {
        typeParamMapping = ((PsiCapturedWildcardType) typeParamMapping).getWildcard();
      }
      if (!typeParamMapping.isAssignableFrom(argType)) {
        if (typeParamMapping.isConvertibleFrom(argType)) {
          if (reportConvertibleMethodCalls) {
            message =
                InspectionsBundle.message(
                    "inspection.suspicious.collections.method.calls.problem.descriptor1",
                    PsiFormatUtil.formatMethod(
                        calleeMethod,
                        substitutor,
                        PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_CONTAINING_CLASS,
                        PsiFormatUtilBase.SHOW_TYPE));
          }
        } else {
          PsiType qualifierType = qualifier.getType();
          if (qualifierType != null) {
            message =
                InspectionsBundle.message(
                    "inspection.suspicious.collections.method.calls.problem.descriptor",
                    PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
                    PsiFormatUtil.formatType(argType, 0, PsiSubstitutor.EMPTY));
          }
        }
      }
      return message;
    }
    return null;
  }
Ejemplo n.º 29
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);
  }
  private void checkExistingMethods(MultiMap<PsiElement, String> conflicts, boolean isGetter) {
    if (isGetter) {
      if (!myDescriptor.isToEncapsulateGet()) return;
    } else {
      if (!myDescriptor.isToEncapsulateSet()) return;
    }

    for (FieldDescriptor descriptor : myFieldDescriptors) {
      PsiMethod prototype =
          isGetter ? descriptor.getGetterPrototype() : descriptor.getSetterPrototype();

      final PsiType prototypeReturnType = prototype.getReturnType();
      PsiMethod existing = myClass.findMethodBySignature(prototype, true);
      if (existing != null) {
        final PsiType returnType = existing.getReturnType();
        if (!RefactoringUtil.equivalentTypes(
            prototypeReturnType, returnType, myClass.getManager())) {
          final String descr =
              PsiFormatUtil.formatMethod(
                  existing,
                  PsiSubstitutor.EMPTY,
                  PsiFormatUtilBase.SHOW_NAME
                      | PsiFormatUtilBase.SHOW_PARAMETERS
                      | PsiFormatUtilBase.SHOW_TYPE,
                  PsiFormatUtilBase.SHOW_TYPE);
          String message =
              isGetter
                  ? RefactoringBundle.message(
                      "encapsulate.fields.getter.exists",
                      CommonRefactoringUtil.htmlEmphasize(descr),
                      CommonRefactoringUtil.htmlEmphasize(prototype.getName()))
                  : RefactoringBundle.message(
                      "encapsulate.fields.setter.exists",
                      CommonRefactoringUtil.htmlEmphasize(descr),
                      CommonRefactoringUtil.htmlEmphasize(prototype.getName()));
          conflicts.putValue(existing, message);
        }
      } else {
        PsiClass containingClass = myClass.getContainingClass();
        while (containingClass != null && existing == null) {
          existing = containingClass.findMethodBySignature(prototype, true);
          if (existing != null) {
            for (PsiReference reference : ReferencesSearch.search(existing)) {
              final PsiElement place = reference.getElement();
              LOG.assertTrue(place instanceof PsiReferenceExpression);
              final PsiExpression qualifierExpression =
                  ((PsiReferenceExpression) place).getQualifierExpression();
              final PsiClass inheritor;
              if (qualifierExpression == null) {
                inheritor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
              } else {
                inheritor = PsiUtil.resolveClassInType(qualifierExpression.getType());
              }

              if (InheritanceUtil.isInheritorOrSelf(inheritor, myClass, true)) {
                conflicts.putValue(
                    existing,
                    "There is already a "
                        + RefactoringUIUtil.getDescription(existing, true)
                        + " which would be hidden by generated "
                        + (isGetter ? "getter" : "setter"));
                break;
              }
            }
          }
          containingClass = containingClass.getContainingClass();
        }
      }
    }
  }