protected List findMethod()

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;
    }