private static boolean isIndexOfCall(@NotNull PsiMethodCallExpression expression) {
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   final String methodName = methodExpression.getReferenceName();
   if (!HardcodedMethodConstants.INDEX_OF.equals(methodName)) {
     return false;
   }
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length != 1) {
     return false;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   final PsiType qualifierType = qualifier.getType();
   if (qualifierType == null) {
     return false;
   }
   final Project project = expression.getProject();
   final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project);
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass javaUtilListClass =
       psiFacade.findClass(CommonClassNames.JAVA_UTIL_LIST, projectScope);
   if (javaUtilListClass == null) {
     return false;
   }
   final PsiElementFactory factory = psiFacade.getElementFactory();
   final PsiClassType javaUtilListType = factory.createType(javaUtilListClass);
   return javaUtilListType.isAssignableFrom(qualifierType);
 }
  @NotNull
  private static Set<PsiClassType> filterInProjectExceptions(
      @Nullable PsiMethod targetMethod, @NotNull List<PsiClassType> unhandledExceptions) {
    if (targetMethod == null) return Collections.emptySet();

    Set<PsiClassType> result = new HashSet<PsiClassType>();

    if (targetMethod.getManager().isInProject(targetMethod)) {
      PsiMethod[] superMethods = targetMethod.findSuperMethods();
      for (PsiMethod superMethod : superMethods) {
        Set<PsiClassType> classTypes = filterInProjectExceptions(superMethod, unhandledExceptions);
        result.addAll(classTypes);
      }

      if (superMethods.length == 0) {
        result.addAll(unhandledExceptions);
      }
    } else {
      PsiClassType[] referencedTypes = targetMethod.getThrowsList().getReferencedTypes();
      for (PsiClassType referencedType : referencedTypes) {
        PsiClass psiClass = referencedType.resolve();
        if (psiClass == null) continue;
        for (PsiClassType exception : unhandledExceptions) {
          if (referencedType.isAssignableFrom(exception)) result.add(exception);
        }
      }
    }

    return result;
  }
  private static boolean hasSuperMethodsWithoutExceptions(
      @NotNull PsiMethod[] superMethods, @NotNull Set<PsiClassType> unhandledExceptions) {
    for (PsiMethod superMethod : superMethods) {
      PsiClassType[] referencedTypes = superMethod.getThrowsList().getReferencedTypes();

      Set<PsiClassType> exceptions = new HashSet<PsiClassType>(unhandledExceptions);
      for (PsiClassType referencedType : referencedTypes) {
        for (PsiClassType exception : unhandledExceptions) {
          if (referencedType.isAssignableFrom(exception)) exceptions.remove(exception);
        }
      }

      if (!exceptions.isEmpty()) return true;
    }

    return false;
  }
