public boolean resolveMethodArg(Template template, ClassType classType, TypeExpression argType, IRubyObject receiver, IRubyObject arg) {
if (argType == null) { return true; }
switch (argType.getType()) {
case VARIABLE: {
TypeVariable var = (TypeVariable) argType;
TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(receiver);
if (classType != null
&& typeVarMap != null
&& classType.containsType(var)) {
Vertex vertex = typeVarMap.get(var);
if (vertex == null) {
vertex = graph.createFreeVertex();
typeVarMap.put(var, vertex);
}
vertex.addType(arg);
graph.propagateEdges(vertex);
} else {
Vertex vertex = env.get(var);
if (vertex == null) {
vertex = graph.createFreeVertex();
env.put(var, vertex);
}
vertex.addType(arg);
graph.propagateEdges(vertex);
}
return true;
}
case APPLICATION: {
TypeApplication app = (TypeApplication) argType;
List<TypeExpression> types = app.getTypes();
IRubyObject ret = resolveIdentity(template, app.getIdentity());
if (!(ret instanceof RubyModule) || !arg.isKindOf((RubyModule) ret)) {
return false;
} else {
RubyModule klass = (RubyModule) ret;
ClassType klassType = RuntimeHelper.getClassAnnotation(klass);
TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(arg);
if (klassType != null && typeVarMap != null) {
List<TypeVariable> vars = klassType.getTypes();
for (int i = 0; i < vars.size(); i++) {
TypeVariable var = vars.get(i);
Vertex vertex = typeVarMap.get(var);
if (i < types.size() && vertex != null) {
TypeExpression expr = types.get(i);
for (IRubyObject a : vertex.getTypeSet()) {
if (!resolveMethodArg(template, klassType, expr, receiver, a)) {