コード例 #1
0
 /**
  * The parameter <code>allowIndirect</code> determines if the method should look for indirect
  * annotations, i.e. annotations which have themselves been annotated by the supplied annotation
  * name. Currently, this only allows one level of indirection and returns an array of
  * [base-annotation, indirect annotation]
  *
  * <p>The <code>annotationName</code> parameter is a pair of the target annotation class' fully
  * qualified name as a String and as a Set. This is done for performance reasons because the Set
  * is required by the {@link com.intellij.codeInsight.AnnotationUtil} utility class and allows to
  * avoid unnecessary object constructions.
  */
 public static PsiAnnotation[] getAnnotationsFromImpl(
     PsiModifierListOwner owner,
     Pair<String, ? extends Set<String>> annotationName,
     boolean allowIndirect,
     boolean inHierarchy) {
   final PsiAnnotation directAnnotation =
       inHierarchy
           ? AnnotationUtil.findAnnotationInHierarchy(owner, annotationName.second)
           : AnnotationUtil.findAnnotation(owner, annotationName.second);
   if (directAnnotation != null) {
     return new PsiAnnotation[] {directAnnotation};
   }
   if (allowIndirect) {
     final PsiAnnotation[] annotations = getAnnotations(owner, inHierarchy);
     for (PsiAnnotation annotation : annotations) {
       PsiJavaCodeReferenceElement nameReference = annotation.getNameReferenceElement();
       if (nameReference == null) continue;
       PsiElement resolved = nameReference.resolve();
       if (resolved instanceof PsiClass) {
         final PsiAnnotation psiAnnotation =
             AnnotationUtil.findAnnotationInHierarchy(
                 (PsiModifierListOwner) resolved, annotationName.second);
         if (psiAnnotation != null) {
           return new PsiAnnotation[] {psiAnnotation, annotation};
         }
       }
     }
   }
   return PsiAnnotation.EMPTY_ARRAY;
 }
コード例 #2
0
  @Override
  public boolean isEntryPoint(@NotNull PsiElement element) {
    if (!(element instanceof PsiModifierListOwner)) return false;
    PsiModifierListOwner owner = (PsiModifierListOwner) element;
    if (!ADDITIONAL_ANNOTATIONS.isEmpty()
        && ADDITIONAL_ANNOTATIONS.contains(Deprecated.class.getName())
        && element instanceof PsiDocCommentOwner
        && ((PsiDocCommentOwner) element).isDeprecated()) {
      return true;
    }

    if (element instanceof PsiClass) {
      final String qualifiedName = ((PsiClass) element).getQualifiedName();
      if (qualifiedName != null) {
        for (ClassPattern pattern : getPatterns()) {
          if (isAcceptedByPattern((PsiClass) element, qualifiedName, pattern, new HashSet<>())) {
            return true;
          }
        }
      }
    }

    return AnnotationUtil.checkAnnotatedUsingPatterns(owner, ADDITIONAL_ANNOTATIONS)
        || AnnotationUtil.checkAnnotatedUsingPatterns(owner, getAdditionalAnnotations());
  }
コード例 #3
0
 /** @return were javadoc params used */
 public static void collectAnnotationValues(
     final Map<String, Collection<String>> results, PsiMethod[] psiMethods, PsiClass... classes) {
   final Set<String> test = new HashSet<>(1);
   test.add(TEST_ANNOTATION_FQN);
   ContainerUtil.addAll(test, CONFIG_ANNOTATIONS_FQN);
   if (psiMethods != null) {
     for (final PsiMethod psiMethod : psiMethods) {
       ApplicationManager.getApplication()
           .runReadAction(
               () ->
                   appendAnnotationAttributeValues(
                       results, AnnotationUtil.findAnnotation(psiMethod, test), psiMethod));
     }
   } else {
     for (final PsiClass psiClass : classes) {
       ApplicationManager.getApplication()
           .runReadAction(
               () -> {
                 if (psiClass != null && hasTest(psiClass)) {
                   appendAnnotationAttributeValues(
                       results, AnnotationUtil.findAnnotation(psiClass, test), psiClass);
                   PsiMethod[] methods = psiClass.getMethods();
                   for (PsiMethod method : methods) {
                     if (method != null) {
                       appendAnnotationAttributeValues(
                           results, AnnotationUtil.findAnnotation(method, test), method);
                     }
                   }
                 }
               });
     }
   }
 }
