@Nullable
 private static PsiType guessElementTypeFromReference(
     MethodPatternMap methodPatternMap, PsiElement ref, TextRange rangeToIgnore) {
   PsiElement refParent = ref.getParent();
   if (refParent instanceof PsiReferenceExpression) {
     PsiReferenceExpression parentExpr = (PsiReferenceExpression) refParent;
     if (ref.equals(parentExpr.getQualifierExpression())
         && parentExpr.getParent() instanceof PsiMethodCallExpression) {
       String methodName = parentExpr.getReferenceName();
       PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parentExpr.getParent();
       PsiExpression[] args = methodCall.getArgumentList().getExpressions();
       MethodPattern pattern = methodPatternMap.findPattern(methodName, args.length);
       if (pattern != null) {
         if (pattern.parameterIndex < 0) { // return value
           if (methodCall.getParent() instanceof PsiTypeCastExpression
               && (rangeToIgnore == null || !rangeToIgnore.contains(methodCall.getTextRange()))) {
             return ((PsiTypeCastExpression) methodCall.getParent()).getType();
           }
         } else {
           return args[pattern.parameterIndex].getType();
         }
       }
     }
   }
   return null;
 }
Пример #2
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 void processCallArgument(
     PsiMethodCallExpression expression,
     Map<String, Computable<String>> argumentMap,
     List<String> result,
     final int index) {
   final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
   if (arguments.length > index) {
     String testDataFile = evaluate(arguments[index], argumentMap);
     if (testDataFile != null) {
       result.add(myTestDataPath + testDataFile);
     }
   }
 }
  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 PsiMethodCallExpression methodCall =
              ((MethodCallUsageInfo) usageInfo).getMethodCallExpression();
          final PsiExpression[] expressions = 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);
            }
          }
        }
      }
    }

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

    return showConflicts(conflicts, usages);
  }
 @Nullable
 private String evaluate(PsiExpression expression, Map<String, Computable<String>> arguments) {
   if (expression instanceof PsiPolyadicExpression) {
     PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression) expression;
     if (binaryExpression.getOperationTokenType() == JavaTokenType.PLUS) {
       String r = "";
       for (PsiExpression op : binaryExpression.getOperands()) {
         String lhs = evaluate(op, arguments);
         if (lhs == null) return null;
         r += lhs;
       }
       return r;
     }
   } else if (expression instanceof PsiLiteralExpression) {
     final Object value = ((PsiLiteralExpression) expression).getValue();
     if (value instanceof String) {
       return (String) value;
     }
   } else if (expression instanceof PsiReferenceExpression) {
     final PsiElement result = ((PsiReferenceExpression) expression).resolve();
     if (result instanceof PsiParameter) {
       final String name = ((PsiParameter) result).getName();
       final Computable<String> arg = arguments.get(name);
       return arg == null ? null : arg.compute();
     }
     if (result instanceof PsiVariable) {
       final PsiExpression initializer = ((PsiVariable) result).getInitializer();
       if (initializer != null) {
         return evaluate(initializer, arguments);
       }
     }
   } else if (expression instanceof PsiMethodCallExpression) {
     final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
     final String callText = methodCall.getMethodExpression().getText();
     if (callText.equals("getTestName")) {
       final PsiExpression[] psiExpressions = methodCall.getArgumentList().getExpressions();
       if (psiExpressions.length == 1) {
         if ("true".equals(psiExpressions[0].getText()) && !StringUtil.isEmpty(myTestName)) {
           return UsefulTestCase.lowercaseFirstLetter(myTestName, true);
         }
         return myTestName;
       }
     }
   }
   if (expression != null) {
     myLogMessages.add("Failed to evaluate " + expression.getText());
   }
   return null;
 }
 private Map<String, Computable<String>> buildArgumentMap(
     PsiMethodCallExpression expression, PsiMethod method) {
   Map<String, Computable<String>> result = new HashMap<String, Computable<String>>();
   final PsiParameter[] parameters = method.getParameterList().getParameters();
   final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
   for (int i = 0; i < arguments.length && i < parameters.length; i++) {
     final int finalI = i;
     result.put(
         parameters[i].getName(),
         new NullableComputable<String>() {
           public String compute() {
             return evaluate(
                 arguments[finalI], Collections.<String, Computable<String>>emptyMap());
           }
         });
   }
   return result;
 }
 private void addExprTypesWhenContainerElement(LinkedHashSet<PsiType> set, PsiExpression expr) {
   if (expr instanceof PsiMethodCallExpression) {
     PsiMethodCallExpression callExpr = (PsiMethodCallExpression) expr;
     PsiReferenceExpression methodExpr = callExpr.getMethodExpression();
     String methodName = methodExpr.getReferenceName();
     MethodPattern pattern =
         myMethodPatternMap.findPattern(
             methodName, callExpr.getArgumentList().getExpressions().length);
     if (pattern != null && pattern.parameterIndex < 0 /* return value */) {
       PsiExpression qualifier = methodExpr.getQualifierExpression();
       if (qualifier != null) {
         PsiType[] types = guessContainerElementType(qualifier, null);
         for (PsiType type : types) {
           if (type instanceof PsiClassType) {
             if (((PsiClassType) type).resolve() instanceof PsiAnonymousClass) continue;
           }
           set.add(type);
         }
       }
     }
   }
 }