예제 #4
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;
  }
  @Override
  protected String validateAndCommitData() {
    PsiManager manager = PsiManager.getInstance(myProject);
    PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();

    String name = getMethodName();
    if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
      return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
    }

    if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) {
      try {
        ((PsiTypeCodeFragment) myReturnTypeCodeFragment).getType();
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        myReturnTypeField.requestFocus();
        return RefactoringBundle.message(
            "changeSignature.wrong.return.type", myReturnTypeCodeFragment.getText());
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        myReturnTypeField.requestFocus();
        return RefactoringBundle.message("changeSignature.no.return.type");
      }
    }

    List<ParameterTableModelItemBase<ParameterInfoImpl>> parameterInfos =
        myParametersTableModel.getItems();
    final int newParametersNumber = parameterInfos.size();

    for (int i = 0; i < newParametersNumber; i++) {
      final ParameterTableModelItemBase<ParameterInfoImpl> item = parameterInfos.get(i);

      if (!JavaPsiFacade.getInstance(manager.getProject())
          .getNameHelper()
          .isIdentifier(item.parameter.getName())) {
        return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName());
      }

      final PsiType type;
      try {
        type = ((PsiTypeCodeFragment) parameterInfos.get(i).typeCodeFragment).getType();
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        return RefactoringBundle.message(
            "changeSignature.wrong.type.for.parameter",
            item.typeCodeFragment.getText(),
            item.parameter.getName());
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        return RefactoringBundle.message(
            "changeSignature.no.type.for.parameter", item.parameter.getName());
      }

      item.parameter.setType(type);

      if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) {
        return RefactoringBundle.message("changeSignature.vararg.not.last");
      }

      if (item.parameter.oldParameterIndex < 0) {
        item.parameter.defaultValue =
            ApplicationManager.getApplication()
                .runWriteAction(
                    new Computable<String>() {
                      @Override
                      public String compute() {
                        return JavaCodeStyleManager.getInstance(myProject)
                            .qualifyClassReferences(item.defaultValueCodeFragment)
                            .getText();
                      }
                    });
        String def = item.parameter.defaultValue;
        def = def.trim();
        if (!(type instanceof PsiEllipsisType)) {
          try {
            if (!StringUtil.isEmpty(def)) {
              factory.createExpressionFromText(def, null);
            }
          } catch (IncorrectOperationException e) {
            return e.getMessage();
          }
        }
      }
    }

    ThrownExceptionInfo[] exceptionInfos = myExceptionsModel.getThrownExceptions();
    PsiTypeCodeFragment[] typeCodeFragments = myExceptionsModel.getTypeCodeFragments();
    for (int i = 0; i < exceptionInfos.length; i++) {
      ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
      PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
      try {
        PsiType type = typeCodeFragment.getType();
        if (!(type instanceof PsiClassType)) {
          return RefactoringBundle.message(
              "changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
        }

        PsiClassType throwable =
            JavaPsiFacade.getInstance(myProject)
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Throwable", type.getResolveScope());
        if (!throwable.isAssignableFrom(type)) {
          return RefactoringBundle.message(
              "changeSignature.not.throwable.type", typeCodeFragment.getText());
        }
        exceptionInfo.setType((PsiClassType) type);
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        return RefactoringBundle.message(
            "changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        return RefactoringBundle.message("changeSignature.no.type.for.exception");
      }
    }

    // warnings
    try {
      if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) {
        if (!RefactoringUtil.isResolvableType(
            ((PsiTypeCodeFragment) myReturnTypeCodeFragment).getType())) {
          if (Messages.showOkCancelDialog(
                  myProject,
                  RefactoringBundle.message(
                      "changeSignature.cannot.resolve.return.type",
                      myReturnTypeCodeFragment.getText()),
                  RefactoringBundle.message("changeSignature.refactoring.name"),
                  Messages.getWarningIcon())
              != 0) {
            return EXIT_SILENTLY;
          }
        }
      }
      for (ParameterTableModelItemBase<ParameterInfoImpl> item : parameterInfos) {

        if (!RefactoringUtil.isResolvableType(
            ((PsiTypeCodeFragment) item.typeCodeFragment).getType())) {
          if (Messages.showOkCancelDialog(
                  myProject,
                  RefactoringBundle.message(
                      "changeSignature.cannot.resolve.parameter.type",
                      item.typeCodeFragment.getText(),
                      item.parameter.getName()),
                  RefactoringBundle.message("changeSignature.refactoring.name"),
                  Messages.getWarningIcon())
              != 0) {
            return EXIT_SILENTLY;
          }
        }
      }
    } catch (PsiTypeCodeFragment.IncorrectTypeException ignored) {
    }
    return null;
  }
  private boolean validateInputData() {
    if (!isGroovyMethodName(getNewName())) {
      showErrorHint(message("name.is.wrong", getNewName()));
      return false;
    }

    if (!checkType(myReturnTypeCodeFragment, true)) {
      showErrorHint(message("return.type.is.wrong"));
      return false;
    }

    List<GrTableParameterInfo> parameterInfos = myParameterModel.getParameterInfos();
    for (int i = 0; i < parameterInfos.size(); i++) {
      GrTableParameterInfo info = parameterInfos.get(i);
      if (!StringUtil.isJavaIdentifier(info.getName())) {
        showErrorHint(message("name.is.wrong", info.getName()));
        return false;
      }
      if (!checkType(info.getTypeFragment(), i == parameterInfos.size() - 1)) {
        showErrorHint(message("type.for.parameter.is.incorrect", info.getName()));
        return false;
      }
      String defaultValue = info.getDefaultValue();
      final String initializer = info.getDefaultInitializerFragment().getText();
      if (info.getOldIndex() < 0
          && defaultValue.trim().length() == 0
          && initializer.trim().length() == 0) {
        showErrorHint(message("specify.default.value", info.getName()));
        return false;
      }
    }

    ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions();
    PsiTypeCodeFragment[] typeCodeFragments = myExceptionTableModel.getTypeCodeFragments();
    for (int i = 0; i < exceptionInfos.length; i++) {
      ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
      PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
      try {
        PsiType type = typeCodeFragment.getType();
        if (!(type instanceof PsiClassType)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
          return false;
        }

        PsiClassType throwable =
            JavaPsiFacade.getInstance(myMethod.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Throwable", myMethod.getResolveScope());
        if (!throwable.isAssignableFrom(type)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.not.throwable.type", typeCodeFragment.getText()));
          return false;
        }
        exceptionInfo.setType((PsiClassType) type);
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        showErrorHint(
            GroovyRefactoringBundle.message(
                "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
        return false;
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        showErrorHint(GroovyRefactoringBundle.message("changeSignature.no.type.for.exception"));
        return false;
      }
    }

    return true;
  }