Package com.dci.intellij.dbn.language.common.psi

Source Code of com.dci.intellij.dbn.language.common.psi.PsiUtil

package com.dci.intellij.dbn.language.common.psi;

import com.dci.intellij.dbn.common.util.DocumentUtil;
import com.dci.intellij.dbn.connection.mapping.FileConnectionMappingManager;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeAttribute;
import com.dci.intellij.dbn.language.common.psi.lookup.ObjectLookupAdapter;
import com.dci.intellij.dbn.object.DBSchema;
import com.dci.intellij.dbn.object.common.DBObjectType;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageDialect;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiInvalidElementAccessException;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiWhiteSpace;
import gnu.trove.THashSet;

import java.util.Iterator;
import java.util.Set;

public class PsiUtil {

    public static DBSchema getCurrentSchema(PsiElement psiElement) {
        VirtualFile virtualFile = getVirtualFileForElement(psiElement);
        FileConnectionMappingManager mappingManager = FileConnectionMappingManager.getInstance(psiElement.getProject());
        return mappingManager.getCurrentSchema(virtualFile);
    }

    public static VirtualFile getVirtualFileForElement(PsiElement psiElement) {
        PsiFile psiFile = null;
        try {
            psiFile = psiElement.getContainingFile().getOriginalFile();
            if (psiFile == null) psiFile = psiElement.getContainingFile();
        } catch (PsiInvalidElementAccessException e) {
            System.out.println("");
        }
        return psiFile == null ? null : psiFile.getVirtualFile();
    }

    public static BasePsiElement resolveAliasedEntityElement(IdentifierPsiElement aliasElement) {
        PsiElement psiElement = aliasElement.isReference() ? aliasElement.resolve() : aliasElement;
        if (psiElement instanceof BasePsiElement) {
            BasePsiElement basePsiElement = (BasePsiElement) psiElement;
            BasePsiElement scope = basePsiElement.lookupEnclosingNamedPsiElement();

            DBObjectType objectType = aliasElement.getObjectType();
            ObjectLookupAdapter lookupInput = new ObjectLookupAdapter(aliasElement, objectType);

            BasePsiElement objectPsiElement = lookupInput.findInScope(scope);
            if (objectPsiElement == null) {
                scope = scope.lookupEnclosingSequencePsiElement();
                if (scope != null)
                    objectPsiElement = lookupInput.findInScope(scope);
            }
            if (objectPsiElement != null) {
                Set<BasePsiElement> virtualObjectPsiElements = new THashSet<BasePsiElement>();
                scope.collectVirtualObjectPsiElements(virtualObjectPsiElements, objectType);
                for (BasePsiElement virtualObjectPsiElement : virtualObjectPsiElements) {
                    if (virtualObjectPsiElement.containsPsiElement(objectPsiElement))
                        return virtualObjectPsiElement;

                }
            }
            return objectPsiElement;

        }
        return null;
    }

