Search in sources :

Example 21 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.

the class DartFoldingBuilder method foldMultilineStrings.

private static void foldMultilineStrings(@NotNull final List<FoldingDescriptor> descriptors, @NotNull final Collection<PsiElement> psiElements) {
    for (PsiElement element : psiElements) {
        if (element instanceof DartStringLiteralExpression) {
            DartStringLiteralExpression dartString = (DartStringLiteralExpression) element;
            PsiElement child = dartString.getFirstChild();
            if (child == null)
                continue;
            IElementType type = child.getNode().getElementType();
            if (type == DartTokenTypes.RAW_TRIPLE_QUOTED_STRING || (type == DartTokenTypes.OPEN_QUOTE && child.getTextLength() == 3)) {
                descriptors.add(new FoldingDescriptor(dartString, dartString.getTextRange()));
            }
        }
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) PsiElement(com.intellij.psi.PsiElement)

Example 22 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.

the class DartFoldingBuilder method foldComments.

private static void foldComments(@NotNull final List<FoldingDescriptor> descriptors, @NotNull final Collection<PsiElement> psiElements, @Nullable final TextRange fileHeaderRange) {
    PsiElement psiElement;
    for (Iterator<PsiElement> iter = psiElements.iterator(); iter.hasNext(); ) {
        psiElement = iter.next();
        if (!(psiElement instanceof PsiComment)) {
            continue;
        }
        if (fileHeaderRange != null && fileHeaderRange.intersects(psiElement.getTextRange())) {
            continue;
        }
        final IElementType elementType = psiElement.getNode().getElementType();
        if ((elementType == DartTokenTypesSets.MULTI_LINE_DOC_COMMENT || elementType == DartTokenTypesSets.MULTI_LINE_COMMENT) && !isCustomRegionElement(psiElement)) {
            descriptors.add(new FoldingDescriptor(psiElement, psiElement.getTextRange()));
        } else if (elementType == DartTokenTypesSets.SINGLE_LINE_DOC_COMMENT || elementType == DartTokenTypesSets.SINGLE_LINE_COMMENT) {
            final PsiElement firstCommentInSequence = psiElement;
            PsiElement lastCommentInSequence = firstCommentInSequence;
            PsiElement nextElement = firstCommentInSequence;
            boolean containsCustomRegionMarker = isCustomRegionElement(nextElement);
            while (iter.hasNext() && (nextElement = nextElement.getNextSibling()) != null && (nextElement instanceof PsiWhiteSpace || nextElement.getNode().getElementType() == elementType)) {
                if (nextElement.getNode().getElementType() == elementType) {
                    // advance iterator to skip processed comments sequence
                    iter.next();
                    lastCommentInSequence = nextElement;
                    containsCustomRegionMarker |= isCustomRegionElement(nextElement);
                }
            }
            if (lastCommentInSequence != firstCommentInSequence && !containsCustomRegionMarker) {
                final TextRange range = TextRange.create(firstCommentInSequence.getTextRange().getStartOffset(), lastCommentInSequence.getTextRange().getEndOffset());
                descriptors.add(new FoldingDescriptor(firstCommentInSequence, range));
            }
        }
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PsiComment(com.intellij.psi.PsiComment) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 23 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-plugins by JetBrains.

the class HbFoldingBuilder method appendDescriptors.

private void appendDescriptors(PsiElement psi, List<FoldingDescriptor> descriptors, Document document) {
    if (isSingleLine(psi, document)) {
        return;
    }
    if (HbTokenTypes.COMMENT == psi.getNode().getElementType()) {
        ASTNode commentNode = psi.getNode();
        String commentText = commentNode.getText();
        // tags before we allow folding
        if (commentText.length() > 6 && commentText.substring(0, 3).equals("{{!") && commentText.substring(commentText.length() - 2, commentText.length()).equals("}}")) {
            TextRange range = new TextRange(commentNode.getTextRange().getStartOffset() + 3, commentNode.getTextRange().getEndOffset() - 2);
            descriptors.add(new FoldingDescriptor(commentNode, range));
        }
    }
    if (psi instanceof HbBlockWrapper) {
        PsiElement endOpenBlockStache = getOpenBlockCloseStacheElement(psi.getFirstChild());
        PsiElement endCloseBlockStache = getCloseBlockCloseStacheElement(psi.getLastChild());
        // if we've got a well formed block with the open and close elems we need, define a region to fold
        if (endOpenBlockStache != null && endCloseBlockStache != null) {
            int endOfFirstOpenStacheLine = document.getLineEndOffset(document.getLineNumber(psi.getTextRange().getStartOffset()));
            // we set the start of the text we'll fold to be just before the close braces of the open stache,
            //     or, if the open stache spans multiple lines, to the end of the first line
            int foldingRangeStartOffset = Math.min(endOpenBlockStache.getTextRange().getStartOffset(), endOfFirstOpenStacheLine);
            // we set the end of the text we'll fold to be just before the final close braces in this block
            int foldingRangeEndOffset = endCloseBlockStache.getTextRange().getStartOffset();
            TextRange range = new TextRange(foldingRangeStartOffset, foldingRangeEndOffset);
            descriptors.add(new FoldingDescriptor(psi, range));
        }
    }
    PsiElement child = psi.getFirstChild();
    while (child != null) {
        appendDescriptors(child, descriptors, document);
        child = child.getNextSibling();
    }
}
Also used : HbBlockWrapper(com.dmarcotte.handlebars.psi.HbBlockWrapper) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement)

Example 24 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-elixir by KronicDeth.

the class Builder method buildFoldRegions.

/*
     * Instance Methods
     */
/**
     * Builds the folding regions for the specified node in the AST tree and its children.
     *
     * @param root     the element for which folding is requested.
     * @param document the document for which folding is built. Can be used to retrieve line
     *                 numbers for folding regions.
     * @param quick    whether the result should be provided as soon as possible. Is true, when
     *                 an editor is opened and we need to auto-fold something immediately, like Java imports.
     *                 If true, one should perform no reference resolving and avoid complex checks if possible.
     * @return the array of folding descriptors.
     */
@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, final boolean quick) {
    final List<FoldingDescriptor> foldingDescriptorList = new ArrayList<FoldingDescriptor>();
    PsiTreeUtil.processElements(root, new PsiElementProcessor() {

        private Map<String, FoldingGroup> foldingGroupByModuleAttributeName = new HashMap<String, FoldingGroup>();

        /*
                     *
                     * Instance Methods
                     *
                     */
        /*
                     * Public Instance Methods
                     */
        @Override
        public boolean execute(@NotNull PsiElement element) {
            boolean keepProcessing = true;
            if (element instanceof AtNonNumericOperation) {
                keepProcessing = execute((AtNonNumericOperation) element);
            } else if (element instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = execute((AtUnqualifiedNoParenthesesCall) element);
            } else if (element instanceof ElixirDoBlock) {
                keepProcessing = execute((ElixirDoBlock) element);
            } else if (element instanceof ElixirStabOperation) {
                keepProcessing = execute((ElixirStabOperation) element);
            } else if (element instanceof Call) {
                keepProcessing = execute((Call) element);
            }
            return keepProcessing;
        }

        /*
                     * Private Instance Methods
                     */
        private boolean execute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            if (!quick) {
                keepProcessing = slowExecute(atNonNumericOperation);
            }
            return keepProcessing;
        }

        private boolean execute(@NotNull AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            String moduleAttributeName = moduleAttributeName(atUnqualifiedNoParenthesesCall);
            String name = moduleAttributeName.substring(1);
            if (ModuleAttribute.isDocumentationName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                foldingDescriptorList.add(new NamedFoldingDescriptor(noParenthesesOneArgument.getNode(), noParenthesesOneArgument.getTextRange(), null, "\"...\""));
            } else if (ModuleAttribute.isTypeName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                PsiElement[] children = noParenthesesOneArgument.getChildren();
                if (children.length == 1) {
                    PsiElement child = children[0];
                    if (child instanceof Type) {
                        Type type = (Type) child;
                        PsiElement rightOperand = Normalized.rightOperand(type);
                        if (rightOperand != null) {
                            foldingDescriptorList.add(new NamedFoldingDescriptor(rightOperand.getNode(), rightOperand.getTextRange(), null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull Call call) {
            for (String resolvedFunctionName : RESOLVED_FUNCTION_NAMES) {
                if (call.isCalling(KERNEL, resolvedFunctionName)) {
                    if (isFirstInGroup(call, KERNEL, resolvedFunctionName)) {
                        Call last = lastInGroup(call, KERNEL, resolvedFunctionName);
                        PsiElement[] finalArguments = finalArguments(call);
                        if (finalArguments != null && finalArguments.length >= 1) {
                            TextRange textRange = new TextRange(finalArguments[0].getTextOffset(), last.getTextRange().getEndOffset());
                            foldingDescriptorList.add(new NamedFoldingDescriptor(call.getParent().getNode(), textRange, null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull ElixirDoBlock doBlock) {
            foldingDescriptorList.add(new FoldingDescriptor(doBlock, doBlock.getTextRange()));
            return true;
        }

        private boolean execute(@NotNull ElixirStabOperation stabOperation) {
            int startOffset = stabOperation.operator().getTextOffset();
            int endOffset = stabOperation.getTextRange().getEndOffset();
            TextRange textRange = new TextRange(startOffset, endOffset);
            foldingDescriptorList.add(new FoldingDescriptor(stabOperation, textRange));
            return true;
        }

        private boolean isFirstInGroup(@NotNull Call call, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement previousSiblingExpression = previousSiblingExpression(call);
            boolean first = true;
            if (previousSiblingExpression instanceof Call) {
                Call previousSiblingExpressionCall = (Call) previousSiblingExpression;
                first = !previousSiblingExpressionCall.isCalling(resolvedModuleName, resolvedFunctionName);
            }
            return first;
        }

        @NotNull
        private Call lastInGroup(@NotNull Call first, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement expression = first;
            Call last = first;
            while (true) {
                expression = nextSiblingExpression(expression);
                if (expression instanceof Call) {
                    Call call = (Call) expression;
                    if (call.isCalling(resolvedModuleName, resolvedFunctionName)) {
                        last = call;
                        continue;
                    }
                }
                break;
            }
            return last;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            PsiReference reference = atNonNumericOperation.getReference();
            if (reference != null) {
                keepProcessing = slowExecute(atNonNumericOperation, reference);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            return slowExecute(atNonNumericOperation, atUnqualifiedNoParenthesesCall, atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument().getText());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement target) {
            boolean keepProcessing = true;
            if (target instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = slowExecute(atNonNumericOperation, (AtUnqualifiedNoParenthesesCall) target);
            } else if (target instanceof QualifiableAlias) {
                keepProcessing = slowExecute(atNonNumericOperation, (QualifiableAlias) target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiReference reference) {
            PsiElement target = reference.resolve();
            boolean keepProcessing = true;
            if (target != null) {
                keepProcessing = slowExecute(atNonNumericOperation, target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final QualifiableAlias qualifiableAlias) {
            return slowExecute(atNonNumericOperation, qualifiableAlias, qualifiableAlias.getName());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement element, @Nullable final String placeHolderText) {
            String moduleAttributeName = atNonNumericOperation.moduleAttributeName();
            FoldingGroup foldingGroup = foldingGroupByModuleAttributeName.get(moduleAttributeName);
            if (foldingGroup == null) {
                foldingGroup = FoldingGroup.newGroup(moduleAttributeName);
                foldingGroupByModuleAttributeName.put(moduleAttributeName, foldingGroup);
            }
            foldingDescriptorList.add(new FoldingDescriptor(atNonNumericOperation.getNode(), atNonNumericOperation.getTextRange(), foldingGroup, Collections.<Object>singleton(element)) {

                @Nullable
                @Override
                public String getPlaceholderText() {
                    return placeHolderText;
                }
            });
            return true;
        }
    });
    return foldingDescriptorList.toArray(new FoldingDescriptor[foldingDescriptorList.size()]);
}
Also used : Call(org.elixir_lang.psi.call.Call) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) PsiReference(com.intellij.psi.PsiReference) TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) Type(org.elixir_lang.psi.operation.Type) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 25 with FoldingDescriptor

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

the class JsonFoldingBuilder method collectDescriptorsRecursively.

private static void collectDescriptorsRecursively(@NotNull ASTNode node, @NotNull Document document, @NotNull List<FoldingDescriptor> descriptors) {
    final IElementType type = node.getElementType();
    if ((type == JsonElementTypes.OBJECT || type == JsonElementTypes.ARRAY) && spanMultipleLines(node, document)) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
    } else if (type == JsonElementTypes.BLOCK_COMMENT) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
    } else if (type == JsonElementTypes.LINE_COMMENT) {
        final Couple<PsiElement> commentRange = expandLineCommentsRange(node.getPsi());
        final int startOffset = commentRange.getFirst().getTextRange().getStartOffset();
        final int endOffset = commentRange.getSecond().getTextRange().getEndOffset();
        if (document.getLineNumber(startOffset) != document.getLineNumber(endOffset)) {
            descriptors.add(new FoldingDescriptor(node, new TextRange(startOffset, endOffset)));
        }
    }
    for (ASTNode child : node.getChildren(null)) {
        collectDescriptorsRecursively(child, document, descriptors);
    }
}
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) PsiElement(com.intellij.psi.PsiElement)

Aggregations

FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)39 TextRange (com.intellij.openapi.util.TextRange)24 ASTNode (com.intellij.lang.ASTNode)17 PsiElement (com.intellij.psi.PsiElement)12 IElementType (com.intellij.psi.tree.IElementType)9 NamedFoldingDescriptor (com.intellij.lang.folding.NamedFoldingDescriptor)8 UnfairTextRange (com.intellij.openapi.util.UnfairTextRange)6 PsiComment (com.intellij.psi.PsiComment)5 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)5 FoldingGroup (com.intellij.openapi.editor.FoldingGroup)4 NotNull (org.jetbrains.annotations.NotNull)4 FoldRegion (com.intellij.openapi.editor.FoldRegion)3 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)3 LinkedList (java.util.LinkedList)3 HbBlockWrapper (com.dmarcotte.handlebars.psi.HbBlockWrapper)2 FoldingBuilder (com.intellij.lang.folding.FoldingBuilder)2 ArrayList (java.util.ArrayList)2 Nullable (org.jetbrains.annotations.Nullable)2 LocalResourceRepository (com.android.tools.idea.res.LocalResourceRepository)1 BraceMatcher (com.intellij.codeInsight.highlighting.BraceMatcher)1