KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > MethodBinding


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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
12 package org.eclipse.jdt.core.dom;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.jdt.core.IJavaElement;
18 import org.eclipse.jdt.core.IMethod;
19 import org.eclipse.jdt.core.IType;
20 import org.eclipse.jdt.core.JavaModelException;
21 import org.eclipse.jdt.core.Signature;
22 import org.eclipse.jdt.core.compiler.CharOperation;
23 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
24 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
25 import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
26 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
27 import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
28 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
29 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
30 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
31 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
32 import org.eclipse.jdt.internal.core.JavaElement;
33 import org.eclipse.jdt.internal.core.Member;
34 import org.eclipse.jdt.internal.core.util.Util;
35
36 /**
37  * Internal implementation of method bindings.
38  */

39 class MethodBinding implements IMethodBinding {
40
41     private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
42         Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | Modifier.NATIVE |
43         Modifier.STRICTFP;
44     private static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
45     private org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding;
46     private BindingResolver resolver;
47     private ITypeBinding[] parameterTypes;
48     private ITypeBinding[] exceptionTypes;
49     private String JavaDoc name;
50     private ITypeBinding declaringClass;
51     private ITypeBinding returnType;
52     private String JavaDoc key;
53     private ITypeBinding[] typeParameters;
54     private ITypeBinding[] typeArguments;
55     private IAnnotationBinding[] annotations;
56     private IAnnotationBinding[] parameterAnnotations;
57
58     MethodBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding) {
59         this.resolver = resolver;
60         this.binding = binding;
61     }
62
63     public boolean isAnnotationMember() {
64         return getDeclaringClass().isAnnotation();
65     }
66
67     /**
68      * @see IMethodBinding#isConstructor()
69      */

70     public boolean isConstructor() {
71         return this.binding.isConstructor();
72     }
73
74     /**
75      * @see IMethodBinding#isDefaultConstructor()
76      * @since 3.0
77      */

78     public boolean isDefaultConstructor() {
79         final ReferenceBinding declaringClassBinding = this.binding.declaringClass;
80         if (declaringClassBinding.isRawType()) {
81             RawTypeBinding rawTypeBinding = (RawTypeBinding) declaringClassBinding;
82             if (rawTypeBinding.genericType().isBinaryBinding()) {
83                 return false;
84             }
85             return (this.binding.modifiers & ExtraCompilerModifiers.AccIsDefaultConstructor) != 0;
86         }
87         if (declaringClassBinding.isBinaryBinding()) {
88             return false;
89         }
90         return (this.binding.modifiers & ExtraCompilerModifiers.AccIsDefaultConstructor) != 0;
91     }
92
93     /**
94      * @see IBinding#getName()
95      */

96     public String JavaDoc getName() {
97         if (name == null) {
98             if (this.binding.isConstructor()) {
99                 name = this.getDeclaringClass().getName();
100             } else {
101                 name = new String JavaDoc(this.binding.selector);
102             }
103         }
104         return name;
105     }
106
107     public IAnnotationBinding[] getAnnotations() {
108         if (this.annotations != null) {
109             return this.annotations;
110         }
111         org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] annots = this.binding.getAnnotations();
112         int length = annots == null ? 0 : annots.length;
113         if (length == 0) {
114             return this.annotations = AnnotationBinding.NoAnnotations;
115         }
116         IAnnotationBinding[] domInstances = new AnnotationBinding[length];
117         for (int i = 0; i < length; i++) {
118             final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(annots[i]);
119             if (annotationInstance == null) {
120                 return this.annotations = AnnotationBinding.NoAnnotations;
121             }
122             domInstances[i] = annotationInstance;
123         }
124         return this.annotations = domInstances;
125     }
126
127     /**
128      * @see IMethodBinding#getDeclaringClass()
129      */

130     public ITypeBinding getDeclaringClass() {
131         if (this.declaringClass == null) {
132             this.declaringClass = this.resolver.getTypeBinding(this.binding.declaringClass);
133         }
134         return declaringClass;
135     }
136
137     public IAnnotationBinding[] getParameterAnnotations(int index) {
138         if (this.parameterAnnotations != null) {
139             return this.parameterAnnotations;
140         }
141         org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] annots = this.binding.getParameterAnnotations(index);
142         int length = annots == null ? 0 : annots.length;
143         if (length == 0) {
144             return this.parameterAnnotations = AnnotationBinding.NoAnnotations;
145         }
146         IAnnotationBinding[] domInstances =new AnnotationBinding[length];
147         for (int i = 0; i < length; i++) {
148             final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(annots[i]);
149             if (annotationInstance == null) {
150                 return this.parameterAnnotations = AnnotationBinding.NoAnnotations;
151             }
152             domInstances[i] = annotationInstance;
153         }
154         return this.parameterAnnotations = domInstances;
155     }
156
157     /**
158      * @see IMethodBinding#getParameterTypes()
159      */

