1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package org.codehaus.groovy.runtime;
36
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.List;
40
41 /***
42 * An abstract base class for a key used for comparators and Map keys to lookup a method by
43 * name and parameter types
44 *
45 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
46 * @version $Revision: 4661 $
47 */
48 public abstract class MethodKey {
49
50 private int hash;
51 private String name;
52 private Class sender;
53 private boolean isCallToSuper;
54
55 public MethodKey(Class sender, String name, boolean isCallToSuper) {
56 this.sender = sender;
57 this.name = name;
58 this.isCallToSuper = isCallToSuper;
59 }
60
61 /***
62 * Creates an immutable copy that we can cache.
63 */
64 public MethodKey createCopy() {
65 int size = getParameterCount();
66 Class[] paramTypes = new Class[size];
67 for (int i = 0; i < size; i++) {
68 paramTypes[i] = getParameterType(i);
69 }
70 return new DefaultMethodKey(sender, name, paramTypes, isCallToSuper);
71 }
72
73 public boolean equals(Object that) {
74 if (this == that) {
75 return true;
76 }
77 else if (hashCode() == that.hashCode() && that instanceof MethodKey) {
78 return equals((MethodKey) that);
79 }
80 return false;
81 }
82
83 public boolean equals(MethodKey that) {
84 int size = getParameterCount();
85 if (sender!=that.sender) return false;
86 if (isCallToSuper!=that.isCallToSuper) return false;
87 if (name.equals(that.name) && size == that.getParameterCount()) {
88 for (int i = 0; i < size; i++) {
89 if (!getParameterType(i).equals(that.getParameterType(i))) {
90 return false;
91 }
92 }
93 return true;
94 }
95 return false;
96 }
97
98 public int hashCode() {
99 if (hash == 0) {
100 hash = createHashCode();
101 if (hash == 0) {
102 hash = 0xcafebabe;
103 }
104 }
105 return hash;
106 }
107
108 public String toString() {
109 return super.toString() + "[name:" + name + "; params:" + getParamterTypes();
110 }
111
112 public String getName() {
113 return name;
114 }
115
116 public List getParamterTypes() {
117 int size = getParameterCount();
118 if (size <= 0) {
119 return Collections.EMPTY_LIST;
120 }
121 List params = new ArrayList(size);
122 for (int i = 0; i < size; i++) {
123 params.add(getParameterType(i));
124 }
125 return params;
126 }
127
128 public abstract int getParameterCount();
129 public abstract Class getParameterType(int index);
130
131 protected int createHashCode() {
132 int answer = name.hashCode();
133 int size = getParameterCount();
134
135 /*** @todo we should use the real Josh Bloch algorithm here */
136
137
138
139 for (int i = 0; i < size; i++) {
140 answer *= 37;
141 answer += 1 + getParameterType(i).hashCode();
142 }
143 answer *= 37;
144 answer += isCallToSuper?1:0;
145 answer *= 37;
146 answer += 1 + sender.hashCode();
147 return answer;
148 }
149 }