1 11 12 package org.eclipse.jdt.core.dom; 13 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 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 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 name; 50 private ITypeBinding declaringClass; 51 private ITypeBinding returnType; 52 private String 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 70 public boolean isConstructor() { 71 return this.binding.isConstructor(); 72 } 73 74 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 96 public String getName() { 97 if (name == null) { 98 if (this.binding.isConstructor()) { 99 name = this.getDeclaringClass().getName(); 100 } else { 101 name = new String (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 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 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 StringBuffer message = new StringBuffer ("Report method binding where a parameter is null:\n"); message.append(this.toString()); 182 Util.log(new IllegalArgumentException (), message.toString()); 183 return this.parameterTypes = NO_TYPE_BINDINGS; 185 } 186 } 187 return this.parameterTypes = paramTypes; 188 } 189 } 190 191 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 getDefaultValue() { 202 if (isAnnotationMember()) 203 return MemberValuePairBinding.buildDOMValue(this.binding.getDefaultValue(), this.resolver); 204 return null; 205 } 206 207 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 parameterSignatures = new ArrayList (); 246 Iterator iterator = methodDeclaration.parameters().iterator(); 247 while (iterator.hasNext()) { 248 SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next(); 249 Type type = parameter.getType(); 250 String 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 [] parameters = new String [parameterCount]; 262 parameterSignatures.toArray(parameters); 263 return (JavaElement) declaringType.getMethod(getName(), parameters); 264 } else { 265 AnnotationTypeMemberDeclaration typeMemberDeclaration = (AnnotationTypeMemberDeclaration) node; 267 return (JavaElement) declaringType.getMethod(typeMemberDeclaration.getName().getIdentifier(), CharOperation.NO_STRINGS); } 269 } else { 270 org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = this.binding.original(); 272 String selector = original.isConstructor() ? declaringType.getElementName() : new String (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 [] parameterSignatures = new String [declaringIndex + length]; 280 if (isInnerBinaryTypeConstructor) 281 parameterSignatures[0] = new String (enclosingType.genericTypeSignature()).replace('/', '.'); 282 for (int i = 0; i < length; i++) { 283 parameterSignatures[declaringIndex + i] = new String (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 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 305 public int getKind() { 306 return IBinding.METHOD; 307 } 308 309 312 public int getModifiers() { 313 return this.binding.getAccessFlags() & VALID_MODIFIERS; 314 } 315 316 319 public boolean isDeprecated() { 320 return this.binding.isDeprecated(); 321 } 322 323 326 public boolean isRecovered() { 327 return false; 328 } 329 330 333 public boolean isSynthetic() { 334 return this.binding.isSynthetic(); 335 } 336 337 341 public boolean isVarargs() { 342 return this.binding.isVarargs(); 343 } 344 345 348 public String getKey() { 349 if (this.key == null) { 350 this.key = new String (this.binding.computeUniqueKey()); 351 } 352 return this.key; 353 } 354 355 359 public boolean isEqualTo(IBinding other) { 360 if (other == this) { 361 return true; 363 } 364 if (other == null) { 365 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 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 402 public boolean isGenericMethod() { 403 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 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 441 public boolean isParameterizedMethod() { 442 return (this.binding instanceof ParameterizedGenericMethodBinding) 443 && !((ParameterizedGenericMethodBinding) this.binding).isRaw; 444 } 445 446 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 return false; 464 } 465 } 466 467 470 public IMethodBinding getMethodDeclaration() { 471 return this.resolver.getMethodBinding(this.binding.original()); 472 } 473 474 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 return false; 507 } 508 } 509 510 514 public String toString() { 515 return this.binding.toString(); 516 } 517 } 518 | Popular Tags |