    public static IdentifierPsiElement lookupObjectPriorTo(BasePsiElement element, DBObjectType objectType) {
        SequencePsiElement scope = element.lookupEnclosingSequencePsiElement();

        Iterator<PsiElement> children = PsiUtil.getChildrenIterator(scope);
        while (children.hasNext()) {
            PsiElement child = children.next();
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                ObjectLookupAdapter lookupInput = new ObjectLookupAdapter(null, objectType);
                BasePsiElement objectPsiElement = lookupInput.findInScope(basePsiElement);
                if (objectPsiElement != null && objectPsiElement instanceof IdentifierPsiElement) {
                    return (IdentifierPsiElement) objectPsiElement;
                }                                       
            }
            if (child == element) break;
        }
        return null;
    }

    public static ExecutablePsiElement lookupExecutableAtCaret(PsiFile file) {
        // GTK: PsiElement psiElement = PsiFile.findElementA(offset)
        int offset = getCaretOffset(file);
        PsiElement current = file.findElementAt(offset);
        if (current != null) {
            PsiElement parent = current.getParent();
            while (parent != null) {
                if (parent instanceof ExecutablePsiElement){
                    ExecutablePsiElement executable = (ExecutablePsiElement) parent;
                    if (!executable.isNestedExecutable()) {
                        return executable;
                    }

                }
                parent = parent.getParent();
            }
        }
        return null;
    }

    public static BasePsiElement lookupElementAtOffset(PsiFile file, ElementTypeAttribute typeAttribute, int offset) {
        PsiElement psiElement = file.findElementAt(offset);
        while (psiElement != null) {
            if (psiElement instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) psiElement;
                if (basePsiElement.getElementType().is(typeAttribute)) {
                    return basePsiElement;
                }
            }
            psiElement = psiElement.getParent();
        }
        return null;
    }

    public static BasePsiElement lookupRootAtCaret(PsiFile file) {
        int offset = getCaretOffset(file);
        PsiElement current = file.findElementAt(offset);
        if (current != null) {
            PsiElement parent = current.getParent();
            while (parent != null) {
                if (parent instanceof BasePsiElement){
                    BasePsiElement basePsiElement = (BasePsiElement) parent;
                    if (basePsiElement.getElementType().is(ElementTypeAttribute.ROOT)) {
                        return basePsiElement;
                    }

                }
                parent = parent.getParent();
            }
        }
        return null;
    }


    public static boolean introduceWhitespace(PsiFile file, int caretOffset) {
        PsiFile originalFile = file.getOriginalFile();
        if (originalFile != null && originalFile != file) {
            PsiElement elementAtCaret = originalFile.findElementAt(caretOffset);
            return !(elementAtCaret instanceof PsiWhiteSpace) || elementAtCaret.getNextSibling() == null;
        }
        return false;
    }

    public static LeafPsiElement lookupLeafBeforeOffset(PsiFile file, int originalOffset) {
        int offset = originalOffset;
        if (offset > 0 && offset == file.getTextLength()) {
            offset--;
        }
        PsiElement element = file.findElementAt(offset);
        while (element != null && offset >= 0) {
            int elementEndOffset = element.getTextOffset() + element.getTextLength();
            if (elementEndOffset <= originalOffset && element.getParent() instanceof LeafPsiElement) {
                LeafPsiElement leafPsiElement = (LeafPsiElement) element.getParent();
                if (leafPsiElement instanceof IdentifierPsiElement) {
                    if (elementEndOffset < originalOffset) {
                        return leafPsiElement;
                    }
                } else {
                    return (LeafPsiElement) element.getParent();
                }
            }
            offset = element.getTextOffset() - 1;
            element = file.findElementAt(offset);
        }
        return null;
    }

    private static boolean ignore(PsiElement element) {
        return element instanceof PsiWhiteSpace || element instanceof PsiComment;
    }


    public static LeafPsiElement lookupLeafAtOffset(PsiFile file, int originalOffset) {
        int offset = originalOffset;
        PsiElement element = file.findElementAt(offset);
        while (element != null && offset >= 0) {
            int elementEndOffset = element.getTextOffset() + element.getTextLength();
            if (element.getParent() instanceof LeafPsiElement) {
                LeafPsiElement leafPsiElement = (LeafPsiElement) element.getParent();
                if (leafPsiElement instanceof IdentifierPsiElement) {
                    if (elementEndOffset < originalOffset) {
                        return leafPsiElement;
                    }
                } else {
                    return (LeafPsiElement) element.getParent();
                }
            }
            offset = element.getTextOffset() - 1;
            element = file.findElementAt(offset);
        }
        return null;
    }

    public static int getCaretOffset(PsiFile file) {
        PsiFile originalFile = file.getOriginalFile();
        if (originalFile != null) file = originalFile;
        Document document = DocumentUtil.getDocument(file);
        Editor[] editors = EditorFactory.getInstance().getEditors(document);

        //Editor editor = FileEditorManager.getInstance(file.getProject()).getSelectedTextEditor();

        return editors.length == 0 ? -1 : editors[0].getCaretModel().getOffset();
    }

    public static int getCodeCompletionCaretOffset(PsiFile file) {
        int caretOffset = getCaretOffset(file);
        PsiElement elementAtCaret = file.findElementAt(caretOffset-1);

        if (elementAtCaret != null && !(elementAtCaret instanceof PsiWhiteSpace || elementAtCaret.getTextLength() == 1) ) {
            caretOffset = elementAtCaret.getTextOffset();
        }
        return caretOffset;
    }

    public static void moveCaretOutsideExecutable(Editor editor) {
        PsiFile file = DocumentUtil.getFile(editor);

        ExecutablePsiElement executablePsiElement = lookupExecutableAtCaret(file);
        if (executablePsiElement != null) {
            int offset = executablePsiElement.getTextOffset();
            editor.getCaretModel().moveToOffset(offset);
        }
    }

    public static Iterator<PsiElement> getChildrenIterator(final PsiElement element) {
        return new Iterator<PsiElement>() {
            private PsiElement current = element.getFirstChild();
            public boolean hasNext() {
                return current != null;
            }

            public PsiElement next() {
                PsiElement oldCurrent = current;
                current = current.getNextSibling();
                return oldCurrent;
            }

            public void remove() {

            }
        };
    }

    public static int getChildrenCount(PsiElement element) {
        int count = 0;
        PsiElement current = element.getFirstChild();
        while (current != null) {
            count ++ ;
            current = current.getNextSibling();
        }
        return count;
    }

    public static PsiElement getNextSibling(PsiElement psiElement) {
        PsiElement nextPsiElement = psiElement.getNextSibling();
        while (nextPsiElement instanceof PsiWhiteSpace || nextPsiElement instanceof PsiComment) {
            nextPsiElement = nextPsiElement.getNextSibling();
        }
        return nextPsiElement;
    }

    public static PsiFile getPsiFile(Project project, Document document) {
        PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
        return psiDocumentManager == null ? null : psiDocumentManager.getPsiFile(document);
    }

    public static PsiFile getPsiFile(Project project, VirtualFile virtualFile) {
        return PsiManager.getInstance(project).findFile(virtualFile);
    }


    public static BasePsiElement getBasePsiElement(PsiElement psiElement) {
        while (psiElement != null) {
            if (psiElement instanceof BasePsiElement) {
                return (BasePsiElement) psiElement;
            }
            psiElement = psiElement.getParent();
        }

        return null;
    }

    public static Language getLanguage(PsiElement element) {
        Language language = element.getLanguage();
        if (language instanceof LanguageDialect) {
            LanguageDialect languageDialect = (LanguageDialect) language;
            language = languageDialect.getBaseLanguage();
        }
        return language;
    }
}
TOP

Related Classes of com.dci.intellij.dbn.language.common.psi.PsiUtil

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.