Search in sources :

Example 81 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class PyCompletionConfidence method shouldSkipAutopopup.

@NotNull
@Override
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
    ASTNode node = contextElement.getNode();
    if (node != null) {
        if (node.getElementType() == PyTokenTypes.FLOAT_LITERAL) {
            return ThreeState.YES;
        }
        if (PyTokenTypes.STRING_NODES.contains(node.getElementType())) {
            final PsiElement parent = contextElement.getParent();
            if (parent instanceof PyStringLiteralExpression) {
                final List<TextRange> ranges = ((PyStringLiteralExpression) parent).getStringValueTextRanges();
                int relativeOffset = offset - parent.getTextRange().getStartOffset();
                if (ranges.size() > 0 && relativeOffset < ranges.get(0).getStartOffset()) {
                    return ThreeState.YES;
                }
            }
        }
    }
    return super.shouldSkipAutopopup(contextElement, psiFile, offset);
}
Also used : PyStringLiteralExpression(com.jetbrains.python.psi.PyStringLiteralExpression) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 82 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class PythonFoldingBuilder method appendDescriptors.

private static void appendDescriptors(ASTNode node, List<FoldingDescriptor> descriptors) {
    IElementType elementType = node.getElementType();
    if (elementType instanceof PyFileElementType) {
        final List<PyImportStatementBase> imports = ((PyFile) node.getPsi()).getImportBlock();
        if (imports.size() > 1) {
            final PyImportStatementBase firstImport = imports.get(0);
            final PyImportStatementBase lastImport = imports.get(imports.size() - 1);
            descriptors.add(new FoldingDescriptor(firstImport, new TextRange(firstImport.getTextRange().getStartOffset(), lastImport.getTextRange().getEndOffset())));
        }
    } else if (elementType == PyElementTypes.STATEMENT_LIST) {
        foldStatementList(node, descriptors);
    } else if (elementType == PyElementTypes.STRING_LITERAL_EXPRESSION) {
        foldLongStrings(node, descriptors);
    } else if (FOLDABLE_COLLECTIONS_LITERALS.contains(elementType)) {
        foldCollectionLiteral(node, descriptors);
    } else if (elementType == PyTokenTypes.END_OF_LINE_COMMENT) {
        foldSequentialComments(node, descriptors);
    }
    ASTNode child = node.getFirstChildNode();
    while (child != null) {
        appendDescriptors(child, descriptors);
        child = child.getTreeNext();
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange)

Example 83 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class PythonFoldingBuilder method foldSequentialComments.

private static void foldSequentialComments(ASTNode node, List<FoldingDescriptor> descriptors) {
    //do not start folded comments from custom region
    if (isCustomRegionElement(node.getPsi())) {
        return;
    }
    //need to skip previous comments in sequence
    ASTNode curNode = node.getTreePrev();
    while (curNode != null) {
        if (curNode.getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
            if (isCustomRegionElement(curNode.getPsi())) {
                break;
            }
            return;
        }
        curNode = curNode.getPsi() instanceof PsiWhiteSpace ? curNode.getTreePrev() : null;
    }
    //fold sequence comments in one block
    curNode = node.getTreeNext();
    ASTNode lastCommentNode = node;
    while (curNode != null) {
        if (curNode.getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
            //do not end folded comments with custom region
            if (isCustomRegionElement(curNode.getPsi())) {
                break;
            }
            lastCommentNode = curNode;
            curNode = curNode.getTreeNext();
            continue;
        }
        curNode = curNode.getPsi() instanceof PsiWhiteSpace ? curNode.getTreeNext() : null;
    }
    if (lastCommentNode != node) {
        descriptors.add(new FoldingDescriptor(node, TextRange.create(node.getStartOffset(), lastCommentNode.getTextRange().getEndOffset())));
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 84 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class XmlCopyPastePreProcessor method preprocessOnPaste.

@Override
@NotNull
public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
    final Document document = editor.getDocument();
    PsiDocumentManager.getInstance(project).commitDocument(document);
    int caretOffset = editor.getCaretModel().getOffset();
    PsiElement element = PsiUtilCore.getElementAtOffset(file, caretOffset);
    ASTNode node = element.getNode();
    if (node != null) {
        boolean hasMarkup = text.indexOf('>') >= 0 || text.indexOf('<') >= 0;
        if (element.getTextOffset() == caretOffset && node.getElementType() == XmlTokenType.XML_END_TAG_START && node.getTreePrev().getElementType() == XmlTokenType.XML_TAG_END) {
            return hasMarkup ? text : encode(text, element);
        } else {
            XmlElement parent = PsiTreeUtil.getParentOfType(element, XmlText.class, XmlAttributeValue.class);
            if (parent != null) {
                if (parent instanceof XmlText && hasMarkup) {
                    return text;
                }
                if (TreeUtil.findParent(node, XmlElementType.XML_CDATA) == null && TreeUtil.findParent(node, XmlElementType.XML_COMMENT) == null) {
                    return encode(text, element);
                }
            }
        }
    }
    return text;
}
Also used : ASTNode(com.intellij.lang.ASTNode) Document(com.intellij.openapi.editor.Document) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 85 with ASTNode

use of com.intellij.lang.ASTNode in project intellij-community by JetBrains.

the class XmlGtTypedHandler method beforeCharTyped.

@Override
public Result beforeCharTyped(final char c, final Project project, Editor editor, PsiFile editedFile, final FileType fileType) {
    final WebEditorOptions webEditorOptions = WebEditorOptions.getInstance();
    if (c == '>' && webEditorOptions != null && webEditorOptions.isAutomaticallyInsertClosingTag() && fileContainsXmlLanguage(editedFile)) {
        PsiDocumentManager.getInstance(project).commitAllDocuments();
        PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
        FileViewProvider provider = editedFile.getViewProvider();
        int offset = editor.getCaretModel().getOffset();
        PsiElement element, elementAtCaret = null;
        if (offset < editor.getDocument().getTextLength()) {
            elementAtCaret = element = provider.findElementAt(offset, XMLLanguage.class);
            if (element == null && offset > 0) {
                // seems like a template language
                // <xml_code><caret><outer_element>
                elementAtCaret = element = provider.findElementAt(offset - 1, XMLLanguage.class);
            }
            if (!(element instanceof PsiWhiteSpace)) {
                boolean nonAcceptableDelimiter = true;
                if (element instanceof XmlToken) {
                    IElementType tokenType = ((XmlToken) element).getTokenType();
                    if (tokenType == XmlTokenType.XML_START_TAG_START || tokenType == XmlTokenType.XML_END_TAG_START) {
                        if (offset > 0) {
                            PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class);
                            if (previousElement instanceof XmlToken) {
                                tokenType = ((XmlToken) previousElement).getTokenType();
                                element = previousElement;
                                nonAcceptableDelimiter = false;
                            }
                        }
                    } else if (tokenType == XmlTokenType.XML_NAME || tokenType == XmlTokenType.XML_TAG_NAME) {
                        if (element.getNextSibling() instanceof PsiErrorElement) {
                            nonAcceptableDelimiter = false;
                        }
                    }
                    if (tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) {
                        EditorModificationUtil.moveCaretRelatively(editor, 1);
                        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
                        return Result.STOP;
                    }
                }
                if (nonAcceptableDelimiter)
                    return Result.CONTINUE;
            } else {
                // check if right after empty end
                PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class);
                if (previousElement instanceof XmlToken) {
                    final IElementType tokenType = ((XmlToken) previousElement).getTokenType();
                    if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
                        return Result.STOP;
                    }
                }
            }
            PsiElement parent = element.getParent();
            if (parent instanceof XmlText) {
                final String text = parent.getText();
                // check /
                final int index = offset - parent.getTextOffset() - 1;
                if (index >= 0 && text.charAt(index) == '/') {
                    // already seen /
                    return Result.CONTINUE;
                }
                element = parent.getPrevSibling();
            } else if (parent instanceof XmlTag && !(element.getPrevSibling() instanceof XmlTag) && !(element.getPrevSibling() instanceof OuterLanguageElement)) {
                element = parent;
            } else if (parent instanceof XmlAttributeValue) {
                element = parent;
            }
        } else {
            element = provider.findElementAt(editor.getDocument().getTextLength() - 1, XMLLanguage.class);
            if (element == null)
                return Result.CONTINUE;
            element = element.getParent();
        }
        if (offset > 0 && offset <= editor.getDocument().getTextLength()) {
            if (editor.getDocument().getCharsSequence().charAt(offset - 1) == '/') {
                // Some languages (e.g. GSP) allow character '/' in tag name.
                return Result.CONTINUE;
            }
        }
        if (element instanceof XmlAttributeValue) {
            element = element.getParent().getParent();
        }
        while (element instanceof PsiWhiteSpace || element instanceof OuterLanguageElement) element = element.getPrevSibling();
        if (element instanceof XmlDocument) {
            // hack for closing tags in RHTML
            element = element.getLastChild();
        }
        if (element == null)
            return Result.CONTINUE;
        if (!(element instanceof XmlTag)) {
            if (element instanceof XmlTokenImpl && element.getPrevSibling() != null && element.getPrevSibling().getText().equals("<")) {
                // tag is started and there is another text in the end
                EditorModificationUtil.insertStringAtCaret(editor, "</" + element.getText() + ">", false, 0);
            }
            return Result.CONTINUE;
        }
        XmlTag tag = (XmlTag) element;
        if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_TAG_END) != null)
            return Result.CONTINUE;
        if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null)
            return Result.CONTINUE;
        final XmlToken startToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_START_TAG_START);
        if (startToken == null || !startToken.getText().equals("<"))
            return Result.CONTINUE;
        String name = tag.getName();
        if (elementAtCaret instanceof XmlToken && (((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_NAME || ((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_TAG_NAME)) {
            name = name.substring(0, offset - elementAtCaret.getTextOffset());
        }
        if (tag instanceof HtmlTag && HtmlUtil.isSingleHtmlTag(name))
            return Result.CONTINUE;
        if (name.isEmpty())
            return Result.CONTINUE;
        int tagOffset = tag.getTextRange().getStartOffset();
        final XmlToken nameToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_NAME);
        if (nameToken != null && nameToken.getTextRange().getStartOffset() > offset)
            return Result.CONTINUE;
        HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(tagOffset);
        if (BraceMatchingUtil.matchBrace(editor.getDocument().getCharsSequence(), editedFile.getFileType(), iterator, true, true)) {
            PsiElement parent = tag.getParent();
            boolean hasBalance = true;
            loop: while (parent instanceof XmlTag) {
                if (name.equals(((XmlTag) parent).getName())) {
                    hasBalance = false;
                    ASTNode astNode = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode());
                    if (astNode == null) {
                        hasBalance = true;
                        break;
                    }
                    for (PsiElement el = parent.getNextSibling(); el != null; el = el.getNextSibling()) {
                        if (el instanceof PsiErrorElement && el.getText().startsWith("</" + name)) {
                            hasBalance = true;
                            break loop;
                        }
                    }
                }
                parent = parent.getParent();
            }
            if (hasBalance)
                return Result.CONTINUE;
        }
        Collection<TextRange> cdataReformatRanges = null;
        final XmlElementDescriptor descriptor = tag.getDescriptor();
        EditorModificationUtil.insertStringAtCaret(editor, "</" + name + ">", false, 0);
        if (descriptor instanceof XmlElementDescriptorWithCDataContent) {
            final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent) descriptor;
            cdataReformatRanges = ContainerUtil.newSmartList();
            if (cDataContainer.requiresCdataBracesInContext(tag)) {
                @NonNls final String cDataStart = "><![CDATA[";
                final String inserted = cDataStart + "\n]]>";
                EditorModificationUtil.insertStringAtCaret(editor, inserted, false, cDataStart.length());
                int caretOffset = editor.getCaretModel().getOffset();
                if (caretOffset >= cDataStart.length()) {
                    cdataReformatRanges.add(TextRange.from(caretOffset - cDataStart.length(), inserted.length() + 1));
                }
            }
        }
        if (cdataReformatRanges != null && !cdataReformatRanges.isEmpty()) {
            PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
            try {
                CodeStyleManager.getInstance(project).reformatText(file, cdataReformatRanges);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
        }
        return cdataReformatRanges != null && !cdataReformatRanges.isEmpty() ? Result.STOP : Result.CONTINUE;
    }
    return Result.CONTINUE;
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) XmlTokenImpl(com.intellij.psi.impl.source.xml.XmlTokenImpl) TemplateLanguageFileViewProvider(com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider) WebEditorOptions(com.intellij.application.options.editor.WebEditorOptions) ASTNode(com.intellij.lang.ASTNode) XMLLanguage(com.intellij.lang.xml.XMLLanguage) NonNls(org.jetbrains.annotations.NonNls) HtmlTag(com.intellij.psi.html.HtmlTag) TextRange(com.intellij.openapi.util.TextRange) IElementType(com.intellij.psi.tree.IElementType) XmlElementDescriptorWithCDataContent(com.intellij.xml.XmlElementDescriptorWithCDataContent) IncorrectOperationException(com.intellij.util.IncorrectOperationException) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) HighlighterIterator(com.intellij.openapi.editor.highlighter.HighlighterIterator)

Aggregations

ASTNode (com.intellij.lang.ASTNode)748 PsiElement (com.intellij.psi.PsiElement)142 NotNull (org.jetbrains.annotations.NotNull)132 IElementType (com.intellij.psi.tree.IElementType)127 Nullable (org.jetbrains.annotations.Nullable)99 TextRange (com.intellij.openapi.util.TextRange)91 ArrayList (java.util.ArrayList)53 IncorrectOperationException (com.intellij.util.IncorrectOperationException)35 PsiFile (com.intellij.psi.PsiFile)31 Annotation (com.intellij.lang.annotation.Annotation)22 CharTable (com.intellij.util.CharTable)22 Document (com.intellij.openapi.editor.Document)18 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)17 XmlTag (com.intellij.psi.xml.XmlTag)17 Project (com.intellij.openapi.project.Project)16 AbstractBlock (com.intellij.psi.formatter.common.AbstractBlock)16 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)16 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)15 CompositeElement (com.intellij.psi.impl.source.tree.CompositeElement)15 PsiReference (com.intellij.psi.PsiReference)14