in src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java [5022:5129]
protected List<MethodNode> findMethod(ClassNode receiver, final String name, final ClassNode... args) {
if (isPrimitiveType(receiver)) receiver = getWrapper(receiver);
List<MethodNode> methods;
if ("<init>".equals(name)) {
if (receiver.isInterface()) {
methods = EMPTY_METHODNODE_LIST;
} else {
methods = withDefaultArgumentMethods(receiver.getDeclaredConstructors());
if (methods.isEmpty()) {
Parameter[] parameters = receiver.isArray() ? new Parameter[]{new Parameter(int_TYPE, "array_length")} : Parameter.EMPTY_ARRAY;
var defaultConstructor = new ConstructorNode(Opcodes.ACC_PUBLIC, parameters, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
defaultConstructor.setDeclaringClass(receiver);
methods.add(defaultConstructor);
}
}
} else {
methods = findMethodsWithGenerated(receiver, name);
if ("call".equals(name) && receiver.isInterface()) {
MethodNode sam = findSAM(receiver);
if (sam != null) {
MethodNode callMethod = new MethodNode("call", sam.getModifiers(), sam.getReturnType(), sam.getParameters(), sam.getExceptions(), sam.getCode());
callMethod.setDeclaringClass(sam.getDeclaringClass());
callMethod.setSourcePosition(sam);
methods.add(callMethod);
}
}
if (typeCheckingContext.getEnclosingClassNodes().contains(receiver)) {
boolean staticOnly = Modifier.isStatic(receiver.getModifiers());
for (ClassNode outer = receiver; (outer = outer.getOuterClass()) != null;
staticOnly = staticOnly || Modifier.isStatic(outer.getModifiers())) {
methods.addAll(allowStaticAccessToMember(findMethodsWithGenerated(outer, name), staticOnly));
}
}
if (args == null || args.length == 0) {
// check for property accessor
String pname = extractPropertyNameFromMethodName("get", name);
if (pname == null) {
pname = extractPropertyNameFromMethodName("is", name);
}
PropertyNode property = null;
if (pname != null) {
property = findProperty(receiver, pname);
} else {
out: // look for property via getGetterName() for non-canonical case
for (ClassNode cn = receiver; cn != null; cn = cn.getSuperClass()) {
for (PropertyNode pn : cn.getProperties()) {
if (name.equals(pn.getGetterName())) {
property = pn;
break out;
}
}
}
}
if (property != null && property.getDeclaringClass().getGetterMethod(name) == null) {
MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC | (property.isStatic() ? Opcodes.ACC_STATIC : 0),
property.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
node.setDeclaringClass(property.getDeclaringClass());
node.setSynthetic(true);
methods.add(node);
}
} else if (args.length == 1 && (methods.isEmpty()
|| methods.stream().allMatch(MethodNode::isAbstract))) { // GROOVY-10922
// check for property mutator
String pname = extractPropertyNameFromMethodName("set", name);
if (pname != null) {
PropertyNode property = findProperty(receiver, pname);
if (property != null && !property.isFinal()) {
ClassNode type = property.getOriginType();
if (implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]), wrapTypeIfNecessary(type))) {
MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC | (property.isStatic() ? Opcodes.ACC_STATIC : 0),
VOID_TYPE, new Parameter[]{new Parameter(type, name)}, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
node.setDeclaringClass(property.getDeclaringClass());
node.setSynthetic(true);
methods.add(node);
}
}
}
}
}
if (!name.endsWith("init>")) { // also search for extension methods
methods.addAll(findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), receiver, name));
}
methods = filterMethodsByVisibility(methods, typeCheckingContext.getEnclosingClassNode());
List<MethodNode> chosen = chooseBestMethod(receiver, methods, args);
if (!chosen.isEmpty()) return chosen;
// GROOVY-5566
if (receiver instanceof InnerClassNode && ((InnerClassNode) receiver).isAnonymous() && methods.size() == 1 && args != null && "<init>".equals(name)) {
MethodNode constructor = methods.get(0);
if (constructor.getParameters().length == args.length) {
return methods;
}
}
if (isClassClassNodeWrappingConcreteType(receiver)) { // GROOVY-6802, GROOVY-6803, GROOVY-9415
List<MethodNode> result = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
result = allowStaticAccessToMember(result, true); // GROOVY-11427
if (!result.isEmpty()) return result;
}
if (isGStringType(receiver)) {
return findMethod(STRING_TYPE, name, args);
}
return EMPTY_METHODNODE_LIST;
}