KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > search > matching > MethodPattern


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.core.search.matching;
12
13 import java.io.IOException JavaDoc;
14
15 import org.eclipse.jdt.core.*;
16 import org.eclipse.jdt.core.compiler.CharOperation;
17 import org.eclipse.jdt.core.search.SearchPattern;
18 import org.eclipse.jdt.internal.core.index.*;
19 import org.eclipse.jdt.internal.core.util.Util;
20
21 public class MethodPattern extends JavaSearchPattern {
22
23 protected boolean findDeclarations;
24 protected boolean findReferences;
25
26 public char[] selector;
27
28 public char[] declaringQualification;
29 public char[] declaringSimpleName;
30
31 public char[] returnQualification;
32 public char[] returnSimpleName;
33
34 public char[][] parameterQualifications;
35 public char[][] parameterSimpleNames;
36 public int parameterCount;
37 public boolean varargs = false;
38
39 // extra reference info
40
protected IType declaringType;
41
42 // Signatures and arguments for generic search
43
char[][] returnTypeSignatures;
44 char[][][] returnTypeArguments;
45 char[][][] parametersTypeSignatures;
46 char[][][][] parametersTypeArguments;
47 boolean methodParameters = false;
48 char[][] methodArguments;
49
50 protected static char[][] REF_CATEGORIES = { METHOD_REF };
51 protected static char[][] REF_AND_DECL_CATEGORIES = { METHOD_REF, METHOD_DECL };
52 protected static char[][] DECL_CATEGORIES = { METHOD_DECL };
53
54 /**
55  * Method entries are encoded as selector '/' Arity:
56  * e.g. 'foo/0'
57  */

58 public static char[] createIndexKey(char[] selector, int argCount) {
59     char[] countChars = argCount < 10
60         ? COUNTS[argCount]
61         : ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
62
return CharOperation.concat(selector, countChars);
63 }
64
65 MethodPattern(int matchRule) {
66     super(METHOD_PATTERN, matchRule);
67 }
68 public MethodPattern(
69     boolean findDeclarations,
70     boolean findReferences,
71     char[] selector,
72     char[] declaringQualification,
73     char[] declaringSimpleName,
74     char[] returnQualification,
75     char[] returnSimpleName,
76     char[][] parameterQualifications,
77     char[][] parameterSimpleNames,
78     IType declaringType,
79     int matchRule) {
80
81     this(matchRule);
82
83     this.findDeclarations = findDeclarations;
84     this.findReferences = findReferences;
85
86     this.selector = (isCaseSensitive() || isCamelCase()) ? selector : CharOperation.toLowerCase(selector);
87     this.declaringQualification = isCaseSensitive() ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
88     this.declaringSimpleName = isCaseSensitive() ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
89     this.returnQualification = isCaseSensitive() ? returnQualification : CharOperation.toLowerCase(returnQualification);
90     this.returnSimpleName = isCaseSensitive() ? returnSimpleName : CharOperation.toLowerCase(returnSimpleName);
91     if (parameterSimpleNames != null) {
92         this.parameterCount = parameterSimpleNames.length;
93         this.parameterQualifications = new char[this.parameterCount][];
94         this.parameterSimpleNames = new char[this.parameterCount][];
95         for (int i = 0; i < this.parameterCount; i++) {
96             this.parameterQualifications[i] = isCaseSensitive() ? parameterQualifications[i] : CharOperation.toLowerCase(parameterQualifications[i]);
97             this.parameterSimpleNames[i] = isCaseSensitive() ? parameterSimpleNames[i] : CharOperation.toLowerCase(parameterSimpleNames[i]);
98         }
99     } else {
100         this.parameterCount = -1;
101     }
102     this.declaringType = declaringType;
103     ((InternalSearchPattern)this).mustResolve = mustResolve();
104 }
105 /*
106  * Instanciate a method pattern with signatures for generics search
107  */

108 public MethodPattern(
109     boolean findDeclarations,
110     boolean findReferences,
111     char[] selector,
112     char[] declaringQualification,
113     char[] declaringSimpleName,
114     char[] returnQualification,
115     char[] returnSimpleName,
116     String JavaDoc returnSignature,
117     char[][] parameterQualifications,
118     char[][] parameterSimpleNames,
119     String JavaDoc[] parameterSignatures,
120     IMethod method,
121     int matchRule) {
122
123     this(findDeclarations,
124         findReferences,
125         selector,
126         declaringQualification,
127         declaringSimpleName,
128         returnQualification,
129         returnSimpleName,
130         parameterQualifications,
131         parameterSimpleNames,
132         method.getDeclaringType(),
133         matchRule);
134     
135     // Set flags
136
try {
137         this.varargs = (method.getFlags() & Flags.AccVarargs) != 0;
138     } catch (JavaModelException e) {
139         // do nothing
140
}
141
142     // Get unique key for parameterized constructors
143
String JavaDoc genericDeclaringTypeSignature = null;
144 // String genericSignature = null;
145
String JavaDoc key;
146     if (method.isResolved() && (new BindingKey(key = method.getKey())).isParameterizedType()) {
147         genericDeclaringTypeSignature = Util.getDeclaringTypeSignature(key);
148     } else {
149         methodParameters = true;
150     }
151
152     // Store type signature and arguments for declaring type
153
if (genericDeclaringTypeSignature != null) {
154         this.typeSignatures = Util.splitTypeLevelsSignature(genericDeclaringTypeSignature);
155         setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
156     } else {
157         storeTypeSignaturesAndArguments(declaringType);
158     }
159
160     // Store type signatures and arguments for return type
161
if (returnSignature != null) {
162         returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
163         returnTypeArguments = Util.getAllTypeArguments(returnTypeSignatures);
164     }
165
166     // Store type signatures and arguments for method parameters type
167
if (parameterSignatures != null) {
168         int length = parameterSignatures.length;
169         if (length > 0) {
170             parametersTypeSignatures = new char[length][][];
171             parametersTypeArguments = new char[length][][][];
172             for (int i=0; i<length; i++) {
173                 parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
174                 parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
175             }
176         }
177     }
178
179     // Store type signatures and arguments for method
180
methodArguments = extractMethodArguments(method);
181     if (hasMethodArguments()) ((InternalSearchPattern)this).mustResolve = true;
182 }
183 /*
184  * Instanciate a method pattern with signatures for generics search
185  */

186 public MethodPattern(
187     boolean findDeclarations,
188     boolean findReferences,
189     char[] selector,
190     char[] declaringQualification,
191     char[] declaringSimpleName,
192     String JavaDoc declaringSignature,
193     char[] returnQualification,
194     char[] returnSimpleName,
195     String JavaDoc returnSignature,
196     char[][] parameterQualifications,
197     char[][] parameterSimpleNames,
198     String JavaDoc[] parameterSignatures,
199     char[][] arguments,
200     int matchRule) {
201
202     this(findDeclarations,
203         findReferences,
204         selector,
205         declaringQualification,
206         declaringSimpleName,
207         returnQualification,
208         returnSimpleName,
209         parameterQualifications,
210         parameterSimpleNames,
211         null,
212         matchRule);
213
214     // Store type signature and arguments for declaring type
215
if (declaringSignature != null) {
216         typeSignatures = Util.splitTypeLevelsSignature(declaringSignature);
217         setTypeArguments(Util.getAllTypeArguments(typeSignatures));
218     }
219
220     // Store type signatures and arguments for return type
221
if (returnSignature != null) {
222         returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
223         returnTypeArguments = Util.getAllTypeArguments(returnTypeSignatures);
224     }
225
226     // Store type signatures and arguments for method parameters type
227
if (parameterSignatures != null) {
228         int length = parameterSignatures.length;
229         if (length > 0) {
230             parametersTypeSignatures = new char[length][][];
231             parametersTypeArguments = new char[length][][][];
232             for (int i=0; i<length; i++) {
233                 parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
234                 parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
235             }
236         }
237     }
238
239     // Store type signatures and arguments for method
240
methodArguments = arguments;
241     if (hasMethodArguments()) ((InternalSearchPattern)this).mustResolve = true;
242 }
243 public void decodeIndexKey(char[] key) {
244     int last = key.length - 1;
245     this.parameterCount = 0;
246     this.selector = null;
247     int power = 1;
248     for (int i=last; i>=0; i--) {
249         if (key[i] == SEPARATOR) {
250             System.arraycopy(key, 0, this.selector = new char[i], 0, i);
251             break;
252         }
253         if (i == last) {
254             this.parameterCount = key[i] - '0';
255         } else {
256             power *= 10;
257             this.parameterCount += power * (key[i] - '0');
258         }
259     }
260 }
261 public SearchPattern getBlankPattern() {
262     return new MethodPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
263 }
264 public char[][] getIndexCategories() {
265     if (this.findReferences)
266         return this.findDeclarations ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES;
267     if (this.findDeclarations)
268         return DECL_CATEGORIES;
269     return CharOperation.NO_CHAR_CHAR;
270 }
271 boolean hasMethodArguments() {
272     return methodArguments != null && methodArguments.length > 0;
273 }
274 boolean hasMethodParameters() {
275     return methodParameters;
276 }
277 boolean isPolymorphicSearch() {
278     return this.findReferences;
279 }
280 public boolean matchesDecodedKey(SearchPattern decodedPattern) {
281     MethodPattern pattern = (MethodPattern) decodedPattern;
282
283     return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
284         && matchesName(this.selector, pattern.selector);
285 }
286 /**
287  * Returns whether a method declaration or message send must be resolved to
288  * find out if this method pattern matches it.
289  */

290 protected boolean mustResolve() {
291     // declaring type
292
// If declaring type is specified - even with simple name - always resolves
293
if (declaringSimpleName != null || declaringQualification != null) return true;
294
295     // return type
296
// If return type is specified - even with simple name - always resolves
297
if (returnSimpleName != null || returnQualification != null) return true;
298
299     // parameter types
300
if (parameterSimpleNames != null)
301         for (int i = 0, max = parameterSimpleNames.length; i < max; i++)
302             if (parameterQualifications[i] != null) return true;
303     return false;
304 }
305 EntryResult[] queryIn(Index index) throws IOException JavaDoc {
306     char[] key = this.selector; // can be null
307
int matchRule = getMatchRule();
308
309     switch(getMatchMode()) {
310         case R_EXACT_MATCH :
311             if (this.isCamelCase) break;
312             if (this.selector != null && this.parameterCount >= 0 && !this.varargs)
313                 key = createIndexKey(this.selector, this.parameterCount);
314             else { // do a prefix query with the selector
315
matchRule &= ~R_EXACT_MATCH;
316                 matchRule |= R_PREFIX_MATCH;
317             }
318             break;
319         case R_PREFIX_MATCH :
320             // do a prefix query with the selector
321
break;
322         case R_PATTERN_MATCH :
323             if (this.parameterCount >= 0 && !this.varargs)
324                 key = createIndexKey(this.selector == null ? ONE_STAR : this.selector, this.parameterCount);
325             else if (this.selector != null && this.selector[this.selector.length - 1] != '*')
326                 key = CharOperation.concat(this.selector, ONE_STAR, SEPARATOR);
327             // else do a pattern query with just the selector
328
break;
329         case R_REGEXP_MATCH :
330             // TODO (frederic) implement regular expression match
331
break;
332     }
333
334     return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
335
}
336 protected StringBuffer JavaDoc print(StringBuffer JavaDoc output) {
337     if (this.findDeclarations) {
338         output.append(this.findReferences
339             ? "MethodCombinedPattern: " //$NON-NLS-1$
340
: "MethodDeclarationPattern: "); //$NON-NLS-1$
341
} else {
342         output.append("MethodReferencePattern: "); //$NON-NLS-1$
343
}
344     if (declaringQualification != null)
345         output.append(declaringQualification).append('.');
346     if (declaringSimpleName != null)
347         output.append(declaringSimpleName).append('.');
348     else if (declaringQualification != null)
349         output.append("*."); //$NON-NLS-1$
350

351     if (selector != null)
352         output.append(selector);
353     else
354         output.append("*"); //$NON-NLS-1$
355
output.append('(');
356     if (parameterSimpleNames == null) {
357         output.append("..."); //$NON-NLS-1$
358
} else {
359         for (int i = 0, max = parameterSimpleNames.length; i < max; i++) {
360             if (i > 0) output.append(", "); //$NON-NLS-1$
361
if (parameterQualifications[i] != null) output.append(parameterQualifications[i]).append('.');
362             if (parameterSimpleNames[i] == null) output.append('*'); else output.append(parameterSimpleNames[i]);
363         }
364     }
365     output.append(')');
366     if (returnQualification != null)
367         output.append(" --> ").append(returnQualification).append('.'); //$NON-NLS-1$
368
else if (returnSimpleName != null)
369         output.append(" --> "); //$NON-NLS-1$
370
if (returnSimpleName != null)
371         output.append(returnSimpleName);
372     else if (returnQualification != null)
373         output.append("*"); //$NON-NLS-1$
374
return super.print(output);
375 }
376 }
377
Popular Tags