コード例 #4
0
  /**
   * Filter the specified collection of classes to return only ones that contain any of the
   * specified values in the specified annotation parameter. For example, this method can be used to
   * return all classes that contain all tesng annotations that are in the groups 'foo' or 'bar'.
   */
  public static Map<PsiClass, Collection<PsiMethod>> filterAnnotations(
      String parameter, Set<String> values, Collection<PsiClass> classes) {
    Map<PsiClass, Collection<PsiMethod>> results = new HashMap<>();
    Set<String> test = new HashSet<>(1);
    test.add(TEST_ANNOTATION_FQN);
    ContainerUtil.addAll(test, CONFIG_ANNOTATIONS_FQN);
    for (PsiClass psiClass : classes) {
      if (isBrokenPsiClass(psiClass)) continue;

      PsiAnnotation annotation;
      try {
        annotation = AnnotationUtil.findAnnotation(psiClass, test);
      } catch (Exception e) {
        LOGGER.error(
            "Exception trying to findAnnotation on "
                + psiClass.getClass().getName()
                + ".\n\n"
                + e.getMessage());
        annotation = null;
      }
      if (annotation != null) {
        if (isAnnotatedWithParameter(annotation, parameter, values)) {
          results.put(psiClass, new LinkedHashSet<>());
        }
      } else {
        Collection<String> matches =
            extractAnnotationValuesFromJavaDoc(getTextJavaDoc(psiClass), parameter);
        for (String s : matches) {
          if (values.contains(s)) {
            results.put(psiClass, new LinkedHashSet<>());
            break;
          }
        }
      }

      // we already have the class, no need to look through its methods
      PsiMethod[] methods = psiClass.getMethods();
      for (PsiMethod method : methods) {
        if (method != null) {
          annotation = AnnotationUtil.findAnnotation(method, test);
          if (annotation != null) {
            if (isAnnotatedWithParameter(annotation, parameter, values)) {
              if (results.get(psiClass) == null) results.put(psiClass, new LinkedHashSet<>());
              results.get(psiClass).add(method);
            }
          } else {
            Collection<String> matches =
                extractAnnotationValuesFromJavaDoc(getTextJavaDoc(psiClass), parameter);
            for (String s : matches) {
              if (values.contains(s)) {
                results.get(psiClass).add(method);
              }
            }
          }
        }
      }
    }
    return results;
  }
コード例 #5
0
ファイル: PropertyUtil.java プロジェクト: jexp/idea2
 private static void annotateWithNullableStuff(
     final PsiModifierListOwner field,
     final PsiElementFactory factory,
     final PsiModifierListOwner listOwner)
     throws IncorrectOperationException {
   if (AnnotationUtil.isAnnotated(field, AnnotationUtil.NOT_NULL, false)) {
     annotate(factory, listOwner, AnnotationUtil.NOT_NULL);
   } else if (AnnotationUtil.isAnnotated(field, AnnotationUtil.NULLABLE, false)) {
     annotate(factory, listOwner, AnnotationUtil.NULLABLE);
   }
 }
コード例 #6
0
 @Override
 public void visitMethod(@NotNull PsiMethod method) {
   super.visitMethod(method);
   final PsiCodeBlock body = method.getBody();
   if (body == null) {
     return;
   }
   if (method.getNameIdentifier() == null) {
     return;
   }
   final PsiMethod leastConcreteSuperMethod = getLeastConcreteSuperMethod(method);
   if (leastConcreteSuperMethod == null) {
     return;
   }
   final PsiClass objectClass = ClassUtils.findObjectClass(method);
   final PsiMethod[] superMethods = method.findSuperMethods(objectClass);
   if (superMethods.length > 0) {
     return;
   }
   if (ignoreEmptySuperMethods) {
     final PsiMethod superMethod = (PsiMethod) leastConcreteSuperMethod.getNavigationElement();
     if (MethodUtils.isTrivial(superMethod, true)) {
       return;
     }
   }
   if (onlyReportWhenAnnotated) {
     if (!AnnotationUtil.isAnnotated(leastConcreteSuperMethod, annotations)) {
       return;
     }
   }
   if (containsSuperCall(body, leastConcreteSuperMethod)) {
     return;
   }
   registerMethodError(method);
 }
コード例 #7
0
 private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
   final PsiAnnotation annotation =
       AnnotationUtil.findAnnotation(oMethod, Override.class.getName());
   if (annotation != null) {
     annotation.delete();
   }
 }
