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

Source Code of ro.redeul.google.go.lang.psi.impl.types.GoPsiTypeStructImpl

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

import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.impl.PsiElementBase;
import com.intellij.psi.scope.PsiScopeProcessor;
import org.jetbrains.annotations.NotNull;
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralIdentifier;
import ro.redeul.google.go.lang.psi.impl.types.struct.PromotedFieldsDiscover;
import ro.redeul.google.go.lang.psi.types.GoPsiType;
import ro.redeul.google.go.lang.psi.types.GoPsiTypeName;
import ro.redeul.google.go.lang.psi.types.GoPsiTypeStruct;
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.types.struct.GoTypeStructPromotedFields;
import ro.redeul.google.go.lang.psi.visitors.GoElementVisitor;

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

import static ro.redeul.google.go.lang.psi.utils.GoTypeUtils.resolveToFinalType;

/**
* Author: Toader Mihai Claudiu <mtoader@gmail.com>
* <p/>
* Date: 5/27/11
* Time: 12:17 AM
*/
public class GoPsiTypeStructImpl extends GoPsiTypeImpl implements
        GoPsiTypeStruct {

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

    @Override
    public String getName() {
        return super.getParent().getFirstChild().getText();
    }

    @Override
    public GoTypeStructField[] getFields() {
        return findChildrenByClass(GoTypeStructField.class);
    }

    @NotNull
    @Override
    public GoTypeStructPromotedFields getPromotedFields() {
        return new PromotedFieldsDiscover(this).getPromotedFields();
    }

    @Override
    public GoTypeStructAnonymousField[] getAnonymousFields() {
        return findChildrenByClass(GoTypeStructAnonymousField.class);
    }

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

    //    @Override
//    public GoPsiElement[] getMembers() {
//        List<GoPsiElement> members = new ArrayList<GoPsiElement>();
//
//        GoTypeStructField fields[] = getFields();
//        for (GoTypeStructField field : fields) {
//            Collections.addAll(members, field.getIdentifiers());
//        }
//
//        GoTypeStructAnonymousField fieldAnonymous[] = getAnonymousFields();
//        for (GoTypeStructAnonymousField field : fieldAnonymous) {
//            GoType type = field.getType();
//            Collections.addAll(members, type.getMembers());
//        }
//
//        return members.toArray(new GoPsiElement[members.size()]);
//    }

    //    @Override
//    public GoType getMemberType(String name) {
//
//        GoTypeStructField fields[] = getFields();
//        for (GoTypeStructField field : fields) {
//            for (GoLiteralIdentifier identifier : field.getIdentifiers()) {
//                String identifierName = identifier.getName();
//
//                if ( identifierName != null && identifierName.equals(name) ) {
//                    return field.getType();
//                }
//            }
//        }
//
//        GoTypeStructAnonymousField fieldAnonymous[] = getAnonymousFields();
//        for (GoTypeStructAnonymousField field : fieldAnonymous) {
//            GoType type = field.getType();
//            GoType memberType = type.getMemberType(name);
//            if ( memberType != null ) {
//                return memberType;
//            }
//        }
//
//        return null;
//    }
//
    @Override
    public void accept(GoElementVisitor visitor) {
        visitor.visitStructType(this);
    }

    public PsiElement[] getAllFields() {
        List<PsiElement> vector = new ArrayList<PsiElement>();

        for (PsiElement element = getFirstChild(); element != null; element = element.getNextSibling()) {
            if (element instanceof GoTypeStructField || element instanceof GoTypeStructAnonymousField) {
                vector.add(element);
            }
        }
        return vector.toArray(new PsiElement[vector.size()]);
    }

    @Override
    public boolean isIdentical(GoPsiType goType) {
        if (goType instanceof GoPsiTypeName) {
            goType = resolveToFinalType(goType);
        }
        if (!(goType instanceof GoPsiTypeStruct))
            return false;
        GoPsiTypeStruct otherStruct = (GoPsiTypeStruct) goType;

        PsiElement[] allFields = getAllFields();
        PsiElement[] otherStructAllFields = otherStruct.getAllFields();


        if (allFields.length != otherStructAllFields.length)
            return false;

        for (int i = 0; i < allFields.length; i++) {
            if (allFields[0] instanceof GoTypeStructField) {
                if (!(otherStructAllFields[i] instanceof GoTypeStructField)) {
                    return false;
                }

                GoTypeStructField field = (GoTypeStructField) allFields[i];
                GoTypeStructField otherField = (GoTypeStructField) otherStructAllFields[i];
                PsiElementBase tag = field.getTag();
                PsiElementBase otherTag = otherField.getTag();
                if ((tag == null && otherTag != null) || (otherTag == null && tag != null))
                    return false;
                if (tag != null && !tag.getText().equals(otherTag.getText()))
                    return false;

                GoLiteralIdentifier[] identifiers = field.getIdentifiers();
                GoLiteralIdentifier[] otherIdentifiers = otherField.getIdentifiers();
                if (identifiers.length != otherIdentifiers.length)
                    return false;
                for (int j = 0; j < identifiers.length; j++) {
                    GoLiteralIdentifier identifier = identifiers[j];
                    GoLiteralIdentifier otherIdentifier = otherIdentifiers[j];
                    if (!identifier.getName().equals(otherIdentifier.getName()))
                        return false;
                    if (!field.getType().isIdentical(otherField.getType()))
                        return false;
                }
            } else {
                //Check anonymous fields
                if (!(otherStructAllFields[i] instanceof GoTypeStructAnonymousField))
                    return false;
                GoTypeStructAnonymousField field = (GoTypeStructAnonymousField) allFields[i];
                GoTypeStructAnonymousField otherField = (GoTypeStructAnonymousField) otherStructAllFields[i];
                if (!field.getFieldName().equals(otherField.getFieldName()))
                    return false;
                if (!field.getType().isIdentical(otherField.getType()))
                    return false;
                PsiElementBase tag = field.getTag();
                PsiElementBase otherTag = otherField.getTag();
                if ((tag == null && otherTag != null) || (otherTag == null && tag != null))
                    return false;
                if (tag != null && !tag.getText().equals(otherTag.getText()))
                    return false;
            }
        }

        return true;

    }


}
TOP

Related Classes of ro.redeul.google.go.lang.psi.impl.types.GoPsiTypeStructImpl

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.