@Override
  public boolean checkApplicability(
      @NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) {
    final String qname = annotation.getQualifiedName();
    if (!GroovyCommonClassNames.GROOVY_TRANSFORM_FIELD.equals(qname)) return false;

    checkScriptField(holder, annotation);

    PsiElement annoParent = annotation.getParent();
    PsiElement ownerToUse =
        annoParent instanceof PsiModifierList ? annoParent.getParent() : annoParent;
    if (!(ownerToUse instanceof GrVariableDeclaration)
        || !PsiUtil.isLocalVariable(((GrVariableDeclaration) ownerToUse).getVariables()[0])) {
      return false;
    }

    if (!GrAnnotationImpl.isAnnotationApplicableTo(
        annotation, PsiAnnotation.TargetType.LOCAL_VARIABLE)) {
      GrCodeReferenceElement ref = annotation.getClassReference();
      String target = JavaErrorMessages.message("annotation.target.LOCAL_VARIABLE");
      String description =
          JavaErrorMessages.message("annotation.not.applicable", ref.getText(), target);
      holder.createErrorAnnotation(ref, description);
    }

    return true;
  }
  @Nullable
  public PsiBuilder.Marker parseConditional(final PsiBuilder builder) {
    final PsiBuilder.Marker condition = parseExpression(builder, ExprType.CONDITIONAL_OR);
    if (condition == null) return null;

    if (builder.getTokenType() != JavaTokenType.QUEST) return condition;
    final PsiBuilder.Marker ternary = condition.precede();
    builder.advanceLexer();

    final PsiBuilder.Marker truePart = parse(builder);
    if (truePart == null) {
      error(builder, JavaErrorMessages.message("expected.expression"));
      ternary.done(JavaElementType.CONDITIONAL_EXPRESSION);
      return ternary;
    }

    if (builder.getTokenType() != JavaTokenType.COLON) {
      error(builder, JavaErrorMessages.message("expected.colon"));
      ternary.done(JavaElementType.CONDITIONAL_EXPRESSION);
      return ternary;
    }
    builder.advanceLexer();

    final PsiBuilder.Marker falsePart = parseConditional(builder);
    if (falsePart == null) {
      error(builder, JavaErrorMessages.message("expected.expression"));
      ternary.done(JavaElementType.CONDITIONAL_EXPRESSION);
      return ternary;
    }

    ternary.done(JavaElementType.CONDITIONAL_EXPRESSION);
    return ternary;
  }
 @SuppressWarnings({"UnresolvedPropertyKey"})
 public String getUnresolvedMessagePattern(int index) {
   if (canReferencePackage(index)) {
     return JavaErrorMessages.message("error.cannot.resolve.class.or.package");
   }
   return JavaErrorMessages.message("error.cannot.resolve.class");
 }
  @Nullable
  static HighlightInfo checkFileDuplicates(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
    Module module = ModuleUtilCore.findModuleForPsiElement(element);
    if (module != null) {
      Project project = file.getProject();
      Collection<VirtualFile> others =
          FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, new ModulesScope(module));
      if (others.size() > 1) {
        String message = JavaErrorMessages.message("module.file.duplicate");
        HighlightInfo info =
            HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
                .range(range(element))
                .description(message)
                .create();
        others
            .stream()
            .map(f -> PsiManager.getInstance(project).findFile(f))
            .filter(f -> f != file)
            .findFirst()
            .ifPresent(
                duplicate ->
                    QuickFixAction.registerQuickFixAction(
                        info,
                        new GoToSymbolFix(
                            duplicate, JavaErrorMessages.message("module.open.duplicate.text"))));
        return info;
      }
    }

    return null;
  }
  @Nullable
  private PsiBuilder.Marker parseUnary(final PsiBuilder builder) {
    final IElementType tokenType = builder.getTokenType();

    if (PREFIX_OPS.contains(tokenType)) {
      final PsiBuilder.Marker unary = builder.mark();
      builder.advanceLexer();

      final PsiBuilder.Marker operand = parseUnary(builder);
      if (operand == null) {
        error(builder, JavaErrorMessages.message("expected.expression"));
      }

      unary.done(JavaElementType.PREFIX_EXPRESSION);
      return unary;
    } else if (tokenType == JavaTokenType.LPARENTH) {
      final PsiBuilder.Marker typeCast = builder.mark();
      builder.advanceLexer();

      ReferenceParser.TypeInfo typeInfo =
          myParser
              .getReferenceParser()
              .parseTypeInfo(
                  builder,
                  ReferenceParser.EAT_LAST_DOT
                      | ReferenceParser.WILDCARD
                      | ReferenceParser.CONJUNCTIONS
                      | ReferenceParser.INCOMPLETE_ANNO);
      if (typeInfo == null || !expect(builder, JavaTokenType.RPARENTH)) {
        typeCast.rollbackTo();
        return parsePostfix(builder);
      }

      if (PREF_ARITHMETIC_OPS.contains(builder.getTokenType()) && !typeInfo.isPrimitive) {
        typeCast.rollbackTo();
        return parsePostfix(builder);
      }

      final PsiBuilder.Marker expr = parseUnary(builder);
      if (expr == null) {
        if (!typeInfo
            .isParameterized) { // cannot parse correct parenthesized expression after correct
                                // parameterized type
          typeCast.rollbackTo();
          return parsePostfix(builder);
        } else {
          error(builder, JavaErrorMessages.message("expected.expression"));
        }
      }

      typeCast.done(JavaElementType.TYPE_CAST_EXPRESSION);
      return typeCast;
    } else {
      return parsePostfix(builder);
    }
  }
  @Nullable
  private PsiBuilder.Marker parseArrayInitializer(final PsiBuilder builder) {
    if (builder.getTokenType() != JavaTokenType.LBRACE) return null;

    final PsiBuilder.Marker arrayInit = builder.mark();
    builder.advanceLexer();

    boolean expressionMissed = false;
    PsiBuilder.Marker lastComma = null;
    while (true) {
      if (builder.getTokenType() == JavaTokenType.RBRACE) {
        builder.advanceLexer();
        break;
      }

      if (builder.getTokenType() == null) {
        error(builder, JavaErrorMessages.message("expected.rbrace"));
        break;
      }

      if (expressionMissed && lastComma != null) {
        // before comma must be an expression
        lastComma
            .precede()
            .errorBefore(JavaErrorMessages.message("expected.expression"), lastComma);
        lastComma.drop();
        lastComma = null;
      }

      final PsiBuilder.Marker arg = parse(builder);
      if (arg == null) {
        if (builder.getTokenType() == JavaTokenType.COMMA) {
          expressionMissed = true;
          lastComma = builder.mark();
        } else {
          error(builder, JavaErrorMessages.message("expected.rbrace"));
          break;
        }
      }

      final IElementType tokenType = builder.getTokenType();
      if (tokenType == JavaTokenType.COMMA) {
        builder.advanceLexer();
      } else if (tokenType != JavaTokenType.RBRACE) {
        error(builder, JavaErrorMessages.message("expected.comma"));
      }
    }

    if (lastComma != null) {
      lastComma.drop();
    }

    arrayInit.done(JavaElementType.ARRAY_INITIALIZER_EXPRESSION);
    return arrayInit;
  }
  @Nullable
  static HighlightInfo checkFinalFieldInitialized(@NotNull PsiField field) {
    if (!field.hasModifierProperty(PsiModifier.FINAL)) return null;
    if (isFieldInitializedAfterObjectConstruction(field)) return null;

    String description = JavaErrorMessages.message("variable.not.initialized", field.getName());
    TextRange range = HighlightNamesUtil.getFieldDeclarationTextRange(field);
    HighlightInfo highlightInfo =
        HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(range)
            .descriptionAndTooltip(description)
            .create();
    QuickFixAction.registerQuickFixAction(
        highlightInfo,
        HighlightMethodUtil.getFixRange(field),
        QUICK_FIX_FACTORY.createCreateConstructorParameterFromFieldFix(field));
    QuickFixAction.registerQuickFixAction(
        highlightInfo,
        HighlightMethodUtil.getFixRange(field),
        QUICK_FIX_FACTORY.createInitializeFinalFieldInConstructorFix(field));
    final PsiClass containingClass = field.getContainingClass();
    if (containingClass != null && !containingClass.isInterface()) {
      QuickFixAction.registerQuickFixAction(
          highlightInfo,
          QUICK_FIX_FACTORY.createModifierListFix(field, PsiModifier.FINAL, false, false));
    }
    QuickFixAction.registerQuickFixAction(
        highlightInfo, QUICK_FIX_FACTORY.createAddVariableInitializerFix(field));
    return highlightInfo;
  }
  @NotNull
  static List<HighlightInfo> checkDuplicateRequires(@NotNull PsiJavaModule module) {
    List<HighlightInfo> results = ContainerUtil.newSmartList();

    Map<String, PsiElement> map = ContainerUtil.newHashMap();
    for (PsiElement child = module.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (child instanceof PsiRequiresStatement) {
        PsiJavaModuleReferenceElement ref = ((PsiRequiresStatement) child).getReferenceElement();
        if (ref != null) {
          String text = ref.getReferenceText();
          if (!map.containsKey(text)) {
            map.put(text, child);
          } else {
            String message = JavaErrorMessages.message("module.duplicate.requires", text);
            HighlightInfo info =
                HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
                    .range(child)
                    .description(message)
                    .create();
            QuickFixAction.registerQuickFixAction(info, new DeleteElementFix(child));
            results.add(info);
          }
        }
      }
    }

    return results;
  }
  @Nullable
  private PsiBuilder.Marker parseLambdaExpression(
      final PsiBuilder builder, final boolean typed, @Nullable final PsiBuilder.Marker typeList) {
    final PsiBuilder.Marker start = typeList != null ? typeList.precede() : builder.mark();

    myParser.getDeclarationParser().parseLambdaParameterList(builder, typed);

    if (!expect(builder, JavaTokenType.ARROW)) {
      start.rollbackTo();
      return null;
    }

    final PsiBuilder.Marker body;
    if (builder.getTokenType() == JavaTokenType.LBRACE) {
      body = myParser.getStatementParser().parseCodeBlock(builder);
    } else {
      body = parse(builder);
    }

    if (body == null) {
      builder.error(JavaErrorMessages.message("expected.lbrace"));
    }

    start.done(JavaElementType.LAMBDA_EXPRESSION);
    return start;
  }