コード例 #8
0
  private void reportNullableReturns(
      DataFlowInstructionVisitor visitor,
      ProblemsHolder holder,
      Set<PsiElement> reportedAnchors,
      @NotNull PsiElement block) {
    final PsiMethod method = getScopeMethod(block);
    if (method == null || NullableStuffInspectionBase.isNullableNotInferred(method, true)) return;

    boolean notNullRequired = NullableNotNullManager.isNotNull(method);
    if (!notNullRequired && !SUGGEST_NULLABLE_ANNOTATIONS) return;

    PsiType returnType = method.getReturnType();
    // no warnings in void lambdas, where the expression is not returned anyway
    if (block instanceof PsiExpression
        && block.getParent() instanceof PsiLambdaExpression
        && returnType == PsiType.VOID) return;

    // no warnings for Void methods, where only null can be possibly returned
    if (returnType == null || returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID)) return;

    for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
      assert statement instanceof PsiExpression;
      final PsiExpression expr = (PsiExpression) statement;
      if (!reportedAnchors.add(expr)) continue;

      if (notNullRequired) {
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
                : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
        holder.registerProblem(expr, text);
      } else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
        final NullableNotNullManager manager =
            NullableNotNullManager.getInstance(expr.getProject());
        final String defaultNullable = manager.getDefaultNullable();
        final String presentableNullable = StringUtil.getShortName(defaultNullable);
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message(
                    "dataflow.message.return.null.from.notnullable", presentableNullable)
                : InspectionsBundle.message(
                    "dataflow.message.return.nullable.from.notnullable", presentableNullable);
        final LocalQuickFix[] fixes =
            PsiTreeUtil.getParentOfType(expr, PsiMethod.class, PsiLambdaExpression.class)
                    instanceof PsiLambdaExpression
                ? LocalQuickFix.EMPTY_ARRAY
                : new LocalQuickFix[] {
                  new AnnotateMethodFix(
                      defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) {
                    @Override
                    public int shouldAnnotateBaseMethod(
                        PsiMethod method, PsiMethod superMethod, Project project) {
                      return 1;
                    }
                  }
                };
        holder.registerProblem(expr, text, fixes);
      }
    }
  }
コード例 #9
0
 @Nullable
 protected InspectionGadgetsFix buildFix(Object... infos) {
   if (!AnnotationUtil.isAnnotatingApplicable((PsiElement) infos[0])) {
     return null;
   }
   return new DelegatingFix(
       new AnnotateMethodFix(AnnotationUtil.NULLABLE, AnnotationUtil.NOT_NULL));
 }
コード例 #10
0
 public static String getConfigAnnotation(PsiMethod method) {
   if (method != null) {
     for (String fqn : CONFIG_ANNOTATIONS_FQN) {
       if (AnnotationUtil.isAnnotated(method, fqn, false)) return fqn;
     }
   }
   return null;
 }
コード例 #11
0
  @Override
  public boolean isAvailable(
      @NotNull Project project,
      @NotNull PsiFile file,
      @NotNull PsiElement startElement,
      @NotNull PsiElement endElement) {
    if (!startElement.isValid()) return false;
    if (!PsiUtil.isLanguageLevel5OrHigher(startElement)) return false;
    final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner) startElement;

    return !AnnotationUtil.isAnnotated(myModifierListOwner, myAnnotation, false);
  }
コード例 #12
0
 private void makeStatic(PsiMethod member) {
   final PsiAnnotation overrideAnnotation =
       AnnotationUtil.findAnnotation(member, CommonClassNames.JAVA_LANG_OVERRIDE);
   if (overrideAnnotation != null) {
     overrideAnnotation.delete();
   }
   setupTypeParameterList(member);
   // Add static modifier
   final PsiModifierList modifierList = member.getModifierList();
   modifierList.setModifierProperty(PsiModifier.STATIC, true);
   modifierList.setModifierProperty(PsiModifier.FINAL, false);
   modifierList.setModifierProperty(PsiModifier.DEFAULT, false);
 }
コード例 #13
0
 private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
   final PsiAnnotation annotation =
       AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE);
   if (annotation != null) {
     PsiElement prev = annotation.getPrevSibling();
     PsiElement next = annotation.getNextSibling();
     if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev))
         && org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) {
       next.delete();
     }
     annotation.delete();
   }
 }
