if (!(receiver instanceof RubyModule)) {
// FIXME toplevel
receiver = receiver.getMetaClass();
}
if (receiver instanceof RubyModule) {
RubyModule module = (RubyModule) receiver;
for (IRubyObject target : arg.getTypeSet()) {
if (target instanceof RubyModule) {
module.includeModule((RubyModule) target);
included = true;
}
}
}
}
}
}
if (!included) {
result.setCallNextMethod(true);
}
}
});
addSpecialMethod("[]", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
Collection<IRubyObject> arg = null;
TypeSet ts = new TypeSet();
for (IRubyObject receiver : receivers) {
if (receiver instanceof Hash) {
if (args != null && args.length > 0) {
Hash hash = (Hash) receiver;
Object key = Hash.getRealKey(args[0].getNode());
if (!hash.isModified() && key != null) {
Vertex v = hash.get(key);
if (v != null) {
ts.addAll(v.getTypeSet());
}
}
}
} else if (receiver instanceof Array) {
if (args != null && args.length > 0) {
Array array = (Array) receiver;
Integer n = Vertex.getFixnum(args[0]);
if (!array.isModified() && n != null) {
Vertex v = array.getElement(n);
if (v != null) {
ts.addAll(v.getTypeSet());
}
}
}
} else if (receiver instanceof Proc) {
if (arg == null) {
if (args == null) {
arg = Arrays.asList((IRubyObject) RuntimeHelper.createArray(Graph.this, new Vertex[0]));
} else if (args.length == 1) {
arg = args[0].getTypeSet();
} else { arg = Arrays.asList((IRubyObject) RuntimeHelper.createArray(Graph.this, args));
}
}
Vertex returnVertex = createFreeVertex();
RuntimeHelper.yield(Graph.this, (Proc) receiver, arg, true, returnVertex);
ts.addAll(returnVertex.getTypeSet());
}
}
if (ts.isEmpty()) {
result.setCallNextMethod(true);
} else {
result.setResultTypeSet(ts);
}
}
});
addSpecialMethod("private", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PRIVATE);
}
});
addSpecialMethod("protected", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PROTECTED);
}
});
addSpecialMethod("public", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.PUBLIC);
}
});
addSpecialMethod("module_function", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.setMethodsVisibility(Graph.this, receivers, args, Visibility.MODULE_FUNCTION);
}
});
addSpecialMethod("attr", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
if (args != null && args.length > 0) {
RuntimeHelper.defineAttrs(Graph.this, receivers, new Vertex[] { args[0] }, true, args.length > 1);
}
}
});
addSpecialMethod("attr_reader", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.defineAttrs(Graph.this, receivers, args, true, false);
}
});
addSpecialMethod("attr_writer", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.defineAttrs(Graph.this, receivers, args, false, true);
}
});
addSpecialMethod("attr_accessor", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
RuntimeHelper.defineAttrs(Graph.this, receivers, args, true, true);
}
});
addSpecialMethod("alias_method", new SpecialMethod() {
public void call(Ruby runtime, TypeSet receivers, Vertex[] args, Block block, Result result) {
boolean callNextMethod = true;
if (args != null && args.length == 2) {
for (IRubyObject receiver : receivers) {
if (receiver instanceof RubyModule) {
callNextMethod = false;
String newName = Vertex.getStringOrSymbol(args[0]);
String oldName = Vertex.getStringOrSymbol(args[1]);
if (newName != null && oldName != null) {
RubyModule module = (RubyModule) receiver;
DynamicMethod method = module.getMethod(oldName);
if (method instanceof Method)
module.addMethod(newName, new AliasMethod(newName, (Method) method));
}
}
}
}
result.setCallNextMethod(callNextMethod);