Package com.redhat.ceylon.compiler.typechecker.analyzer

Source Code of com.redhat.ceylon.compiler.typechecker.analyzer.AliasVisitor

package com.redhat.ceylon.compiler.typechecker.analyzer;

import static java.util.Collections.singleton;

import java.util.List;

import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.UnknownType;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.TupleType;

/**
* Detects recursive type aliases and eliminates the
* circularities.
*
* @author Gavin King
*
*/
public class AliasVisitor extends Visitor {

    private void check(Node that, ProducedType t, TypeDeclaration d) {
        if (t!=null) {
            List<TypeDeclaration> l = t.isRecursiveTypeAliasDefinition(singleton(d));
            if (!l.isEmpty()) {
                that.addError("type alias is circular: definition of '" +
                        d.getName() + "' is recursive, involving " + typeList(l));
                //to avoid stack overflows, throw
                //away the recursive definition:
                d.setExtendedType(new UnknownType(that.getUnit()).getType());
                d.addBrokenSupertype(t);
            }
        }
    }

    public static String typeList(List<TypeDeclaration> l) {
        StringBuffer sb = new StringBuffer();
        for (TypeDeclaration td: l) {
            sb.append("'").append(td.getName()).append("', ");
        }
        sb.setLength(sb.length()-2);
        return sb.toString();
    }

    @Override
    public void visit(Tree.TypeAliasDeclaration that) {
        super.visit(that);
        Tree.TypeSpecifier ts = that.getTypeSpecifier();
        if (ts!=null) {
            Tree.StaticType st = ts.getType();
            if (st!=null) {
                check(ts, st.getTypeModel(),
                        that.getDeclarationModel());
            }
        }
    }

    @Override
    public void visit(Tree.ClassDeclaration that) {
        super.visit(that);
        Tree.ClassSpecifier ts = that.getClassSpecifier();
        if (ts!=null) {
            Tree.StaticType st = ts.getType();
            if (st!=null) {
                check(ts, st.getTypeModel(),
                        that.getDeclarationModel());
            }
        }
    }

    @Override
    public void visit(Tree.InterfaceDeclaration that) {
        super.visit(that);
        Tree.TypeSpecifier ts = that.getTypeSpecifier();
        if (ts!=null) {
            Tree.StaticType st = ts.getType();
            if (st!=null) {
                check(ts, st.getTypeModel(),
                        that.getDeclarationModel());
            }
        }
    }
   
    @Override
    public void visit(TupleType that) {
        super.visit(that);
        that.setTypeModel(that.getTypeModel().resolveAliases());
    }
   
    @Override
    public void visit(Tree.FunctionType that) {
        super.visit(that);
        that.setTypeModel(that.getTypeModel().resolveAliases());
    }
   
}
TOP

Related Classes of com.redhat.ceylon.compiler.typechecker.analyzer.AliasVisitor

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.