コード例 #14
0
  @Nullable
  public static List<String> findTestDataFiles(@NotNull DataContext context) {
    final PsiMethod method = findTargetMethod(context);
    if (method == null) {
      return null;
    }
    final String name = method.getName();

    if (name.startsWith("test")) {
      String testDataPath =
          TestDataLineMarkerProvider.getTestDataBasePath(method.getContainingClass());
      final TestDataReferenceCollector collector =
          new TestDataReferenceCollector(testDataPath, name.substring(4));
      return collector.collectTestDataReferences(method);
    }

    final Location<?> location = Location.DATA_KEY.getData(context);
    if (location instanceof PsiMemberParameterizedLocation) {
      PsiClass containingClass = ((PsiMemberParameterizedLocation) location).getContainingClass();
      if (containingClass == null) {
        containingClass =
            PsiTreeUtil.getParentOfType(location.getPsiElement(), PsiClass.class, false);
      }
      if (containingClass != null) {
        final PsiAnnotation annotation =
            AnnotationUtil.findAnnotationInHierarchy(
                containingClass, Collections.singleton(JUnitUtil.RUN_WITH));
        if (annotation != null) {
          final PsiAnnotationMemberValue memberValue = annotation.findAttributeValue("value");
          if (memberValue instanceof PsiClassObjectAccessExpression) {
            final PsiTypeElement operand =
                ((PsiClassObjectAccessExpression) memberValue).getOperand();
            if (operand.getType().equalsToText(Parameterized.class.getName())) {
              final String testDataPath =
                  TestDataLineMarkerProvider.getTestDataBasePath(containingClass);
              final String paramSetName =
                  ((PsiMemberParameterizedLocation) location).getParamSetName();
              final String baseFileName =
                  StringUtil.trimEnd(StringUtil.trimStart(paramSetName, "["), "]");
              final ProjectFileIndex fileIndex =
                  ProjectRootManager.getInstance(containingClass.getProject()).getFileIndex();
              return TestDataGuessByExistingFilesUtil.suggestTestDataFiles(
                  fileIndex, baseFileName, testDataPath, containingClass);
            }
          }
        }
      }
    }

    return null;
  }
コード例 #15
0
  private void checkAnnotations(Class<?> javaClass) {
    PsiClass psiClass =
        myJavaPsiFacade.findClass(
            javaClass.getName(), GlobalSearchScope.moduleWithLibrariesScope(myModule));
    assertNotNull(psiClass);

    for (java.lang.reflect.Method javaMethod : javaClass.getDeclaredMethods()) {
      PsiMethod psiMethod = psiClass.findMethodsByName(javaMethod.getName(), false)[0];
      Annotation[][] annotations = javaMethod.getParameterAnnotations();

      // not-null parameters
      params:
      for (int i = 0; i < annotations.length; i++) {
        Annotation[] parameterAnnotations = annotations[i];
        PsiParameter psiParameter = psiMethod.getParameterList().getParameters()[i];
        PsiAnnotation inferredAnnotation =
            myInferredAnnotationsManager.findInferredAnnotation(
                psiParameter, AnnotationUtil.NOT_NULL);
        for (Annotation parameterAnnotation : parameterAnnotations) {
          if (parameterAnnotation.annotationType() == ExpectNotNull.class) {
            assertNotNull(javaMethod.toString() + " " + i, inferredAnnotation);
            continue params;
          }
        }
        assertNull(javaMethod.toString() + " " + i, inferredAnnotation);
      }

      // not-null result
      ExpectNotNull expectedAnnotation = javaMethod.getAnnotation(ExpectNotNull.class);
      PsiAnnotation actualAnnotation =
          myInferredAnnotationsManager.findInferredAnnotation(psiMethod, AnnotationUtil.NOT_NULL);
      assertEquals(javaMethod.toString(), expectedAnnotation == null, actualAnnotation == null);

      // contracts
      ExpectContract expectedContract = javaMethod.getAnnotation(ExpectContract.class);
      PsiAnnotation actualContractAnnotation =
          myInferredAnnotationsManager.findInferredAnnotation(
              psiMethod, ORG_JETBRAINS_ANNOTATIONS_CONTRACT);

      assertEquals(expectedContract == null, actualContractAnnotation == null);

      if (expectedContract != null) {
        String expectedContractValue = expectedContract.value();
        String actualContractValue =
            AnnotationUtil.getStringAttributeValue(actualContractAnnotation, null);
        assertEquals(javaMethod.toString(), expectedContractValue, actualContractValue);
      }
    }
  }
