Search in sources :

Example 66 with HighlightInfo

use of com.intellij.codeInsight.daemon.impl.HighlightInfo in project intellij-community by JetBrains.

the class HighlightUtil method checkLiteralExpressionParsingError.

@Nullable
public static HighlightInfo checkLiteralExpressionParsingError(@NotNull PsiLiteralExpression expression, LanguageLevel level, PsiFile file) {
    PsiElement literal = expression.getFirstChild();
    assert literal instanceof PsiJavaToken : literal;
    IElementType type = ((PsiJavaToken) literal).getTokenType();
    if (type == JavaTokenType.TRUE_KEYWORD || type == JavaTokenType.FALSE_KEYWORD || type == JavaTokenType.NULL_KEYWORD) {
        return null;
    }
    boolean isInt = PsiLiteralExpressionImpl.INTEGER_LITERALS.contains(type);
    boolean isFP = PsiLiteralExpressionImpl.REAL_LITERALS.contains(type);
    String text = isInt || isFP ? literal.getText().toLowerCase() : literal.getText();
    Object value = expression.getValue();
    if (level != null && file != null) {
        if (isFP) {
            if (text.startsWith(PsiLiteralExpressionImpl.HEX_PREFIX)) {
                final HighlightInfo info = checkFeature(expression, Feature.HEX_FP_LITERALS, level, file);
                if (info != null)
                    return info;
            }
        }
        if (isInt) {
            if (text.startsWith(PsiLiteralExpressionImpl.BIN_PREFIX)) {
                final HighlightInfo info = checkFeature(expression, Feature.BIN_LITERALS, level, file);
                if (info != null)
                    return info;
            }
        }
        if (isInt || isFP) {
            if (text.contains("_")) {
                HighlightInfo info = checkFeature(expression, Feature.UNDERSCORES, level, file);
                if (info != null)
                    return info;
                info = checkUnderscores(expression, text, isInt);
                if (info != null)
                    return info;
            }
        }
    }
    final PsiElement parent = expression.getParent();
    if (type == JavaTokenType.INTEGER_LITERAL) {
        String cleanText = StringUtil.replace(text, "_", "");
        //literal 2147483648 may appear only as the operand of the unary negation operator -.
        if (!(cleanText.equals(PsiLiteralExpressionImpl._2_IN_31) && parent instanceof PsiPrefixExpression && ((PsiPrefixExpression) parent).getOperationTokenType() == JavaTokenType.MINUS)) {
            if (cleanText.equals(PsiLiteralExpressionImpl.HEX_PREFIX)) {
                String message = JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            if (cleanText.equals(PsiLiteralExpressionImpl.BIN_PREFIX)) {
                String message = JavaErrorMessages.message("binary.numbers.must.contain.at.least.one.hexadecimal.digit");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            if (value == null || cleanText.equals(PsiLiteralExpressionImpl._2_IN_31)) {
                String message = JavaErrorMessages.message("integer.number.too.large");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
        }
    } else if (type == JavaTokenType.LONG_LITERAL) {
        String cleanText = StringUtil.replace(StringUtil.trimEnd(text, 'l'), "_", "");
        //literal 9223372036854775808L may appear only as the operand of the unary negation operator -.
        if (!(cleanText.equals(PsiLiteralExpressionImpl._2_IN_63) && parent instanceof PsiPrefixExpression && ((PsiPrefixExpression) parent).getOperationTokenType() == JavaTokenType.MINUS)) {
            if (cleanText.equals(PsiLiteralExpressionImpl.HEX_PREFIX)) {
                String message = JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            if (cleanText.equals(PsiLiteralExpressionImpl.BIN_PREFIX)) {
                String message = JavaErrorMessages.message("binary.numbers.must.contain.at.least.one.hexadecimal.digit");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            if (value == null || cleanText.equals(PsiLiteralExpressionImpl._2_IN_63)) {
                String message = JavaErrorMessages.message("long.number.too.large");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
        }
    } else if (isFP) {
        if (value == null) {
            String message = JavaErrorMessages.message("malformed.floating.point.literal");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        }
    } else if (type == JavaTokenType.CHARACTER_LITERAL) {
        if (value != null) {
            if (!StringUtil.endsWithChar(text, '\'')) {
                String message = JavaErrorMessages.message("unclosed.char.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
        } else {
            if (!StringUtil.startsWithChar(text, '\'')) {
                return null;
            }
            if (StringUtil.endsWithChar(text, '\'')) {
                if (text.length() == 1) {
                    String message = JavaErrorMessages.message("illegal.line.end.in.character.literal");
                    return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
                }
                text = text.substring(1, text.length() - 1);
            } else {
                String message = JavaErrorMessages.message("illegal.line.end.in.character.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            StringBuilder chars = new StringBuilder();
            boolean success = PsiLiteralExpressionImpl.parseStringCharacters(text, chars, null);
            if (!success) {
                String message = JavaErrorMessages.message("illegal.escape.character.in.character.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            int length = chars.length();
            if (length > 1) {
                String message = JavaErrorMessages.message("too.many.characters.in.character.literal");
                HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
                QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createConvertToStringLiteralAction());
                return info;
            } else if (length == 0) {
                String message = JavaErrorMessages.message("empty.character.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
        }
    } else if (type == JavaTokenType.STRING_LITERAL) {
        if (value == null) {
            for (PsiElement element : expression.getChildren()) {
                if (element instanceof OuterLanguageElement) {
                    return null;
                }
            }
            if (!StringUtil.startsWithChar(text, '\"'))
                return null;
            if (StringUtil.endsWithChar(text, '\"')) {
                if (text.length() == 1) {
                    String message = JavaErrorMessages.message("illegal.line.end.in.string.literal");
                    return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
                }
                text = text.substring(1, text.length() - 1);
            } else {
                String message = JavaErrorMessages.message("illegal.line.end.in.string.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
            StringBuilder chars = new StringBuilder();
            boolean success = PsiLiteralExpressionImpl.parseStringCharacters(text, chars, null);
            if (!success) {
                String message = JavaErrorMessages.message("illegal.escape.character.in.string.literal");
                return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
            }
        }
    }
    if (value instanceof Float) {
        Float number = (Float) value;
        if (number.isInfinite()) {
            String message = JavaErrorMessages.message("floating.point.number.too.large");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        }
        if (number.floatValue() == 0 && !TypeConversionUtil.isFPZero(text)) {
            String message = JavaErrorMessages.message("floating.point.number.too.small");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        }
    } else if (value instanceof Double) {
        Double number = (Double) value;
        if (number.isInfinite()) {
            String message = JavaErrorMessages.message("floating.point.number.too.large");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        }
        if (number.doubleValue() == 0 && !TypeConversionUtil.isFPZero(text)) {
            String message = JavaErrorMessages.message("floating.point.number.too.small");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        }
    }
    return null;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo)

Example 67 with HighlightInfo

use of com.intellij.codeInsight.daemon.impl.HighlightInfo in project intellij-community by JetBrains.

the class HighlightUtil method checkReferenceToOurInstanceInsideThisOrSuper.

@Nullable
private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper(@NotNull final PsiElement expression, @NotNull PsiClass referencedClass, final String resolvedName, @NotNull PsiFile containingFile) {
    if (PsiTreeUtil.getParentOfType(expression, PsiReferenceParameterList.class) != null)
        return null;
    PsiElement element = expression.getParent();
    while (element != null) {
        // check if expression inside super()/this() call
        if (RefactoringChangeUtil.isSuperOrThisMethodCall(element)) {
            PsiElement parentClass = new PsiMatcherImpl(element).parent(PsiMatchers.hasClass(PsiExpressionStatement.class)).parent(PsiMatchers.hasClass(PsiCodeBlock.class)).parent(PsiMatchers.hasClass(PsiMethod.class)).dot(JavaMatchers.isConstructor(true)).parent(PsiMatchers.hasClass(PsiClass.class)).getElement();
            if (parentClass == null) {
                return null;
            }
            // only this class/superclasses instance methods are not allowed to call
            PsiClass aClass = (PsiClass) parentClass;
            if (PsiUtil.isInnerClass(aClass) && referencedClass == aClass.getContainingClass())
                return null;
            // field or method should be declared in this class or super
            if (!InheritanceUtil.isInheritorOrSelf(aClass, referencedClass, true))
                return null;
            // and point to our instance
            if (expression instanceof PsiReferenceExpression && !thisOrSuperReference(((PsiReferenceExpression) expression).getQualifierExpression(), aClass)) {
                return null;
            }
            if (expression instanceof PsiJavaCodeReferenceElement && !aClass.equals(PsiTreeUtil.getParentOfType(expression, PsiClass.class)) && PsiTreeUtil.getParentOfType(expression, PsiTypeElement.class) != null) {
                return null;
            }
            if (expression instanceof PsiJavaCodeReferenceElement && PsiTreeUtil.getParentOfType(expression, PsiClassObjectAccessExpression.class) != null) {
                return null;
            }
            final HighlightInfo highlightInfo = createMemberReferencedError(resolvedName, expression.getTextRange());
            if (expression instanceof PsiReferenceExpression && PsiUtil.isInnerClass(aClass)) {
                final String referenceName = ((PsiReferenceExpression) expression).getReferenceName();
                final PsiClass containingClass = aClass.getContainingClass();
                LOG.assertTrue(containingClass != null);
                final PsiField fieldInContainingClass = containingClass.findFieldByName(referenceName, true);
                if (fieldInContainingClass != null && ((PsiReferenceExpression) expression).getQualifierExpression() == null) {
                    QuickFixAction.registerQuickFixAction(highlightInfo, new QualifyWithThisFix(containingClass, expression));
                }
            }
            return highlightInfo;
        }
        if (element instanceof PsiReferenceExpression) {
            final PsiElement resolve;
            if (element instanceof PsiReferenceExpressionImpl) {
                PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl) element;
                JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(referenceExpression, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, false, containingFile);
                resolve = results.length == 1 ? results[0].getElement() : null;
            } else {
                resolve = ((PsiReferenceExpression) element).resolve();
            }
            if (resolve instanceof PsiField && ((PsiField) resolve).hasModifierProperty(PsiModifier.STATIC)) {
                return null;
            }
        }
        element = element.getParent();
        if (element instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass) element, referencedClass, true))
            return null;
    }
    return null;
}
Also used : HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) PsiReferenceExpressionImpl(com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl)

Example 68 with HighlightInfo

use of com.intellij.codeInsight.daemon.impl.HighlightInfo in project intellij-community by JetBrains.

the class HighlightUtil method checkClassReferenceAfterQualifier.

@Nullable
static HighlightInfo checkClassReferenceAfterQualifier(@NotNull final PsiReferenceExpression expression, final PsiElement resolved) {
    if (!(resolved instanceof PsiClass))
        return null;
    final PsiExpression qualifier = expression.getQualifierExpression();
    if (qualifier == null)
        return null;
    if (qualifier instanceof PsiReferenceExpression) {
        PsiElement qualifierResolved = ((PsiReferenceExpression) qualifier).resolve();
        if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage)
            return null;
    }
    String description = JavaErrorMessages.message("expected.class.or.package");
    HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
    QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createRemoveQualifierFix(qualifier, expression, (PsiClass) resolved));
    return info;
}
Also used : HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo)

Example 69 with HighlightInfo

use of com.intellij.codeInsight.daemon.impl.HighlightInfo in project intellij-community by JetBrains.

the class HighlightUtil method checkVariableInitializerType.

@Nullable
static HighlightInfo checkVariableInitializerType(@NotNull PsiVariable variable) {
    PsiExpression initializer = variable.getInitializer();
    // array initializer checked in checkArrayInitializerApplicable
    if (initializer == null || initializer instanceof PsiArrayInitializerExpression)
        return null;
    PsiType lType = variable.getType();
    PsiType rType = initializer.getType();
    PsiTypeElement typeElement = variable.getTypeElement();
    int start = typeElement != null ? typeElement.getTextRange().getStartOffset() : variable.getTextRange().getStartOffset();
    int end = variable.getTextRange().getEndOffset();
    HighlightInfo highlightInfo = checkAssignability(lType, rType, initializer, new TextRange(start, end), 0);
    if (highlightInfo != null) {
        registerChangeVariableTypeFixes(variable, rType, variable.getInitializer(), highlightInfo);
        registerChangeVariableTypeFixes(initializer, lType, null, highlightInfo);
    }
    return highlightInfo;
}
Also used : HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange)

Example 70 with HighlightInfo

use of com.intellij.codeInsight.daemon.impl.HighlightInfo in project intellij-community by JetBrains.

the class HighlightUtil method checkSwitchSelectorType.

@Nullable
static HighlightInfo checkSwitchSelectorType(@NotNull PsiSwitchStatement statement, @NotNull LanguageLevel level) {
    PsiExpression expression = statement.getExpression();
    if (expression == null)
        return null;
    PsiType type = expression.getType();
    if (type == null)
        return null;
    SelectorKind kind = getSwitchSelectorKind(type);
    if (kind == SelectorKind.INT)
        return null;
    LanguageLevel requiredLevel = null;
    if (kind == SelectorKind.ENUM)
        requiredLevel = LanguageLevel.JDK_1_5;
    if (kind == SelectorKind.STRING)
        requiredLevel = LanguageLevel.JDK_1_7;
    if (kind == null || requiredLevel != null && !level.isAtLeast(requiredLevel)) {
        boolean is7 = level.isAtLeast(LanguageLevel.JDK_1_7);
        String expected = JavaErrorMessages.message(is7 ? "valid.switch.17.selector.types" : "valid.switch.selector.types");
        String message = JavaErrorMessages.message("incompatible.types", expected, JavaHighlightUtil.formatType(type));
        HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
        QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createConvertSwitchToIfIntention(statement));
        if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
            QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddTypeCastFix(PsiType.INT, expression));
            QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(PsiType.INT, expression));
        }
        if (requiredLevel != null) {
            QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createIncreaseLanguageLevelFix(requiredLevel));
        }
        return info;
    }
    PsiClass member = PsiUtil.resolveClassInClassTypeOnly(type);
    if (member != null && !PsiUtil.isAccessible(member.getProject(), member, expression, null)) {
        String className = PsiFormatUtil.formatClass(member, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_FQ_NAME);
        String message = JavaErrorMessages.message("inaccessible.type", className);
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
    }
    return null;
}
Also used : LanguageLevel(com.intellij.pom.java.LanguageLevel) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo)

Aggregations

HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)221 Nullable (org.jetbrains.annotations.Nullable)51 TextRange (com.intellij.openapi.util.TextRange)33 IntentionAction (com.intellij.codeInsight.intention.IntentionAction)30 VirtualFile (com.intellij.openapi.vfs.VirtualFile)28 NotNull (org.jetbrains.annotations.NotNull)17 HighlightInfoType (com.intellij.codeInsight.daemon.impl.HighlightInfoType)16 Document (com.intellij.openapi.editor.Document)12 ArrayList (java.util.ArrayList)11 PsiElement (com.intellij.psi.PsiElement)10 File (java.io.File)8 TextAttributes (com.intellij.openapi.editor.markup.TextAttributes)7 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)6 Pair (com.intellij.openapi.util.Pair)6 PsiFile (com.intellij.psi.PsiFile)6 Editor (com.intellij.openapi.editor.Editor)5 NonNls (org.jetbrains.annotations.NonNls)5 StringUtil (com.intellij.openapi.util.text.StringUtil)4 IElementType (com.intellij.psi.tree.IElementType)4 ContainerUtil (com.intellij.util.containers.ContainerUtil)4