Esempio n. 10
0
  @Nullable
  private static PsiBuilder.Marker parseBinary(
      final PsiBuilder builder, final ExprType type, final TokenSet ops) {
    PsiBuilder.Marker left = parseExpression(builder, type);
    if (left == null) return null;

    while (true) {
      final IElementType tokenType = getGtTokenType(builder);
      if (tokenType == null || !ops.contains(tokenType)) break;

      final PsiBuilder.Marker binary = left.precede();
      advanceGtToken(builder, tokenType);

      final PsiBuilder.Marker right = parseExpression(builder, type);
      if (right == null) {
        error(builder, JavaErrorMessages.message("expected.expression"));
        binary.done(JavaElementType.BINARY_EXPRESSION);
        return binary;
      }

      binary.done(JavaElementType.BINARY_EXPRESSION);
      left = binary;
    }

    return left;
  }
  @Nullable
  public static HighlightInfo checkMissingReturnStatement(PsiCodeBlock body, PsiType returnType) {
    if (body == null
        || returnType == null
        || PsiType.VOID.equals(returnType.getDeepComponentType())) {
      return null;
    }

    // do not compute constant expressions for if() statement condition
    // see JLS 14.20 Unreachable Statements
    try {
      ControlFlow controlFlow = getControlFlowNoConstantEvaluate(body);
      if (!ControlFlowUtil.returnPresent(controlFlow)) {
        PsiJavaToken rBrace = body.getRBrace();
        PsiElement context = rBrace == null ? body.getLastChild() : rBrace;
        String message = JavaErrorMessages.message("missing.return.statement");
        HighlightInfo info =
            HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
                .range(context)
                .descriptionAndTooltip(message)
                .create();
        PsiElement parent = body.getParent();
        if (parent instanceof PsiMethod) {
          PsiMethod method = (PsiMethod) parent;
          QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddReturnFix(method));
          QuickFixAction.registerQuickFixAction(
              info, QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true));
        }
        return info;
      }
    } catch (AnalysisCanceledException ignored) {
    }

    return null;
  }
  @Nullable
  private static String doCheckRepeatableAnnotation(@NotNull PsiAnnotation annotation) {
    PsiAnnotationOwner owner = annotation.getOwner();
    if (!(owner instanceof PsiModifierList)) return null;
    PsiElement target = ((PsiModifierList) owner).getParent();
    if (!(target instanceof PsiClass) || !((PsiClass) target).isAnnotationType()) return null;
    PsiClass container = getRepeatableContainer(annotation);
    if (container == null) return null;

    PsiMethod[] methods = container.findMethodsByName("value", false);
    if (methods.length == 0) {
      return JavaErrorMessages.message(
          "annotation.container.no.value", container.getQualifiedName());
    }

    if (methods.length == 1) {
      PsiType expected =
          new PsiImmediateClassType((PsiClass) target, PsiSubstitutor.EMPTY).createArrayType();
      if (!expected.equals(methods[0].getReturnType())) {
        return JavaErrorMessages.message(
            "annotation.container.bad.type",
            container.getQualifiedName(),
            JavaHighlightUtil.formatType(expected));
      }
    }

    RetentionPolicy targetPolicy = getRetentionPolicy((PsiClass) target);
    if (targetPolicy != null) {
      RetentionPolicy containerPolicy = getRetentionPolicy(container);
      if (containerPolicy != null && targetPolicy.compareTo(containerPolicy) > 0) {
        return JavaErrorMessages.message(
            "annotation.container.low.retention", container.getQualifiedName(), containerPolicy);
      }
    }

    Set<PsiAnnotation.TargetType> repeatableTargets =
        PsiImplUtil.getAnnotationTargets((PsiClass) target);
    if (repeatableTargets != null) {
      Set<PsiAnnotation.TargetType> containerTargets = PsiImplUtil.getAnnotationTargets(container);
      if (containerTargets != null && !repeatableTargets.containsAll(containerTargets)) {
        return JavaErrorMessages.message(
            "annotation.container.wide.target", container.getQualifiedName());
      }
    }

    return null;
  }