コード例 #16
0
  private static boolean isConfigMethod(PsiMethod method, String[] configAnnotationsFqn) {
    for (String fqn : configAnnotationsFqn) {
      if (AnnotationUtil.isAnnotated(method, fqn, false)) return true;
    }

    if (hasDocTagsSupport) {
      final PsiDocComment comment = method.getDocComment();
      if (comment != null) {
        for (String javadocTag : CONFIG_JAVADOC_TAGS) {
          if (comment.findTagByName(javadocTag) != null) return true;
        }
      }
    }
    return false;
  }
コード例 #17
0
 public static boolean mustBePropertyKey(
     @NotNull Project project,
     @NotNull PsiLiteralExpression expression,
     @NotNull Map<String, Object> annotationAttributeValues) {
   final PsiElement parent = expression.getParent();
   if (parent instanceof PsiVariable) {
     final PsiAnnotation annotation =
         AnnotationUtil.findAnnotation((PsiVariable) parent, AnnotationUtil.PROPERTY_KEY);
     if (annotation != null) {
       return processAnnotationAttributes(annotationAttributeValues, annotation);
     }
   }
   return isPassedToAnnotatedParam(
       project, expression, AnnotationUtil.PROPERTY_KEY, annotationAttributeValues, null);
 }
コード例 #18
0
  @Override
  public boolean isAvailable(
      @NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
    if (!super.isAvailable(project, editor, element)) {
      return false;
    }
    PsiModifierListOwner owner = getContainer(element);
    if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false)) {
      return false;
    }
    if (owner instanceof PsiMethod) {
      PsiType returnType = ((PsiMethod) owner).getReturnType();

      return returnType != null && !(returnType instanceof PsiPrimitiveType);
    }
    return true;
  }
コード例 #19
0
  public static boolean isMethodParameterAnnotatedWith(
      final PsiMethod method,
      final int idx,
      @Nullable Collection<PsiMethod> processed,
      final String annFqn,
      @Nullable Map<String, Object> annotationAttributeValues,
      @Nullable final Set<PsiModifierListOwner> nonNlsTargets) {
    if (processed != null) {
      if (processed.contains(method)) return false;
    } else {
      processed = new THashSet<PsiMethod>();
    }
    processed.add(method);

    final PsiParameter[] params = method.getParameterList().getParameters();
    PsiParameter param;
    if (idx >= params.length) {
      if (params.length == 0) {
        return false;
      }
      PsiParameter lastParam = params[params.length - 1];
      if (lastParam.isVarArgs()) {
        param = lastParam;
      } else {
        return false;
      }
    } else {
      param = params[idx];
    }
    final PsiAnnotation annotation = AnnotationUtil.findAnnotation(param, annFqn);
    if (annotation != null) {
      return processAnnotationAttributes(annotationAttributeValues, annotation);
    }
    if (nonNlsTargets != null) {
      nonNlsTargets.add(param);
    }

    final PsiMethod[] superMethods = method.findSuperMethods();
    for (PsiMethod superMethod : superMethods) {
      if (isMethodParameterAnnotatedWith(
          superMethod, idx, processed, annFqn, annotationAttributeValues, null)) return true;
    }

    return false;
  }
コード例 #20
0
 public static boolean isJUnitTestMethod(PsiMethod method) {
   //noinspection HardCodedStringLiteral
   if (AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) {
     return true;
   }
   final PsiType returnType = method.getReturnType();
   if (!PsiType.VOID.equals(returnType)) {
     return false;
   }
   if (!method.hasModifierProperty(PsiModifier.PUBLIC)) {
     return false;
   }
   @NonNls final String methodName = method.getName();
   if (!methodName.startsWith("test")) {
     return false;
   }
   final PsiClass containingClass = method.getContainingClass();
   return containingClass != null && isJUnitTestCase(containingClass);
 }
 @Override
 public void visitField(@NotNull PsiField field) {
   if (field.hasModifierProperty(PsiModifier.STATIC)) {
     return;
   }
   if (field.getInitializer() != null) {
     return;
   }
   final PsiAnnotation annotation = AnnotationUtil.findAnnotation(field, annotationNames);
   if (annotation != null) {
     return;
   }
   if (m_ignorePrimitives) {
     final PsiType fieldType = field.getType();
     if (ClassUtils.isPrimitive(fieldType)) {
       return;
     }
   }
   final PsiClass aClass = field.getContainingClass();
   if (aClass == null) {
     return;
   }
   for (ImplicitUsageProvider provider :
       Extensions.getExtensions(ImplicitUsageProvider.EP_NAME)) {
     if (provider.isImplicitWrite(field)) {
       return;
     }
   }
   final UninitializedReadCollector uninitializedReadsCollector =
       new UninitializedReadCollector();
   if (!isInitializedInInitializer(field, uninitializedReadsCollector)) {
     final PsiMethod[] constructors = aClass.getConstructors();
     for (final PsiMethod constructor : constructors) {
       final PsiCodeBlock body = constructor.getBody();
       uninitializedReadsCollector.blockAssignsVariable(body, field);
     }
   }
   final PsiExpression[] badReads = uninitializedReadsCollector.getUninitializedReads();
   for (PsiExpression expression : badReads) {
     registerError(expression);
   }
 }
