Package ro.redeul.google.go.lang.folding

Source Code of ro.redeul.google.go.lang.folding.GoFoldingBuilder

package ro.redeul.google.go.lang.folding;

import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import ro.redeul.google.go.lang.parser.GoElementTypes;

import java.util.ArrayList;
import java.util.List;

/**
* Created by IntelliJ IDEA.
* User: mtoader
* Date: Aug 17, 2010
* Time: 11:21:29 PM
* To change this template use File | Settings | File Templates.
*/
public class GoFoldingBuilder implements FoldingBuilder, DumbAware, GoElementTypes {
    @NotNull
    public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) {
        List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
        appendDescriptors(node.getPsi(), document, descriptors);
        return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
    }

    private void appendDescriptors(PsiElement psi, Document document, List<FoldingDescriptor> descriptors) {
        ASTNode node = psi.getNode();
        if (node == null || !isMultiline(psi)) return;
        IElementType type = node.getElementType();

        if (mML_COMMENT == type) {
            descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
            return;
        }

        if ( TYPE_DECLARATIONS == type) {
            addDescriptorStartFromChildNode(descriptors, node, "{");
            return;
        }

        if (CONST_DECLARATIONS == type || VAR_DECLARATIONS == type || IMPORT_DECLARATIONS == type) {
            addDescriptorStartFromChildNode(descriptors, node, "(");
            return;
        }

        if ( BLOCK_STATEMENT == type) {
            descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
        }

        PsiElement child = psi.getFirstChild();
        while (child != null) {
            appendDescriptors(child, document, descriptors);
            child = child.getNextSibling();
        }
    }

    private void addDescriptorStartFromChildNode(List<FoldingDescriptor> descriptors, ASTNode node, String childText) {
        ASTNode startNode = findChildOfText(node, childText);
        if (startNode != null) {
            int end = node.getStartOffset() + node.getTextLength();
            descriptors.add(new FoldingDescriptor(node, new TextRange(startNode.getStartOffset(), end)));
        }
    }

    private static ASTNode findChildOfText(ASTNode parent, String text) {
        ASTNode child = parent.getFirstChildNode();
        while (child != null) {
            if (child.getText().equals(text)) {
                break;
            }
            ASTNode sub = findChildOfText(child, text);
            if (sub != null) {
                return sub;
            }
            child = child.getTreeNext();
        }
        return child;
    }

    public String getPlaceholderText(@NotNull ASTNode node) {
        return "{ ... }";
    }

    public boolean isCollapsedByDefault(@NotNull ASTNode node) {
        return false;
    }

    private static boolean isMultiline(PsiElement element) {
        String text = element.getText();
        return text.contains("\n") || text.contains("\r") || text.contains("\r\n");
    }
}
TOP

Related Classes of ro.redeul.google.go.lang.folding.GoFoldingBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.