Package ro.redeul.google.go.lang.psi.impl.expressions.primary

Source Code of ro.redeul.google.go.lang.psi.impl.expressions.primary.GoSelectorExpressionImpl

package ro.redeul.google.go.lang.psi.impl.expressions.primary;

import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ro.redeul.google.go.lang.psi.GoPsiElement;
import ro.redeul.google.go.lang.psi.declarations.GoVarDeclaration;
import ro.redeul.google.go.lang.psi.expressions.GoPrimaryExpression;
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralIdentifier;
import ro.redeul.google.go.lang.psi.expressions.primary.GoSelectorExpression;
import ro.redeul.google.go.lang.psi.impl.expressions.GoExpressionBase;
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionDeclaration;
import ro.redeul.google.go.lang.psi.types.GoPsiType;
import ro.redeul.google.go.lang.psi.types.struct.GoTypeStructAnonymousField;
import ro.redeul.google.go.lang.psi.types.struct.GoTypeStructField;
import ro.redeul.google.go.lang.psi.typing.GoType;
import ro.redeul.google.go.lang.psi.typing.GoTypeName;
import ro.redeul.google.go.lang.psi.typing.GoTypePointer;
import ro.redeul.google.go.lang.psi.typing.GoTypeStruct;
import ro.redeul.google.go.lang.psi.utils.GoIdentifierUtils;
import ro.redeul.google.go.lang.psi.visitors.GoElementVisitor;
import ro.redeul.google.go.services.GoPsiManager;

import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.resolveSafely;

public class GoSelectorExpressionImpl extends GoExpressionBase implements GoSelectorExpression {

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

    public void accept(GoElementVisitor visitor) {
        visitor.visitSelectorExpression(this);
    }

    @NotNull
    @Override
    protected GoType[] resolveTypes() {
        PsiElement target = resolveSafely(getIdentifier(), PsiElement.class);

        if (target instanceof GoFunctionDeclaration) {
            GoFunctionDeclaration functionDeclaration = (GoFunctionDeclaration) target;
            return new GoType[]{
                    types().fromPsiType(functionDeclaration)
            };
        }

        if (target != null && target.getParent() instanceof GoTypeStructField) {

            GoTypeStructField structField = (GoTypeStructField) target.getParent();

            return new GoType[]{types().fromPsiType(structField.getType())};
        }

        if (target instanceof GoTypeStructAnonymousField) {
            GoTypeStructAnonymousField structField =
                    (GoTypeStructAnonymousField) target;

            return new GoType[]{
                    types().fromPsiType(structField.getType())
            };
        }

        if (target instanceof GoLiteralIdentifier) {
            GoFunctionDeclaration functionDeclaration = GoIdentifierUtils.getFunctionDeclaration(target);
            if (functionDeclaration != null) {
                return new GoType[]{
                        types().fromPsiType(functionDeclaration)
                };
            }
            if (target.getParent() instanceof GoVarDeclaration){
                GoType output = ((GoVarDeclaration)target.getParent()).getIdentifierType((GoLiteralIdentifier)target);
                if (output==null){
                    return GoType.EMPTY_ARRAY;
                }
                return new GoType[]{
                        output
                };
            }
        }

        return GoType.EMPTY_ARRAY;
    }

    @Override
    public GoPrimaryExpression getBaseExpression() {
        return findChildByClass(GoPrimaryExpression.class);
    }

    @Override
    @Nullable
    public GoLiteralIdentifier getIdentifier() {
        return findChildByClass(GoLiteralIdentifier.class);
    }

    private Object[] convertToPresentation(GoPsiType type, GoPsiElement[] members) {

        Object[] presentations = new Object[members.length];

        for (int i = 0, numMembers = members.length; i < numMembers; i++) {
            GoPsiElement member = members[i];

            if (member instanceof GoLiteralIdentifier) {
                LookupElementBuilder presentation =
                        getFieldPresentation(type, (GoLiteralIdentifier) member);

                if (presentation != null)
                    presentations[i] = presentation;

            } else {
                presentations[i] = member;
            }
        }

        return presentations;
    }

    @Nullable
    private LookupElementBuilder getFieldPresentation(GoPsiType type, GoLiteralIdentifier id) {

        String name = id.getName();
        if (name == null)
            return null;

        LookupElementBuilder builder = LookupElementBuilder.create(id, name);

        GoPsiType ownerType = null;
        if (id.getParent() != null && id.getParent() instanceof GoTypeStructField) {
            GoTypeStructField structField = (GoTypeStructField) id.getParent();
            ownerType = (GoPsiType) structField.getParent();
        }

        if (ownerType == null) {
            return builder;
        }

        return builder
                .bold()
                .withTailText(String.format(" (defined by: %s)",
                        ownerType.getName()))
                .withTypeText("<field>", ownerType != type);
    }

    @NotNull
    @Override
    public PsiReference[] defineReferences() {
        // TODO understand if this can be removed.
        GoPrimaryExpression baseExpression = getBaseExpression();

        if (baseExpression == null) {
            return PsiReference.EMPTY_ARRAY;
        }

        GoType[] baseTypes = baseExpression.getType();
        if (baseTypes.length == 0) {
            return PsiReference.EMPTY_ARRAY;
        }

        GoType type = baseTypes[0];

//        if (type instanceof GoTypePackage) {
//            GoPackage goPackage = ((GoTypePackage) type).getPackage();
//            return getIdentifier() != null
//                    ? new PsiReference[]{new PackageSymbolReference(getIdentifier(), goPackage)}
//                    : PsiReference.EMPTY_ARRAY;
//        }

        if (type instanceof GoTypePointer)
            type = ((GoTypePointer) type).getTargetType();

        GoType x = type.underlyingType();

//        if (x instanceof GoUnderlyingTypeInterface)
//            return new PsiReference[]{new InterfaceMethodReference(this)};

        if (x instanceof GoTypeStruct && getIdentifier() != null)
            return new PsiReference[]{
//                    new SelectorOfStructFieldReference(this),
//                    new MethodReference(this)
            };

        if (x instanceof GoTypePointer) {
            return new PsiReference[]{
//                    new SelectorOfStructFieldReference(this),
//                    new MethodReference(this)
            };
        }

        if (type instanceof GoTypeName) {
            return new PsiReference[]{
//                    new MethodReference(this)
            };
        }

//        if ( type instanceof GoPsiTypeStruct) {
//            return new StructFieldReference(this);
        return PsiReference.EMPTY_ARRAY;
    }
}
TOP

Related Classes of ro.redeul.google.go.lang.psi.impl.expressions.primary.GoSelectorExpressionImpl

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.