160     public ITypeBinding[] getParameterTypes() {
161         if (this.parameterTypes != null) {
162             return parameterTypes;
163         }
164         org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] parameters = this.binding.parameters;
165         int length = parameters == null ? 0 : parameters.length;
166         if (length == 0) {
167             return this.parameterTypes = NO_TYPE_BINDINGS;
168         } else {
169             ITypeBinding[] paramTypes = new ITypeBinding[length];
170             for (int i = 0; i < length; i++) {
171                 final TypeBinding parameterBinding = parameters[i];
172                 if (parameterBinding != null) {
173                     ITypeBinding typeBinding = this.resolver.getTypeBinding(parameterBinding);
174                     if (typeBinding == null) {
175                         return this.parameterTypes = NO_TYPE_BINDINGS;
176                     }
177                     paramTypes[i] = typeBinding;
178                 } else {
179                     // log error
180
StringBuffer JavaDoc message = new StringBuffer JavaDoc("Report method binding where a parameter is null:\n"); //$NON-NLS-1$
181
message.append(this.toString());
182                     Util.log(new IllegalArgumentException JavaDoc(), message.toString());
183                     // report no binding since one or more parameter has no binding
184
return this.parameterTypes = NO_TYPE_BINDINGS;
185                 }
186             }
187             return this.parameterTypes = paramTypes;
188         }
189     }
190
191     /**
192      * @see IMethodBinding#getReturnType()
193      */

194     public ITypeBinding getReturnType() {
195         if (this.returnType == null) {
196             this.returnType = this.resolver.getTypeBinding(this.binding.returnType);
197         }
198         return this.returnType;
199     }
200
201     public Object JavaDoc getDefaultValue() {
202         if (isAnnotationMember())
203             return MemberValuePairBinding.buildDOMValue(this.binding.getDefaultValue(), this.resolver);
204         return null;
205     }
206
207     /**
208      * @see IMethodBinding#getExceptionTypes()
209      */

210     public ITypeBinding[] getExceptionTypes() {
211         if (this.exceptionTypes != null) {
212             return exceptionTypes;
213         }
214         org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] exceptions = this.binding.thrownExceptions;
215         int length = exceptions == null ? 0 : exceptions.length;
216         if (length == 0) {
217             return this.exceptionTypes = NO_TYPE_BINDINGS;
218         }
219         ITypeBinding[] exTypes = new ITypeBinding[length];
220         for (int i = 0; i < length; i++) {
221             ITypeBinding typeBinding = this.resolver.getTypeBinding(exceptions[i]);
222             if (typeBinding == null) {
223                 return this.exceptionTypes = NO_TYPE_BINDINGS;
224             }
225             exTypes[i] = typeBinding;
226         }
227         return this.exceptionTypes = exTypes;
228     }
229
230     public IJavaElement getJavaElement() {
231         JavaElement element = getUnresolvedJavaElement();
232         if (element == null)
233             return null;
234         return element.resolved(this.binding);
235     }
236
237     private JavaElement getUnresolvedJavaElement() {
238         IType declaringType = (IType) getDeclaringClass().getJavaElement();
239         if (declaringType == null) return null;
240         if (!(this.resolver instanceof DefaultBindingResolver)) return null;
241         ASTNode node = (ASTNode) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
242         if (node != null && declaringType.getParent().getElementType() != IJavaElement.CLASS_FILE) {
243             if (node instanceof MethodDeclaration) {
244                 MethodDeclaration methodDeclaration = (MethodDeclaration) node;
245                 ArrayList JavaDoc parameterSignatures = new ArrayList JavaDoc();
246                 Iterator JavaDoc iterator = methodDeclaration.parameters().iterator();
247                 while (iterator.hasNext()) {
248                     SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
249                     Type type = parameter.getType();
250                     String JavaDoc typeSig = Util.getSignature(type);
251                     int arrayDim = parameter.getExtraDimensions();
252                     if (parameter.getAST().apiLevel() >= AST.JLS3 && parameter.isVarargs()) {
253                         arrayDim++;
254                     }
255                     if (arrayDim > 0) {
256                         typeSig = Signature.createArraySignature(typeSig, arrayDim);
257                     }
258                     parameterSignatures.add(typeSig);
259                 }
260                 int parameterCount = parameterSignatures.size();
261                 String JavaDoc[] parameters = new String JavaDoc[parameterCount];
262                 parameterSignatures.toArray(parameters);
263                 return (JavaElement) declaringType.getMethod(getName(), parameters);
264             } else {
265                 // annotation type member declaration
266
AnnotationTypeMemberDeclaration typeMemberDeclaration = (AnnotationTypeMemberDeclaration) node;
267                 return (JavaElement) declaringType.getMethod(typeMemberDeclaration.getName().getIdentifier(), CharOperation.NO_STRINGS); // annotation type members don't have parameters
268
}
269         } else {
270             // case of method not in the created AST, or a binary method
271
org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = this.binding.original();
272             String JavaDoc selector = original.isConstructor() ? declaringType.getElementName() : new String JavaDoc(original.selector);
273             boolean isBinary = declaringType.isBinary();
274             ReferenceBinding enclosingType = original.declaringClass.enclosingType();
275             boolean isInnerBinaryTypeConstructor = isBinary && original.isConstructor() && enclosingType != null;
276             TypeBinding[] parameters = original.parameters;
277             int length = parameters == null ? 0 : parameters.length;
278             int declaringIndex = isInnerBinaryTypeConstructor ? 1 : 0;
279             String JavaDoc[] parameterSignatures = new String JavaDoc[declaringIndex + length];
280             if (isInnerBinaryTypeConstructor)
281                 parameterSignatures[0] = new String JavaDoc(enclosingType.genericTypeSignature()).replace('/', '.');
282             for (int i = 0; i < length; i++) {
283                 parameterSignatures[declaringIndex + i] = new String JavaDoc(parameters[i].genericTypeSignature()).replace('/', '.');
284             }
285             IMethod result = declaringType.getMethod(selector, parameterSignatures);
286             if (isBinary)
287                 return (JavaElement) result;
288             IMethod[] methods = null;
289             try {
290                 methods = declaringType.getMethods();
291             } catch (JavaModelException e) {
292                 // declaring type doesn't exist
293
return null;
294             }
295             IMethod[] candidates = Member.findMethods(result, methods);
296             if (candidates == null || candidates.length == 0)
297                 return null;
298             return (JavaElement) candidates[0];
299         }
300     }
301
302     /**
303      * @see IBinding#getKind()
304      */