Esempio n. 13
0
  @NotNull
  public static PsiBuilder.Marker parseArgumentList(final PsiBuilder builder) {
    final PsiBuilder.Marker list = builder.mark();
    builder.advanceLexer();

    boolean first = true;
    while (true) {
      final IElementType tokenType = builder.getTokenType();
      if (first && (ARGS_LIST_END.contains(tokenType) || builder.eof())) break;
      if (!first && !ARGS_LIST_CONTINUE.contains(tokenType)) break;

      boolean hasError = false;
      if (!first) {
        if (builder.getTokenType() == JavaTokenType.COMMA) {
          builder.advanceLexer();
        } else {
          hasError = true;
          error(builder, JavaErrorMessages.message("expected.comma.or.rparen"));
          emptyExpression(builder);
        }
      }
      first = false;

      final PsiBuilder.Marker arg = parse(builder);
      if (arg == null) {
        if (!hasError) {
          error(builder, JavaErrorMessages.message("expected.expression"));
          emptyExpression(builder);
        }
        if (!ARGS_LIST_CONTINUE.contains(builder.getTokenType())) break;
        if (builder.getTokenType() != JavaTokenType.COMMA && !builder.eof()) {
          builder.advanceLexer();
        }
      }
    }

    final boolean closed =
        JavaParserUtil.expectOrError(
            builder, JavaTokenType.RPARENTH, JavaErrorMessages.message("expected.rparen"));

    list.done(JavaElementType.EXPRESSION_LIST);
    if (!closed) {
      list.setCustomEdgeTokenBinders(null, GREEDY_RIGHT_EDGE_PROCESSOR);
    }
    return list;
  }
  @Nullable
  public static String isAnnotationApplicable(
      @NotNull GrAnnotation annotation, final PsiElement parent) {
    PsiElement owner = parent.getParent();

    final PsiElement ownerToUse = parent instanceof PsiModifierList ? owner : parent;

    String[] elementTypeFields = GrAnnotationImpl.getApplicableElementTypeFields(ownerToUse);
    if (elementTypeFields != null
        && !GrAnnotationImpl.isAnnotationApplicableTo(annotation, false, elementTypeFields)) {
      final String annotationTargetText =
          JavaErrorMessages.message("annotation.target." + elementTypeFields[0]);
      GrCodeReferenceElement ref = annotation.getClassReference();
      return JavaErrorMessages.message(
          "annotation.not.applicable", ref.getText(), annotationTargetText);
    }

    return null;
  }
 @Nullable
 public static HighlightInfo checkValidAnnotationType(final PsiTypeElement typeElement) {
   PsiType type = typeElement.getType();
   if (type.accept(AnnotationReturnTypeVisitor.INSTANCE).booleanValue()) {
     return null;
   }
   String description = JavaErrorMessages.message("annotation.invalid.annotation.member.type");
   return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
       .range(typeElement)
       .descriptionAndTooltip(description)
       .create();
 }
  @Nullable
  private PsiBuilder.Marker parseRelational(final PsiBuilder builder) {
    PsiBuilder.Marker left = parseExpression(builder, ExprType.SHIFT);
    if (left == null) return null;

    IElementType tokenType;
    while ((tokenType = getGtTokenType(builder)) != null) {
      final IElementType toCreate;
      final ExprType toParse;
      if (RELATIONAL_OPS.contains(tokenType)) {
        toCreate = JavaElementType.BINARY_EXPRESSION;
        toParse = ExprType.SHIFT;
      } else if (tokenType == JavaTokenType.INSTANCEOF_KEYWORD) {
        toCreate = JavaElementType.INSTANCE_OF_EXPRESSION;
        toParse = ExprType.TYPE;
      } else {
        break;
      }

      final PsiBuilder.Marker expression = left.precede();
      advanceGtToken(builder, tokenType);

      final PsiBuilder.Marker right = parseExpression(builder, toParse);
      if (right == null) {
        error(
            builder,
            toParse == ExprType.TYPE
                ? JavaErrorMessages.message("expected.type")
                : JavaErrorMessages.message("expected.expression"));
        expression.done(toCreate);
        return expression;
      }

      expression.done(toCreate);
      left = expression;
    }

    return left;
  }
  @Nullable
  public static HighlightInfo checkNameValuePair(PsiNameValuePair pair) {
    PsiReference ref = pair.getReference();
    if (ref == null) return null;
    PsiMethod method = (PsiMethod) ref.resolve();
    if (method == null) {
      if (pair.getName() != null) {
        final String description =
            JavaErrorMessages.message("annotation.unknown.method", ref.getCanonicalText());
        PsiElement element = ref.getElement();
        final HighlightInfo highlightInfo =
            HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
                .range(element)
                .descriptionAndTooltip(description)
                .create();
        QuickFixAction.registerQuickFixAction(
            highlightInfo,
            QuickFixFactory.getInstance().createCreateAnnotationMethodFromUsageFix(pair));
        return highlightInfo;
      } else {
        String description =
            JavaErrorMessages.message("annotation.missing.method", ref.getCanonicalText());
        PsiElement element = ref.getElement();
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(element)
            .descriptionAndTooltip(description)
            .create();
      }
    } else {
      PsiType returnType = method.getReturnType();
      assert returnType != null : method;
      PsiAnnotationMemberValue value = pair.getValue();
      HighlightInfo info = checkMemberValueType(value, returnType);
      if (info != null) return info;

      return checkDuplicateAttribute(pair);
    }
  }
 @Nullable
 public static HighlightInfo checkCyclicMemberType(PsiTypeElement typeElement, PsiClass aClass) {
   LOG.assertTrue(aClass.isAnnotationType());
   PsiType type = typeElement.getType();
   final Set<PsiClass> checked = new HashSet<PsiClass>();
   if (cyclicDependencies(aClass, type, checked, aClass.getManager())) {
     String description = JavaErrorMessages.message("annotation.cyclic.element.type");
     return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
         .range(typeElement)
         .descriptionAndTooltip(description)
         .create();
   }
   return null;
 }
  @Nullable
  private static HighlightInfo checkReferenceTarget(
      PsiAnnotation annotation, @Nullable PsiJavaCodeReferenceElement ref) {
    if (ref == null) return null;
    PsiElement refTarget = ref.resolve();
    if (refTarget == null) return null;

    String message = null;
    if (!(refTarget instanceof PsiClass)) {
      message = JavaErrorMessages.message("annotation.not.allowed.ref");
    } else {
      PsiElement parent = ref.getParent();
      if (parent instanceof PsiJavaCodeReferenceElement) {
        PsiElement qualified = ((PsiJavaCodeReferenceElement) parent).resolve();
        if (qualified instanceof PsiMember
            && ((PsiMember) qualified).hasModifierProperty(PsiModifier.STATIC)) {
          message = JavaErrorMessages.message("annotation.not.allowed.static");
        }
      }
    }

    return message != null ? annotationError(annotation, message) : null;
  }
  @NotNull
  private PsiBuilder.Marker parseMethodReference(
      final PsiBuilder builder, final PsiBuilder.Marker start) {
    builder.advanceLexer();

    myParser.getReferenceParser().parseReferenceParameterList(builder, false, false);

    if (!expect(builder, JavaTokenType.IDENTIFIER) && !expect(builder, JavaTokenType.NEW_KEYWORD)) {
      error(builder, JavaErrorMessages.message("expected.identifier"));
    }

    start.done(JavaElementType.METHOD_REF_EXPRESSION);
    return start;
  }
  @Nullable
  static HighlightInfo checkVariableMustBeFinal(
      PsiVariable variable,
      PsiJavaCodeReferenceElement context,
      @NotNull LanguageLevel languageLevel) {
    if (variable.hasModifierProperty(PsiModifier.FINAL)) return null;
    final PsiClass innerClass = getInnerClassVariableReferencedFrom(variable, context);
    if (innerClass != null) {
      if (variable instanceof PsiParameter) {
        final PsiElement parent = variable.getParent();
        if (parent instanceof PsiParameterList
            && parent.getParent() instanceof PsiLambdaExpression
            && notAccessedForWriting(
                variable, new LocalSearchScope(((PsiParameter) variable).getDeclarationScope()))) {
          return null;
        }
      }
      if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)
          && isEffectivelyFinal(variable, innerClass, context)) {
        return null;
      }
      final String description =
          JavaErrorMessages.message("variable.must.be.final", context.getText());

      final HighlightInfo highlightInfo =
          HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
              .range(context)
              .descriptionAndTooltip(description)
              .create();
      QuickFixAction.registerQuickFixAction(
          highlightInfo,
          QUICK_FIX_FACTORY.createVariableAccessFromInnerClassFix(variable, innerClass));
      return highlightInfo;
    }
    final PsiLambdaExpression lambdaExpression =
        PsiTreeUtil.getParentOfType(context, PsiLambdaExpression.class);
    if (lambdaExpression != null && !PsiTreeUtil.isAncestor(lambdaExpression, variable, true)) {
      final PsiElement parent = variable.getParent();
      if (parent instanceof PsiParameterList && parent.getParent() == lambdaExpression) {
        return null;
      }
      if (!isEffectivelyFinal(variable, lambdaExpression, context)) {
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(context)
            .descriptionAndTooltip("Variable used in lambda expression should be effectively final")
            .create();
      }
    }
    return null;
  }
 @Nullable
 public static HighlightInfo checkAnnotationDeclaration(
     final PsiElement parent, final PsiReferenceList list) {
   if (PsiUtil.isAnnotationMethod(parent)) {
     PsiAnnotationMethod method = (PsiAnnotationMethod) parent;
     if (list == method.getThrowsList()) {
       String description =
           JavaErrorMessages.message("annotation.members.may.not.have.throws.list");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(list)
           .descriptionAndTooltip(description)
           .create();
     }
   } else if (parent instanceof PsiClass && ((PsiClass) parent).isAnnotationType()) {
     if (PsiKeyword.EXTENDS.equals(list.getFirstChild().getText())) {
       String description = JavaErrorMessages.message("annotation.may.not.have.extends.list");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(list)
           .descriptionAndTooltip(description)
           .create();
     }
   }
   return null;
 }
 @Nullable
 public static HighlightInfo checkAnnotationType(PsiAnnotation annotation) {
   PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
   if (nameReferenceElement != null) {
     PsiElement resolved = nameReferenceElement.resolve();
     if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) {
       String description = JavaErrorMessages.message("annotation.annotation.type.expected");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(nameReferenceElement)
           .descriptionAndTooltip(description)
           .create();
     }
   }
   return null;
 }
  @Nullable
  static HighlightInfo checkFileName(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
    if (!MODULE_INFO_FILE.equals(file.getName())) {
      String message = JavaErrorMessages.message("module.file.wrong.name");
      HighlightInfo info =
          HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
              .range(range(element))
              .description(message)
              .create();
      QuickFixAction.registerQuickFixAction(info, factory().createRenameFileFix(MODULE_INFO_FILE));
      return info;
    }

    return null;
  }
 @Nullable
 public static HighlightInfo checkPackageAnnotationContainingFile(
     final PsiPackageStatement statement) {
   if (statement.getAnnotationList() == null) {
     return null;
   }
   PsiFile file = statement.getContainingFile();
   if (file != null && !PsiPackage.PACKAGE_INFO_FILE.equals(file.getName())) {
     String description = JavaErrorMessages.message("invalid.package.annotation.containing.file");
     HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR);
     builder.range(statement.getAnnotationList().getTextRange());
     builder.descriptionAndTooltip(description);
     return builder.create();
   }
   return null;
 }
  @Nullable
  public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) {
    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;
    PsiClass aClass = (PsiClass) nameRef.resolve();
    if (aClass != null && aClass.isAnnotationType()) {
      Set<String> names = new HashSet<String>();
      PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final String name = attribute.getName();
        if (name != null) {
          names.add(name);
        } else {
          names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
        }
      }

      PsiMethod[] annotationMethods = aClass.getMethods();
      List<String> missed = new ArrayList<String>();
      for (PsiMethod method : annotationMethods) {
        if (PsiUtil.isAnnotationMethod(method)) {
          PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
          if (annotationMethod.getDefaultValue() == null) {
            if (!names.contains(annotationMethod.getName())) {
              missed.add(annotationMethod.getName());
            }
          }
        }
      }

      if (!missed.isEmpty()) {
        StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'");
        for (int i = 1; i < missed.size(); i++) {
          buff.append(", ");
          buff.append("'").append(missed.get(i)).append("'");
        }

        String description = JavaErrorMessages.message("annotation.missing.attribute", buff);
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(nameRef)
            .descriptionAndTooltip(description)
            .create();
      }
    }

    return null;
  }
  @Nullable
  public static HighlightInfo checkConstantExpression(PsiExpression expression) {
    final PsiElement parent = expression.getParent();
    if (PsiUtil.isAnnotationMethod(parent)
        || parent instanceof PsiNameValuePair
        || parent instanceof PsiArrayInitializerMemberValue) {
      if (!PsiUtil.isConstantExpression(expression)) {
        String description = JavaErrorMessages.message("annotation.non.constant.attribute.value");
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(expression)
            .descriptionAndTooltip(description)
            .create();
      }
    }

    return null;
  }
  @Nullable
  static HighlightInfo checkModuleReference(@Nullable PsiJavaModuleReferenceElement refElement) {
    if (refElement != null) {
      PsiPolyVariantReference ref = refElement.getReference();
      assert ref != null : refElement.getParent();
      if (ref.multiResolve(false).length == 0) {
        String message =
            JavaErrorMessages.message("module.ref.unknown", refElement.getReferenceText());
        return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
            .range(refElement)
            .description(message)
            .create();
      }
    }

    return null;
  }
 public static HighlightInfo checkUnreachableStatement(PsiCodeBlock codeBlock) {
   if (codeBlock == null) return null;
   // do not compute constant expressions for if() statement condition
   // see JLS 14.20 Unreachable Statements
   try {
     final ControlFlow controlFlow = getControlFlowNoConstantEvaluate(codeBlock);
     final PsiElement unreachableStatement = ControlFlowUtil.getUnreachableStatement(controlFlow);
     if (unreachableStatement != null) {
       String description = JavaErrorMessages.message("unreachable.statement");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(unreachableStatement)
           .descriptionAndTooltip(description)
           .create();
     }
   } catch (AnalysisCanceledException e) {
     // incomplete code
   } catch (IndexNotReadyException ignored) {
   }
   return null;
 }
 @Nullable
 static HighlightInfo checkFinalVariableInitializedInLoop(
     @NotNull PsiReferenceExpression expression, @NotNull PsiElement resolved) {
   if (ControlFlowUtil.isVariableAssignedInLoop(expression, resolved)) {
     String description =
         JavaErrorMessages.message(
             "variable.assigned.in.loop", ((PsiVariable) resolved).getName());
     final HighlightInfo highlightInfo =
         HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
             .range(expression)
             .descriptionAndTooltip(description)
             .create();
     QuickFixAction.registerQuickFixAction(
         highlightInfo,
         QUICK_FIX_FACTORY.createModifierListFix(
             (PsiVariable) resolved, PsiModifier.FINAL, false, false));
     return highlightInfo;
   }
   return null;
 }