src/java.base/share/classes/java/lang/PublicMethods.java
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 42947 jdk/src/java.base/share/classes/java/lang/PublicMethods.java@2453d65278f3
child 48373 f9152f462cbc
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42947
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     1
/*
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     2
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     4
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     7
 * published by the Free Software Foundation.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     8
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    13
 * accompanied this code).
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    14
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    18
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    21
 * questions.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    22
 */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    23
package java.lang;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    24
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    25
import jdk.internal.reflect.ReflectionFactory;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    26
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    27
import java.lang.reflect.Method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    28
import java.lang.reflect.Modifier;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    29
import java.security.AccessController;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    30
import java.util.Arrays;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    31
import java.util.LinkedHashMap;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    32
import java.util.Map;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    33
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    34
/**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    35
 * A collection of most specific public methods. Methods are added to it using
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    36
 * {@link #merge(Method)} method. Only the most specific methods for a
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    37
 * particular signature are kept.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    38
 */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    39
final class PublicMethods {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    40
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    41
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    42
     * a map of (method name, parameter types) -> linked list of Method(s)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    43
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    44
    private final Map<Key, MethodList> map = new LinkedHashMap<>();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    45
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    46
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    47
     * keeps track of the number of collected methods
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    48
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    49
    private int methodCount;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    50
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    51
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    52
     * Merges new method with existing methods. New method is either
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    53
     * ignored (if a more specific method with same signature exists) or added
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    54
     * to the collection. When it is added to the collection, it may replace one
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    55
     * or more existing methods with same signature if they are less specific
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    56
     * than added method.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    57
     * See comments in code...
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    58
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    59
    void merge(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    60
        Key key = new Key(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    61
        MethodList existing = map.get(key);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    62
        int xLen = existing == null ? 0 : existing.length();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    63
        MethodList merged = MethodList.merge(existing, method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    64
        methodCount += merged.length() - xLen;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    65
        // replace if head of list changed
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    66
        if (merged != existing) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    67
            map.put(key, merged);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    68
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    69
    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    70
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    71
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    72
     * Dumps methods to array.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    73
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    74
    Method[] toArray() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    75
        Method[] array = new Method[methodCount];
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    76
        int i = 0;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    77
        for (MethodList ml : map.values()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    78
            for (; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    79
                array[i++] = ml.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    80
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    81
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    82
        return array;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    83
    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    84
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    85
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    86
     * Method (name, parameter types) tuple.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    87
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    88
    private static final class Key {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    89
        private static final ReflectionFactory reflectionFactory =
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    90
            AccessController.doPrivileged(
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    91
                new ReflectionFactory.GetReflectionFactoryAction());
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    92
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    93
        private final String name; // must be interned (as from Method.getName())
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    94
        private final Class<?>[] ptypes;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    95
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    96
        Key(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    97
            name = method.getName();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    98
            ptypes = reflectionFactory.getExecutableSharedParameterTypes(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    99
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   100
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   101
        static boolean matches(Method method,
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   102
                               String name, // may not be interned
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   103
                               Class<?>[] ptypes) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   104
            return method.getName().equals(name) &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   105
                   Arrays.equals(
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   106
                       reflectionFactory.getExecutableSharedParameterTypes(method),
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   107
                       ptypes
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   108
                   );
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   109
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   110
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   111
        @Override
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   112
        public boolean equals(Object o) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   113
            if (this == o) return true;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   114
            if (!(o instanceof Key)) return false;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   115
            Key that = (Key) o;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   116
            //noinspection StringEquality (guaranteed interned String(s))
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   117
            return name == that.name &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   118
                   Arrays.equals(ptypes, that.ptypes);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   119
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   120
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   121
        @Override
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   122
        public int hashCode() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   123
            return System.identityHashCode(name) + // guaranteed interned String
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   124
                   31 * Arrays.hashCode(ptypes);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   125
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   126
    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   127
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   128
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   129
     * Node of a inked list containing Method(s) sharing the same
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   130
     * (name, parameter types) tuple.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   131
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   132
    static final class MethodList {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   133
        Method method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   134
        MethodList next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   135
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   136
        private MethodList(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   137
            this.method = method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   138
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   139
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   140
        /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   141
         * @return the head of a linked list containing given {@code methods}
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   142
         *         filtered by given method {@code name}, parameter types
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   143
         *         {@code ptypes} and including or excluding static methods as
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   144
         *         requested by {@code includeStatic} flag.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   145
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   146
        static MethodList filter(Method[] methods, String name,
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   147
                                 Class<?>[] ptypes, boolean includeStatic) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   148
            MethodList head = null, tail = null;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   149
            for (Method method : methods) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   150
                if ((includeStatic || !Modifier.isStatic(method.getModifiers())) &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   151
                    Key.matches(method, name, ptypes)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   152
                    if (tail == null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   153
                        head = tail = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   154
                    } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   155
                        tail = tail.next = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   156
                    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   157
                }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   158
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   159
            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   160
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   161
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   162
        /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   163
         * This method should only be called with the {@code head} (possibly null)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   164
         * of a list of Method(s) that share the same (method name, parameter types)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   165
         * and another {@code methodList} that also contains Method(s) with the
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   166
         * same and equal (method name, parameter types) as the 1st list.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   167
         * It modifies the 1st list and returns the head of merged list
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   168
         * containing only the most specific methods for each signature
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   169
         * (i.e. return type). The returned head of the merged list may or
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   170
         * may not be the same as the {@code head} of the given list.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   171
         * The given {@code methodList} is not modified.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   172
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   173
        static MethodList merge(MethodList head, MethodList methodList) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   174
            for (MethodList ml = methodList; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   175
                head = merge(head, ml.method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   176
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   177
            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   178
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   179
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   180
        private static MethodList merge(MethodList head, Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   181
            Class<?> dclass = method.getDeclaringClass();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   182
            Class<?> rtype = method.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   183
            MethodList prev = null;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   184
            for (MethodList l = head; l != null; l = l.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   185
                // eXisting method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   186
                Method xmethod = l.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   187
                // only merge methods with same signature:
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   188
                // (return type, name, parameter types) tuple
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   189
                // as we only keep methods with same (name, parameter types)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   190
                // tuple together in one list, we only need to check return type
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   191
                if (rtype == xmethod.getReturnType()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   192
                    Class<?> xdclass = xmethod.getDeclaringClass();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   193
                    if (dclass.isInterface() == xdclass.isInterface()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   194
                        // both methods are declared by interfaces
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   195
                        // or both by classes
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   196
                        if (dclass.isAssignableFrom(xdclass)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   197
                            // existing method is the same or overrides
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   198
                            // new method - ignore new method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   199
                            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   200
                        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   201
                        if (xdclass.isAssignableFrom(dclass)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   202
                            // new method overrides existing
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   203
                            // method - knock out existing method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   204
                            if (prev != null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   205
                                prev.next = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   206
                            } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   207
                                head = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   208
                            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   209
                            // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   210
                        } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   211
                            // unrelated (should only happen for interfaces)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   212
                            prev = l;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   213
                            // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   214
                        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   215
                    } else if (dclass.isInterface()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   216
                        // new method is declared by interface while
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   217
                        // existing method is declared by class -
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   218
                        // ignore new method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   219
                        return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   220
                    } else /* xdclass.isInterface() */ {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   221
                        // new method is declared by class while
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   222
                        // existing method is declared by interface -
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   223
                        // knock out existing method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   224
                        if (prev != null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   225
                            prev.next = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   226
                        } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   227
                            head = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   228
                        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   229
                        // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   230
                    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   231
                } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   232
                    // distinct signatures
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   233
                    prev = l;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   234
                    // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   235
                }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   236
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   237
            // append new method to the list
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   238
            if (prev == null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   239
                head = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   240
            } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   241
                prev.next = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   242
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   243
            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   244
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   245
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   246
        private int length() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   247
            int len = 1;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   248
            for (MethodList ml = next; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   249
                len++;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   250
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   251
            return len;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   252
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   253
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   254
        /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   255
         * @return 1st method in list with most specific return type
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   256
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   257
        Method getMostSpecific() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   258
            Method m = method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   259
            Class<?> rt = m.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   260
            for (MethodList ml = next; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   261
                Method m2 = ml.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   262
                Class<?> rt2 = m2.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   263
                if (rt2 != rt && rt.isAssignableFrom(rt2)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   264
                    // found more specific return type
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   265
                    m = m2;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   266
                    rt = rt2;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   267
                }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   268
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   269
            return m;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   270
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   271
    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   272
}