305     public int getKind() {
306         return IBinding.METHOD;
307     }
308
309     /**
310      * @see IBinding#getModifiers()
311      */

312     public int getModifiers() {
313         return this.binding.getAccessFlags() & VALID_MODIFIERS;
314     }
315
316     /**
317      * @see IBinding#isDeprecated()
318      */

319     public boolean isDeprecated() {
320         return this.binding.isDeprecated();
321     }
322
323     /**
324      * @see IBinding#isRecovered()
325      */

326     public boolean isRecovered() {
327         return false;
328     }
329
330     /**
331      * @see IBinding#isSynthetic()
332      */

333     public boolean isSynthetic() {
334         return this.binding.isSynthetic();
335     }
336
337     /**
338      * @see org.eclipse.jdt.core.dom.IMethodBinding#isVarargs()
339      * @since 3.1
340      */

341     public boolean isVarargs() {
342         return this.binding.isVarargs();
343     }
344
345     /**
346      * @see IBinding#getKey()
347      */

348     public String JavaDoc getKey() {
349         if (this.key == null) {
350             this.key = new String JavaDoc(this.binding.computeUniqueKey());
351         }
352         return this.key;
353     }
354
355     /**
356      * @see IBinding#isEqualTo(IBinding)
357      * @since 3.1
358      */

359     public boolean isEqualTo(IBinding other) {
360         if (other == this) {
361             // identical binding - equal (key or no key)
362
return true;
363         }
364         if (other == null) {
365             // other binding missing
366
return false;
367         }
368         if (!(other instanceof MethodBinding)) {
369             return false;
370         }
371         org.eclipse.jdt.internal.compiler.lookup.MethodBinding otherBinding = ((MethodBinding) other).binding;
372         return BindingComparator.isEqual(this.binding, otherBinding);
373     }
374
375     /**
376      * @see org.eclipse.jdt.core.dom.IMethodBinding#getTypeParameters()
377      */

378     public ITypeBinding[] getTypeParameters() {
379         if (this.typeParameters != null) {
380             return this.typeParameters;
381         }
382         TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
383         int typeVariableBindingsLength = typeVariableBindings == null ? 0 : typeVariableBindings.length;
384         if (typeVariableBindingsLength == 0) {
385             return this.typeParameters = NO_TYPE_BINDINGS;
386         }
387         ITypeBinding[] tParameters = new ITypeBinding[typeVariableBindingsLength];
388         for (int i = 0; i < typeVariableBindingsLength; i++) {
389             ITypeBinding typeBinding = this.resolver.getTypeBinding(typeVariableBindings[i]);
390             if (typeBinding == null) {
391                 return this.typeParameters = NO_TYPE_BINDINGS;
392             }
393             tParameters[i] = typeBinding;
394         }
395         return this.typeParameters = tParameters;
396     }
397
398     /**
399      * @see org.eclipse.jdt.core.dom.IMethodBinding#isGenericMethod()
400      * @since 3.1
401      */

