Package com.dci.intellij.dbn.language.psql

Source Code of com.dci.intellij.dbn.language.psql.PSQLFoldingBuilder

package com.dci.intellij.dbn.language.psql;

import com.dci.intellij.dbn.language.common.element.ElementType;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeAttribute;
import com.dci.intellij.dbn.language.common.psi.BasePsiElement;
import com.dci.intellij.dbn.language.common.psi.ChameleonPsiElement;
import com.dci.intellij.dbn.language.common.psi.TokenPsiElement;
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.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;

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

public class PSQLFoldingBuilder implements FoldingBuilder {

    @NotNull
    public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) {
        List<FoldingDescriptor> foldingDescriptors = new ArrayList<FoldingDescriptor>();
        createFoldingDescriptors(node.getPsi(), document, foldingDescriptors, 0);
        return foldingDescriptors.toArray(new FoldingDescriptor[foldingDescriptors.size()]);
    }

    private void createFoldingDescriptors(PsiElement psiElement, Document document, List<FoldingDescriptor> foldingDescriptors, int nestingIndex) {
        PsiElement child = psiElement.getFirstChild();
        while (child != null) {
            if (child instanceof PsiComment) {
                String text = child.getText();
                if (text.startsWith("/*") && text.indexOf('\n') > -1) {
                    FoldingDescriptor foldingDescriptor = new FoldingDescriptor(
                            child.getNode(),
                            child.getTextRange());

                    foldingDescriptors.add(foldingDescriptor);
                }
            }
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                ElementType elementType = basePsiElement.getElementType();
                int blockEndOffset = basePsiElement.getTextOffset() + basePsiElement.getTextLength();

                boolean folded = false;

                if (elementType.is(ElementTypeAttribute.FOLDABLE_BLOCK)) {
                    BasePsiElement subjectPsiElement = basePsiElement.lookupFirstPsiElement(ElementTypeAttribute.SUBJECT);
                    if (subjectPsiElement == null) {
                        PsiElement firstChild = basePsiElement.getFirstChild();
                        if (firstChild instanceof TokenPsiElement) {
                            subjectPsiElement = (BasePsiElement) firstChild;
                        }
                    }
                    if (subjectPsiElement != null && subjectPsiElement.getParent() == basePsiElement) {

                        int subjectEndOffset = subjectPsiElement.getTextOffset() + subjectPsiElement.getTextLength();

                        int subjectLineNumber = document.getLineNumber(subjectEndOffset);
                        int blockEndOffsetLineNumber = document.getLineNumber(blockEndOffset);

                        if (subjectLineNumber < blockEndOffsetLineNumber) {
                            TextRange textRange = new TextRange(subjectEndOffset, blockEndOffset);

                            FoldingDescriptor foldingDescriptor = new FoldingDescriptor(basePsiElement.getNode(), textRange);

                            foldingDescriptors.add(foldingDescriptor);
                            nestingIndex++;
                            folded = true;
                        }
                    }
                }

                if (!folded && elementType.is(ElementTypeAttribute.STATEMENT)) {
                    if (basePsiElement.containsLineBreaks()) {
                        TextRange textRange = null;

                        BasePsiElement firstPsiElement = basePsiElement.lookupFirstLeafPsiElement();
                        int firstElementEndOffset = firstPsiElement.getTextOffset() + firstPsiElement.getTextLength();
                        int firstElementLineNumber = document.getLineNumber(firstElementEndOffset);


                        BasePsiElement subjectPsiElement = basePsiElement.lookupFirstPsiElement(ElementTypeAttribute.SUBJECT);
                        if (subjectPsiElement != null && subjectPsiElement.getParent() == basePsiElement) {
                            int subjectEndOffset = subjectPsiElement.getTextOffset() + subjectPsiElement.getTextLength();
                            int subjectLineNumber = document.getLineNumber(subjectEndOffset);

                            if (subjectLineNumber == firstElementLineNumber) {
                                textRange = new TextRange(subjectEndOffset, blockEndOffset);
                            }
                        }

                        if (textRange == null) {
                            textRange = new TextRange(firstElementEndOffset, blockEndOffset);
                        }

                        FoldingDescriptor foldingDescriptor = new FoldingDescriptor(basePsiElement.getNode(), textRange);
                        foldingDescriptors.add(foldingDescriptor);
                        nestingIndex++;
                    }
                }

                if (nestingIndex < 9) {
                    createFoldingDescriptors(child, document, foldingDescriptors, nestingIndex);
                }
            }
            child = child.getNextSibling();
        }
    }

    public String getPlaceholderText(@NotNull ASTNode node) {
        PsiElement psiElement = node.getPsi();
        if (psiElement instanceof BasePsiElement) {
            /*BasePsiElement basePsiElement = (BasePsiElement) psiElement;
            PsiElement subject = basePsiElement.lookupFirstSubjectPsiElement();
            StringBuilder buffer = new StringBuilder(basePsiElement.getElementType().getDescription());
            if (subject != null) {
                buffer.append(" (");
                buffer.append(subject.getText());
                buffer.append(")");
            }
            return buffer.toString();*/
            return "(...)";
        }

        if (psiElement instanceof PsiComment) {
            return "/*...*/";
        }

        if (psiElement instanceof ChameleonPsiElement) {
            ChameleonPsiElement chameleonPsiElement = (ChameleonPsiElement) psiElement;
            return chameleonPsiElement.getLanguage().getDisplayName() + " block";
        }
        return "";
    }

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

}
TOP

Related Classes of com.dci.intellij.dbn.language.psql.PSQLFoldingBuilder

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.