Search in sources :

Example 1 with NamedFoldingDescriptor

use of com.intellij.lang.folding.NamedFoldingDescriptor in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoFoldingBuilder method buildLanguageFoldRegions.

@Override
protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> result, @NotNull PsiElement root, @NotNull Document document, boolean quick) {
    if (!(root instanceof GoFile))
        return;
    GoFile file = (GoFile) root;
    if (!file.isContentsLoaded())
        return;
    GoImportList importList = ((GoFile) root).getImportList();
    if (importList != null) {
        GoImportDeclaration firstImport = ContainerUtil.getFirstItem(importList.getImportDeclarationList());
        if (firstImport != null) {
            PsiElement importKeyword = firstImport.getImport();
            int offset = importKeyword.getTextRange().getEndOffset();
            int startOffset = importKeyword.getNextSibling() instanceof PsiWhiteSpace ? offset + 1 : offset;
            int endOffset = importList.getTextRange().getEndOffset();
            if (endOffset - startOffset > 3) {
                result.add(new NamedFoldingDescriptor(importList, startOffset, endOffset, null, "..."));
            }
        }
    }
    for (GoBlock block : PsiTreeUtil.findChildrenOfType(file, GoBlock.class)) {
        if (block.getTextRange().getLength() > 1) {
            result.add(new NamedFoldingDescriptor(block.getNode(), block.getTextRange(), null, "{...}"));
        }
    }
    for (GoExprSwitchStatement switchStatement : PsiTreeUtil.findChildrenOfType(file, GoExprSwitchStatement.class)) {
        fold(switchStatement, switchStatement.getLbrace(), switchStatement.getRbrace(), "{...}", result);
    }
    for (GoSelectStatement selectStatement : PsiTreeUtil.findChildrenOfType(file, GoSelectStatement.class)) {
        fold(selectStatement, selectStatement.getLbrace(), selectStatement.getRbrace(), "{...}", result);
    }
    for (GoTypeSpec type : file.getTypes()) {
        foldTypes(type.getSpecType().getType(), result);
    }
    for (GoCaseClause caseClause : PsiTreeUtil.findChildrenOfType(file, GoCaseClause.class)) {
        PsiElement colon = caseClause.getColon();
        if (colon != null && !caseClause.getStatementList().isEmpty()) {
            fold(caseClause, colon.getNextSibling(), caseClause, "...", result);
        }
    }
    for (GoCommClause commClause : PsiTreeUtil.findChildrenOfType(file, GoCommClause.class)) {
        PsiElement colon = commClause.getColon();
        if (colon != null && !commClause.getStatementList().isEmpty()) {
            fold(commClause, colon.getNextSibling(), commClause, "...", result);
        }
    }
    for (GoVarDeclaration varDeclaration : PsiTreeUtil.findChildrenOfType(file, GoVarDeclaration.class)) {
        if (varDeclaration.getVarSpecList().size() > 1) {
            fold(varDeclaration, varDeclaration.getLparen(), varDeclaration.getRparen(), "(...)", result);
        }
    }
    for (GoConstDeclaration constDeclaration : PsiTreeUtil.findChildrenOfType(file, GoConstDeclaration.class)) {
        if (constDeclaration.getConstSpecList().size() > 1) {
            fold(constDeclaration, constDeclaration.getLparen(), constDeclaration.getRparen(), "(...)", result);
        }
    }
    for (GoTypeDeclaration typeDeclaration : PsiTreeUtil.findChildrenOfType(file, GoTypeDeclaration.class)) {
        if (typeDeclaration.getTypeSpecList().size() > 1) {
            fold(typeDeclaration, typeDeclaration.getLparen(), typeDeclaration.getRparen(), "(...)", result);
        }
    }
    for (GoCompositeLit compositeLit : PsiTreeUtil.findChildrenOfType(file, GoCompositeLit.class)) {
        GoLiteralValue literalValue = compositeLit.getLiteralValue();
        if (literalValue != null && literalValue.getElementList().size() > 1) {
            fold(literalValue, literalValue.getLbrace(), literalValue.getRbrace(), "{...}", result);
        }
    }
    if (!quick) {
        Set<PsiElement> processedComments = ContainerUtil.newHashSet();
        PsiTreeUtil.processElements(file, element -> {
            ASTNode node = element.getNode();
            IElementType type = node.getElementType();
            TextRange range = element.getTextRange();
            if (type == GoParserDefinition.MULTILINE_COMMENT && range.getLength() > 2) {
                result.add(new NamedFoldingDescriptor(node, range, null, "/*...*/"));
            }
            if (type == GoParserDefinition.LINE_COMMENT) {
                addCommentFolds(element, processedComments, result);
            }
            foldTypes(element, result);
            return true;
        });
    }
}
Also used : TextRange(com.intellij.openapi.util.TextRange) IElementType(com.intellij.psi.tree.IElementType) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 2 with NamedFoldingDescriptor

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

the class GroovyFoldingBuilder method addFoldingForStrings.

