Search code examples
javaintellij-ideaintellij-plugincode-inspection

Code Inspection for method signatures


i want to create a custom Code Inspection Rule for IntelliJ IDEA. The rule should check, if a special annotated argument type of a method call is equivalent to the parameter type of the method signature.

Example:

public void method(@MyAnnotation String input){
}

public void method2(){
    String invalid = "";
    method(invalid); // error

    @MyAnnotation String valid = (@MyAnnotation String) "";
    method(valid); // no error
}

What I tried:

[...]
protected static class visitor extends JavaElementVisitor {
    @Override
    public void visitMethodCallExpression(PsiMethodCallExpression expression) {
      PsiMethod method = expression.resolveMethod();

      //returns no annotations
      PsiAnnotation[] annotations = method.getModifierList().getAnnotations();

      //returns also no annotations
      MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
      PsiType[] types = methodSignature.getParameterTypes();
      for (PsiType psiType : types){
        TypeAnnotationProvider provider = psiType.getAnnotationProvider();
        PsiAnnotation[] annotations = provider.getAnnotations();
      }    
      super.visitMethodCallExpression(expression);
    }
[...]
}

How can I compare the annotation of the argument type with the annotation of the parameter type of the method?

Thanks!


Solution

  • method.getModifierList() returns the modifier list of the method, but the method is not annotated. You want the annotation of the parameter. So you will need to do something like this:

    method.getParameterList().getParameters()[indexOfParameter].getModifierList()
    

    To get the annotations of an argument of a method call, do something like this:

    PsiExpression argument = expression.getArgumentList().getExpressions()[indexOfArgument];
    argument = PsiUtil.skipParenthesizedExprDown(argument);
    if (argument instanceof PsiReferenceExpression) {
      PsiElement target = ((PsiReferenceExpression)argument).resolve();
      if (target instanceof PsiVariable) {
        ((PsiVariable)target).getModifierList();
        // get annotations
      }
    }