Search in sources :

Example 6 with OuterLanguageElement

use of com.intellij.psi.templateLanguages.OuterLanguageElement in project intellij-community by JetBrains.

the class JavaTreeCopyHandler method decodeInformation.

@Override
public TreeElement decodeInformation(TreeElement element, final Map<Object, Object> decodingState) {
    boolean shallDecodeEscapedTexts = shallEncodeEscapedTexts(element, decodingState);
    if (element instanceof CompositeElement) {
        final IElementType elementType = element.getElementType();
        if (elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION || elementType == JavaElementType.METHOD_REF_EXPRESSION) {
            PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element);
            final PsiClass refClass = element.getCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY);
            if (refClass != null) {
                element.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, null);
                PsiManager manager = refClass.getManager();
                JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(refClass.getProject());
                PsiElement refElement1 = ref.resolve();
                try {
                    if (refClass != refElement1 && !manager.areElementsEquivalent(refClass, refElement1)) {
                        if (((CompositeElement) element).findChildByRole(ChildRole.QUALIFIER) == null) {
                            // can restore only if short (otherwise qualifier should be already restored)
                            ref = (PsiJavaCodeReferenceElement) ref.bindToElement(refClass);
                        }
                    } else {
                        // shorten references to the same package and to inner classes that can be accessed by short name
                        ref = (PsiJavaCodeReferenceElement) codeStyleManager.shortenClassReferences(ref, JavaCodeStyleManager.DO_NOT_ADD_IMPORTS);
                    }
                    return (TreeElement) SourceTreeToPsiMap.psiElementToTree(ref);
                } catch (IncorrectOperationException e) {
                    ((PsiImportHolder) ref.getContainingFile()).importClass(refClass);
                }
            } else {
                final PsiMember refMember = element.getCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY);
                if (refMember != null) {
                    LOG.assertTrue(ref instanceof PsiReferenceExpression);
                    element.putCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY, null);
                    PsiElement refElement1 = ref.resolve();
                    if (refMember != refElement1 && !refMember.getManager().areElementsEquivalent(refMember, refElement1)) {
                        try {
                            ref = (PsiJavaCodeReferenceElement) ((PsiReferenceExpression) ref).bindToElementViaStaticImport(refMember.getContainingClass());
                        } catch (IncorrectOperationException e) {
                        // TODO[yole] ignore?
                        }
                        return (TreeElement) SourceTreeToPsiMap.psiElementToTree(ref);
                    }
                }
            }
        } else if (element.getElementType() == JavaElementType.MODIFIER_LIST) {
            if (element.getUserData(INTERFACE_MODIFIERS_FLAG_KEY) != null) {
                element.putUserData(INTERFACE_MODIFIERS_FLAG_KEY, null);
                try {
                    PsiModifierList modifierList = (PsiModifierList) SourceTreeToPsiMap.treeElementToPsi(element);
                    if (element.getTreeParent().getElementType() == JavaElementType.FIELD) {
                        modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
                        modifierList.setModifierProperty(PsiModifier.STATIC, true);
                        modifierList.setModifierProperty(PsiModifier.FINAL, true);
                    } else if (element.getTreeParent().getElementType() == JavaElementType.METHOD || element.getTreeParent().getElementType() == JavaElementType.ANNOTATION_METHOD) {
                        modifierList.setModifierProperty(PsiModifier.PUBLIC, true);
                        modifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
                    }
                } catch (IncorrectOperationException e) {
                    LOG.error(e);
                }
            }
        }
    } else if (shallDecodeEscapedTexts && element instanceof LeafElement && !(element instanceof OuterLanguageElement)) {
        if (!isInCData(element)) {
            final String original = element.getText();
            final String escaped = StringUtil.escapeXml(original);
            if (!Comparing.equal(original, escaped) && element.getCopyableUserData(ALREADY_ESCAPED) == null) {
                LeafElement copy = ((LeafElement) element).replaceWithText(escaped);
                copy.putCopyableUserData(ALREADY_ESCAPED, Boolean.TRUE);
                return copy;
            }
        }
    }
    return null;
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) IElementType(com.intellij.psi.tree.IElementType) JavaCodeStyleManager(com.intellij.psi.codeStyle.JavaCodeStyleManager) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 7 with OuterLanguageElement

