Package ro.redeul.google.go.lang.psi.impl.declarations

Source Code of ro.redeul.google.go.lang.psi.impl.declarations.GoConstDeclarationImpl

package ro.redeul.google.go.lang.psi.impl.declarations;

import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import org.jetbrains.annotations.NotNull;
import ro.redeul.google.go.lang.lexer.GoTokenTypes;
import ro.redeul.google.go.lang.psi.declarations.GoConstDeclaration;
import ro.redeul.google.go.lang.psi.declarations.GoConstDeclarations;
import ro.redeul.google.go.lang.psi.expressions.GoExpr;
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralIdentifier;
import ro.redeul.google.go.lang.psi.impl.GoPsiElementBase;
import ro.redeul.google.go.lang.psi.types.GoPsiType;
import ro.redeul.google.go.lang.psi.utils.GoPsiUtils;
import ro.redeul.google.go.lang.psi.visitors.GoElementVisitor;
import ro.redeul.google.go.lang.psi.visitors.GoRecursiveElementVisitor;

import java.util.Collections;
import java.util.List;

public class GoConstDeclarationImpl extends GoPsiElementBase
        implements GoConstDeclaration {

    public GoConstDeclarationImpl(@NotNull ASTNode node) {
        super(node);
    }

    @Override
    public boolean hasInitializers() {
        return findChildByType(GoTokenTypes.oASSIGN) != null;
    }

    @Override
    public GoLiteralIdentifier[] getIdentifiers() {
        return findChildrenByClass(GoLiteralIdentifier.class);
    }

    private Integer getIdentifierIndex(GoLiteralIdentifier identifier){
        GoLiteralIdentifier[] goIdentifiers = getIdentifiers();
        for (int i = 0; i < goIdentifiers.length; i++) {
            if (goIdentifiers[i] == identifier){
                return i;
            }
        }
        return null;
    }

    @Override
    public Integer getConstSpecIndex() {
        PsiElement parent = getParent();
        if (parent instanceof GoConstDeclarations) {
            GoConstDeclaration[] consSpecs = ((GoConstDeclarations) parent).getDeclarations();
            for (int i = 0; i < consSpecs.length; i++) {
                if (consSpecs[i] == this) {
                    return i;
                }
            }
        }
        return null;
    }

    private GoPsiType getType() {
        return findChildByClass(GoPsiType.class);
    }

    @Override
    public GoPsiType getIdentifiersType() {
        GoPsiType type = findChildByClass(GoPsiType.class);

        if ( type != null )
            return type;

        PsiElement declaration = this.getPrevSibling();

        while (declaration != null && !(declaration instanceof GoConstDeclaration))
            declaration = declaration.getPrevSibling();

        return declaration != null ? ((GoConstDeclaration)declaration).getIdentifiersType() : null;
    }

    @Override
    @NotNull
    public GoExpr[] getExpressions() {
        GoExpr goExprs[] = findChildrenByClass(GoExpr.class);
//        if (goExprs.length == 0 && !hasInitializers()) {
//
//            // Omitting the list of expressions is therefore equivalent to repeating the previous list
//            // So we will find the previous list and clone it.
//
//            List<GoExpr> expressions = Collections.emptyList();
//            PsiElement sibling = this.getPrevSibling();
//            while ( sibling != null && expressions.size() == 0) {
//                while ( sibling != null && !(sibling instanceof GoConstDeclaration))
//                    sibling = sibling.getPrevSibling();
//
//                if ( sibling != null) {
//                    expressions = GoPsiUtils.findChildrenOfType(sibling, GoExpr.class);
//                    sibling = sibling.getPrevSibling();
//                }
//            }
//
//            goExprs = new GoExpr[expressions.size()];
//            for (int i = 0; i < expressions.size(); i++) {
//                GoExpr expression = expressions.get(i);
//                goExprs[i] = (GoExpr) expression.copy();
//            }
//        }

        for (GoExpr expr : goExprs) {
            setIotaValue(expr, getConstSpecIndex());
        }

        return goExprs;
    }

    private void setIotaValue(GoExpr expr, final Integer iotaValue) {
        expr.accept(new GoRecursiveElementVisitor() {
            @Override
            public void visitLiteralIdentifier(GoLiteralIdentifier identifier) {
                if (identifier.isIota())
                    identifier.setIotaValue(iotaValue);
            }
        });
    }

    @Override
    public GoExpr getExpression(GoLiteralIdentifier identifier) {
        Integer identifierIndex = getIdentifierIndex(identifier);
        if (identifierIndex == null ) {
            return null;
        }

        GoExpr[] goExprs = getExpressions();
        if (goExprs.length == 0 && !hasInitializers()) {
            // Omitting the list of expressions is therefore equivalent to repeating the previous list
            // So we will find the previous list and clone it.
            List<GoExpr> expressions = Collections.emptyList();
            PsiElement sibling = this.getPrevSibling();
            while ( sibling != null && expressions.size() == 0) {
                while ( sibling != null && !(sibling instanceof GoConstDeclaration))
                    sibling = sibling.getPrevSibling();

                if ( sibling != null) {
                    expressions = GoPsiUtils.findChildrenOfType(sibling, GoExpr.class);
                    sibling = sibling.getPrevSibling();
                }
            }

            goExprs = new GoExpr[expressions.size()];
            Integer iotaValue = getConstSpecIndex();
            for (int i = 0; i < expressions.size(); i++) {
                GoExpr expression = expressions.get(i);
                goExprs[i] = (GoExpr) expression.copy();
                setIotaValue(goExprs[i], iotaValue);
            }
        }

        if (goExprs.length <= identifierIndex)
            return null;

        return goExprs[identifierIndex];
    }

    @Override
    public void accept(GoElementVisitor visitor) {
        visitor.visitConstDeclaration(this);
    }

    @Override
    public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
                                       @NotNull ResolveState state,
                                       PsiElement lastParent,
                                       @NotNull PsiElement place) {
        return processor.execute(this, state);
    }
}
TOP

Related Classes of ro.redeul.google.go.lang.psi.impl.declarations.GoConstDeclarationImpl

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.