1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import java.util.HashMap ; 14 import java.util.Hashtable ; 15 import java.util.Iterator ; 16 17 import org.eclipse.jdt.core.compiler.CharOperation; 18 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 19 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 20 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; 21 import org.eclipse.jdt.internal.compiler.ast.Argument; 22 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 23 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; 24 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 25 import org.eclipse.jdt.internal.compiler.ast.TypeParameter; 26 import org.eclipse.jdt.internal.compiler.ast.TypeReference; 27 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 28 import org.eclipse.jdt.internal.compiler.impl.Constant; 29 import org.eclipse.jdt.internal.compiler.util.Util; 30 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; 31 32 public class SourceTypeBinding extends ReferenceBinding { 33 public ReferenceBinding superclass; 34 public ReferenceBinding[] superInterfaces; 35 private FieldBinding[] fields; 36 private MethodBinding[] methods; 37 public ReferenceBinding[] memberTypes; 38 public TypeVariableBinding[] typeVariables; 39 40 public ClassScope scope; 41 42 public final static int METHOD_EMUL = 0; 44 public final static int FIELD_EMUL = 1; 45 public final static int CLASS_LITERAL_EMUL = 2; 46 public final static int RECEIVER_TYPE_EMUL = 3; 47 HashMap [] synthetics; 48 char[] genericReferenceTypeSignature; 49 50 private SimpleLookupTable storedAnnotations = null; 52 public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) { 53 this.compoundName = compoundName; 54 this.fPackage = fPackage; 55 this.fileName = scope.referenceCompilationUnit().getFileName(); 56 this.modifiers = scope.referenceContext.modifiers; 57 this.sourceName = scope.referenceContext.name; 58 this.scope = scope; 59 60 this.fields = Binding.NO_FIELDS; 62 this.methods = Binding.NO_METHODS; 63 64 computeId(); 65 } 66 67 private void addDefaultAbstractMethods() { 68 if ((this.tagBits & TagBits.KnowsDefaultAbstractMethods) != 0) return; 69 70 this.tagBits |= TagBits.KnowsDefaultAbstractMethods; 71 if (isClass() && isAbstract()) { 72 if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2) 73 return; 75 ReferenceBinding[] itsInterfaces = superInterfaces(); 76 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 77 MethodBinding[] defaultAbstracts = null; 78 int defaultAbstractsCount = 0; 79 ReferenceBinding[] interfacesToVisit = itsInterfaces; 80 int nextPosition = interfacesToVisit.length; 81 for (int i = 0; i < nextPosition; i++) { 82 ReferenceBinding superType = interfacesToVisit[i]; 83 if (superType.isValidBinding()) { 84 MethodBinding[] superMethods = superType.methods(); 85 nextAbstractMethod: for (int m = superMethods.length; --m >= 0;) { 86 MethodBinding method = superMethods[m]; 87 if (implementsMethod(method)) 89 continue nextAbstractMethod; 90 if (defaultAbstractsCount == 0) { 91 defaultAbstracts = new MethodBinding[5]; 92 } else { 93 for (int k = 0; k < defaultAbstractsCount; k++) { 95 MethodBinding alreadyAdded = defaultAbstracts[k]; 96 if (CharOperation.equals(alreadyAdded.selector, method.selector) && alreadyAdded.areParametersEqual(method)) 97 continue nextAbstractMethod; 98 } 99 } 100 MethodBinding defaultAbstract = new MethodBinding( 101 method.modifiers | ExtraCompilerModifiers.AccDefaultAbstract, 102 method.selector, 103 method.returnType, 104 method.parameters, 105 method.thrownExceptions, 106 this); 107 if (defaultAbstractsCount == defaultAbstracts.length) 108 System.arraycopy(defaultAbstracts, 0, defaultAbstracts = new MethodBinding[2 * defaultAbstractsCount], 0, defaultAbstractsCount); 109 defaultAbstracts[defaultAbstractsCount++] = defaultAbstract; 110 } 111 112 if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 113 int itsLength = itsInterfaces.length; 114 if (nextPosition + itsLength >= interfacesToVisit.length) 115 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 116 nextInterface : for (int a = 0; a < itsLength; a++) { 117 ReferenceBinding next = itsInterfaces[a]; 118 for (int b = 0; b < nextPosition; b++) 119 if (next == interfacesToVisit[b]) continue nextInterface; 120 interfacesToVisit[nextPosition++] = next; 121 } 122 } 123 } 124 } 125 if (defaultAbstractsCount > 0) { 126 int length = this.methods.length; 127 System.arraycopy(this.methods, 0, this.methods = new MethodBinding[length + defaultAbstractsCount], 0, length); 128 System.arraycopy(defaultAbstracts, 0, this.methods, length, defaultAbstractsCount); 129 length = length + defaultAbstractsCount; 131 if (length > 1) 132 ReferenceBinding.sortMethods(this.methods, 0, length); 133 } 135 } 136 } 137 } 138 141 public FieldBinding addSyntheticFieldForInnerclass(LocalVariableBinding actualOuterLocalVariable) { 142 if (this.synthetics == null) 143 this.synthetics = new HashMap [4]; 144 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) 145 this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap (5); 146 147 FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable); 148 if (synthField == null) { 149 synthField = new SyntheticFieldBinding( 150 CharOperation.concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX, actualOuterLocalVariable.name), 151 actualOuterLocalVariable.type, 152 ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic, 153 this, 154 Constant.NotAConstant, 155 this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); 156 this.synthetics[SourceTypeBinding.FIELD_EMUL].put(actualOuterLocalVariable, synthField); 157 } 158 159 boolean needRecheck; 161 int index = 1; 162 do { 163 needRecheck = false; 164 FieldBinding existingField; 165 if ((existingField = this.getField(synthField.name, true )) != null) { 166 TypeDeclaration typeDecl = this.scope.referenceContext; 167 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 168 FieldDeclaration fieldDecl = typeDecl.fields[i]; 169 if (fieldDecl.binding == existingField) { 170 synthField.name = CharOperation.concat( 171 TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX, 172 actualOuterLocalVariable.name, 173 ("$" + String.valueOf(index++)).toCharArray()); needRecheck = true; 175 break; 176 } 177 } 178 } 179 } while (needRecheck); 180 return synthField; 181 } 182 185 public FieldBinding addSyntheticFieldForInnerclass(ReferenceBinding enclosingType) { 186 if (this.synthetics == null) 187 this.synthetics = new HashMap [4]; 188 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) 189 this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap (5); 190 191 FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(enclosingType); 192 if (synthField == null) { 193 synthField = new SyntheticFieldBinding( 194 CharOperation.concat( 195 TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, 196 String.valueOf(enclosingType.depth()).toCharArray()), 197 enclosingType, 198 ClassFileConstants.AccDefault | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic, 199 this, 200 Constant.NotAConstant, 201 this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); 202 this.synthetics[SourceTypeBinding.FIELD_EMUL].put(enclosingType, synthField); 203 } 204 boolean needRecheck; 206 do { 207 needRecheck = false; 208 FieldBinding existingField; 209 if ((existingField = this.getField(synthField.name, true )) != null) { 210 TypeDeclaration typeDecl = this.scope.referenceContext; 211 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 212 FieldDeclaration fieldDecl = typeDecl.fields[i]; 213 if (fieldDecl.binding == existingField) { 214 if (this.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) { 215 synthField.name = CharOperation.concat( 216 synthField.name, 217 "$".toCharArray()); needRecheck = true; 219 } else { 220 this.scope.problemReporter().duplicateFieldInType(this, fieldDecl); 221 } 222 break; 223 } 224 } 225 } 226 } while (needRecheck); 227 return synthField; 228 } 229 232 public FieldBinding addSyntheticFieldForClassLiteral(TypeBinding targetType, BlockScope blockScope) { 233 if (this.synthetics == null) 234 this.synthetics = new HashMap [4]; 235 if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null) 236 this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] = new HashMap (5); 237 238 FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].get(targetType); 240 if (synthField == null) { 241 synthField = new SyntheticFieldBinding( 242 CharOperation.concat( 243 TypeConstants.SYNTHETIC_CLASS, 244 String.valueOf(this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size()).toCharArray()), 245 blockScope.getJavaLangClass(), 246 ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic, 247 this, 248 Constant.NotAConstant, 249 this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size()); 250 this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].put(targetType, synthField); 251 } 252 FieldBinding existingField; 254 if ((existingField = this.getField(synthField.name, true )) != null) { 255 TypeDeclaration typeDecl = blockScope.referenceType(); 256 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 257 FieldDeclaration fieldDecl = typeDecl.fields[i]; 258 if (fieldDecl.binding == existingField) { 259 blockScope.problemReporter().duplicateFieldInType(this, fieldDecl); 260 break; 261 } 262 } 263 } 264 return synthField; 265 } 266 269 public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) { 270 if (this.synthetics == null) 271 this.synthetics = new HashMap [4]; 272 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) 273 this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap (5); 274 275 FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("assertionEmulation"); if (synthField == null) { 277 synthField = new SyntheticFieldBinding( 278 TypeConstants.SYNTHETIC_ASSERT_DISABLED, 279 TypeBinding.BOOLEAN, 280 ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal, 281 this, 282 Constant.NotAConstant, 283 this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); 284 this.synthetics[SourceTypeBinding.FIELD_EMUL].put("assertionEmulation", synthField); } 286 boolean needRecheck; 289 int index = 0; 290 do { 291 needRecheck = false; 292 FieldBinding existingField; 293 if ((existingField = this.getField(synthField.name, true )) != null) { 294 TypeDeclaration typeDecl = this.scope.referenceContext; 295 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 296 FieldDeclaration fieldDecl = typeDecl.fields[i]; 297 if (fieldDecl.binding == existingField) { 298 synthField.name = CharOperation.concat( 299 TypeConstants.SYNTHETIC_ASSERT_DISABLED, 300 ("_" + String.valueOf(index++)).toCharArray()); needRecheck = true; 302 break; 303 } 304 } 305 } 306 } while (needRecheck); 307 return synthField; 308 } 309 312 public FieldBinding addSyntheticFieldForEnumValues() { 313 if (this.synthetics == null) 314 this.synthetics = new HashMap [4]; 315 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) 316 this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap (5); 317 318 FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("enumConstantValues"); if (synthField == null) { 320 synthField = new SyntheticFieldBinding( 321 TypeConstants.SYNTHETIC_ENUM_VALUES, 322 this.scope.createArrayType(this,1), 323 ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal, 324 this, 325 Constant.NotAConstant, 326 this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); 327 this.synthetics[SourceTypeBinding.FIELD_EMUL].put("enumConstantValues", synthField); } 329 boolean needRecheck; 332 int index = 0; 333 do { 334 needRecheck = false; 335 FieldBinding existingField; 336 if ((existingField = this.getField(synthField.name, true )) != null) { 337 TypeDeclaration typeDecl = this.scope.referenceContext; 338 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 339 FieldDeclaration fieldDecl = typeDecl.fields[i]; 340 if (fieldDecl.binding == existingField) { 341 synthField.name = CharOperation.concat( 342 TypeConstants.SYNTHETIC_ENUM_VALUES, 343 ("_" + String.valueOf(index++)).toCharArray()); needRecheck = true; 345 break; 346 } 347 } 348 } 349 } while (needRecheck); 350 return synthField; 351 } 352 355 public SyntheticMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) { 356 if (this.synthetics == null) 357 this.synthetics = new HashMap [4]; 358 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) 359 this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap (5); 360 361 SyntheticMethodBinding accessMethod = null; 362 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetField); 363 if (accessors == null) { 364 accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, this); 365 this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetField, accessors = new SyntheticMethodBinding[2]); 366 accessors[isReadAccess ? 0 : 1] = accessMethod; 367 } else { 368 if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) { 369 accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, this); 370 accessors[isReadAccess ? 0 : 1] = accessMethod; 371 } 372 } 373 return accessMethod; 374 } 375 378 public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) { 379 if (this.synthetics == null) 380 this.synthetics = new HashMap [4]; 381 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) 382 this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap (5); 383 384 SyntheticMethodBinding accessMethod = null; 385 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(selector); 386 if (accessors == null) { 387 accessMethod = new SyntheticMethodBinding(this, selector); 388 this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, accessors = new SyntheticMethodBinding[2]); 389 accessors[0] = accessMethod; 390 } else { 391 if ((accessMethod = accessors[0]) == null) { 392 accessMethod = new SyntheticMethodBinding(this, selector); 393 accessors[0] = accessMethod; 394 } 395 } 396 return accessMethod; 397 } 398 401 public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) { 402 if (this.synthetics == null) 403 this.synthetics = new HashMap [4]; 404 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) 405 this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap (5); 406 407 SyntheticFieldBinding synthField = (SyntheticFieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(key); 408 if (synthField == null) { 409 synthField = new SyntheticFieldBinding( 410 fieldName, 411 this.scope.createArrayType(TypeBinding.INT,1), 412 ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic, 413 this, 414 Constant.NotAConstant, 415 this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); 416 this.synthetics[SourceTypeBinding.FIELD_EMUL].put(key, synthField); 417 } 418 boolean needRecheck; 420 int index = 0; 421 do { 422 needRecheck = false; 423 FieldBinding existingField; 424 if ((existingField = this.getField(synthField.name, true )) != null) { 425 TypeDeclaration typeDecl = this.scope.referenceContext; 426 for (int i = 0, max = typeDecl.fields.length; i < max; i++) { 427 FieldDeclaration fieldDecl = typeDecl.fields[i]; 428 if (fieldDecl.binding == existingField) { 429 synthField.name = CharOperation.concat( 430 fieldName, 431 ("_" + String.valueOf(index++)).toCharArray()); needRecheck = true; 433 break; 434 } 435 } 436 } 437 } while (needRecheck); 438 return synthField; 439 } 440 443 public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding enumBinding) { 444 if (this.synthetics == null) 445 this.synthetics = new HashMap [4]; 446 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) 447 this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap (5); 448 449 SyntheticMethodBinding accessMethod = null; 450 char[] selector = CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding.constantPoolName()); 451 CharOperation.replace(selector, '/', '$'); 452 final String key = new String (selector); 453 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(key); 454 if (accessors == null) { 456 final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key); 458 accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector); 459 this.synthetics[SourceTypeBinding.METHOD_EMUL].put(key, accessors = new SyntheticMethodBinding[2]); 460 accessors[0] = accessMethod; 461 } else { 462 if ((accessMethod = accessors[0]) == null) { 463 final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key); 464 accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector); 465 accessors[0] = accessMethod; 466 } 467 } 468 return accessMethod; 469 } 470 474 public SyntheticMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) { 475 if (this.synthetics == null) 476 this.synthetics = new HashMap [4]; 477 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) 478 this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap (5); 479 480 SyntheticMethodBinding accessMethod = null; 481 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetMethod); 482 if (accessors == null) { 483 accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this); 484 this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetMethod, accessors = new SyntheticMethodBinding[2]); 485 accessors[isSuperAccess ? 0 : 1] = accessMethod; 486 } else { 487 if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) { 488 accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this); 489 accessors[isSuperAccess ? 0 : 1] = accessMethod; 490 } 491 } 492 return accessMethod; 493 } 494 497 public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding targetMethod) { 498 if (isInterface()) return null; if (inheritedMethodToBridge.returnType.erasure() == targetMethod.returnType.erasure() 501 && inheritedMethodToBridge.areParameterErasuresEqual(targetMethod)) { 502 return null; } 504 if (this.synthetics == null) 505 this.synthetics = new HashMap [4]; 506 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) { 507 this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap (5); 508 } else { 509 Iterator synthMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator(); 511 while (synthMethods.hasNext()) { 512 Object synthetic = synthMethods.next(); 513 if (synthetic instanceof MethodBinding) { 514 MethodBinding method = (MethodBinding) synthetic; 515 if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector) 516 && inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure() 517 && inheritedMethodToBridge.areParameterErasuresEqual(method)) { 518 return null; 519 } 520 } 521 } 522 } 523 524 SyntheticMethodBinding accessMethod = null; 525 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge); 526 if (accessors == null) { 527 accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this); 528 this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]); 529 accessors[1] = accessMethod; 530 } else { 531 if ((accessMethod = accessors[1]) == null) { 532 accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this); 533 accessors[1] = accessMethod; 534 } 535 } 536 return accessMethod; 537 } 538 public int kind() { 539 if (this.typeVariables != Binding.NO_TYPE_VARIABLES) return Binding.GENERIC_TYPE; 540 return Binding.TYPE; 541 } 542 public char[] computeUniqueKey(boolean isLeaf) { 543 char[] uniqueKey = super.computeUniqueKey(isLeaf); 544 if (uniqueKey.length == 2) return uniqueKey; if (Util.isClassFileName(this.fileName)) return uniqueKey; 547 int end = CharOperation.lastIndexOf('.', this.fileName); 549 if (end != -1) { 550 int start = CharOperation.lastIndexOf('/', this.fileName) + 1; 551 char[] mainTypeName = CharOperation.subarray(this.fileName, start, end); 552 start = CharOperation.lastIndexOf('/', uniqueKey) + 1; 553 if (start == 0) 554 start = 1; end = CharOperation.indexOf('$', uniqueKey, start); 556 if (end == -1) 557 end = CharOperation.indexOf('<', uniqueKey, start); 558 if (end == -1) 559 end = CharOperation.indexOf(';', uniqueKey, start); 560 char[] topLevelType = CharOperation.subarray(uniqueKey, start, end); 561 if (!CharOperation.equals(topLevelType, mainTypeName)) { 562 StringBuffer buffer = new StringBuffer (); 563 buffer.append(uniqueKey, 0, start); 564 buffer.append(mainTypeName); 565 buffer.append('~'); 566 buffer.append(topLevelType); 567 buffer.append(uniqueKey, end, uniqueKey.length - end); 568 int length = buffer.length(); 569 uniqueKey = new char[length]; 570 buffer.getChars(0, length, uniqueKey, 0); 571 return uniqueKey; 572 } 573 } 574 return uniqueKey; 575 } 576 void faultInTypesForFieldsAndMethods() { 577 getAnnotationTagBits(); ReferenceBinding enclosingType = this.enclosingType(); 580 if (enclosingType != null && enclosingType.isViewedAsDeprecated() && !this.isDeprecated()) 581 this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly; 582 fields(); 583 methods(); 584 585 for (int i = 0, length = this.memberTypes.length; i < length; i++) 586 ((SourceTypeBinding) this.memberTypes[i]).faultInTypesForFieldsAndMethods(); 587 } 588 public FieldBinding[] fields() { 590 if ((this.tagBits & TagBits.AreFieldsComplete) != 0) 591 return this.fields; 592 593 int failed = 0; 594 FieldBinding[] resolvedFields = this.fields; 595 try { 596 if ((this.tagBits & TagBits.AreFieldsSorted) == 0) { 598 int length = this.fields.length; 599 if (length > 1) 600 ReferenceBinding.sortFields(this.fields, 0, length); 601 this.tagBits |= TagBits.AreFieldsSorted; 602 } 603 for (int i = 0, length = this.fields.length; i < length; i++) { 604 if (resolveTypeFor(this.fields[i]) == null) { 605 if (resolvedFields == this.fields) { 607 System.arraycopy(this.fields, 0, resolvedFields = new FieldBinding[length], 0, length); 608 } 609 resolvedFields[i] = null; 610 failed++; 611 } 612 } 613 } finally { 614 if (failed > 0) { 615 int newSize = resolvedFields.length - failed; 617 if (newSize == 0) 618 return this.fields = Binding.NO_FIELDS; 619 620 FieldBinding[] newFields = new FieldBinding[newSize]; 621 for (int i = 0, j = 0, length = resolvedFields.length; i < length; i++) { 622 if (resolvedFields[i] != null) 623 newFields[j++] = resolvedFields[i]; 624 } 625 this.fields = newFields; 626 } 627 } 628 this.tagBits |= TagBits.AreFieldsComplete; 629 return this.fields; 630 } 631 634 public char[] genericTypeSignature() { 635 if (this.genericReferenceTypeSignature == null) 636 this.genericReferenceTypeSignature = computeGenericTypeSignature(this.typeVariables); 637 return this.genericReferenceTypeSignature; 638 } 639 643 public char[] genericSignature() { 644 StringBuffer sig = null; 645 if (this.typeVariables != Binding.NO_TYPE_VARIABLES) { 646 sig = new StringBuffer (10); 647 sig.append('<'); 648 for (int i = 0, length = this.typeVariables.length; i < length; i++) 649 sig.append(this.typeVariables[i].genericSignature()); 650 sig.append('>'); 651 } else { 652 noSignature: if (this.superclass == null || !this.superclass.isParameterizedType()) { 654 for (int i = 0, length = this.superInterfaces.length; i < length; i++) 655 if (this.superInterfaces[i].isParameterizedType()) 656 break noSignature; 657 return null; 658 } 659 sig = new StringBuffer (10); 660 } 661 if (this.superclass != null) 662 sig.append(this.superclass.genericTypeSignature()); 663 else sig.append(this.scope.getJavaLangObject().genericTypeSignature()); 665 for (int i = 0, length = this.superInterfaces.length; i < length; i++) 666 sig.append(this.superInterfaces[i].genericTypeSignature()); 667 return sig.toString().toCharArray(); 668 } 669 670 675 public long getAnnotationTagBits() { 676 if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope != null) { 677 TypeDeclaration typeDecl = this.scope.referenceContext; 678 boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation; 679 try { 680 typeDecl.staticInitializerScope.insideTypeAnnotation = true; 681 ASTNode.resolveAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this); 682 } finally { 683 typeDecl.staticInitializerScope.insideTypeAnnotation = old; 684 } 685 if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) 686 this.modifiers |= ClassFileConstants.AccDeprecated; 687 } 688 return this.tagBits; 689 } 690 public MethodBinding[] getDefaultAbstractMethods() { 691 int count = 0; 692 for (int i = this.methods.length; --i >= 0;) 693 if (this.methods[i].isDefaultAbstract()) 694 count++; 695 if (count == 0) return Binding.NO_METHODS; 696 697 MethodBinding[] result = new MethodBinding[count]; 698 count = 0; 699 for (int i = this.methods.length; --i >= 0;) 700 if (this.methods[i].isDefaultAbstract()) 701 result[count++] = this.methods[i]; 702 return result; 703 } 704 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { 706 int argCount = argumentTypes.length; 707 if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { long range; 709 if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) { 710 nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) { 711 MethodBinding method = this.methods[imethod]; 712 if (method.parameters.length == argCount) { 713 TypeBinding[] toMatch = method.parameters; 714 for (int iarg = 0; iarg < argCount; iarg++) 715 if (toMatch[iarg] != argumentTypes[iarg]) 716 continue nextMethod; 717 return method; 718 } 719 } 720 } 721 } else { 722 if ((this.tagBits & TagBits.AreMethodsSorted) == 0) { 724 int length = this.methods.length; 725 if (length > 1) 726 ReferenceBinding.sortMethods(this.methods, 0, length); 727 this.tagBits |= TagBits.AreMethodsSorted; 728 } 729 long range; 730 if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) { 731 nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) { 732 MethodBinding method = this.methods[imethod]; 733 if (resolveTypesFor(method) == null || method.returnType == null) { 734 methods(); 735 return getExactConstructor(argumentTypes); } 737 if (method.parameters.length == argCount) { 738 TypeBinding[] toMatch = method.parameters; 739 for (int iarg = 0; iarg < argCount; iarg++) 740 if (toMatch[iarg] != argumentTypes[iarg]) 741 continue nextMethod; 742 return method; 743 } 744 } 745 } 746 } 747 return null; 748 } 749 750 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) { 753 int argCount = argumentTypes.length; 755 boolean foundNothing = true; 756 757 if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { long range; 759 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 760 nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) { 761 MethodBinding method = this.methods[imethod]; 762 foundNothing = false; if (method.parameters.length == argCount) { 764 TypeBinding[] toMatch = method.parameters; 765 for (int iarg = 0; iarg < argCount; iarg++) 766 if (toMatch[iarg] != argumentTypes[iarg]) 767 continue nextMethod; 768 return method; 769 } 770 } 771 } 772 } else { 773 if ((this.tagBits & TagBits.AreMethodsSorted) == 0) { 775 int length = this.methods.length; 776 if (length > 1) 777 ReferenceBinding.sortMethods(this.methods, 0, length); 778 this.tagBits |= TagBits.AreMethodsSorted; 779 } 780 781 long range; 782 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 783 int start = (int) range, end = (int) (range >> 32); 785 for (int imethod = start; imethod <= end; imethod++) { 786 MethodBinding method = this.methods[imethod]; 787 if (resolveTypesFor(method) == null || method.returnType == null) { 788 methods(); 789 return getExactMethod(selector, argumentTypes, refScope); } 791 } 792 boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 794 for (int i = start; i <= end; i++) { 795 MethodBinding method1 = this.methods[i]; 796 for (int j = end; j > i; j--) { 797 MethodBinding method2 = this.methods[j]; 798 boolean paramsMatch = isSource15 799 ? method1.areParameterErasuresEqual(method2) 800 : method1.areParametersEqual(method2); 801 if (paramsMatch) { 802 methods(); 803 return getExactMethod(selector, argumentTypes, refScope); } 805 } 806 } 807 nextMethod: for (int imethod = start; imethod <= end; imethod++) { 808 MethodBinding method = this.methods[imethod]; 809 TypeBinding[] toMatch = method.parameters; 810 if (toMatch.length == argCount) { 811 for (int iarg = 0; iarg < argCount; iarg++) 812 if (toMatch[iarg] != argumentTypes[iarg]) 813 continue nextMethod; 814 return method; 815 } 816 } 817 } 818 } 819 820 if (foundNothing) { 821 if (isInterface()) { 822 if (this.superInterfaces.length == 1) { 823 if (refScope != null) 824 refScope.recordTypeReference(this.superInterfaces[0]); 825 return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope); 826 } 827 } else if (this.superclass != null) { 828 if (refScope != null) 829 refScope.recordTypeReference(this.superclass); 830 return this.superclass.getExactMethod(selector, argumentTypes, refScope); 831 } 832 } 833 return null; 834 } 835 836 public FieldBinding getField(char[] fieldName, boolean needResolve) { 838 839 if ((this.tagBits & TagBits.AreFieldsComplete) != 0) 840 return ReferenceBinding.binarySearch(fieldName, this.fields); 841 842 if ((this.tagBits & TagBits.AreFieldsSorted) == 0) { 844 int length = this.fields.length; 845 if (length > 1) 846 ReferenceBinding.sortFields(this.fields, 0, length); 847 this.tagBits |= TagBits.AreFieldsSorted; 848 } 849 FieldBinding field = ReferenceBinding.binarySearch(fieldName, this.fields); 851 if (field != null) { 852 FieldBinding result = null; 853 try { 854 result = resolveTypeFor(field); 855 return result; 856 } finally { 857 if (result == null) { 858 int newSize = this.fields.length - 1; 860 if (newSize == 0) { 861 this.fields = Binding.NO_FIELDS; 862 } else { 863 FieldBinding[] newFields = new FieldBinding[newSize]; 864 int index = 0; 865 for (int i = 0, length = this.fields.length; i < length; i++) { 866 FieldBinding f = this.fields[i]; 867 if (f == field) continue; 868 newFields[index++] = f; 869 } 870 this.fields = newFields; 871 } 872 } 873 } 874 } 875 return null; 876 } 877 878 public MethodBinding[] getMethods(char[] selector) { 880 if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { 881 long range; 882 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 883 int start = (int) range, end = (int) (range >> 32); 884 int length = end - start + 1; 885 MethodBinding[] result; 886 System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length); 887 return result; 888 } else { 889 return Binding.NO_METHODS; 890 } 891 } 892 if ((this.tagBits & TagBits.AreMethodsSorted) == 0) { 894 int length = this.methods.length; 895 if (length > 1) 896 ReferenceBinding.sortMethods(this.methods, 0, length); 897 this.tagBits |= TagBits.AreMethodsSorted; 898 } 899 MethodBinding[] result; 900 long range; 901 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 902 int start = (int) range, end = (int) (range >> 32); 903 for (int i = start; i <= end; i++) { 904 MethodBinding method = this.methods[i]; 905 if (resolveTypesFor(method) == null || method.returnType == null) { 906 methods(); 907 return getMethods(selector); } 909 } 910 int length = end - start + 1; 911 System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length); 912 } else { 913 return Binding.NO_METHODS; 914 } 915 boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 916 for (int i = 0, length = result.length - 1; i < length; i++) { 917 MethodBinding method = result[i]; 918 for (int j = length; j > i; j--) { 919 boolean paramsMatch = isSource15 920 ? method.areParameterErasuresEqual(result[j]) 921 : method.areParametersEqual(result[j]); 922 if (paramsMatch) { 923 methods(); 924 return getMethods(selector); } 926 } 927 } 928 return result; 929 } 930 933 public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) { 934 if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null; 935 return (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable); 936 } 937 940 public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) { 941 942 if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null; 943 FieldBinding field = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(targetEnclosingType); 944 if (field != null) return field; 945 946 if (!onlyExactMatch){ 950 Iterator accessFields = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator(); 951 while (accessFields.hasNext()) { 952 field = (FieldBinding) accessFields.next(); 953 if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name) 954 && field.type.findSuperTypeWithSameErasure(targetEnclosingType) != null) 955 return field; 956 } 957 } 958 return null; 959 } 960 963 public SyntheticMethodBinding getSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) { 964 if (this.synthetics == null) return null; 965 if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) return null; 966 SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge); 967 if (accessors == null) return null; 968 return accessors[1]; 969 } 970 971 974 public void initializeDeprecatedAnnotationTagBits() { 975 if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) { 976 TypeDeclaration typeDecl = this.scope.referenceContext; 977 boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation; 978 try { 979 typeDecl.staticInitializerScope.insideTypeAnnotation = true; 980 ASTNode.resolveDeprecatedAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this); 981 this.tagBits |= TagBits.DeprecatedAnnotationResolved; 982 } finally { 983 typeDecl.staticInitializerScope.insideTypeAnnotation = old; 984 } 985 if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) { 986 this.modifiers |= ClassFileConstants.AccDeprecated; 987 } 988 } 989 } 990 991 995 public boolean isEquivalentTo(TypeBinding otherType) { 996 997 if (this == otherType) return true; 998 if (otherType == null) return false; 999 switch(otherType.kind()) { 1000 1001 case Binding.WILDCARD_TYPE : 1002 return ((WildcardBinding) otherType).boundCheck(this); 1003 1004 case Binding.PARAMETERIZED_TYPE : 1005 if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0 && (!this.isMemberType() || !otherType.isMemberType())) 1006 return false; ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType; 1008 if (this != otherParamType.genericType()) 1009 return false; 1010 if (!isStatic()) { ReferenceBinding enclosing = enclosingType(); 1012 if (enclosing != null) { 1013 ReferenceBinding otherEnclosing = otherParamType.enclosingType(); 1014 if (otherEnclosing == null) return false; 1015 if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) { 1016 if (enclosing != otherEnclosing) return false; 1017 } else { 1018 if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false; 1019 } 1020 } 1021 } 1022 int length = this.typeVariables == null ? 0 : this.typeVariables.length; 1023 TypeBinding[] otherArguments = otherParamType.arguments; 1024 int otherLength = otherArguments == null ? 0 : otherArguments.length; 1025 if (otherLength != length) 1026 return false; 1027 for (int i = 0; i < length; i++) 1028 if (!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i])) 1029 return false; 1030 return true; 1031 1032 case Binding.RAW_TYPE : 1033 return otherType.erasure() == this; 1034 } 1035 return false; 1036} 1037public boolean isGenericType() { 1038 return this.typeVariables != Binding.NO_TYPE_VARIABLES; 1039} 1040public ReferenceBinding[] memberTypes() { 1041 return this.memberTypes; 1042} 1043public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) { 1044 if (this.synthetics == null) 1045 this.synthetics = new HashMap [4]; 1046 if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null) 1047 this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap (5); 1048 1049 Hashtable fieldMap = (Hashtable ) this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetField); 1050 if (fieldMap == null) { 1051 fieldMap = new Hashtable (5); 1052 this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetField, fieldMap); 1053 } 1054 FieldBinding updatedField = (FieldBinding) fieldMap.get(newDeclaringClass); 1055 if (updatedField == null){ 1056 updatedField = new FieldBinding(targetField, newDeclaringClass); 1057 fieldMap.put(newDeclaringClass, updatedField); 1058 } 1059 return updatedField; 1060} 1061public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) { 1062 if (this.synthetics == null) 1063 this.synthetics = new HashMap [4]; 1064 if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null) 1065 this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap (5); 1066 1067 Hashtable methodMap = (Hashtable ) this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetMethod); 1068 if (methodMap == null) { 1069 methodMap = new Hashtable (5); 1070 this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetMethod, methodMap); 1071 } 1072 MethodBinding updatedMethod = (MethodBinding) methodMap.get(newDeclaringClass); 1073 if (updatedMethod == null){ 1074 updatedMethod = new MethodBinding(targetMethod, newDeclaringClass); 1075 methodMap.put(newDeclaringClass, updatedMethod); 1076 } 1077 return updatedMethod; 1078} 1079public boolean hasMemberTypes() { 1080 return this.memberTypes.length > 0; 1081} 1082public MethodBinding[] methods() { 1084 if ((this.tagBits & TagBits.AreMethodsComplete) != 0) 1085 return this.methods; 1086 1087 if ((this.tagBits & TagBits.AreMethodsSorted) == 0) { 1089 int length = this.methods.length; 1090 if (length > 1) 1091 ReferenceBinding.sortMethods(this.methods, 0, length); 1092 this.tagBits |= TagBits.AreMethodsSorted; 1093 } 1094 1095 int failed = 0; 1096 MethodBinding[] resolvedMethods = this.methods; 1097 try { 1098 for (int i = 0, length = this.methods.length; i < length; i++) { 1099 if (resolveTypesFor(this.methods[i]) == null) { 1100 if (resolvedMethods == this.methods) { 1102 System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length); 1103 } 1104 resolvedMethods[i] = null; failed++; 1106 } 1107 } 1108 1109 boolean complyTo15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 1111 for (int i = 0, length = this.methods.length; i < length; i++) { 1112 MethodBinding method = resolvedMethods[i]; 1113 if (method == null) 1114 continue; 1115 char[] selector = method.selector; 1116 AbstractMethodDeclaration methodDecl = null; 1117 nextSibling: for (int j = i + 1; j < length; j++) { 1118 MethodBinding method2 = resolvedMethods[j]; 1119 if (method2 == null) 1120 continue nextSibling; 1121 if (!CharOperation.equals(selector, method2.selector)) 1122 break nextSibling; 1124 if (complyTo15 && method.returnType != null && method2.returnType != null) { 1125 TypeBinding[] params1 = method.parameters; 1129 TypeBinding[] params2 = method2.parameters; 1130 int pLength = params1.length; 1131 if (pLength != params2.length) 1132 continue nextSibling; 1133 1134 TypeVariableBinding[] vars = method.typeVariables; 1135 TypeVariableBinding[] vars2 = method2.typeVariables; 1136 boolean equalTypeVars = vars == vars2; 1137 MethodBinding subMethod = method2; 1138 if (!equalTypeVars) { 1139 MethodBinding temp = method.computeSubstitutedMethod(method2, this.scope.environment()); 1140 if (temp != null) { 1141 equalTypeVars = true; 1142 subMethod = temp; 1143 } 1144 } 1145 boolean equalParams = method.areParametersEqual(subMethod); 1146 if (equalParams && equalTypeVars) { 1147 } else if (method.returnType.erasure() == subMethod.returnType.erasure() && (equalParams || method.areParameterErasuresEqual(method2))) { 1149 } else if (!equalTypeVars && vars != Binding.NO_TYPE_VARIABLES && vars2 != Binding.NO_TYPE_VARIABLES) { 1151 continue nextSibling; 1153 } else if (pLength > 0) { 1154 int index = pLength; 1156 for (; --index >= 0;) { 1157 if (params1[index] != params2[index].erasure()) 1158 break; 1159 if (params1[index] == params2[index]) { 1160 TypeBinding type = params1[index].leafComponentType(); 1161 if (type instanceof SourceTypeBinding && type.typeVariables() != Binding.NO_TYPE_VARIABLES) { 1162 index = pLength; break; 1164 } 1165 } 1166 } 1167 if (index >= 0 && index < pLength) { 1168 for (index = pLength; --index >= 0;) 1169 if (params1[index].erasure() != params2[index]) 1170 break; 1171 } 1172 if (index >= 0) 1173 continue nextSibling; 1174 } 1175 } else if (!method.areParametersEqual(method2)) { continue nextSibling; 1177 } 1178 boolean isEnumSpecialMethod = isEnum() && (CharOperation.equals(selector,TypeConstants.VALUEOF) || CharOperation.equals(selector,TypeConstants.VALUES)); 1179 if (methodDecl == null) { 1181 methodDecl = method.sourceMethod(); if (methodDecl != null && methodDecl.binding != null) { if (isEnumSpecialMethod) { 1184 this.scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl); 1185 } else { 1186 this.scope.problemReporter().duplicateMethodInType(this, methodDecl); 1187 } 1188 methodDecl.binding = null; 1189 if (resolvedMethods == this.methods) { 1191 System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length); 1192 } 1193 resolvedMethods[i] = null; 1194 failed++; 1195 } 1196 } 1197 AbstractMethodDeclaration method2Decl = method2.sourceMethod(); 1198 if (method2Decl != null && method2Decl.binding != null) { if (isEnumSpecialMethod) { 1200 this.scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl); 1201 } else { 1202 this.scope.problemReporter().duplicateMethodInType(this, method2Decl); 1203 } 1204 method2Decl.binding = null; 1205 if (resolvedMethods == this.methods) { 1207 System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length); 1208 } 1209 resolvedMethods[j] = null; 1210 failed++; 1211 } 1212 } 1213 if (method.returnType == null && methodDecl == null) { methodDecl = method.sourceMethod(); 1215 if (methodDecl != null) { 1216 methodDecl.binding = null; 1217 } 1218 if (resolvedMethods == this.methods) { 1220 System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length); 1221 } 1222 resolvedMethods[i] = null; 1223 failed++; 1224 } 1225 } 1226 } finally { 1227 if (failed > 0) { 1228 int newSize = resolvedMethods.length - failed; 1229 if (newSize == 0) { 1230 this.methods = Binding.NO_METHODS; 1231 } else { 1232 MethodBinding[] newMethods = new MethodBinding[newSize]; 1233 for (int i = 0, j = 0, length = resolvedMethods.length; i < length; i++) 1234 if (resolvedMethods[i] != null) 1235 newMethods[j++] = resolvedMethods[i]; 1236 this.methods = newMethods; 1237 } 1238 } 1239 1240 addDefaultAbstractMethods(); 1242 this.tagBits |= TagBits.AreMethodsComplete; 1243 } 1244 return this.methods; 1245} 1246private FieldBinding resolveTypeFor(FieldBinding field) { 1247 if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0) 1248 return field; 1249 1250 if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 1251 if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0) 1252 field.modifiers |= ClassFileConstants.AccDeprecated; 1253 } 1254 if (isViewedAsDeprecated() && !field.isDeprecated()) 1255 field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly; 1256 if (hasRestrictedAccess()) 1257 field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess; 1258 FieldDeclaration[] fieldDecls = this.scope.referenceContext.fields; 1259 for (int f = 0, length = fieldDecls.length; f < length; f++) { 1260 if (fieldDecls[f].binding != field) 1261 continue; 1262 1263 MethodScope initializationScope = field.isStatic() 1264 ? this.scope.referenceContext.staticInitializerScope 1265 : this.scope.referenceContext.initializerScope; 1266 FieldBinding previousField = initializationScope.initializedField; 1267 try { 1268 initializationScope.initializedField = field; 1269 FieldDeclaration fieldDecl = fieldDecls[f]; 1270 TypeBinding fieldType = 1271 fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT 1272 ? initializationScope.environment().convertToRawType(this) : fieldDecl.type.resolveType(initializationScope, true ); 1274 field.type = fieldType; 1275 field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved; 1276 if (fieldType == null) { 1277 fieldDecl.binding = null; 1278 return null; 1279 } 1280 if (fieldType == TypeBinding.VOID) { 1281 this.scope.problemReporter().variableTypeCannotBeVoid(fieldDecl); 1282 fieldDecl.binding = null; 1283 return null; 1284 } 1285 if (fieldType.isArrayType() && ((ArrayBinding) fieldType).leafComponentType == TypeBinding.VOID) { 1286 this.scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecl); 1287 fieldDecl.binding = null; 1288 return null; 1289 } 1290 TypeBinding leafType = fieldType.leafComponentType(); 1291 if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) { 1292 field.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 1293 } 1294 } finally { 1295 initializationScope.initializedField = previousField; 1296 } 1297 return field; 1298 } 1299 return null; } 1301public MethodBinding resolveTypesFor(MethodBinding method) { 1302 if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0) 1303 return method; 1304 1305 if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 1306 if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0) 1307 method.modifiers |= ClassFileConstants.AccDeprecated; 1308 } 1309 if (isViewedAsDeprecated() && !method.isDeprecated()) 1310 method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly; 1311 if (hasRestrictedAccess()) 1312 method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess; 1313 1314 AbstractMethodDeclaration methodDecl = method.sourceMethod(); 1315 if (methodDecl == null) return null; 1317 TypeParameter[] typeParameters = methodDecl.typeParameters(); 1318 if (typeParameters != null) { 1319 methodDecl.scope.connectTypeVariables(typeParameters, true); 1320 for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) 1322 typeParameters[i].checkBounds(methodDecl.scope); 1323 } 1324 TypeReference[] exceptionTypes = methodDecl.thrownExceptions; 1325 if (exceptionTypes != null) { 1326 int size = exceptionTypes.length; 1327 method.thrownExceptions = new ReferenceBinding[size]; 1328 int count = 0; 1329 ReferenceBinding resolvedExceptionType; 1330 for (int i = 0; i < size; i++) { 1331 resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true ); 1332 if (resolvedExceptionType == null) 1333 continue; 1334 if (resolvedExceptionType.isBoundParameterizedType()) { 1335 methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]); 1336 continue; 1337 } 1338 if (resolvedExceptionType.findSuperTypeErasingTo(TypeIds.T_JavaLangThrowable, true) == null) { 1339 methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i], resolvedExceptionType); 1340 continue; 1341 } 1342 if ((resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) 1343 method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 1344 method.thrownExceptions[count++] = resolvedExceptionType; 1345 } 1346 if (count < size) 1347 System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count); 1348 } 1349 1350 boolean foundArgProblem = false; 1351 Argument[] arguments = methodDecl.arguments; 1352 if (arguments != null) { 1353 int size = arguments.length; 1354 method.parameters = Binding.NO_PARAMETERS; 1355 TypeBinding[] newParameters = new TypeBinding[size]; 1356 for (int i = 0; i < size; i++) { 1357 Argument arg = arguments[i]; 1358 TypeBinding parameterType = arg.type.resolveType(methodDecl.scope, true ); 1359 if (parameterType == null) { 1360 foundArgProblem = true; 1361 } else if (parameterType == TypeBinding.VOID) { 1362 methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg); 1363 foundArgProblem = true; 1364 } else { 1365 TypeBinding leafType = parameterType.leafComponentType(); 1366 if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) 1367 method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 1368 newParameters[i] = parameterType; 1369 arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true); 1370 } 1371 } 1372 if (!foundArgProblem) { 1374 method.parameters = newParameters; 1375 } 1376 } 1377 1378 boolean foundReturnTypeProblem = false; 1379 if (!method.isConstructor()) { 1380 TypeReference returnType = methodDecl instanceof MethodDeclaration 1381 ? ((MethodDeclaration) methodDecl).returnType 1382 : null; 1383 if (returnType == null) { 1384 methodDecl.scope.problemReporter().missingReturnType(methodDecl); 1385 method.returnType = null; 1386 foundReturnTypeProblem = true; 1387 } else { 1388 TypeBinding methodType = returnType.resolveType(methodDecl.scope, true ); 1389 if (methodType == null) { 1390 foundReturnTypeProblem = true; 1391 } else if (methodType.isArrayType() && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) { 1392 methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration) methodDecl); 1393 foundReturnTypeProblem = true; 1394 } else { 1395 method.returnType = methodType; 1396 TypeBinding leafType = methodType.leafComponentType(); 1397 if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) 1398 method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 1399 } 1400 } 1401 } 1402 if (foundArgProblem) { 1403 methodDecl.binding = null; 1404 method.parameters = Binding.NO_PARAMETERS; if (typeParameters != null) 1408 for (int i = 0, length = typeParameters.length; i < length; i++) 1409 typeParameters[i].binding = null; 1410 return null; 1411 } 1412 if (foundReturnTypeProblem) 1413 return method; 1415 method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved; 1416 return method; 1417} 1418public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) { 1419 if (forceInitialization) 1420 binding.getAnnotationTagBits(); return super.retrieveAnnotationHolder(binding, false); 1422} 1423public void setFields(FieldBinding[] fields) { 1424 this.fields = fields; 1425} 1426public void setMethods(MethodBinding[] methods) { 1427 this.methods = methods; 1428} 1429public final int sourceEnd() { 1430 return this.scope.referenceContext.sourceEnd; 1431} 1432public final int sourceStart() { 1433 return this.scope.referenceContext.sourceStart; 1434} 1435SimpleLookupTable storedAnnotations(boolean forceInitialize) { 1436 if (forceInitialize && this.storedAnnotations == null && this.scope != null) { this.scope.referenceCompilationUnit().compilationResult.hasAnnotations = true; 1438 if (!this.scope.environment().globalOptions.storeAnnotations) 1439 return null; this.storedAnnotations = new SimpleLookupTable(3); 1441 } 1442 return this.storedAnnotations; 1443} 1444public ReferenceBinding superclass() { 1445 return this.superclass; 1446} 1447public ReferenceBinding[] superInterfaces() { 1448 return this.superInterfaces; 1449} 1450public SyntheticMethodBinding[] syntheticMethods() { 1452 1453 if (this.synthetics == null || this.synthetics[SourceTypeBinding.METHOD_EMUL] == null || this.synthetics[SourceTypeBinding.METHOD_EMUL].size() == 0) return null; 1454 1455 int index = 0; 1457 SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1]; 1458 Iterator fieldsOrMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator(); 1459 while (fieldsOrMethods.hasNext()) { 1460 1461 Object fieldOrMethod = fieldsOrMethods.next(); 1462 1463 if (fieldOrMethod instanceof MethodBinding) { 1464 1465 SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod); 1466 int numberOfAccessors = 0; 1467 if (methodAccessors[0] != null) numberOfAccessors++; 1468 if (methodAccessors[1] != null) numberOfAccessors++; 1469 if (index + numberOfAccessors > bindings.length) 1470 System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + numberOfAccessors]), 0, index); 1471 if (methodAccessors[0] != null) 1472 bindings[index++] = methodAccessors[0]; if (methodAccessors[1] != null) 1474 bindings[index++] = methodAccessors[1]; 1476 } else { 1477 1478 SyntheticMethodBinding[] fieldAccessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod); 1479 int numberOfAccessors = 0; 1480 if (fieldAccessors[0] != null) numberOfAccessors++; 1481 if (fieldAccessors[1] != null) numberOfAccessors++; 1482 if (index + numberOfAccessors > bindings.length) 1483 System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + numberOfAccessors]), 0, index); 1484 if (fieldAccessors[0] != null) 1485 bindings[index++] = fieldAccessors[0]; if (fieldAccessors[1] != null) 1487 bindings[index++] = fieldAccessors[1]; } 1489 } 1490 1491 int length; 1493 SyntheticMethodBinding[] sortedBindings = new SyntheticMethodBinding[length = bindings.length]; 1494 for (int i = 0; i < length; i++){ 1495 SyntheticMethodBinding binding = bindings[i]; 1496 sortedBindings[binding.index] = binding; 1497 } 1498 return sortedBindings; 1499} 1500 1503public FieldBinding[] syntheticFields() { 1504 1505 if (this.synthetics == null) return null; 1506 1507 int fieldSize = this.synthetics[SourceTypeBinding.FIELD_EMUL] == null ? 0 : this.synthetics[SourceTypeBinding.FIELD_EMUL].size(); 1508 int literalSize = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null ? 0 :this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size(); 1509 int totalSize = fieldSize + literalSize; 1510 if (totalSize == 0) return null; 1511 FieldBinding[] bindings = new FieldBinding[totalSize]; 1512 1513 if (this.synthetics[SourceTypeBinding.FIELD_EMUL] != null){ 1515 Iterator elements = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator(); 1516 for (int i = 0; i < fieldSize; i++) { 1517 SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next(); 1518 bindings[synthBinding.index] = synthBinding; 1519 } 1520 } 1521 if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] != null){ 1523 Iterator elements = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].values().iterator(); 1524 for (int i = 0; i < literalSize; i++) { 1525 SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next(); 1526 bindings[fieldSize+synthBinding.index] = synthBinding; 1527 } 1528 } 1529 return bindings; 1530} 1531public String toString() { 1532 StringBuffer buffer = new StringBuffer (30); 1533 buffer.append("(id="); if (this.id == TypeIds.NoId) 1535 buffer.append("NoId"); else 1537 buffer.append(this.id); 1538 buffer.append(")\n"); if (isDeprecated()) buffer.append("deprecated "); if (isPublic()) buffer.append("public "); if (isProtected()) buffer.append("protected "); if (isPrivate()) buffer.append("private "); if (isAbstract() && isClass()) buffer.append("abstract "); if (isStatic() && isNestedType()) buffer.append("static "); if (isFinal()) buffer.append("final "); 1547 if (isEnum()) buffer.append("enum "); else if (isAnnotationType()) buffer.append("@interface "); else if (isClass()) buffer.append("class "); else buffer.append("interface "); buffer.append((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED TYPE"); 1553 if (this.typeVariables == null) { 1554 buffer.append("<NULL TYPE VARIABLES>"); } else if (this.typeVariables != Binding.NO_TYPE_VARIABLES) { 1556 buffer.append("\n\t<"); for (int i = 0, length = this.typeVariables.length; i < length; i++) { 1558 if (i > 0) 1559 buffer.append(", "); buffer.append((this.typeVariables[i] != null) ? this.typeVariables[i].toString() : "NULL TYPE VARIABLE"); } 1562 buffer.append(">"); } 1564 buffer.append("\n\textends "); buffer.append((this.superclass != null) ? this.superclass.debugName() : "NULL TYPE"); 1567 if (this.superInterfaces != null) { 1568 if (this.superInterfaces != Binding.NO_SUPERINTERFACES) { 1569 buffer.append("\n\timplements : "); for (int i = 0, length = this.superInterfaces.length; i < length; i++) { 1571 if (i > 0) 1572 buffer.append(", "); buffer.append((this.superInterfaces[i] != null) ? this.superInterfaces[i].debugName() : "NULL TYPE"); } 1575 } 1576 } else { 1577 buffer.append("NULL SUPERINTERFACES"); } 1579 1580 if (enclosingType() != null) { 1581 buffer.append("\n\tenclosing type : "); buffer.append(enclosingType().debugName()); 1583 } 1584 1585 if (this.fields != null) { 1586 if (this.fields != Binding.NO_FIELDS) { 1587 buffer.append("\n/* fields */"); for (int i = 0, length = this.fields.length; i < length; i++) 1589 buffer.append('\n').append((this.fields[i] != null) ? this.fields[i].toString() : "NULL FIELD"); } 1591 } else { 1592 buffer.append("NULL FIELDS"); } 1594 1595 if (this.methods != null) { 1596 if (this.methods != Binding.NO_METHODS) { 1597 buffer.append("\n/* methods */"); for (int i = 0, length = this.methods.length; i < length; i++) 1599 buffer.append('\n').append((this.methods[i] != null) ? this.methods[i].toString() : "NULL METHOD"); } 1601 } else { 1602 buffer.append("NULL METHODS"); } 1604 1605 if (this.memberTypes != null) { 1606 if (this.memberTypes != Binding.NO_MEMBER_TYPES) { 1607 buffer.append("\n/* members */"); for (int i = 0, length = this.memberTypes.length; i < length; i++) 1609 buffer.append('\n').append((this.memberTypes[i] != null) ? this.memberTypes[i].toString() : "NULL TYPE"); } 1611 } else { 1612 buffer.append("NULL MEMBER TYPES"); } 1614 1615 buffer.append("\n\n"); return buffer.toString(); 1617} 1618public TypeVariableBinding[] typeVariables() { 1619 return this.typeVariables; 1620} 1621void verifyMethods(MethodVerifier verifier) { 1622 verifier.verify(this); 1623 1624 for (int i = this.memberTypes.length; --i >= 0;) 1625 ((SourceTypeBinding) this.memberTypes[i]).verifyMethods(verifier); 1626} 1627} 1628 | Popular Tags |