if (isPrimitiveType(receiver)) receiver = getWrapper(receiver);
List<MethodNode> methods;
if (!receiver.isInterface() && "<init>".equals(name)) {
methods = addGeneratedMethods(receiver,new ArrayList<MethodNode>(receiver.getDeclaredConstructors()));
if (methods.isEmpty()) {
MethodNode node = new ConstructorNode(Opcodes.ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
node.setDeclaringClass(receiver);
return Collections.singletonList(node);
}
} else {
methods = findMethodsWithGenerated(receiver,name);
if (receiver.isInterface()) {
collectAllInterfaceMethodsByName(receiver, name, methods);
methods.addAll(OBJECT_TYPE.getMethods(name));
}
if (typeCheckingContext.getEnclosingClosure() == null) {
// not in a closure
ClassNode parent = receiver;
while (parent instanceof InnerClassNode && !parent.isStaticClass()) {
parent = parent.getOuterClass();
methods.addAll(findMethodsWithGenerated(parent,name));
}
}
if (methods.isEmpty()) {
addArrayMethods(methods, receiver, name, args);
}
if (methods.isEmpty() && (args == null || args.length == 0)) {
// check if it's a property
String pname = extractPropertyNameFromMethodName("get", name);
if (pname==null) {
pname = extractPropertyNameFromMethodName("is", name);
}
if (pname != null) {
// we don't use property exists there because findMethod is called on super clases recursively
PropertyNode property = null;
ClassNode curNode = receiver;
while (property == null && curNode != null) {
property = curNode.getProperty(pname);
ClassNode svCur = curNode;
while (property==null && svCur instanceof InnerClassNode && !svCur.isStaticClass()) {
svCur = svCur.getOuterClass();
property = svCur.getProperty(pname);
if (property!=null) {
receiver = svCur;
break;
}
}
curNode = curNode.getSuperClass();
}
if (property != null) {
MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, property.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
if (property.isStatic()) {
node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
}
node.setDeclaringClass(receiver);
return Collections.singletonList(
node);
}
}
} else if (methods.isEmpty() && args != null && args.length == 1) {
// maybe we are looking for a setter ?
String pname = extractPropertyNameFromMethodName("set", name);
if (pname!=null) {
ClassNode curNode = receiver;
PropertyNode property = null;
while (property == null && curNode != null) {
property = curNode.getProperty(pname);
curNode = curNode.getSuperClass();
}
if (property != null) {
ClassNode type = property.getOriginType();
if (implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]), wrapTypeIfNecessary(type))) {
MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, VOID_TYPE, new Parameter[]{
new Parameter(type, "arg")
}, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
if (property.isStatic()) {
node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
}
node.setDeclaringClass(receiver);
return Collections.singletonList(node);
}
}
}
}