402     public boolean isGenericMethod() {
403         // equivalent to return getTypeParameters().length > 0;
404
if (this.typeParameters != null) {
405             return this.typeParameters.length > 0;
406         }
407         TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
408         return (typeVariableBindings != null && typeVariableBindings.length > 0);
409     }
410
411     /**
412      * @see org.eclipse.jdt.core.dom.IMethodBinding#getTypeArguments()
413      */

414     public ITypeBinding[] getTypeArguments() {
415         if (this.typeArguments != null) {
416             return this.typeArguments;
417         }
418
419         if (this.binding instanceof ParameterizedGenericMethodBinding) {
420             ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) this.binding;
421             org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] typeArgumentsBindings = genericMethodBinding.typeArguments;
422             int typeArgumentsLength = typeArgumentsBindings == null ? 0 : typeArgumentsBindings.length;
423             if (typeArgumentsLength != 0) {
424                 ITypeBinding[] tArguments = new ITypeBinding[typeArgumentsLength];
425                 for (int i = 0; i < typeArgumentsLength; i++) {
426                     ITypeBinding typeBinding = this.resolver.getTypeBinding(typeArgumentsBindings[i]);
427                     if (typeBinding == null) {
428                         return this.typeArguments = NO_TYPE_BINDINGS;
429                     }
430                     tArguments[i] = typeBinding;
431                 }
432                 return this.typeArguments = tArguments;
433             }
434         }
435         return this.typeArguments = NO_TYPE_BINDINGS;
436     }
437
438     /**
439      * @see org.eclipse.jdt.core.dom.IMethodBinding#isParameterizedMethod()
440      */

441     public boolean isParameterizedMethod() {
442         return (this.binding instanceof ParameterizedGenericMethodBinding)
443             && !((ParameterizedGenericMethodBinding) this.binding).isRaw;
444     }
445
446     /**
447      * @see org.eclipse.jdt.core.dom.IMethodBinding#isRawMethod()
448      */

449     public boolean isRawMethod() {
450         return (this.binding instanceof ParameterizedGenericMethodBinding)
451             && ((ParameterizedGenericMethodBinding) this.binding).isRaw;
452     }
453
454     public boolean isSubsignature(IMethodBinding otherMethod) {
455         try {
456             org.eclipse.jdt.internal.compiler.lookup.MethodBinding other = ((MethodBinding) otherMethod).binding;
457             if (!CharOperation.equals(this.binding.selector, other.selector))
458                 return false;
459             return this.binding.areParameterErasuresEqual(other) && this.binding.areTypeVariableErasuresEqual(other);
460         } catch (AbortCompilation e) {
461             // don't surface internal exception to clients
462
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
463
return false;
464         }
465     }
466
467     /**
468      * @see org.eclipse.jdt.core.dom.IMethodBinding#getMethodDeclaration()
469      */

470     public IMethodBinding getMethodDeclaration() {
471         return this.resolver.getMethodBinding(this.binding.original());
472     }
473
474     /**
475      * @see IMethodBinding#overrides(IMethodBinding)
476      */

477     public boolean overrides(IMethodBinding overridenMethod) {
478         try {
479             org.eclipse.jdt.internal.compiler.lookup.MethodBinding overridenCompilerBinding = ((MethodBinding) overridenMethod).binding;
480             if (this.binding == overridenCompilerBinding
481                     || overridenCompilerBinding.isStatic()
482                     || overridenCompilerBinding.isPrivate()
483                     || this.binding.isStatic())
484                 return false;
485             char[] selector = this.binding.selector;
486             if (!CharOperation.equals(selector, overridenCompilerBinding.selector))
487                 return false;
488             TypeBinding match = this.binding.declaringClass.findSuperTypeWithSameErasure(overridenCompilerBinding.declaringClass);
489             if (!(match instanceof ReferenceBinding)) return false;
490
491             org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] superMethods = ((ReferenceBinding)match).getMethods(selector);
492             for (int i = 0, length = superMethods.length; i < length; i++) {
493                 if (superMethods[i].original() == overridenCompilerBinding) {
494                     LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
495                     if (lookupEnvironment == null) return false;
496                     MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
497                     org.eclipse.jdt.internal.compiler.lookup.MethodBinding superMethod = superMethods[i];
498                     return !(superMethod.isDefault() && (superMethod.declaringClass.getPackage()) != this.binding.declaringClass.getPackage())
499                         && methodVerifier.doesMethodOverride(this.binding, superMethod);
500                 }
501             }
502             return false;
503         } catch (AbortCompilation e) {
504             // don't surface internal exception to clients
505
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
506
return false;
507         }
508     }
509
510     /**
511      * For debugging purpose only.
512      * @see java.lang.Object#toString()
513      */

514     public String JavaDoc toString() {
515         return this.binding.toString();
516     }
517 }
518
Popular Tags