private static void addFoldingForStrings(List<FoldingDescriptor> descriptors, ASTNode node) {
    if (!isMultiLineStringLiteral(node))
        return;
    if (!node.getElementType().equals(GroovyElementTypes.GSTRING) && !node.getElementType().equals(GroovyElementTypes.REGEX)) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
        return;
    }
    final GrString grString = (GrString) node.getPsi();
    if (grString == null)
        return;
    final GrStringInjection[] injections = grString.getInjections();
    if (injections.length == 0) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
        return;
    }
    final String start_quote = GrStringUtil.getStartQuote(node.getText());
    final String end_quote = GrStringUtil.getEndQuote(node.getText());
    final FoldingGroup group = FoldingGroup.newGroup("GString");
    final TextRange nodeRange = node.getTextRange();
    int startOffset = nodeRange.getStartOffset();
    GrStringInjection injection = injections[0];
    TextRange injectionRange = injection.getTextRange();
    if (startOffset + 1 < injectionRange.getStartOffset()) {
        descriptors.add(new NamedFoldingDescriptor(node, startOffset, injectionRange.getStartOffset(), group, start_quote));
    }
    final String placeholder = " ";
    startOffset = injectionRange.getEndOffset();
    for (int i = 1; i < injections.length; i++) {
        injection = injections[i];
        injectionRange = injection.getTextRange();
        final int endOffset = injectionRange.getStartOffset();
        if (endOffset - startOffset >= 2) {
            descriptors.add(new NamedFoldingDescriptor(injection.getNode().getTreePrev(), startOffset, endOffset, group, placeholder));
        }
        startOffset = injectionRange.getEndOffset();
    }
    if (startOffset + 1 < nodeRange.getEndOffset()) {
        descriptors.add(new NamedFoldingDescriptor(node.getLastChildNode(), startOffset, nodeRange.getEndOffset(), group, end_quote));
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) GrString(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString) TextRange(com.intellij.openapi.util.TextRange) GrString(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString) GrStringInjection(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection)

Example 3 with NamedFoldingDescriptor

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

the class GroovyFoldingBuilder method collapseBlock.

private static void collapseBlock(List<FoldingDescriptor> descriptors, PsiElement psi) {
    if (psi instanceof GrCodeBlock) {
        final int lineFeedCount = StringUtil.countChars(psi.getText(), '\n');
        if (lineFeedCount <= 2) {
            final PsiElement lbrace = ((GrCodeBlock) psi).getLBrace();
            final PsiElement rbrace = ((GrCodeBlock) psi).getRBrace();
            if (lbrace != null && rbrace != null) {
                final PsiElement next = lbrace.getNextSibling();
                final PsiElement prev = rbrace.getPrevSibling();
                if (next != null && PsiImplUtil.isWhiteSpaceOrNls(next) && prev != null && PsiImplUtil.isWhiteSpaceOrNls(prev)) {
                    final FoldingGroup group = FoldingGroup.newGroup("block_group");
                    descriptors.add(new NamedFoldingDescriptor(psi, lbrace.getTextRange().getStartOffset(), next.getTextRange().getEndOffset(), group, "{"));
                    descriptors.add(new NamedFoldingDescriptor(psi, prev.getTextRange().getStartOffset(), rbrace.getTextRange().getEndOffset(), group, "}"));
                    return;
                }
            }
        }
    }
    descriptors.add(new FoldingDescriptor(psi, psi.getTextRange()));
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) GrCodeBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)

Example 4 with NamedFoldingDescriptor

use of com.intellij.lang.folding.NamedFoldingDescriptor in project go-lang-idea-plugin by go-lang-plugin-org.

the class GoFoldingBuilder method addCommentFolds.

// com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase.addCodeBlockFolds()
private static void addCommentFolds(@NotNull PsiElement comment, @NotNull Set<PsiElement> processedComments, @NotNull List<FoldingDescriptor> result) {
    if (processedComments.contains(comment))
        return;
    PsiElement end = null;
    for (PsiElement current = comment.getNextSibling(); current != null; current = current.getNextSibling()) {
        ASTNode node = current.getNode();
        if (node == null)
            break;
        IElementType elementType = node.getElementType();
        if (elementType == GoParserDefinition.LINE_COMMENT) {
            end = current;
            processedComments.add(current);
            continue;
        }
        if (elementType == TokenType.WHITE_SPACE)
            continue;
        break;
    }
    if (end != null) {
        int startOffset = comment.getTextRange().getStartOffset();
        int endOffset = end.getTextRange().getEndOffset();
        result.add(new NamedFoldingDescriptor(comment, startOffset, endOffset, null, "/.../"));
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) PsiElement(com.intellij.psi.PsiElement)

Example 5 with NamedFoldingDescriptor

use of com.intellij.lang.folding.NamedFoldingDescriptor 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)

Aggregations

NamedFoldingDescriptor (com.intellij.lang.folding.NamedFoldingDescriptor)7 FoldingGroup (com.intellij.openapi.editor.FoldingGroup)5 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)3 TextRange (com.intellij.openapi.util.TextRange)3 PsiElement (com.intellij.psi.PsiElement)3 ASTNode (com.intellij.lang.ASTNode)2 IElementType (com.intellij.psi.tree.IElementType)2 Document (com.intellij.openapi.editor.Document)1 PsiReference (com.intellij.psi.PsiReference)1 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)1 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)1 PsiElementProcessor (com.intellij.psi.search.PsiElementProcessor)1 ArrayList (java.util.ArrayList)1 Call (org.elixir_lang.psi.call.Call)1 Type (org.elixir_lang.psi.operation.Type)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1 GrCodeBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)1 GrString (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString)1 GrStringInjection (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection)1