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

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

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

import com.dci.intellij.dbn.code.common.style.formatting.FormattingAttributes;
import com.dci.intellij.dbn.common.util.StringUtil;
import com.dci.intellij.dbn.language.common.element.BlockElementType;
import com.dci.intellij.dbn.language.common.element.ElementType;
import com.dci.intellij.dbn.language.common.element.IterationElementType;
import com.dci.intellij.dbn.language.common.element.NamedElementType;
import com.dci.intellij.dbn.language.common.element.OneOfElementType;
import com.dci.intellij.dbn.language.common.element.SequenceElementType;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeAttribute;
import com.dci.intellij.dbn.language.common.psi.lookup.PsiLookupAdapter;
import com.dci.intellij.dbn.object.common.DBObjectType;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiWhiteSpace;
import gnu.trove.THashSet;

import java.util.Set;

public class SequencePsiElement extends BasePsiElement {
    public SequencePsiElement(ASTNode astNode, ElementType elementType) {
        super(astNode, elementType);
    }

    @Override
    public FormattingAttributes getFormattingAttributes() {
        return super.getFormattingAttributes();
    }

    public int approximateLength() {
        int length = 0;
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                length = length + basePsiElement.approximateLength();
            }
            child = child.getNextSibling();
        }
        return length;
    }

    /*********************************************************
     *                   Lookup routines                     *
     *********************************************************/

    public BasePsiElement lookupPsiElement(
            PsiLookupAdapter lookupAdapter,
            int scopeCrossCount) {

        PsiElement child = getFirstChild();
        while (child != null) {
            ProgressIndicatorProvider.checkCanceled();
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                if (lookupAdapter.accepts(basePsiElement)) {
                    boolean isScopeBoundary = basePsiElement.isScopeBoundary();
                    if (!isScopeBoundary || scopeCrossCount > 0) {
                        int childScopeCrossCount = isScopeBoundary ? scopeCrossCount-1 : scopeCrossCount;
                        BasePsiElement result = basePsiElement.lookupPsiElement(lookupAdapter, childScopeCrossCount);
                        if (result != null) return result;
                    }
                }
            }
            child = child.getNextSibling();
        }
        return null;
    }

    public Set<BasePsiElement> collectPsiElements(
            PsiLookupAdapter lookupAdapter,
            Set<BasePsiElement> bucket,
            int scopeCrossCount) {

        if (lookupAdapter.matches(this)) {
            if (bucket == null) bucket = new THashSet<BasePsiElement>();
            bucket.add(this);

        }
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;

                if (lookupAdapter.accepts(basePsiElement)) {
                    boolean isScopeBoundary = basePsiElement.isScopeBoundary();
                    if (!isScopeBoundary || scopeCrossCount > 0) {
                        int childScopeCrossCount = isScopeBoundary ? scopeCrossCount-1 : scopeCrossCount;
                        bucket = basePsiElement.collectPsiElements(lookupAdapter, bucket, childScopeCrossCount);
                    }
                }
            }
            child = child.getNextSibling();
        }
        return bucket;
    }

    public void collectExecVariablePsiElements(Set<ExecVariablePsiElement> bucket) {
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                basePsiElement.collectExecVariablePsiElements(bucket);
            }
            child = child.getNextSibling();
        }
    }

    public void collectSubjectPsiElements(Set<BasePsiElement> bucket) {
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                basePsiElement.collectSubjectPsiElements(bucket);
            }
            child = child.getNextSibling();
        }
    }

    public void collectVirtualObjectPsiElements(Set<BasePsiElement> bucket, DBObjectType objectType) {
        //if (getElementType().getLookupCache().containsVirtualObject(objectType)) {
            if (getElementType().isVirtualObject()) {
                DBObjectType virtualObjectType = getElementType().getVirtualObjectType();
                if (objectType == virtualObjectType) {
                    bucket.add(this);
                }
            }
            PsiElement child = getFirstChild();
            while (child != null) {
                if (child instanceof BasePsiElement) {
                    BasePsiElement basePsiElement = (BasePsiElement) child;
                    basePsiElement.collectVirtualObjectPsiElements(bucket, objectType);
                }
                child = child.getNextSibling();
            }
        //}
    }

    public NamedPsiElement lookupNamedPsiElement(String id) {
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof SequencePsiElement) {
                SequencePsiElement bundlePsiElement = (SequencePsiElement) child;
                if (bundlePsiElement instanceof NamedPsiElement) {
                    NamedPsiElement namedPsiElement = (NamedPsiElement) bundlePsiElement;
                    if (namedPsiElement.getElementType().getId().equals(id)) {
                        return namedPsiElement;
                    }
                }

                NamedPsiElement namedPsiElement = bundlePsiElement.lookupNamedPsiElement(id);
                if (namedPsiElement != null) {
                    return namedPsiElement;
                }
            }
            child = child.getNextSibling();
        }
        return null;
    }

    @Override
    public BasePsiElement lookupFirstPsiElement(ElementTypeAttribute attribute) {
        if (this.getElementType().is(attribute)) {
            return this;
        }

        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                BasePsiElement firstElement = basePsiElement.lookupFirstPsiElement(attribute);
                if (firstElement != null) {
                    return firstElement;
                }
            }
            child = child.getNextSibling();
        }
        return null;
    }
    public BasePsiElement lookupFirstLeafPsiElement() {
        PsiElement firstChild = getFirstChild();
        while (firstChild != null) {
            if (firstChild instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) firstChild;
                return basePsiElement.lookupFirstLeafPsiElement();
            }
            firstChild = firstChild.getNextSibling();
        }
        return null;
    }

    public BasePsiElement lookupPsiElementBySubject(ElementTypeAttribute attribute, CharSequence subjectName, DBObjectType subjectType) {
        if (getElementType().is(attribute)) {
            BasePsiElement subjectPsiElement = lookupFirstPsiElement(ElementTypeAttribute.SUBJECT);
            if (subjectPsiElement instanceof IdentifierPsiElement) {
                IdentifierPsiElement identifierPsiElement = (IdentifierPsiElement) subjectPsiElement;
                if (identifierPsiElement.getObjectType() == subjectType &&
                        StringUtil.equalsIgnoreCase(subjectName, identifierPsiElement.getChars())) {
                    return this;
                }
            }
        }
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                BasePsiElement childPsiElement = basePsiElement.lookupPsiElementBySubject(attribute, subjectName, subjectType);
                if (childPsiElement != null) {
                    return childPsiElement;
                }
            }
            child = child.getNextSibling();
        }
        return null;
    }

    @Override
    public BasePsiElement lookupPsiElementByAttribute(ElementTypeAttribute attribute) {
        if (getElementType().is(attribute)) {
            return this;
        }
        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                BasePsiElement childPsiElement = basePsiElement.lookupPsiElementByAttribute(attribute);
                if (childPsiElement != null) {
                    return childPsiElement;
                }
            }
            child = child.getNextSibling();

        }
        return null;
    }

    public boolean containsPsiElement(BasePsiElement childPsiElement) {
        if (this == childPsiElement) {
            return true;
        }

        PsiElement child = getFirstChild();
        while (child != null) {
            if (child instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) child;
                boolean containsPsiElement = basePsiElement.containsPsiElement(childPsiElement);
                if (containsPsiElement) {
                    return true;
                }
            }
            child = child.getNextSibling();
        }
        return false;
    }

    /*********************************************************
     *                    Miscellaneous                      *
     *********************************************************/
     public boolean hasErrors() {
        PsiElement[] psiElements = getChildren();
        for (PsiElement psiElement: psiElements) {
            if (psiElement instanceof BasePsiElement) {
                BasePsiElement basePsiElement = (BasePsiElement) psiElement;
                if (basePsiElement.hasErrors()) {
                    return true;
                }
            }
        }
         if (true) return false;

        if (getElementType() instanceof SequenceElementType) {
            int offset = 0;
            SequenceElementType sequenceElementType = (SequenceElementType) getElementType();
            ElementType[] elementTypes = sequenceElementType.getElementTypes();


            for (int i=0; i<elementTypes.length; i++) {
                while (offset < psiElements.length &&
                        (psiElements[offset] instanceof PsiWhiteSpace ||
                         psiElements[offset] instanceof PsiErrorElement)) offset++;

                PsiElement psiElement = offset == psiElements.length ? null : psiElements[offset];
                if (psiElement!= null && psiElement instanceof BasePsiElement && elementTypes[i] == ((BasePsiElement)psiElement).getElementType()) {
                    offset++;
                    if (offset == psiElements.length) {
                        boolean isLast = i == elementTypes.length-1;
                        return !isLast && !sequenceElementType.isOptionalFromIndex(i+1);
                    }
                } else {
                    if (!sequenceElementType.isOptional(i) && !(psiElement instanceof PsiWhiteSpace) && !(psiElement instanceof PsiComment)) {
                        return true;
                    }
                }
            }
        } else if (getElementType() instanceof IterationElementType) {
            IterationElementType iterationElementType = (IterationElementType) getElementType();
            PsiElement psiElement = getLastChild();
            if (psiElement == null) {
                return true;
            } else if (psiElement instanceof BasePsiElement){
                BasePsiElement basePsiElement = (BasePsiElement) psiElement;
                return basePsiElement.getElementType() != iterationElementType.getIteratedElementType();
            } else {
                return psiElement instanceof PsiErrorElement;
            }
        }
        return false;
    }

    public boolean isSequence(){
        return getElementType() instanceof SequenceElementType;
    }

    public boolean isBlock(){
        return getElementType() instanceof BlockElementType;
    }

    public boolean isIteration(){
        return getElementType() instanceof IterationElementType;
    }

    public boolean isOneOf() {
        return getElementType() instanceof OneOfElementType;
    }

    public boolean isNamedSequence() {
        return getElementType() instanceof NamedElementType;
    }

    public boolean isFirstChild(PsiElement psiElement){
         return psiElement == getFirstChild();
    }

    public boolean equals(BasePsiElement basePsiElement) {
        if (this == basePsiElement) {
            return true;
        } else {
            PsiElement localChild = getFirstChild();
            PsiElement remoteChild = basePsiElement.getFirstChild();

            while(localChild != null && remoteChild != null) {
                if (localChild instanceof BasePsiElement && remoteChild instanceof BasePsiElement) {
                    BasePsiElement localPsiElement = (BasePsiElement) localChild;
                    BasePsiElement remotePsiElement = (BasePsiElement) remoteChild;
                    if (localPsiElement != remotePsiElement && !localPsiElement.equals(remotePsiElement)) {
                        return false;
                    }
                    localChild = PsiUtil.getNextSibling(localChild);
                    remoteChild = PsiUtil.getNextSibling(remoteChild);
                } else {
                    return false;
                }
            }
            return localChild == null && remoteChild == null;
        }
    }

    public boolean matches(BasePsiElement basePsiElement) {
        if (this == basePsiElement) {
            return true;
        } else if (basePsiElement != null && basePsiElement.isValid()){
            PsiElement localChild = getFirstChild();
            PsiElement remoteChild = basePsiElement.getFirstChild();

            while(localChild != null && remoteChild != null) {
                if (localChild instanceof BasePsiElement && remoteChild instanceof BasePsiElement) {
                    BasePsiElement localPsiElement = (BasePsiElement) localChild;
                    BasePsiElement remotePsiElement = (BasePsiElement) remoteChild;
                    if (localPsiElement != remotePsiElement && !localPsiElement.matches(remotePsiElement)) {
                        return false;
                    }
                    localChild = PsiUtil.getNextSibling(localChild);
                    remoteChild = PsiUtil.getNextSibling(remoteChild);
                } else {
                    return false;
                }
            }
            return localChild == null && remoteChild == null;
        }
        return false;
    }


}
TOP

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

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.