src/java.base/share/classes/java/lang/PublicMethods.java
author darcy
Wed, 15 Aug 2018 10:44:56 -0700
changeset 51413 43e41800d579
parent 48373 f9152f462cbc
permissions -rw-r--r--
5075463: (enum) Serialized Form javadoc for java.lang.Enum is misleading Reviewed-by: lancea, rriggs, smarks
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
48373
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
42947
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    10
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    11
 * 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
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    13
 * 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
    14
 * 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
    15
 * accompanied this code).
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    16
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    17
 * 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
    18
 * 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
    19
 * 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
    20
 *
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    21
 * 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
    22
 * 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
    23
 * questions.
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
package java.lang;
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 jdk.internal.reflect.ReflectionFactory;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    28
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    29
import java.lang.reflect.Method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    30
import java.lang.reflect.Modifier;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    31
import java.security.AccessController;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    32
import java.util.Arrays;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    33
import java.util.LinkedHashMap;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    34
import java.util.Map;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    35
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    36
/**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    37
 * 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
    38
 * {@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
    39
 * particular signature are kept.
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
final class PublicMethods {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    42
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
     * 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
    45
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    46
    private final Map<Key, MethodList> map = new LinkedHashMap<>();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    47
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
     * keeps track of the number of collected methods
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
    private int methodCount;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    52
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    53
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    54
     * Merges new method with existing methods. New method is either
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    55
     * 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
    56
     * 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
    57
     * 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
    58
     * than added method.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    59
     * See comments in code...
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    60
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    61
    void merge(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    62
        Key key = new Key(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    63
        MethodList existing = map.get(key);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    64
        int xLen = existing == null ? 0 : existing.length();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    65
        MethodList merged = MethodList.merge(existing, method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    66
        methodCount += merged.length() - xLen;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    67
        // replace if head of list changed
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    68
        if (merged != existing) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    69
            map.put(key, merged);
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
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
     * Dumps methods to array.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    75
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    76
    Method[] toArray() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    77
        Method[] array = new Method[methodCount];
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    78
        int i = 0;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    79
        for (MethodList ml : map.values()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    80
            for (; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    81
                array[i++] = ml.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    82
            }
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
        return array;
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
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
     * Method (name, parameter types) tuple.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    89
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    90
    private static final class Key {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    91
        private static final ReflectionFactory reflectionFactory =
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    92
            AccessController.doPrivileged(
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    93
                new ReflectionFactory.GetReflectionFactoryAction());
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    94
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    95
        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
    96
        private final Class<?>[] ptypes;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    97
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    98
        Key(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
    99
            name = method.getName();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   100
            ptypes = reflectionFactory.getExecutableSharedParameterTypes(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   101
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   102
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   103
        static boolean matches(Method method,
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   104
                               String name, // may not be interned
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   105
                               Class<?>[] ptypes) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   106
            return method.getName().equals(name) &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   107
                   Arrays.equals(
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   108
                       reflectionFactory.getExecutableSharedParameterTypes(method),
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   109
                       ptypes
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
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   112
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   113
        @Override
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   114
        public boolean equals(Object o) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   115
            if (this == o) return true;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   116
            if (!(o instanceof Key)) return false;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   117
            Key that = (Key) o;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   118
            //noinspection StringEquality (guaranteed interned String(s))
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   119
            return name == that.name &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   120
                   Arrays.equals(ptypes, that.ptypes);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   121
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   122
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   123
        @Override
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   124
        public int hashCode() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   125
            return System.identityHashCode(name) + // guaranteed interned String
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   126
                   31 * Arrays.hashCode(ptypes);
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
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   130
    /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   131
     * 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
   132
     * (name, parameter types) tuple.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   133
     */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   134
    static final class MethodList {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   135
        Method method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   136
        MethodList next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   137
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   138
        private MethodList(Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   139
            this.method = method;
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
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   142
        /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   143
         * @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
   144
         *         filtered by given method {@code name}, parameter types
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   145
         *         {@code ptypes} and including or excluding static methods as
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   146
         *         requested by {@code includeStatic} flag.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   147
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   148
        static MethodList filter(Method[] methods, String name,
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   149
                                 Class<?>[] ptypes, boolean includeStatic) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   150
            MethodList head = null, tail = null;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   151
            for (Method method : methods) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   152
                if ((includeStatic || !Modifier.isStatic(method.getModifiers())) &&
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   153
                    Key.matches(method, name, ptypes)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   154
                    if (tail == null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   155
                        head = tail = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   156
                    } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   157
                        tail = tail.next = new MethodList(method);
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
                }
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
            return head;
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
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   164
        /**
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   165
         * 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
   166
         * 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
   167
         * 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
   168
         * 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
   169
         * 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
   170
         * containing only the most specific methods for each signature
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   171
         * (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
   172
         * 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
   173
         * The given {@code methodList} is not modified.
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   174
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   175
        static MethodList merge(MethodList head, MethodList methodList) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   176
            for (MethodList ml = methodList; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   177
                head = merge(head, ml.method);
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
            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   180
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   181
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   182
        private static MethodList merge(MethodList head, Method method) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   183
            Class<?> dclass = method.getDeclaringClass();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   184
            Class<?> rtype = method.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   185
            MethodList prev = null;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   186
            for (MethodList l = head; l != null; l = l.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   187
                // eXisting method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   188
                Method xmethod = l.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   189
                // only merge methods with same signature:
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   190
                // (return type, name, parameter types) tuple
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   191
                // as we only keep methods with same (name, parameter types)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   192
                // 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
   193
                if (rtype == xmethod.getReturnType()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   194
                    Class<?> xdclass = xmethod.getDeclaringClass();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   195
                    if (dclass.isInterface() == xdclass.isInterface()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   196
                        // both methods are declared by interfaces
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   197
                        // or both by classes
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   198
                        if (dclass.isAssignableFrom(xdclass)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   199
                            // existing method is the same or overrides
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   200
                            // new method - ignore new method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   201
                            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   202
                        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   203
                        if (xdclass.isAssignableFrom(dclass)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   204
                            // new method overrides existing
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   205
                            // method - knock out existing method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   206
                            if (prev != null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   207
                                prev.next = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   208
                            } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   209
                                head = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   210
                            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   211
                            // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   212
                        } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   213
                            // unrelated (should only happen for interfaces)
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   214
                            prev = l;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   215
                            // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   216
                        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   217
                    } else if (dclass.isInterface()) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   218
                        // new method is declared by interface while
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   219
                        // existing method is declared by class -
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   220
                        // ignore new method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   221
                        return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   222
                    } else /* xdclass.isInterface() */ {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   223
                        // new method is declared by class while
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   224
                        // existing method is declared by interface -
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   225
                        // knock out existing method
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   226
                        if (prev != null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   227
                            prev.next = l.next;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   228
                        } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   229
                            head = l.next;
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
                        // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   232
                    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   233
                } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   234
                    // distinct signatures
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   235
                    prev = l;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   236
                    // keep iterating
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   237
                }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   238
            }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   239
            // append new method to the list
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   240
            if (prev == null) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   241
                head = new MethodList(method);
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   242
            } else {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   243
                prev.next = new MethodList(method);
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
            return head;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   246
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   247
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   248
        private int length() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   249
            int len = 1;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   250
            for (MethodList ml = next; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   251
                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
            return len;
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
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
         * @return 1st method in list with most specific return type
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   258
         */
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   259
        Method getMostSpecific() {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   260
            Method m = method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   261
            Class<?> rt = m.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   262
            for (MethodList ml = next; ml != null; ml = ml.next) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   263
                Method m2 = ml.method;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   264
                Class<?> rt2 = m2.getReturnType();
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   265
                if (rt2 != rt && rt.isAssignableFrom(rt2)) {
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   266
                    // found more specific return type
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   267
                    m = m2;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   268
                    rt = rt2;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   269
                }
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
            return m;
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   272
        }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   273
    }
2453d65278f3 8062389: Class.getMethod() is inconsistent with Class.getMethods() results
plevart
parents:
diff changeset
   274
}