/* * 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 * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.ast; import java.util.Map; import polyglot.types.QName; import polyglot.types.SemanticException; import polyglot.types.TypeSystem; import polyglot.util.*; import polyglot.visit.*; import x10.errors.Errors; import x10.types.X10ClassType; import x10.util.CollectionFactory; /** * An <code>AmbPrefix</code> is an ambiguous AST node composed of dot-separated * list of identifiers that must resolve to a prefix. */ public class AmbPrefix_c extends Node_c implements AmbPrefix { protected Prefix prefix; protected Id name; public AmbPrefix_c(Position pos, Prefix prefix, Id name) { super(pos); assert(name != null); // prefix may be null this.prefix = prefix; this.name = name; } /** Get the name of the prefix. */ public Id nameNode() { return this.name; } /** Set the name of the prefix. */ public AmbPrefix name(Id name) { AmbPrefix_c n = (AmbPrefix_c) copy(); n.name = name; return n; } /** Get the prefix of the prefix. */ public Prefix prefix() { return this.prefix; } /** Set the prefix of the prefix. */ public AmbPrefix prefix(Prefix prefix) { AmbPrefix_c n = (AmbPrefix_c) copy(); n.prefix = prefix; return n; } /** Reconstruct the prefix. */ protected AmbPrefix_c reconstruct(Prefix prefix, Id name) { if (prefix != this.prefix || name != this.name) { AmbPrefix_c n = (AmbPrefix_c) copy(); n.prefix = prefix; n.name = name; return n; } return this; } /** Visit the children of the prefix. */ public Node visitChildren(NodeVisitor v) { Prefix prefix = (Prefix) visitChild(this.prefix, v); Id name = (Id) visitChild(this.name, v); return reconstruct(prefix, name); } @Override public Node disambiguate(ContextVisitor ar) { try { return superDisambiguate(ar); } catch (SemanticException e) { Errors.issue(ar.job(), e, this); TypeSystem xts = ar.typeSystem(); X10ClassType ct = xts.createFakeClass(QName.make(null, name.id()), e); return ar.nodeFactory().CanonicalTypeNode(position(), ct); } } /** Disambiguate the prefix. */ public Node superDisambiguate(ContextVisitor ar) throws SemanticException { Position pos = position(); Disamb disamb = ar.nodeFactory().disamb(); Node n = disamb.disambiguate(this, ar, pos, prefix, name); if (n instanceof Prefix) { return n; } String typeName = (prefix != null ? prefix + "." : "") + name; SemanticException ex = new SemanticException("Could not find " + typeName, pos); Map<String, Object> map = CollectionFactory.newHashMap(); map.put(CodedErrorInfo.ERROR_CODE_KEY, CodedErrorInfo.ERROR_CODE_TYPE_NOT_FOUND); map.put("TYPE", typeName); ex.setAttributes(map); throw ex; } public Node typeCheck(ContextVisitor tc) { // Didn't finish disambiguation; just return. return this; } /** Check exceptions thrown by the prefix. */ public Node exceptionCheck(ExceptionChecker ec) { throw new InternalCompilerError(position(), "Cannot exception check ambiguous node " + this + "."); } /** Write the prefix to an output file. */ public void prettyPrint(CodeWriter w, PrettyPrinter tr) { if (prefix != null) { print(prefix, w, tr); w.write("."); } tr.print(this, name, w); } public String toString() { return (prefix == null ? name.toString() : prefix.toString() + "." + name.toString()) + "{amb}"; } }