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; }