コード例 #22
0
  @Override
  public void invoke(
      @NotNull Project project,
      @NotNull PsiFile file,
      @Nullable("is null when called from inspection") Editor editor,
      @NotNull PsiElement startElement,
      @NotNull PsiElement endElement) {
    final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner) startElement;

    final ExternalAnnotationsManager annotationsManager =
        ExternalAnnotationsManager.getInstance(project);
    final PsiModifierList modifierList = myModifierListOwner.getModifierList();
    LOG.assertTrue(modifierList != null);
    if (modifierList.findAnnotation(myAnnotation) != null) return;
    final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace =
        annotationsManager.chooseAnnotationsPlace(myModifierListOwner);
    if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return;
    if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) {
      for (String fqn : myAnnotationsToRemove) {
        annotationsManager.deannotate(myModifierListOwner, fqn);
      }
      annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs);
    } else {
      final PsiFile containingFile = myModifierListOwner.getContainingFile();
      if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return;
      for (String fqn : myAnnotationsToRemove) {
        PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn);
        if (annotation != null) {
          annotation.delete();
        }
      }

      PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation);
      for (PsiNameValuePair pair : myPairs) {
        inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
      }
      JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
      if (containingFile != file) {
        UndoUtil.markPsiFileForUndo(file);
      }
    }
  }
コード例 #23
0
 public static boolean isJUnitTestCase(PsiClass aClass) {
   final Project project = aClass.getProject();
   final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass testCase = psiFacade.findClass("junit.framework.TestCase", scope);
   if (testCase == null) {
     return false;
   }
   if (aClass.isInheritor(testCase, true)) {
     return true;
   }
   final PsiMethod[] methods = aClass.getMethods();
   for (PsiMethod method : methods) {
     //noinspection HardCodedStringLiteral
     if (AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) {
       return true;
     }
   }
   return false;
 }
コード例 #24
0
  private static void reportNullableReturns(
      StandardDataFlowRunner runner,
      DataFlowInstructionVisitor visitor,
      ProblemsHolder holder,
      Set<PsiElement> reportedAnchors) {
    for (PsiElement statement : visitor.getProblems(NullabilityProblem.nullableReturn)) {
      assert statement instanceof PsiExpression;
      final PsiExpression expr = (PsiExpression) statement;
      if (!reportedAnchors.add(expr)) continue;

      if (runner.isInNotNullMethod()) {
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
                : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
        holder.registerProblem(expr, text);
      } else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
        final NullableNotNullManager manager =
            NullableNotNullManager.getInstance(expr.getProject());
        final String defaultNullable = manager.getDefaultNullable();
        final String presentableNullable = StringUtil.getShortName(defaultNullable);
        final String text =
            isNullLiteralExpression(expr)
                ? InspectionsBundle.message(
                    "dataflow.message.return.null.from.notnullable", presentableNullable)
                : InspectionsBundle.message(
                    "dataflow.message.return.nullable.from.notnullable", presentableNullable);
        holder.registerProblem(
            expr,
            text,
            new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) {
              @Override
              public int shouldAnnotateBaseMethod(
                  PsiMethod method, PsiMethod superMethod, Project project) {
                return 1;
              }
            });
      }
    }
  }
