public Object visitExprNew(ExprNew expNew) { Type nt = (Type) expNew.getTypeToConstruct().accept(this); StructDef ts = null; { assert nt instanceof TypeStructRef; ts = TypeInferenceForStars.this.nres.getStruct(((TypeStructRef) nt).getName()); } boolean changed = false; List<ExprNamedParam> enl = new ArrayList<ExprNamedParam>(expNew.getParams().size()); for (ExprNamedParam en : expNew.getParams()) { Expression old = en.getExpr(); Type oldType = type; if (expNew.isHole()) { type = getFieldsMap(ts).get(en.getName()); } else { type = ts.getFieldTypMap().get(en.getName()); } StructDef cur = ts; while (type == null) { cur = nres.getStruct(cur.getParentName()); type = cur.getFieldTypMap().get(en.getName()); } Expression rhs = doExpression(old); if (rhs != old) { enl.add(new ExprNamedParam(en, en.getName(), rhs)); changed = true; } else { enl.add(en); } type = oldType; } if (nt != expNew.getTypeToConstruct() || changed) { if (!changed) { enl = expNew.getParams(); } if (expNew.isHole()) { return new ExprNew(expNew, nt, enl, false, expNew.getStar()); } else { return new ExprNew(expNew, nt, enl, false); } } else { return expNew; } }
public Object visitExprNew(ExprNew expNew) { if (expNew.isHole()) { TypeStructRef t = (TypeStructRef) expNew.getTypeToConstruct(); Map<String, Type> mst; if (ftypeMaps.containsKey(t.getName())) { mst = ftypeMaps.get(t.getName()); } else { mst = new HashMap<String, Type>(); ftypeMaps.put(t.getName(), mst); String cur = t.getName(); LinkedList<String> queue = new LinkedList<String>(); queue.add(cur); addFieldsToMap(mst, nres.getStruct(t.getName())); while (!queue.isEmpty()) { String cs = queue.removeFirst(); StructDef sdef = nres.getStruct(cs); addFieldsToMap(mst, sdef); queue.addAll(nres.getStructChildren(sdef.getFullName())); } } Map<String, Expression> repl = new HashMap<String, Expression>(); VarReplacer vr = new VarReplacer(repl); for (ExprNamedParam en : expNew.getParams()) { Expression actual = en.getExpr(); repl.put(en.getName(), actual); } for (ExprNamedParam en : expNew.getParams()) { String name = en.getName(); if (!mst.containsKey(name)) { throw new ExceptionAtNode("Unknown field " + name, expNew); } Type ftype = mst.get(en.getName()); Expression actual = en.getExpr(); if (ftype == null) { if (actual instanceof ExprStar) { throw new ExceptionAtNode( "The type of field " + name + " is ambiguous. Can't resolve the type of the hole.", expNew); } continue; } upgradeStarToInt(actual, (Type) ftype.accept(vr)); } return expNew; } TypeStructRef nt = (TypeStructRef) expNew.getTypeToConstruct().accept(this); StructDef sd = nres.getStruct(nt.getName()); Map<String, Expression> repl = new HashMap<String, Expression>(); VarReplacer vr = new VarReplacer(repl); for (ExprNamedParam en : expNew.getParams()) { Expression actual = en.getExpr(); repl.put(en.getName(), actual); } for (ExprNamedParam en : expNew.getParams()) { // ADT StructDef current = sd; Type t = null; while (current != null) { t = current.getType(en.getName()); if (t != null) break; String parent; if ((parent = nres.getStructParentName(current.getFullName())) != null) { current = nres.getStruct(parent); } else { current = null; } } Expression actual = en.getExpr(); upgradeStarToInt(actual, (Type) t.accept(vr)); } return expNew; }