| 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 { |