//we already had it (from partial loading elsewhere)
allparms.add((TypeParameter)maybe);
tparms.add((TypeParameter)maybe);
tp.put(MetamodelGenerator.KEY_METATYPE, maybe);
} else {
TypeParameter tparm = new TypeParameter();
tparm.setUnit(u2);
tparm.setDeclaration(container);
container.getMembers().add(tparm);
if (tp.containsKey(MetamodelGenerator.KEY_NAME)) {
tparm.setName((String)tp.get(MetamodelGenerator.KEY_NAME));
} else if (!tp.containsKey(MetamodelGenerator.KEY_TYPES)) {
throw new IllegalArgumentException("Invalid type parameter map " + tp);
}
String variance = (String)tp.get(MetamodelGenerator.KEY_DS_VARIANCE);
if ("out".equals(variance)) {
tparm.setCovariant(true);
} else if ("in".equals(variance)) {
tparm.setContravariant(true);
}
if (container instanceof Scope) {
tparm.setContainer((Scope)container);
}
tparm.setDefaulted(tp.containsKey(MetamodelGenerator.KEY_DEFAULT));
tparms.add(tparm);
allparms.add(tparm);
tp.put(MetamodelGenerator.KEY_METATYPE, tparm);
}
}
if (container instanceof TypeDeclaration) {
((TypeDeclaration) container).setTypeParameters(tparms);
} else if (container instanceof Method) {
((Method) container).setTypeParameters(tparms);
}
//Second, add defaults and heritage
for (Map<String,Object> tp : typeParams) {
TypeParameter tparm = (TypeParameter)tp.get(MetamodelGenerator.KEY_METATYPE);
if (tparm.getExtendedType() == null) {
if (tp.containsKey(MetamodelGenerator.KEY_PACKAGE)) {
//Looks like this never happens but...
ProducedType subtype = getTypeFromJson(tp, container, allparms);
tparm.setExtendedType(subtype);
} else if (tp.containsKey(MetamodelGenerator.KEY_TYPES)) {
if (!("u".equals(tp.get("comp")) || "i".equals(tp.get("comp")))) {
throw new IllegalArgumentException("Only union or intersection types are allowed as 'comp'");
}
ProducedType subtype = getTypeFromJson(tp, container, allparms);
tparm.setName(subtype.getProducedTypeName());
tparm.setExtendedType(subtype);
} else {
tparm.setExtendedType(getTypeFromJson(voidclass, container, null));
}
}
if (tparm.isDefaulted()) {
@SuppressWarnings("unchecked")
final Map<String,Object> deftype = (Map<String,Object>)tp.get(MetamodelGenerator.KEY_DEFAULT);
tparm.setDefaultTypeArgument(getTypeFromJson(deftype, container, existing));
}
if (tp.containsKey(MetamodelGenerator.KEY_SATISFIES)) {
@SuppressWarnings("unchecked")
final List<Map<String,Object>> stypes = (List<Map<String,Object>>)tp.get(MetamodelGenerator.KEY_SATISFIES);
for (ProducedType sat : parseTypeList(stypes, allparms)) {
Util.addToIntersection(tparm.getSatisfiedTypes(), sat, u2);
}
tparm.setConstrained(true);
} else if (tp.containsKey("of")) {
@SuppressWarnings("unchecked")
final List<Map<String,Object>> oftype = (List<Map<String,Object>>)tp.get("of");
tparm.setCaseTypes(parseTypeList(oftype, allparms));
tparm.setConstrained(true);
}
}
return tparms;
}