/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.ast; import java.util.ArrayList; import java.util.Collections; import java.util.List; import polyglot.ast.CanonicalTypeNode; import polyglot.ast.Expr; import polyglot.ast.Node; import polyglot.ast.NodeFactory; import polyglot.ast.TypeNode; import polyglot.ast.TypeNode_c; import polyglot.types.Context; import polyglot.types.Flags; import polyglot.types.LazyRef; import polyglot.types.QName; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.types.Types; import polyglot.util.CodeWriter; import polyglot.util.InternalCompilerError; import polyglot.util.Position; import polyglot.visit.ContextVisitor; import polyglot.visit.ExceptionChecker; import polyglot.visit.NodeVisitor; import polyglot.visit.PrettyPrinter; import polyglot.visit.TypeCheckPreparer; import polyglot.visit.TypeChecker; import x10.errors.Errors; import x10.extension.X10Del; import x10.extension.X10Del_c; import x10.types.X10ClassType; import polyglot.types.Context; import polyglot.types.TypeSystem; import x10.types.checker.VarChecker; import x10.types.constraints.CConstraint; import x10.types.constraints.TypeConstraint; import x10.visit.X10TypeChecker; public class AmbDepTypeNode_c extends TypeNode_c implements AmbDepTypeNode, AddFlags { protected TypeNode base; protected DepParameterExpr dep; public AmbDepTypeNode_c(Position pos, TypeNode base, DepParameterExpr d) { super(pos); assert base != null; assert d != null; this.base = base; this.dep = d; } // public void setResolver(Node parent, final TypeCheckPreparer v) { //// if (parent instanceof ClassMember) // System.out.println("ad parent=" + parent + " n=" + this + " this=" + ((X10Context) v.context()).thisVar()); // super.setResolver(parent, v); // } public TypeNode base() { return base;} public AmbDepTypeNode base(TypeNode base) { if (base == this.base) return this; AmbDepTypeNode_c n = (AmbDepTypeNode_c) copy(); n.base = base; return n; } public DepParameterExpr constraint() { return dep;} public AmbDepTypeNode constraint(DepParameterExpr expr) { if (expr == this.dep) return this; AmbDepTypeNode_c n = (AmbDepTypeNode_c) copy(); n.dep = expr; return n; } public AmbDepTypeNode reconstruct(TypeNode base, DepParameterExpr d) { if (base == this.base && d==dep) return this; AmbDepTypeNode_c n = (AmbDepTypeNode_c) copy(); n.base = base; n.dep=d; return n; } public Context enterChildScope(Node child, Context c) { if (child == this.dep) { TypeSystem ts = c.typeSystem(); c = ((Context) c).pushDepType(base.typeRef()); } Context cc = super.enterChildScope(child, c); return cc; } public Node visitChildren(NodeVisitor v) { TypeNode base = (TypeNode) visitChild(this.base, v); DepParameterExpr dep = (DepParameterExpr) visitChild(this.dep, v); return reconstruct(base, dep); } public String toString() { return (base != null ? base.toString() : "") + (dep != null ? dep.toString() : ""); } public Node typeCheckOverride(Node parent, ContextVisitor tc) { TypeSystem ts = tc.typeSystem(); NodeFactory nf = (NodeFactory) tc.nodeFactory(); LazyRef<Type> sym = (LazyRef<Type>) this.type; assert sym != null; TypeChecker childtc = (TypeChecker) tc.enter(parent, this); TypeNode tn = (TypeNode) visitChild(base, childtc); Type t = tn.type(); if (ts.isUnknown(t)) { // Mark the type resolved to prevent us from trying to resolve this again and again. assert (false); sym.update(ts.unknownType(position())); X10CanonicalTypeNode result = postprocess(nf.CanonicalTypeNode(position(), sym), this, childtc); return result.typeCheck(childtc); } DepParameterExpr constr = (DepParameterExpr) visitChild(dep, childtc); VarChecker ac = (VarChecker) new VarChecker(childtc.job()).context(childtc.context()); try { constr.visit(ac); } catch (InternalCompilerError e) { Errors.issue(childtc.job(), new Errors.GeneralError(e.getMessage(), e.position()), constr); } if (ac.error != null) { Errors.issue(childtc.job(), ac.error, constr); } CConstraint c = Types.get(constr.valueConstraint()); t = Types.xclause(t, c); if (flags != null) { t = Types.processFlags(flags, t); flags = null; } sym.update(t); X10CanonicalTypeNode result = nf.CanonicalTypeNode(position(), sym); result = postprocess(result, this, childtc); return (TypeNode) result.typeCheck(childtc); } static X10CanonicalTypeNode postprocess(X10CanonicalTypeNode result, TypeNode n, ContextVisitor childtc) { n = (TypeNode) X10Del_c.visitAnnotations(n, childtc); result = (X10CanonicalTypeNode) ((X10Del) result.del()).annotations(((X10Del) n.del()).annotations()); result = (X10CanonicalTypeNode) ((X10Del) result.del()).setComment(((X10Del) n.del()).comment()); return result; } public Node exceptionCheck(ExceptionChecker ec) { throw new InternalCompilerError(position(), "Cannot exception check ambiguous node " + this + "."); } @Override public void prettyPrint(CodeWriter w, PrettyPrinter tr) { tr.print(this, base, w); tr.print(this, dep, w); } Flags flags; public void addFlags(Flags f) { this.flags = f; } }