assert rubyObjectClass != null;
assert methodDetails != null;
final RubyContext context = rubyObjectClass.getContext();
RubyModule module;
if (methodDetails.getClassAnnotation().name().equals("main")) {
module = context.getCoreLibrary().getMainObject().getSingletonClass(null);
} else {
module = rubyObjectClass;
for (String moduleName : methodDetails.getClassAnnotation().name().split("::")) {
module = (RubyModule) ModuleOperations.lookupConstant(context, LexicalScope.NONE, module, moduleName).getValue();
}
}
assert module != null : methodDetails.getClassAnnotation().name();
final CoreMethod anno = methodDetails.getMethodAnnotation();
final List<String> names = Arrays.asList(anno.names());
assert names.size() >= 1;
final String canonicalName = names.get(0);
final List<String> aliases = names.subList(1, names.size());
final Visibility visibility = anno.visibility();
if (anno.isModuleFunction()) {
if (visibility != Visibility.PUBLIC) {
System.err.println("WARNING: visibility ignored when isModuleFunction in " + methodDetails.getIndicativeName());
}
if (anno.onSingleton()) {
System.err.println("WARNING: Either onSingleton or isModuleFunction for " + methodDetails.getIndicativeName());
}
}
// Do not use needsSelf=true in module functions, it is either the module/class or the instance.
// Usage of needsSelf is quite rare for singleton methods (except constructors).
final boolean needsSelf = !anno.isModuleFunction() && !anno.onSingleton() && anno.needsSelf();
final RubyRootNode rootNode = makeGenericMethod(context, methodDetails, needsSelf);
final RubyMethod method = new RubyMethod(rootNode.getSharedMethodInfo(), canonicalName, module, visibility, false,
Truffle.getRuntime().createCallTarget(rootNode), null);
if (anno.isModuleFunction()) {
addMethod(module, method, aliases, Visibility.PRIVATE);
addMethod(module.getSingletonClass(null), method, aliases, Visibility.PUBLIC);
} else if (anno.onSingleton()) {
addMethod(module.getSingletonClass(null), method, aliases, visibility);
} else {
addMethod(module, method, aliases, visibility);
}
}