}
public TypeSet processMethodReturn(Template template, ClassType classType, TypeExpression returnType, IRubyObject receiver) {
if (returnType == null) { return TypeSet.EMPTY; }
TypeSet result = new TypeSet();
switch (returnType.getType()) {
case VARIABLE: {
TypeVariable var = (TypeVariable) returnType;
if (var.getName().equals("self")) {
result.add(receiver);
} else if (var.getName().equals("nil")) {
result.add(runtime.getNil());
} else {
Vertex vertex = env.get(var);
TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(receiver);
if (vertex != null) {
result.addAll(vertex.getTypeSet());
} else if (classType != null
&& typeVarMap != null
&& classType.containsType(var)) {
vertex = typeVarMap.get(var);
if (vertex != null) {
result.addAll(vertex.getTypeSet());
} else {
result.add(runtime.getNil());
}
}
}
return result;
}
case APPLICATION: {
TypeApplication app = (TypeApplication) returnType;
List<TypeExpression> types = app.getTypes();
IRubyObject ret = resolveIdentity(template, app.getIdentity());
if (ret != null && ret instanceof RubyClass) {
RubyClass klass = (RubyClass) ret;
ret = graph.newInstanceOf(klass);
ClassType klassType = RuntimeHelper.getClassAnnotation(klass);
TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(ret);
if (klassType != null && typeVarMap != null) {
List<TypeVariable> vars = klassType.getTypes();
for (int i = 0; i < vars.size(); i++) {
TypeVariable var = vars.get(i);
if (i < types.size()) {
TypeExpression expr = types.get(i);
TypeSet ts = processMethodReturn(template, classType, expr, receiver);
Vertex vertex = graph.createFreeVertex();
vertex.addTypes(ts);
typeVarMap.put(var, vertex);
}
}
}
result.add(ret);
}
return result;
}
case SCOPED_IDENTITY:
case ABSOLUTE_IDENTITY:
case RELATIVE_IDENTITY: {
IRubyObject ret = resolveIdentity(template, (TypeIdentity) returnType);
if (ret != null && ret instanceof RubyClass) {
ret = graph.newInstanceOf((RubyClass) ret);
result.add(ret);
}
return result;
}
case UNION:
for (TypeExpression expr : (TypeUnion) returnType) {
TypeSet ts = processMethodReturn(template, classType, expr, receiver);
if (ts != null) {
result.addAll(ts);
}
}
return result;
case TUPLE: {
TypeTuple tupleType = (TypeTuple) returnType;
List<TypeExpression> exprs = tupleType.getList();
if (exprs != null) {
Vertex[] elements = new Vertex[exprs.size()];
for (int i = 0; i < exprs.size(); i++) {
TypeSet ts = processMethodReturn(template, classType, exprs.get(i), receiver);
if (ts == null) {
return result;
}
elements[i] = graph.createFreeVertex();
elements[i].addTypes(ts);