KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2004, 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 org.eclipse.jdt.core.BindingKey;
14 import org.eclipse.jdt.core.IJavaElement;
15 import org.eclipse.jdt.core.IMethod;
16 import org.eclipse.jdt.core.IType;
17 import org.eclipse.jdt.core.ITypeParameter;
18 import org.eclipse.jdt.core.JavaModelException;
19 import org.eclipse.jdt.core.Signature;
20 import org.eclipse.jdt.core.compiler.CharOperation;
21 import org.eclipse.jdt.core.search.SearchPattern;
22 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
23 import org.eclipse.jdt.internal.core.util.Util;
24
25
26 public class JavaSearchPattern extends SearchPattern implements IIndexConstants {
27     
28     /*
29      * Whether this pattern is case sensitive.
30      */

31     boolean isCaseSensitive;
32
33     /*
34      * Whether this pattern is camel case.
35      */

36     boolean isCamelCase;
37
38     /**
39      * One of following pattern value:
40      * <ul>
41      * <li>{@link #R_EXACT_MATCH}</li>
42      * <li>{@link #R_PREFIX_MATCH}</li>
43      * <li>{@link #R_PATTERN_MATCH}</li>
44      * <li>{@link #R_REGEXP_MATCH}</li>
45      * <li>{@link #R_CAMELCASE_MATCH}</li>
46      * </ul>
47      */

48     int matchMode;
49
50     /**
51      * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
52      */

53     int matchCompatibility;
54
55     /**
56      * Mask used on match rule for match mode.
57      */

58     public static final int MATCH_MODE_MASK = R_EXACT_MATCH | R_PREFIX_MATCH | R_PATTERN_MATCH | R_REGEXP_MATCH;
59
60     /**
61      * Mask used on match rule for generic relevance.
62      */

63     public static final int MATCH_COMPATIBILITY_MASK = R_ERASURE_MATCH | R_EQUIVALENT_MATCH | R_FULL_MATCH;
64
65     // Signatures and arguments for parameterized types search
66
char[][] typeSignatures;
67     private char[][][] typeArguments;
68     private int flags = 0;
69     static final int HAS_TYPE_ARGUMENTS = 1;
70
71     protected JavaSearchPattern(int patternKind, int matchRule) {
72         super(matchRule);
73         ((InternalSearchPattern)this).kind = patternKind;
74         // Use getMatchRule() instead of matchRule as super constructor may modify its value
75
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=81377
76
int rule = getMatchRule();
77         this.isCaseSensitive = (rule & R_CASE_SENSITIVE) != 0;
78         this.isCamelCase = (rule & R_CAMELCASE_MATCH) != 0;
79         this.matchCompatibility = rule & MATCH_COMPATIBILITY_MASK;
80         this.matchMode = rule & MATCH_MODE_MASK;
81     }
82     
83     public SearchPattern getBlankPattern() {
84         return null;
85     }
86
87     int getMatchMode() {
88         return this.matchMode;
89     }
90
91     boolean isCamelCase() {
92         return this.isCamelCase;
93     }
94
95     boolean isCaseSensitive () {
96         return this.isCaseSensitive;
97     }
98
99     boolean isErasureMatch() {
100         return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
101     }
102
103     boolean isEquivalentMatch() {
104         return (this.matchCompatibility & R_EQUIVALENT_MATCH) != 0;
105     }
106
107     /*
108      * Extract method arguments using unique key for parameterized methods
109      * and type parameters for non-generic ones.
110      */

111     char[][] extractMethodArguments(IMethod method) {
112         String JavaDoc[] argumentsSignatures = null;
113         BindingKey key;
114         if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
115             argumentsSignatures = key.getTypeArguments();
116         } else {
117             try {
118                 ITypeParameter[] parameters = method.getTypeParameters();
119                 if (parameters != null) {
120                     int length = parameters.length;
121                     if (length > 0) {
122                         char[][] arguments = new char[length][];
123                         for (int i=0; i<length; i++) {
124                             arguments[i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
125                         }
126                         return arguments;
127                     }
128                 }
129             }
130             catch (JavaModelException jme) {
131                 // do nothing
132
}
133             return null;
134         }
135
136         // Parameterized method
137
if (argumentsSignatures != null) {
138             int length = argumentsSignatures.length;
139             if (length > 0) {
140                 char[][] methodArguments = new char[length][];
141                 for (int i=0; i<length; i++) {
142                     methodArguments[i] = argumentsSignatures[i].toCharArray();
143                     CharOperation.replace(methodArguments[i], new char[] { '$', '/' }, '.');
144                 }
145                 return methodArguments;
146             }
147         }
148         return null;
149     }
150
151     /**
152      * @return Returns the typeArguments.
153      */

154     final char[][][] getTypeArguments() {
155         return typeArguments;
156     }
157
158     /**
159      * Returns whether the pattern has signatures or not.
160      * If pattern {@link #typeArguments} field, this field shows that it was built
161      * on a generic source type.
162      * @return true if {@link #typeSignatures} field is not null and has a length greater than 0.
163      */

164     public final boolean hasSignatures() {
165         return this.typeSignatures != null && this.typeSignatures.length > 0;
166     }
167
168     /**
169      * Returns whether the pattern includes type arguments information or not.
170      * @return default is false
171      */

172     public final boolean hasTypeArguments() {
173         return (this.flags & HAS_TYPE_ARGUMENTS) != 0;
174     }
175
176     /**
177      * Returns whether the pattern includes type parameters information or not.
178      * @return true if {@link #typeArguments} contains type parameters instead
179      * type arguments signatures.
180      */

181     public final boolean hasTypeParameters() {
182         return !hasSignatures() && hasTypeArguments();
183     }
184     
185     /**
186      * Return whether two suffixes are compatible.
187      *
188      * Note that obvious compatibility values as equals and {@link IIndexConstants#TYPE_SUFFIX}
189      * has to be tested by caller to avoid unnecessary method call...
190      *
191      * @param typeSuffix
192      * @param patternSuffix
193      * @return true if suffixes are compatible, false otherwise
194      */

195     boolean matchDifferentTypeSuffixes(int typeSuffix, int patternSuffix) {
196         switch(typeSuffix) {
197             case CLASS_SUFFIX :
198                 switch (patternSuffix) {
199                     case CLASS_AND_INTERFACE_SUFFIX :
200                     case CLASS_AND_ENUM_SUFFIX :
201                         return true;
202                 }
203                 return false;
204
205             case INTERFACE_SUFFIX :
206                 switch (patternSuffix) {
207                     case CLASS_AND_INTERFACE_SUFFIX :
208                     case INTERFACE_AND_ANNOTATION_SUFFIX:
209                         return true;
210                 }
211                 return false;
212
213             case ENUM_SUFFIX :
214                 return patternSuffix == CLASS_AND_ENUM_SUFFIX;
215
216             case ANNOTATION_TYPE_SUFFIX :
217                 return patternSuffix == INTERFACE_AND_ANNOTATION_SUFFIX;
218
219             case CLASS_AND_INTERFACE_SUFFIX :
220                 switch (patternSuffix) {
221                     case CLASS_SUFFIX :
222                     case INTERFACE_SUFFIX :
223                         return true;
224                 }
225                 return false;
226
227             case CLASS_AND_ENUM_SUFFIX :
228                 switch (patternSuffix) {
229                     case CLASS_SUFFIX :
230                     case ENUM_SUFFIX :
231                         return true;
232                 }
233                 return false;
234
235             case INTERFACE_AND_ANNOTATION_SUFFIX :
236                 switch (patternSuffix) {
237                     case INTERFACE_SUFFIX :
238                     case ANNOTATION_TYPE_SUFFIX :
239                         return true;
240                 }
241                 return false;
242         }
243         
244         // Default behavior is to match suffixes
245
return true;
246     }
247
248     protected StringBuffer JavaDoc print(StringBuffer JavaDoc output) {
249         output.append(", "); //$NON-NLS-1$
250
if (hasTypeArguments() && hasSignatures()) {
251             output.append("signature:\""); //$NON-NLS-1$
252
output.append(this.typeSignatures[0]);
253             output.append("\", "); //$NON-NLS-1$
254
}
255         if (this.isCamelCase) {
256             output.append("camel case + "); //$NON-NLS-1$
257
}
258         switch(getMatchMode()) {
259             case R_EXACT_MATCH :
260                 output.append("exact match,"); //$NON-NLS-1$
261
break;
262             case R_PREFIX_MATCH :
263                 output.append("prefix match,"); //$NON-NLS-1$
264
break;
265             case R_PATTERN_MATCH :
266                 output.append("pattern match,"); //$NON-NLS-1$
267
break;
268             case R_REGEXP_MATCH :
269                 output.append("regexp match, "); //$NON-NLS-1$
270
break;
271         }
272         if (isCaseSensitive())
273             output.append(" case sensitive"); //$NON-NLS-1$
274
else
275             output.append(" case insensitive"); //$NON-NLS-1$
276
if ((this.matchCompatibility & R_ERASURE_MATCH) != 0) {
277             output.append(", erasure only"); //$NON-NLS-1$
278
}
279         if ((this.matchCompatibility & R_EQUIVALENT_MATCH) != 0) {
280             output.append(", equivalent oronly"); //$NON-NLS-1$
281
}
282         return output;
283     }
284     /**
285      * @param typeArguments The typeArguments to set.
286      */

287     final void setTypeArguments(char[][][] typeArguments) {
288         this.typeArguments = typeArguments;
289         // update flags
290
if (this.typeArguments != null) {
291             int length = this.typeArguments.length;
292             for (int i=0; i<length; i++) {
293                 if (this.typeArguments[i] != null && this.typeArguments[i].length > 0) {
294                     this.flags |= HAS_TYPE_ARGUMENTS;
295                     break;
296                 }
297             }
298         }
299     }
300
301     /*
302      * Extract and store type signatures and arguments using unique key for parameterized types
303      * and type parameters for non-generic ones
304      */

305     void storeTypeSignaturesAndArguments(IType type) {
306         BindingKey key;
307         if (type.isResolved() && (key = new BindingKey(type.getKey())).isParameterizedType()) {
308             String JavaDoc signature = key.toSignature();
309             this.typeSignatures = Util.splitTypeLevelsSignature(signature);
310             setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
311         } else {
312             // Scan hierachy to store type arguments at each level
313
char[][][] typeParameters = new char[10][][];
314             int ptr = -1;
315             boolean hasParameters = false;
316             try {
317                 IJavaElement parent = type;
318                 ITypeParameter[] parameters = null;
319                 while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
320                     if (++ptr > typeParameters.length) {
321                         System.arraycopy(typeParameters, 0, typeParameters = new char[typeParameters.length+10][][], 0, ptr);
322                     }
323                     IType parentType = (IType) parent;
324                     parameters = parentType.getTypeParameters();
325                     if (parameters !=null) {
326                         int length = parameters.length;
327                         if (length > 0) {
328                             hasParameters = true;
329                             typeParameters[ptr] = new char[length][];
330                             for (int i=0; i<length; i++)
331                                 typeParameters[ptr][i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
332                         }
333                     }
334                     parent = parent.getParent();
335                 }
336             }
337             catch (JavaModelException jme) {
338                 return;
339             }
340             // Store type arguments if any
341
if (hasParameters) {
342                 if (++ptr < typeParameters.length)
343                     System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
344                 setTypeArguments(typeParameters);
345             }
346         }
347     }
348     public final String JavaDoc toString() {
349         return print(new StringBuffer JavaDoc(30)).toString();
350     }
351 }
352
Popular Tags