use of com.intellij.psi.templateLanguages.OuterLanguageElement 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 8 with OuterLanguageElement

use of com.intellij.psi.templateLanguages.OuterLanguageElement in project intellij-community by JetBrains.

the class JavaClassListReferenceProvider method getReferencesByString.

@Override
@NotNull
public PsiReference[] getReferencesByString(String str, @NotNull final PsiElement position, int offsetInPosition) {
    if (position instanceof XmlTag && ((XmlTag) position).getValue().getTextElements().length == 0) {
        return PsiReference.EMPTY_ARRAY;
    }
    if (str.length() < 2) {
        return PsiReference.EMPTY_ARRAY;
    }
    int offset = position.getTextRange().getStartOffset() + offsetInPosition;
    for (PsiElement child = position.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (child instanceof OuterLanguageElement && child.getTextRange().contains(offset)) {
            return PsiReference.EMPTY_ARRAY;
        }
    }
    NotNullLazyValue<Set<String>> topLevelPackages = new NotNullLazyValue<Set<String>>() {

        @NotNull
        @Override
        protected Set<String> compute() {
            final Set<String> knownTopLevelPackages = new HashSet<>();
            final List<PsiElement> defaultPackages = getDefaultPackages(position.getProject());
            for (final PsiElement pack : defaultPackages) {
                if (pack instanceof PsiPackage) {
                    knownTopLevelPackages.add(((PsiPackage) pack).getName());
                }
            }
            return knownTopLevelPackages;
        }
    };
    final List<PsiReference> results = new ArrayList<>();
    for (int dot = str.indexOf('.'); dot > 0; dot = str.indexOf('.', dot + 1)) {
        int start = dot;
        while (start > 0 && Character.isLetterOrDigit(str.charAt(start - 1))) start--;
        if (dot == start) {
            continue;
        }
        String candidate = str.substring(start, dot);
        if (topLevelPackages.getValue().contains(candidate)) {
            int end = dot;
            while (end < str.length() - 1) {
                end++;
                char ch = str.charAt(end);
                if (ch != '.' && !Character.isJavaIdentifierPart(ch)) {
                    break;
                }
            }
            String s = str.substring(start, end + 1);
            ContainerUtil.addAll(results, new JavaClassReferenceSet(s, position, offsetInPosition + start, false, this) {

                @Override
                public boolean isSoft() {
                    return true;
                }

                @Override
                public boolean isAllowDollarInNames() {
                    return true;
                }
            }.getAllReferences());
            ProgressManager.checkCanceled();
        }
    }
    return ContainerUtil.toArray(results, new PsiReference[results.size()]);
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) Set(java.util.Set) HashSet(java.util.HashSet) NotNullLazyValue(com.intellij.openapi.util.NotNullLazyValue) ArrayList(java.util.ArrayList) PsiReference(com.intellij.psi.PsiReference) PsiPackage(com.intellij.psi.PsiPackage) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with OuterLanguageElement

use of com.intellij.psi.templateLanguages.OuterLanguageElement in project intellij-community by JetBrains.

the class MultiplePsiFilesPerDocumentFileViewProvider method findElementAt.

@Override
@Nullable
public PsiElement findElementAt(int offset, @NotNull Class<? extends Language> lang) {
    final PsiFile mainRoot = getPsi(getBaseLanguage());
    PsiElement ret = null;
    for (final Language language : getLanguages()) {
        if (!ReflectionUtil.isAssignable(lang, language.getClass()))
            continue;
        if (lang.equals(Language.class) && !getLanguages().contains(language))
            continue;
        final PsiFile psiRoot = getPsi(language);
        final PsiElement psiElement = findElementAt(psiRoot, offset);
        if (psiElement == null || psiElement instanceof OuterLanguageElement)
            continue;
        if (ret == null || psiRoot != mainRoot) {
            ret = psiElement;
        }
    }
    return ret;
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) Language(com.intellij.lang.Language) Nullable(org.jetbrains.annotations.Nullable)

