/** Load a type alias, creating it if necessary.
* @return The TypeAlias declaration. */
@SuppressWarnings("unchecked")
private TypeAlias loadTypeAlias(String name, Map<String, Object> m, Scope parent, List<TypeParameter> existing) {
TypeAlias alias;
if (m.get(MetamodelGenerator.KEY_METATYPE) instanceof TypeAlias) {
//It's been loaded already
alias = (TypeAlias)m.get(MetamodelGenerator.KEY_METATYPE);
if (m.size() == 1) {
return alias;
}
} else {
Declaration maybe = parent.getDirectMember(name, null, false);
if (maybe == null) {
alias = new TypeAlias();
alias.setContainer(parent);
alias.setName(name);
alias.setUnit(u2);
setAnnotations(alias, (Integer)m.remove(MetamodelGenerator.KEY_PACKED_ANNS),
(Map<String,Object>)m.remove(MetamodelGenerator.KEY_ANNOTATIONS));
if (parent == this) {
u2.addDeclaration(alias);
}
parent.addMember(alias);
m.put(MetamodelGenerator.KEY_METATYPE, alias);
} else if (maybe instanceof TypeAlias) {
alias = (TypeAlias)maybe;
} else {
throw new IllegalStateException(maybe + " should be an TypeAlias");
}
}
//All interfaces extend Object, except aliases
if (alias.getExtendedType() == null) {
alias.setExtendedType(getTypeFromJson((Map<String,Object>)m.get("$alias"),
parent instanceof Declaration ? (Declaration)parent : null, existing));
}
List<Map<String,Object>> listOfMaps = (List<Map<String,Object>>)m.get(MetamodelGenerator.KEY_TYPE_PARAMS);
final List<TypeParameter> tparms;
if (listOfMaps != null && alias.getTypeParameters().size()<listOfMaps.size()) {
tparms = parseTypeParameters(listOfMaps, alias, existing);
} else {
tparms = alias.getTypeParameters();
}
final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
if (m.containsKey(MetamodelGenerator.KEY_SELF_TYPE)) {
for (TypeParameter _tp : tparms) {
if (_tp.getName().equals(m.get(MetamodelGenerator.KEY_SELF_TYPE))) {
alias.setSelfType(_tp.getType());
}
}
}
if (m.containsKey("of")) {
alias.setCaseTypes(parseTypeList((List<Map<String,Object>>)m.remove("of"), allparms));
}
if (m.containsKey(MetamodelGenerator.KEY_SATISFIES)) {
for (ProducedType sat :parseTypeList((List<Map<String,Object>>)m.remove(MetamodelGenerator.KEY_SATISFIES), allparms)) {
Util.addToIntersection(alias.getSatisfiedTypes(), sat, u2);
}
}
m.clear();
m.put(MetamodelGenerator.KEY_METATYPE, alias);
return alias;