public JSType substituteGenerics(Map<String, JSType> concreteTypes) { if (isTop() || isUnknown()) { return this; } ImmutableSet<ObjectType> newObjs = null; if (objs != null) { ImmutableSet.Builder<ObjectType> builder = ImmutableSet.builder(); for (ObjectType obj : objs) { builder.add(obj.substituteGenerics(concreteTypes)); } newObjs = builder.build(); } JSType current = new JSType(mask & ~TYPEVAR_MASK, location, newObjs, null); if ((mask & TYPEVAR_MASK) != 0) { current = JSType.join( current, concreteTypes.containsKey(typeVar) ? concreteTypes.get(typeVar) : fromTypeVar(typeVar)); } return current; }