1 package polyglot.ext.jl.ast; 2 3 import polyglot.ast.*; 4 import polyglot.types.*; 5 import polyglot.util.Position; 6 import polyglot.visit.ContextVisitor; 7 8 12 public class Disamb_c implements Disamb 13 { 14 protected ContextVisitor v; 15 protected Position pos; 16 protected Prefix prefix; 17 protected String name; 18 19 protected NodeFactory nf; 20 protected TypeSystem ts; 21 protected Context c; 22 protected Ambiguous amb; 23 24 29 public Node disambiguate(Ambiguous amb, ContextVisitor v, Position pos, 30 Prefix prefix, String name) throws SemanticException { 31 32 this.v = v; 33 this.pos = pos; 34 this.prefix = prefix; 35 this.name = name; 36 this.amb = amb; 37 38 nf = v.nodeFactory(); 39 ts = v.typeSystem(); 40 c = v.context(); 41 42 if (prefix instanceof Ambiguous) { 43 throw new SemanticException( 44 "Cannot disambiguate node with ambiguous prefix."); 45 } 46 47 if (prefix instanceof PackageNode) { 48 PackageNode pn = (PackageNode) prefix; 49 return disambiguatePackagePrefix(pn); 50 } else if (prefix instanceof TypeNode) { 51 TypeNode tn = (TypeNode) prefix; 52 return disambiguateTypeNodePrefix(tn); 53 } else if (prefix instanceof Expr) { 54 Expr e = (Expr) prefix; 55 return disambiguateExprPrefix(e); 56 } else if (prefix == null) { 57 return disambiguateNoPrefix(); 58 } 59 60 return null; 61 } 62 63 protected Node disambiguatePackagePrefix(PackageNode pn) throws SemanticException { 64 Resolver pc = ts.packageContextResolver(c.outerResolver(), 65 pn.package_()); 66 67 Named n = pc.find(name); 68 Qualifier q = null; 69 70 if (n instanceof Qualifier) { 71 q = (Qualifier) n; 72 } else { 73 return null; 74 } 75 76 if (q.isPackage() && packageOK()) { 77 return nf.PackageNode(pos, q.toPackage()); 78 } else if (q.isType() && typeOK()) { 79 return nf.CanonicalTypeNode(pos, q.toType()); 80 } 81 82 return null; 83 } 84 85 86 protected Node disambiguateTypeNodePrefix(TypeNode tn) 87 throws SemanticException 88 { 89 Type t = tn.type(); 91 92 if (t.isReference() && exprOK()) { 93 try { 94 FieldInstance fi = ts.findField(t.toReference(), name, c); 95 return nf.Field(pos, tn, name).fieldInstance(fi); 96 } catch (NoMemberException e) { 97 if (e.getKind() != e.FIELD) { 98 throw e; 100 } 101 102 } 104 } 105 106 if (t.isClass() && typeOK()) { 108 Resolver tc = ts.classContextResolver(t.toClass()); 109 Named n = tc.find(name); 110 if (n instanceof Type) { 111 Type type = (Type) n; 112 return nf.CanonicalTypeNode(pos, type); 113 } 114 } 115 116 return null; 117 } 118 119 protected Node disambiguateExprPrefix(Expr e) throws SemanticException { 120 if (exprOK()) { 122 return nf.Field(pos, e, name); 123 } 124 return null; 125 } 126 127 protected Node disambiguateNoPrefix() throws SemanticException { 128 129 VarInstance vi = c.findVariableSilent(name); 131 132 if (vi != null && exprOK()) { 133 Node n = disambiguateVarInstance(vi); 134 if (n != null) return n; 135 } 136 137 if (typeOK()) { 139 try { 140 Named n = c.find(name); 141 if (n instanceof Type) { 142 Type type = (Type) n; 143 return nf.CanonicalTypeNode(pos, type); 144 } 145 } catch (NoClassException e) { 146 if (!name.equals(e.getClassName())) { 147 throw e; 150 } 151 152 } 155 } 156 157 if (packageOK()) { 159 return nf.PackageNode(pos, ts.packageForName(name)); 160 } 161 162 return null; 163 } 164 165 protected Node disambiguateVarInstance(VarInstance vi) throws SemanticException { 166 if (vi instanceof FieldInstance) { 167 FieldInstance fi = (FieldInstance) vi; 168 Receiver r = makeMissingFieldTarget(fi); 169 return nf.Field(pos, r, name).fieldInstance(fi).targetImplicit(true); 170 } else if (vi instanceof LocalInstance) { 171 LocalInstance li = (LocalInstance) vi; 172 return nf.Local(pos, name).localInstance(li); 173 } 174 return null; 175 } 176 177 protected Receiver makeMissingFieldTarget(FieldInstance fi) throws SemanticException { 178 Receiver r; 179 180 if (fi.flags().isStatic()) { 181 r = nf.CanonicalTypeNode(pos, fi.container()); 182 } else { 183 ClassType scope = c.findFieldScope(name); 190 191 if (! ts.equals(scope, c.currentClass())) { 192 r = nf.This(pos, nf.CanonicalTypeNode(pos, scope)); 193 } else { 194 r = nf.This(pos); 195 } 196 } 197 198 return r; 199 } 200 201 protected boolean typeOK() { 202 return ! (amb instanceof Expr) && 203 (amb instanceof TypeNode || amb instanceof QualifierNode || 204 amb instanceof Receiver || amb instanceof Prefix); 205 206 } 207 208 protected boolean packageOK() { 209 return ! (amb instanceof Receiver) && 210 (amb instanceof QualifierNode || amb instanceof Prefix); 211 } 212 213 protected boolean exprOK() { 214 return ! (amb instanceof QualifierNode) && 215 (amb instanceof Expr || amb instanceof Receiver || 216 amb instanceof Prefix); 217 } 218 } 219 | Popular Tags |