Пример #8
0
  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);
      }
    }
  }
  private void correctMethodCall(
      final PsiMethodCallExpression expression, final boolean isInternalCall) {
    try {
      final PsiManager manager = myMethod.getManager();
      PsiReferenceExpression methodExpression = expression.getMethodExpression();
      if (!methodExpression.isReferenceTo(myMethod)) return;
      final PsiExpression oldQualifier = methodExpression.getQualifierExpression();
      PsiExpression newQualifier = null;
      final PsiClass classReferencedByThis =
          MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression);
      if (myTargetVariable instanceof PsiParameter) {
        final int index =
            myMethod.getParameterList().getParameterIndex((PsiParameter) myTargetVariable);
        final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
        if (index < arguments.length) {
          newQualifier = (PsiExpression) arguments[index].copy();
          arguments[index].delete();
        }
      } else {
        VisibilityUtil.escalateVisibility((PsiField) myTargetVariable, expression);
        String newQualifierName = myTargetVariable.getName();
        if (myTargetVariable instanceof PsiField && oldQualifier != null) {
          final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(oldQualifier.getType());
          if (aClass == ((PsiField) myTargetVariable).getContainingClass()) {
            newQualifierName = oldQualifier.getText() + "." + newQualifierName;
          }
        }
        newQualifier =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createExpressionFromText(newQualifierName, null);
      }

      PsiExpression newArgument = null;

      if (classReferencedByThis != null) {
        @NonNls String thisArgumentText = null;
        if (manager.areElementsEquivalent(myMethod.getContainingClass(), classReferencedByThis)) {
          if (myOldClassParameterNames.containsKey(myMethod.getContainingClass())) {
            thisArgumentText = "this";
          }
        } else {
          thisArgumentText = classReferencedByThis.getName() + ".this";
        }

        if (thisArgumentText != null) {
          newArgument =
              JavaPsiFacade.getInstance(manager.getProject())
                  .getElementFactory()
                  .createExpressionFromText(thisArgumentText, null);
        }
      } else {
        if (!isInternalCall && oldQualifier != null) {
          final PsiType type = oldQualifier.getType();
          if (type instanceof PsiClassType) {
            final PsiClass resolved = ((PsiClassType) type).resolve();
            if (resolved != null && getParameterNameToCreate(resolved) != null) {
              newArgument =
                  replaceRefsToTargetVariable(
                      oldQualifier); // replace is needed in case old qualifier is e.g. the same as
                                     // field as target variable
            }
          }
        }
      }

      if (newArgument != null) {
        expression.getArgumentList().add(newArgument);
      }

      if (newQualifier != null) {
        if (newQualifier instanceof PsiThisExpression
            && ((PsiThisExpression) newQualifier).getQualifier() == null) {
          // Remove now redundant 'this' qualifier
          if (oldQualifier != null) oldQualifier.delete();
        } else {
          final PsiReferenceExpression refExpr =
              (PsiReferenceExpression)
                  JavaPsiFacade.getInstance(manager.getProject())
                      .getElementFactory()
                      .createExpressionFromText("q." + myMethod.getName(), null);
          refExpr.getQualifierExpression().replace(newQualifier);
          methodExpression.replace(refExpr);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  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
          }
        }
      }
    }
  }