コード例 #25
0
 @Nullable
 public static String getTestDataBasePath(PsiClass psiClass) {
   final PsiAnnotation annotation =
       AnnotationUtil.findAnnotationInHierarchy(
           psiClass, Collections.singleton(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME));
   if (annotation != null) {
     final PsiAnnotationMemberValue value =
         annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
     if (value instanceof PsiExpression) {
       final Project project = value.getProject();
       final PsiConstantEvaluationHelper evaluationHelper =
           JavaPsiFacade.getInstance(project).getConstantEvaluationHelper();
       final Object constantValue = evaluationHelper.computeConstantExpression(value, false);
       if (constantValue instanceof String) {
         String path = (String) constantValue;
         if (path.contains(CONTENT_ROOT_VARIABLE)) {
           final ProjectFileIndex fileIndex =
               ProjectRootManager.getInstance(project).getFileIndex();
           final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
           if (file == null) {
             return null;
           }
           final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
           if (contentRoot == null) return null;
           path = path.replace(CONTENT_ROOT_VARIABLE, contentRoot.getPath());
         }
         if (path.contains(PROJECT_ROOT_VARIABLE)) {
           final VirtualFile baseDir = project.getBaseDir();
           if (baseDir == null) {
             return null;
           }
           path = path.replace(PROJECT_ROOT_VARIABLE, baseDir.getPath());
         }
         return path;
       }
     }
   }
   return null;
 }
コード例 #26
0
  private void reportNullableArgumentsPassedToNonAnnotated(
      DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
    for (PsiElement expr :
        visitor.getProblems(NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter)) {
      if (reportedAnchors.contains(expr)) continue;

      final String text =
          isNullLiteralExpression(expr)
              ? "Passing <code>null</code> argument to non annotated parameter"
              : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
      LocalQuickFix[] fixes =
          createNPEFixes((PsiExpression) expr, (PsiExpression) expr, holder.isOnTheFly());
      final PsiElement parent = expr.getParent();
      if (parent instanceof PsiExpressionList) {
        final int idx = ArrayUtilRt.find(((PsiExpressionList) parent).getExpressions(), expr);
        if (idx > -1) {
          final PsiElement gParent = parent.getParent();
          if (gParent instanceof PsiCallExpression) {
            final PsiMethod psiMethod = ((PsiCallExpression) gParent).resolveMethod();
            if (psiMethod != null
                && psiMethod.getManager().isInProject(psiMethod)
                && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
              final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
              if (idx < parameters.length) {
                final AddNullableAnnotationFix addNullableAnnotationFix =
                    new AddNullableAnnotationFix(parameters[idx]);
                fixes =
                    fixes == null
                        ? new LocalQuickFix[] {addNullableAnnotationFix}
                        : ArrayUtil.append(fixes, addNullableAnnotationFix);
                holder.registerProblem(expr, text, fixes);
                reportedAnchors.add(expr);
              }
            }
          }
        }
      }
    }
  }
コード例 #27
0
 public static void addSuppressAnnotation(
     final Project project,
     final Editor editor,
     final PsiElement container,
     final PsiModifierListOwner modifierOwner,
     final String id)
     throws IncorrectOperationException {
   PsiAnnotation annotation =
       AnnotationUtil.findAnnotation(
           modifierOwner, SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME);
   final PsiAnnotation newAnnotation =
       createNewAnnotation(project, editor, container, annotation, id);
   if (newAnnotation != null) {
     if (annotation != null && annotation.isPhysical()) {
       annotation.replace(newAnnotation);
     } else {
       final PsiNameValuePair[] attributes = newAnnotation.getParameterList().getAttributes();
       new AddAnnotationFix(
               SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME, modifierOwner, attributes)
           .invoke(project, editor, container.getContainingFile());
     }
   }
 }
コード例 #28
0
  static AllowedValues getAllowedValues(
      @NotNull PsiModifierListOwner element, PsiType type, Set<PsiClass> visited) {
    PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(element, true, null);
    for (PsiAnnotation annotation : annotations) {
      AllowedValues values;
      if (type != null && MagicConstant.class.getName().equals(annotation.getQualifiedName())) {
        // PsiAnnotation magic = AnnotationUtil.findAnnotationInHierarchy(element,
        // Collections.singleton(MagicConstant.class.getName()));
        values = getAllowedValuesFromMagic(element, type, annotation);
        if (values != null) return values;
      }

      PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
      PsiElement resolved = ref == null ? null : ref.resolve();
      if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) continue;
      PsiClass aClass = (PsiClass) resolved;
      if (visited == null) visited = new THashSet<PsiClass>();
      if (!visited.add(aClass)) continue;
      values = getAllowedValues(aClass, type, visited);
      if (values != null) return values;
    }

    return parseBeanInfo(element);
  }