Example 10 with OuterLanguageElement

use of com.intellij.psi.templateLanguages.OuterLanguageElement in project intellij-community by JetBrains.

the class SelectWordHandler method selectWord.

@Nullable("null means unable to select")
private static TextRange selectWord(@NotNull Caret caret, @NotNull Project project) {
    Document document = caret.getEditor().getDocument();
    PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
    if (file == null)
        return null;
    FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.select.word");
    int caretOffset = adjustCaretOffset(caret);
    PsiElement element = findElementAt(file, caretOffset);
    if (element instanceof PsiWhiteSpace && caretOffset > 0) {
        PsiElement anotherElement = findElementAt(file, caretOffset - 1);
        if (!(anotherElement instanceof PsiWhiteSpace)) {
            element = anotherElement;
        }
    }
    while (element instanceof PsiWhiteSpace || element != null && StringUtil.isEmptyOrSpaces(element.getText())) {
        while (element.getNextSibling() == null) {
            if (element instanceof PsiFile)
                return null;
            final PsiElement parent = element.getParent();
            final PsiElement[] children = parent.getChildren();
            if (children.length > 0 && children[children.length - 1] == element) {
                element = parent;
            } else {
                element = parent;
                break;
            }
        }
        if (element instanceof PsiFile)
            return null;
        element = element.getNextSibling();
        if (element == null)
            return null;
        TextRange range = element.getTextRange();
        // Fix NPE (EA-29110)
        if (range == null)
            return null;
        caretOffset = range.getStartOffset();
    }
    if (element instanceof OuterLanguageElement) {
        PsiElement elementInOtherTree = file.getViewProvider().findElementAt(element.getTextOffset(), element.getLanguage());
        if (elementInOtherTree == null || elementInOtherTree.getContainingFile() != element.getContainingFile()) {
            while (elementInOtherTree != null && elementInOtherTree.getPrevSibling() == null) {
                elementInOtherTree = elementInOtherTree.getParent();
            }
            if (elementInOtherTree != null) {
                assert elementInOtherTree.getTextOffset() == caretOffset;
                element = elementInOtherTree;
            }
        }
    }
    checkElementRange(document, element);
    final TextRange selectionRange = new TextRange(caret.getSelectionStart(), caret.getSelectionEnd());
    final Ref<TextRange> minimumRange = new Ref<>(new TextRange(0, document.getTextLength()));
    SelectWordUtil.processRanges(element, document.getCharsSequence(), caretOffset, caret.getEditor(), range -> {
        if (range.contains(selectionRange) && !range.equals(selectionRange)) {
            if (minimumRange.get().contains(range)) {
                minimumRange.set(range);
                return true;
            }
        }
        return false;
    });
    return minimumRange.get();
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) Ref(com.intellij.openapi.util.Ref) PsiFile(com.intellij.psi.PsiFile) TextRange(com.intellij.openapi.util.TextRange) Document(com.intellij.openapi.editor.Document) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

OuterLanguageElement (com.intellij.psi.templateLanguages.OuterLanguageElement)14 ASTNode (com.intellij.lang.ASTNode)5 PsiElement (com.intellij.psi.PsiElement)5 TextRange (com.intellij.openapi.util.TextRange)4 IElementType (com.intellij.psi.tree.IElementType)4 ArrayList (java.util.ArrayList)4 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)3 NotNull (org.jetbrains.annotations.NotNull)3 XMLLanguage (com.intellij.lang.xml.XMLLanguage)2 PsiFile (com.intellij.psi.PsiFile)2 XmlAttribute (com.intellij.psi.xml.XmlAttribute)2 XmlTag (com.intellij.psi.xml.XmlTag)2 IncorrectOperationException (com.intellij.util.IncorrectOperationException)2 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)2 Nullable (org.jetbrains.annotations.Nullable)2 WebEditorOptions (com.intellij.application.options.editor.WebEditorOptions)1 HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)1 Language (com.intellij.lang.Language)1 Document (com.intellij.openapi.editor.Document)1 HighlighterIterator (com.intellij.openapi.editor.highlighter.HighlighterIterator)1