コード例 #29
0
 @Override
 public void visitLiteralExpression(@NotNull PsiLiteralExpression value) {
   super.visitLiteralExpression(value);
   final String text = value.getText();
   if (!PsiKeyword.NULL.equals(text)) {
     return;
   }
   PsiElement parent = value.getParent();
   while (parent instanceof PsiParenthesizedExpression
       || parent instanceof PsiConditionalExpression
       || parent instanceof PsiTypeCastExpression) {
     parent = parent.getParent();
   }
   if (parent == null || !(parent instanceof PsiReturnStatement)) {
     return;
   }
   final PsiMethod method = PsiTreeUtil.getParentOfType(value, PsiMethod.class);
   if (method == null) {
     return;
   }
   final PsiType returnType = method.getReturnType();
   if (returnType == null) {
     return;
   }
   final boolean isArray = returnType.getArrayDimensions() > 0;
   if (AnnotationUtil.isAnnotated(method, AnnotationUtil.NULLABLE, false)) {
     return;
   }
   if (m_reportCollectionMethods && CollectionUtils.isCollectionClassOrInterface(returnType)) {
     registerError(value, value);
   } else if (m_reportArrayMethods && isArray) {
     registerError(value, value);
   } else if (m_reportObjectMethods && !isArray) {
     registerError(value, value);
   }
 }
コード例 #30
0
  private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) {
    PsiMethod method = null;
    if (owner instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter) owner;
      PsiElement scope = parameter.getDeclarationScope();
      if (!(scope instanceof PsiMethod)) return null;
      PsiElement nav = scope.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
      if (method.isConstructor()) {
        // not a property, try the @ConstructorProperties({"prop"})
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties");
        if (annotation == null) return null;
        PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
        if (!(value instanceof PsiArrayInitializerMemberValue)) return null;
        PsiAnnotationMemberValue[] initializers =
            ((PsiArrayInitializerMemberValue) value).getInitializers();
        PsiElement parent = parameter.getParent();
        if (!(parent instanceof PsiParameterList)) return null;
        int index = ((PsiParameterList) parent).getParameterIndex(parameter);
        if (index >= initializers.length) return null;
        PsiAnnotationMemberValue initializer = initializers[index];
        if (!(initializer instanceof PsiLiteralExpression)) return null;
        Object val = ((PsiLiteralExpression) initializer).getValue();
        if (!(val instanceof String)) return null;
        PsiMethod setter =
            PropertyUtil.findPropertySetter(
                method.getContainingClass(), (String) val, false, false);
        if (setter == null) return null;
        // try the @beaninfo of the corresponding setter
        method = (PsiMethod) setter.getNavigationElement();
      }
    } else if (owner instanceof PsiMethod) {
      PsiElement nav = owner.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
    }
    if (method == null) return null;

    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    if (PropertyUtil.isSimplePropertyGetter(method)) {
      List<PsiMethod> setters =
          PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
      if (setters.size() != 1) return null;
      method = setters.get(0);
    }
    if (!PropertyUtil.isSimplePropertySetter(method)) return null;
    PsiDocComment doc = method.getDocComment();
    if (doc == null) return null;
    PsiDocTag beaninfo = doc.findTagByName("beaninfo");
    if (beaninfo == null) return null;
    String data =
        StringUtil.join(
            beaninfo.getDataElements(),
            new Function<PsiElement, String>() {
              @Override
              public String fun(PsiElement element) {
                return element.getText();
              }
            },
            "\n");
    int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:");
    if (enumIndex == -1) return null;
    data = data.substring(enumIndex);
    int colon = data.indexOf(":");
    int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n");
    data = data.substring(0, last);

    List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>();
    for (String line : StringUtil.splitByLines(data)) {
      List<String> words = StringUtil.split(line, " ", true, true);
      if (words.size() != 2) continue;
      String ref = words.get(1);
      PsiExpression constRef =
          JavaPsiFacade.getElementFactory(aClass.getProject())
              .createExpressionFromText(ref, aClass);
      if (!(constRef instanceof PsiReferenceExpression)) continue;
      PsiReferenceExpression expr = (PsiReferenceExpression) constRef;
      values.add(expr);
    }
    if (values.isEmpty()) return null;
    PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]);
    return new AllowedValues(array, false);
  }