1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import java.util.HashMap ; 14 import java.util.Map ; 15 16 import org.eclipse.jdt.core.compiler.CharOperation; 17 import org.eclipse.jdt.internal.compiler.ClassFilePool; 18 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; 19 import org.eclipse.jdt.internal.compiler.ast.Wildcard; 20 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 21 import org.eclipse.jdt.internal.compiler.env.*; 22 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 23 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor; 24 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 25 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage; 26 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; 27 28 public class LookupEnvironment implements ProblemReasons, TypeConstants { 29 30 final static int BUILD_FIELDS_AND_METHODS = 4; 31 final static int BUILD_TYPE_HIERARCHY = 1; 32 final static int CHECK_AND_SET_IMPORTS = 2; 33 final static int CONNECT_TYPE_HIERARCHY = 3; 34 static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound); 35 static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, null, NotFound); 36 37 40 private Map accessRestrictions; 41 ImportBinding[] defaultImports; 42 43 public PackageBinding defaultPackage; 44 HashtableOfPackage knownPackages; 45 private int lastCompletedUnitIndex = -1; 46 private int lastUnitIndex = -1; 47 48 public INameEnvironment nameEnvironment; 49 public CompilerOptions globalOptions; 50 public ProblemReporter problemReporter; 51 52 public ClassFilePool classFilePool; 53 54 private int stepCompleted; 59 public ITypeRequestor typeRequestor; 60 private ArrayBinding[][] uniqueArrayBindings; 61 private SimpleLookupTable uniqueParameterizedTypeBindings; 62 private SimpleLookupTable uniqueRawTypeBindings; 63 private SimpleLookupTable uniqueWildcardBindings; 64 private SimpleLookupTable uniqueParameterizedGenericMethodBindings; 65 66 public CompilationUnitDeclaration unitBeingCompleted = null; public Object missingClassFileLocation = null; 69 private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4]; 70 private MethodVerifier verifier; 71 72 public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) { 73 this.typeRequestor = typeRequestor; 74 this.globalOptions = globalOptions; 75 this.problemReporter = problemReporter; 76 this.defaultPackage = new PackageBinding(this); this.defaultImports = null; 78 this.nameEnvironment = nameEnvironment; 79 this.knownPackages = new HashtableOfPackage(); 80 this.uniqueArrayBindings = new ArrayBinding[5][]; 81 this.uniqueArrayBindings[0] = new ArrayBinding[50]; this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3); 83 this.uniqueRawTypeBindings = new SimpleLookupTable(3); 84 this.uniqueWildcardBindings = new SimpleLookupTable(3); 85 this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3); 86 this.accessRestrictions = new HashMap (3); 87 this.classFilePool = ClassFilePool.newInstance(); 88 } 89 90 94 95 public ReferenceBinding askForType(char[][] compoundName) { 96 NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName); 97 if (answer == null) 98 return null; 99 100 if (answer.isBinaryType()) 101 typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName), answer.getAccessRestriction()); 103 else if (answer.isCompilationUnit()) 104 typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction()); 106 else if (answer.isSourceType()) 107 typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName), answer.getAccessRestriction()); 109 110 return getCachedType(compoundName); 111 } 112 115 116 ReferenceBinding askForType(PackageBinding packageBinding, char[] name) { 117 if (packageBinding == null) { 118 if (defaultPackage == null) 119 return null; 120 packageBinding = defaultPackage; 121 } 122 NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName); 123 if (answer == null) 124 return null; 125 126 if (answer.isBinaryType()) 127 typeRequestor.accept(answer.getBinaryType(), packageBinding, answer.getAccessRestriction()); 129 else if (answer.isCompilationUnit()) 130 typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction()); 132 else if (answer.isSourceType()) 133 typeRequestor.accept(answer.getSourceTypes(), packageBinding, answer.getAccessRestriction()); 135 136 return packageBinding.getType0(name); 137 } 138 144 145 public void buildTypeBindings(CompilationUnitDeclaration unit, AccessRestriction accessRestriction) { 146 CompilationUnitScope scope = new CompilationUnitScope(unit, this); 147 scope.buildTypeBindings(accessRestriction); 148 149 int unitsLength = units.length; 150 if (++lastUnitIndex >= unitsLength) 151 System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength); 152 units[lastUnitIndex] = unit; 153 } 154 158 159 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, AccessRestriction accessRestriction) { 160 return cacheBinaryType(binaryType, true, accessRestriction); 161 } 162 166 167 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods, AccessRestriction accessRestriction) { 168 char[][] compoundName = CharOperation.splitOn('/', binaryType.getName()); 169 ReferenceBinding existingType = getCachedType(compoundName); 170 171 if (existingType == null || existingType instanceof UnresolvedReferenceBinding) 172 return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods, accessRestriction); 174 return null; } 176 public BinaryTypeBinding cacheMissingBinaryType(char[][] compoundName, CompilationUnitDeclaration unit) { 177 problemReporter.isClassPathCorrect( 179 compoundName, 180 unit == null ? this.unitBeingCompleted : unit, 181 this.missingClassFileLocation); 182 183 PackageBinding packageBinding = computePackageFrom(compoundName); 184 MissingBinaryTypeBinding type = new MissingBinaryTypeBinding(packageBinding, compoundName, this); 186 if (type.id != TypeIds.T_JavaLangObject) { 187 ReferenceBinding objectType = getType(TypeConstants.JAVA_LANG_OBJECT); 189 if (objectType == null) 190 objectType = cacheMissingBinaryType(TypeConstants.JAVA_LANG_OBJECT, unit); type.setMissingSuperclass(objectType); 192 } 193 packageBinding.addType(type); 194 return type; 195 } 196 201 202 208 209 public void completeTypeBindings() { 210 stepCompleted = BUILD_TYPE_HIERARCHY; 211 212 for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) { 213 (this.unitBeingCompleted = this.units[i]).scope.checkAndSetImports(); 214 } 215 stepCompleted = CHECK_AND_SET_IMPORTS; 216 217 for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) { 218 (this.unitBeingCompleted = this.units[i]).scope.connectTypeHierarchy(); 219 } 220 stepCompleted = CONNECT_TYPE_HIERARCHY; 221 222 for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) { 223 CompilationUnitScope unitScope = (this.unitBeingCompleted = this.units[i]).scope; 224 unitScope.checkParameterizedTypes(); 225 unitScope.buildFieldsAndMethods(); 226 this.units[i] = null; } 228 stepCompleted = BUILD_FIELDS_AND_METHODS; 229 this.lastCompletedUnitIndex = this.lastUnitIndex; 230 this.unitBeingCompleted = null; 231 } 232 237 238 243 244 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) { 245 if (stepCompleted == BUILD_FIELDS_AND_METHODS) { 246 completeTypeBindings(); 250 } else { 251 if (parsedUnit.scope == null) return; 253 if (stepCompleted >= CHECK_AND_SET_IMPORTS) 254 (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports(); 255 256 if (stepCompleted >= CONNECT_TYPE_HIERARCHY) 257 (this.unitBeingCompleted = parsedUnit).scope.connectTypeHierarchy(); 258 259 this.unitBeingCompleted = null; 260 } 261 } 262 269 270 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) { 271 if (parsedUnit.scope == null) return; 273 (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports(); 274 parsedUnit.scope.connectTypeHierarchy(); 275 parsedUnit.scope.checkParameterizedTypes(); 276 if (buildFieldsAndMethods) 277 parsedUnit.scope.buildFieldsAndMethods(); 278 this.unitBeingCompleted = null; 279 } 280 public TypeBinding computeBoxingType(TypeBinding type) { 281 TypeBinding boxedType; 282 switch (type.id) { 283 case TypeIds.T_JavaLangBoolean : 284 return TypeBinding.BOOLEAN; 285 case TypeIds.T_JavaLangByte : 286 return TypeBinding.BYTE; 287 case TypeIds.T_JavaLangCharacter : 288 return TypeBinding.CHAR; 289 case TypeIds.T_JavaLangShort : 290 return TypeBinding.SHORT; 291 case TypeIds.T_JavaLangDouble : 292 return TypeBinding.DOUBLE; 293 case TypeIds.T_JavaLangFloat : 294 return TypeBinding.FLOAT; 295 case TypeIds.T_JavaLangInteger : 296 return TypeBinding.INT; 297 case TypeIds.T_JavaLangLong : 298 return TypeBinding.LONG; 299 300 case TypeIds.T_int : 301 boxedType = getType(JAVA_LANG_INTEGER); 302 if (boxedType != null) return boxedType; 303 return new ProblemReferenceBinding(JAVA_LANG_INTEGER, null, NotFound); 304 case TypeIds.T_byte : 305 boxedType = getType(JAVA_LANG_BYTE); 306 if (boxedType != null) return boxedType; 307 return new ProblemReferenceBinding(JAVA_LANG_BYTE, null, NotFound); 308 case TypeIds.T_short : 309 boxedType = getType(JAVA_LANG_SHORT); 310 if (boxedType != null) return boxedType; 311 return new ProblemReferenceBinding(JAVA_LANG_SHORT, null, NotFound); 312 case TypeIds.T_char : 313 boxedType = getType(JAVA_LANG_CHARACTER); 314 if (boxedType != null) return boxedType; 315 return new ProblemReferenceBinding(JAVA_LANG_CHARACTER, null, NotFound); 316 case TypeIds.T_long : 317 boxedType = getType(JAVA_LANG_LONG); 318 if (boxedType != null) return boxedType; 319 return new ProblemReferenceBinding(JAVA_LANG_LONG, null, NotFound); 320 case TypeIds.T_float : 321 boxedType = getType(JAVA_LANG_FLOAT); 322 if (boxedType != null) return boxedType; 323 return new ProblemReferenceBinding(JAVA_LANG_FLOAT, null, NotFound); 324 case TypeIds.T_double : 325 boxedType = getType(JAVA_LANG_DOUBLE); 326 if (boxedType != null) return boxedType; 327 return new ProblemReferenceBinding(JAVA_LANG_DOUBLE, null, NotFound); 328 case TypeIds.T_boolean : 329 boxedType = getType(JAVA_LANG_BOOLEAN); 330 if (boxedType != null) return boxedType; 331 return new ProblemReferenceBinding(JAVA_LANG_BOOLEAN, null, NotFound); 332 } 349 switch (type.kind()) { 351 case Binding.WILDCARD_TYPE : 352 case Binding.TYPE_PARAMETER : 353 switch (type.erasure().id) { 354 case TypeIds.T_JavaLangBoolean : 355 return TypeBinding.BOOLEAN; 356 case TypeIds.T_JavaLangByte : 357 return TypeBinding.BYTE; 358 case TypeIds.T_JavaLangCharacter : 359 return TypeBinding.CHAR; 360 case TypeIds.T_JavaLangShort : 361 return TypeBinding.SHORT; 362 case TypeIds.T_JavaLangDouble : 363 return TypeBinding.DOUBLE; 364 case TypeIds.T_JavaLangFloat : 365 return TypeBinding.FLOAT; 366 case TypeIds.T_JavaLangInteger : 367 return TypeBinding.INT; 368 case TypeIds.T_JavaLangLong : 369 return TypeBinding.LONG; 370 } 371 } 372 return type; 373 } 374 private PackageBinding computePackageFrom(char[][] constantPoolName) { 375 if (constantPoolName.length == 1) 376 return defaultPackage; 377 378 PackageBinding packageBinding = getPackage0(constantPoolName[0]); 379 if (packageBinding == null || packageBinding == TheNotFoundPackage) { 380 packageBinding = new PackageBinding(constantPoolName[0], this); 381 knownPackages.put(constantPoolName[0], packageBinding); 382 } 383 384 for (int i = 1, length = constantPoolName.length - 1; i < length; i++) { 385 PackageBinding parent = packageBinding; 386 if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) { 387 packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this); 388 parent.addPackage(packageBinding); 389 } 390 } 391 return packageBinding; 392 } 393 394 398 public ReferenceBinding convertToParameterizedType(ReferenceBinding originalType) { 399 if (originalType != null) { 400 boolean isGeneric = originalType.isGenericType(); 401 ReferenceBinding originalEnclosingType = originalType.enclosingType(); 402 ReferenceBinding convertedEnclosingType = originalEnclosingType; 403 boolean needToConvert = isGeneric; 404 if (originalEnclosingType != null) { 405 convertedEnclosingType = originalType.isStatic() 406 ? (ReferenceBinding) convertToRawType(originalEnclosingType) 407 : convertToParameterizedType(originalEnclosingType); 408 needToConvert |= originalEnclosingType != convertedEnclosingType; 409 } 410 if (needToConvert) { 411 return createParameterizedType(originalType, isGeneric ? originalType.typeVariables() : null, convertedEnclosingType); 412 } 413 } 414 return originalType; 415 } 416 417 public TypeBinding convertToRawType(TypeBinding type) { 418 int dimension; 419 TypeBinding originalType; 420 switch(type.kind()) { 421 case Binding.BASE_TYPE : 422 case Binding.TYPE_PARAMETER: 423 case Binding.WILDCARD_TYPE: 424 case Binding.RAW_TYPE: 425 return type; 426 case Binding.ARRAY_TYPE: 427 dimension = type.dimensions(); 428 originalType = type.leafComponentType(); 429 break; 430 default: 431 if (type.id == TypeIds.T_JavaLangObject) 432 return type; dimension = 0; 434 originalType = type; 435 } 436 boolean needToConvert; 437 switch (originalType.kind()) { 438 case Binding.BASE_TYPE : 439 return type; 440 case Binding.GENERIC_TYPE : 441 needToConvert = true; 442 break; 443 case Binding.PARAMETERIZED_TYPE : 444 ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType; 445 needToConvert = paramType.genericType().isGenericType(); break; 447 default : 448 needToConvert = false; 449 break; 450 } 451 ReferenceBinding originalEnclosing = originalType.enclosingType(); 452 TypeBinding convertedType; 453 if (originalEnclosing == null) { 454 convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType; 455 } else { 456 ReferenceBinding convertedEnclosing; 457 if (originalEnclosing.kind() == Binding.RAW_TYPE) { 458 needToConvert |= !((ReferenceBinding)originalType).isStatic(); 459 convertedEnclosing = originalEnclosing; 460 } else if (needToConvert || ((ReferenceBinding)originalType).isStatic()) { 461 convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing); 462 } else { 463 convertedEnclosing = convertToParameterizedType(originalEnclosing); 464 } 465 if (needToConvert) { 466 convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing); 467 } else if (originalEnclosing != convertedEnclosing) { 468 convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing); 469 } else { 470 convertedType = originalType; 471 } 472 } 473 if (originalType != convertedType) { 474 return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType; 475 } 476 return type; 477 } 478 479 public TypeBinding convertUnresolvedBinaryToRawType(TypeBinding type) { 481 int dimension; 482 TypeBinding originalType; 483 switch(type.kind()) { 484 case Binding.BASE_TYPE : 485 case Binding.TYPE_PARAMETER: 486 case Binding.WILDCARD_TYPE: 487 case Binding.RAW_TYPE: 488 return type; 489 case Binding.ARRAY_TYPE: 490 dimension = type.dimensions(); 491 originalType = type.leafComponentType(); 492 break; 493 default: 494 if (type.id == TypeIds.T_JavaLangObject) 495 return type; dimension = 0; 497 originalType = type; 498 } 499 boolean needToConvert; 500 switch (originalType.kind()) { 501 case Binding.BASE_TYPE : 502 return type; 503 case Binding.GENERIC_TYPE : 504 needToConvert = true; 505 break; 506 case Binding.PARAMETERIZED_TYPE : 507 ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType; 508 needToConvert = paramType.genericType().isGenericType(); break; 510 default : 511 needToConvert = false; 512 break; 513 } 514 ReferenceBinding originalEnclosing = originalType.enclosingType(); 515 TypeBinding convertedType; 516 if (originalEnclosing == null) { 517 convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType; 518 } else { 519 ReferenceBinding convertedEnclosing = (ReferenceBinding) convertUnresolvedBinaryToRawType(originalEnclosing); 520 if (convertedEnclosing != originalEnclosing) { 521 needToConvert |= !((ReferenceBinding)originalType).isStatic(); 522 } 523 if (needToConvert) { 524 convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing); 525 } else if (originalEnclosing != convertedEnclosing) { 526 convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing); 527 } else { 528 convertedType = originalType; 529 } 530 } 531 if (originalType != convertedType) { 532 return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType; 533 } 534 return type; 535 } 536 539 public AnnotationBinding createAnnotation(ReferenceBinding annotationType, ElementValuePair[] pairs) { 540 if (pairs.length != 0) { 541 AnnotationBinding.setMethodBindings(annotationType, pairs); 542 } 543 return new AnnotationBinding(annotationType, pairs); 544 } 545 546 549 public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount) { 550 if (leafComponentType instanceof LocalTypeBinding) return ((LocalTypeBinding) leafComponentType).createArrayType(dimensionCount, this); 552 553 int dimIndex = dimensionCount - 1; 555 int length = uniqueArrayBindings.length; 556 ArrayBinding[] arrayBindings; 557 if (dimIndex < length) { 558 if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null) 559 uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10]; 560 } else { 561 System.arraycopy( 562 uniqueArrayBindings, 0, 563 uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0, 564 length); 565 uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10]; 566 } 567 568 int index = -1; 570 length = arrayBindings.length; 571 while (++index < length) { 572 ArrayBinding currentBinding = arrayBindings[index]; 573 if (currentBinding == null) return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this); 575 if (currentBinding.leafComponentType == leafComponentType) 576 return currentBinding; 577 } 578 579 System.arraycopy( 581 arrayBindings, 0, 582 (arrayBindings = new ArrayBinding[length * 2]), 0, 583 length); 584 uniqueArrayBindings[dimIndex] = arrayBindings; 585 return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this); 586 } 587 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) { 588 return createBinaryTypeFrom(binaryType, packageBinding, true, accessRestriction); 589 } 590 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods, AccessRestriction accessRestriction) { 591 BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this); 592 593 ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]); 595 if (cachedType != null) { if (cachedType instanceof UnresolvedReferenceBinding) { 597 ((UnresolvedReferenceBinding) cachedType).setResolvedType(binaryBinding, this); 598 } else { 599 if (cachedType.isBinaryBinding()) return (BinaryTypeBinding) cachedType; 601 return null; 604 } 605 } 606 607 packageBinding.addType(binaryBinding); 608 setAccessRestriction(binaryBinding, accessRestriction); 609 binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods); 610 return binaryBinding; 611 } 612 614 615 public PackageBinding createPackage(char[][] compoundName) { 616 PackageBinding packageBinding = getPackage0(compoundName[0]); 617 if (packageBinding == null || packageBinding == TheNotFoundPackage) { 618 packageBinding = new PackageBinding(compoundName[0], this); 619 knownPackages.put(compoundName[0], packageBinding); 620 } 621 622 for (int i = 1, length = compoundName.length; i < length; i++) { 623 ReferenceBinding type = packageBinding.getType0(compoundName[i]); 630 if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding)) 631 return null; 632 633 PackageBinding parent = packageBinding; 634 if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) { 635 if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null) 640 return null; 641 642 packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this); 643 parent.addPackage(packageBinding); 644 } 645 } 646 return packageBinding; 647 } 648 649 public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, RawTypeBinding rawType) { 650 651 ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod); 653 boolean needToGrow = false; 654 int index = 0; 655 if (cachedInfo != null){ 656 nextCachedMethod : 657 for (int max = cachedInfo.length; index < max; index++){ 659 ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index]; 660 if (cachedMethod == null) break nextCachedMethod; 661 if (!cachedMethod.isRaw) continue nextCachedMethod; 662 if (cachedMethod.declaringClass != (rawType == null ? genericMethod.declaringClass : rawType)) continue nextCachedMethod; 663 return cachedMethod; 664 } 665 needToGrow = true; 666 } else { 667 cachedInfo = new ParameterizedGenericMethodBinding[5]; 668 this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo); 669 } 670 int length = cachedInfo.length; 672 if (needToGrow && index == length){ 673 System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length); 674 this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo); 675 } 676 ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, rawType, this); 678 cachedInfo[index] = parameterizedGenericMethod; 679 return parameterizedGenericMethod; 680 } 681 682 public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, TypeBinding[] typeArguments) { 683 684 ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod); 686 int argLength = typeArguments == null ? 0: typeArguments.length; 687 boolean needToGrow = false; 688 int index = 0; 689 if (cachedInfo != null){ 690 nextCachedMethod : 691 for (int max = cachedInfo.length; index < max; index++){ 693 ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index]; 694 if (cachedMethod == null) break nextCachedMethod; 695 if (cachedMethod.isRaw) continue nextCachedMethod; 696 TypeBinding[] cachedArguments = cachedMethod.typeArguments; 697 int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length; 698 if (argLength != cachedArgLength) continue nextCachedMethod; 699 for (int j = 0; j < cachedArgLength; j++){ 700 if (typeArguments[j] != cachedArguments[j]) continue nextCachedMethod; 701 } 702 return cachedMethod; 704 } 705 needToGrow = true; 706 } else { 707 cachedInfo = new ParameterizedGenericMethodBinding[5]; 708 this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo); 709 } 710 int length = cachedInfo.length; 712 if (needToGrow && index == length){ 713 System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length); 714 this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo); 715 } 716 ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, typeArguments, this); 718 cachedInfo[index] = parameterizedGenericMethod; 719 return parameterizedGenericMethod; 720 } 721 722 public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType) { 723 724 ParameterizedTypeBinding[] cachedInfo = (ParameterizedTypeBinding[])this.uniqueParameterizedTypeBindings.get(genericType); 726 int argLength = typeArguments == null ? 0: typeArguments.length; 727 boolean needToGrow = false; 728 int index = 0; 729 if (cachedInfo != null){ 730 nextCachedType : 731 for (int max = cachedInfo.length; index < max; index++){ 733 ParameterizedTypeBinding cachedType = cachedInfo[index]; 734 if (cachedType == null) break nextCachedType; 735 if (cachedType.actualType() != genericType) continue nextCachedType; if (cachedType.enclosingType() != enclosingType) continue nextCachedType; 737 TypeBinding[] cachedArguments = cachedType.arguments; 738 int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length; 739 if (argLength != cachedArgLength) continue nextCachedType; for (int j = 0; j < cachedArgLength; j++){ 741 if (typeArguments[j] != cachedArguments[j]) continue nextCachedType; 742 } 743 return cachedType; 745 } 746 needToGrow = true; 747 } else { 748 cachedInfo = new ParameterizedTypeBinding[5]; 749 this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo); 750 } 751 int length = cachedInfo.length; 753 if (needToGrow && index == length){ 754 System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedTypeBinding[length*2], 0, length); 755 this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo); 756 } 757 ParameterizedTypeBinding parameterizedType = new ParameterizedTypeBinding(genericType,typeArguments, enclosingType, this); 759 cachedInfo[index] = parameterizedType; 760 return parameterizedType; 761 } 762 763 public RawTypeBinding createRawType(ReferenceBinding genericType, ReferenceBinding enclosingType) { 764 RawTypeBinding[] cachedInfo = (RawTypeBinding[])this.uniqueRawTypeBindings.get(genericType); 766 boolean needToGrow = false; 767 int index = 0; 768 if (cachedInfo != null){ 769 nextCachedType : 770 for (int max = cachedInfo.length; index < max; index++){ 772 RawTypeBinding cachedType = cachedInfo[index]; 773 if (cachedType == null) break nextCachedType; 774 if (cachedType.actualType() != genericType) continue nextCachedType; if (cachedType.enclosingType() != enclosingType) continue nextCachedType; 776 return cachedType; 778 } 779 needToGrow = true; 780 } else { 781 cachedInfo = new RawTypeBinding[1]; 782 this.uniqueRawTypeBindings.put(genericType, cachedInfo); 783 } 784 int length = cachedInfo.length; 786 if (needToGrow && index == length){ 787 System.arraycopy(cachedInfo, 0, cachedInfo = new RawTypeBinding[length*2], 0, length); 788 this.uniqueRawTypeBindings.put(genericType, cachedInfo); 789 } 790 RawTypeBinding rawType = new RawTypeBinding(genericType, enclosingType, this); 792 cachedInfo[index] = rawType; 793 return rawType; 794 795 } 796 797 public WildcardBinding createWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind) { 798 799 if (genericType == null) genericType = ReferenceBinding.LUB_GENERIC; 802 WildcardBinding[] cachedInfo = (WildcardBinding[])this.uniqueWildcardBindings.get(genericType); 803 boolean needToGrow = false; 804 int index = 0; 805 if (cachedInfo != null){ 806 nextCachedType : 807 for (int max = cachedInfo.length; index < max; index++){ 809 WildcardBinding cachedType = cachedInfo[index]; 810 if (cachedType == null) break nextCachedType; 811 if (cachedType.genericType != genericType) continue nextCachedType; if (cachedType.rank != rank) continue nextCachedType; 813 if (cachedType.boundKind != boundKind) continue nextCachedType; 814 if (cachedType.bound != bound) continue nextCachedType; 815 if (cachedType.otherBounds != otherBounds) { 816 int cachedLength = cachedType.otherBounds == null ? 0 : cachedType.otherBounds.length; 817 int length = otherBounds == null ? 0 : otherBounds.length; 818 if (cachedLength != length) continue nextCachedType; 819 for (int j = 0; j < length; j++) { 820 if (cachedType.otherBounds[j] != otherBounds[j]) continue nextCachedType; 821 } 822 } 823 return cachedType; 825 } 826 needToGrow = true; 827 } else { 828 cachedInfo = new WildcardBinding[10]; 829 this.uniqueWildcardBindings.put(genericType, cachedInfo); 830 } 831 int length = cachedInfo.length; 833 if (needToGrow && index == length){ 834 System.arraycopy(cachedInfo, 0, cachedInfo = new WildcardBinding[length*2], 0, length); 835 this.uniqueWildcardBindings.put(genericType, cachedInfo); 836 } 837 WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, otherBounds, boundKind, this); 839 cachedInfo[index] = wildcard; 840 return wildcard; 841 } 842 843 846 public AccessRestriction getAccessRestriction(TypeBinding type) { 847 return (AccessRestriction) this.accessRestrictions.get(type); 848 } 849 850 858 859 public ReferenceBinding getCachedType(char[][] compoundName) { 860 if (compoundName.length == 1) { 861 if (defaultPackage == null) 862 return null; 863 return defaultPackage.getType0(compoundName[0]); 864 } 865 866 PackageBinding packageBinding = getPackage0(compoundName[0]); 867 if (packageBinding == null || packageBinding == TheNotFoundPackage) 868 return null; 869 870 for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) 871 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) 872 return null; 873 return packageBinding.getType0(compoundName[compoundName.length - 1]); 874 } 875 882 883 PackageBinding getPackage0(char[] name) { 884 return knownPackages.get(name); 885 } 886 890 public ReferenceBinding getResolvedType(char[][] compoundName, Scope scope) { 891 ReferenceBinding type = getType(compoundName); 892 if (type != null) return type; 893 894 return cacheMissingBinaryType( 896 compoundName, 897 scope == null ? this.unitBeingCompleted : scope.referenceCompilationUnit()); 898 } 899 903 904 PackageBinding getTopLevelPackage(char[] name) { 905 PackageBinding packageBinding = getPackage0(name); 906 if (packageBinding != null) { 907 if (packageBinding == TheNotFoundPackage) 908 return null; 909 return packageBinding; 910 } 911 912 if (nameEnvironment.isPackage(null, name)) { 913 knownPackages.put(name, packageBinding = new PackageBinding(name, this)); 914 return packageBinding; 915 } 916 917 knownPackages.put(name, TheNotFoundPackage); return null; 919 } 920 924 925 public ReferenceBinding getType(char[][] compoundName) { 926 ReferenceBinding referenceBinding; 927 928 if (compoundName.length == 1) { 929 if (defaultPackage == null) 930 return null; 931 932 if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) { 933 PackageBinding packageBinding = getPackage0(compoundName[0]); 934 if (packageBinding != null && packageBinding != TheNotFoundPackage) 935 return null; referenceBinding = askForType(defaultPackage, compoundName[0]); 937 } 938 } else { 939 PackageBinding packageBinding = getPackage0(compoundName[0]); 940 if (packageBinding == TheNotFoundPackage) 941 return null; 942 943 if (packageBinding != null) { 944 for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) { 945 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null) 946 break; 947 if (packageBinding == TheNotFoundPackage) 948 return null; 949 } 950 } 951 952 if (packageBinding == null) 953 referenceBinding = askForType(compoundName); 954 else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null) 955 referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]); 956 } 957 958 if (referenceBinding == null || referenceBinding == TheNotFoundType) 959 return null; 960 referenceBinding = BinaryTypeBinding.resolveType(referenceBinding, this, false); 962 if (referenceBinding.isNestedType()) 964 return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided); 965 return referenceBinding; 966 } 967 private TypeBinding[] getTypeArgumentsFromSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType, ReferenceBinding genericType) { 968 java.util.ArrayList args = new java.util.ArrayList (2); 969 int rank = 0; 970 do { 971 args.add(getTypeFromVariantTypeSignature(wrapper, staticVariables, enclosingType, genericType, rank++)); 972 } while (wrapper.signature[wrapper.start] != '>'); 973 wrapper.start++; TypeBinding[] typeArguments = new TypeBinding[args.size()]; 975 args.toArray(typeArguments); 976 return typeArguments; 977 } 978 984 985 ReferenceBinding getTypeFromCompoundName(char[][] compoundName, boolean isParameterized) { 986 ReferenceBinding binding = getCachedType(compoundName); 987 if (binding == null) { 988 PackageBinding packageBinding = computePackageFrom(compoundName); 989 binding = new UnresolvedReferenceBinding(compoundName, packageBinding); 990 packageBinding.addType(binding); 991 } else if (binding == TheNotFoundType) { 992 binding = cacheMissingBinaryType(compoundName, this.unitBeingCompleted); 994 } else if (!isParameterized) { 995 binding = (ReferenceBinding) convertUnresolvedBinaryToRawType(binding); 997 } 998 return binding; 999 } 1000 1006 1007ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end, boolean isParameterized) { 1008 if (end == -1) 1009 end = signature.length; 1010 1011 char[][] compoundName = CharOperation.splitOn('/', signature, start, end); 1012 return getTypeFromCompoundName(compoundName, isParameterized); 1013} 1014 1020 1021TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean isParameterized, TypeBinding enclosingType) { 1022 int dimension = 0; 1023 while (signature[start] == '[') { 1024 start++; 1025 dimension++; 1026 } 1027 if (end == -1) 1028 end = signature.length - 1; 1029 1030 TypeBinding binding = null; 1032 if (start == end) { 1033 switch (signature[start]) { 1034 case 'I' : 1035 binding = TypeBinding.INT; 1036 break; 1037 case 'Z' : 1038 binding = TypeBinding.BOOLEAN; 1039 break; 1040 case 'V' : 1041 binding = TypeBinding.VOID; 1042 break; 1043 case 'C' : 1044 binding = TypeBinding.CHAR; 1045 break; 1046 case 'D' : 1047 binding = TypeBinding.DOUBLE; 1048 break; 1049 case 'B' : 1050 binding = TypeBinding.BYTE; 1051 break; 1052 case 'F' : 1053 binding = TypeBinding.FLOAT; 1054 break; 1055 case 'J' : 1056 binding = TypeBinding.LONG; 1057 break; 1058 case 'S' : 1059 binding = TypeBinding.SHORT; 1060 break; 1061 default : 1062 problemReporter.corruptedSignature(enclosingType, signature, start); 1063 } 1065 } else { 1066 binding = getTypeFromConstantPoolName(signature, start + 1, end, isParameterized); } 1068 1069 if (dimension == 0) 1070 return binding; 1071 return createArrayType(binding, dimension); 1072} 1073TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType) { 1074 int dimension = 0; 1080 while (wrapper.signature[wrapper.start] == '[') { 1081 wrapper.start++; 1082 dimension++; 1083 } 1084 1085 if (wrapper.signature[wrapper.start] == 'T') { 1086 int varStart = wrapper.start + 1; 1087 int varEnd = wrapper.computeEnd(); 1088 for (int i = staticVariables.length; --i >= 0;) 1089 if (CharOperation.equals(staticVariables[i].sourceName, wrapper.signature, varStart, varEnd)) 1090 return dimension == 0 ? (TypeBinding) staticVariables[i] : createArrayType(staticVariables[i], dimension); 1091 ReferenceBinding initialType = enclosingType; 1092 do { 1093 if (enclosingType instanceof BinaryTypeBinding) { TypeVariableBinding[] enclosingVariables = ((BinaryTypeBinding)enclosingType).typeVariables; for (int i = enclosingVariables.length; --i >= 0;) 1096 if (CharOperation.equals(enclosingVariables[i].sourceName, wrapper.signature, varStart, varEnd)) 1097 return dimension == 0 ? (TypeBinding) enclosingVariables[i] : createArrayType(enclosingVariables[i], dimension); 1098 } 1099 } while ((enclosingType = enclosingType.enclosingType()) != null); 1100 problemReporter.undefinedTypeVariableSignature(CharOperation.subarray(wrapper.signature, varStart, varEnd), initialType); 1101 return null; } 1103 boolean isParameterized; 1104 TypeBinding type = getTypeFromSignature(wrapper.signature, wrapper.start, wrapper.computeEnd(), isParameterized = (wrapper.end == wrapper.bracket), enclosingType); 1105 if (!isParameterized) 1106 return dimension == 0 ? type : createArrayType(type, dimension); 1107 1108 ReferenceBinding actualType = (ReferenceBinding) type; 1110 TypeBinding[] typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, actualType); 1111 ReferenceBinding actualEnclosing = actualType.enclosingType(); 1112 if (actualEnclosing != null) { actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing); 1114 } 1115 ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, actualEnclosing); 1116 1117 while (wrapper.signature[wrapper.start] == '.') { 1118 wrapper.start++; char[] memberName = wrapper.nextWord(); 1120 BinaryTypeBinding.resolveType(parameterizedType, this, false); 1121 ReferenceBinding memberType = parameterizedType.genericType().getMemberType(memberName); 1122 if (wrapper.signature[wrapper.start] == '<') { 1123 wrapper.start++; typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, memberType); 1125 } else { 1126 typeArguments = null; 1127 } 1128 parameterizedType = createParameterizedType(memberType, typeArguments, parameterizedType); 1129 } 1130 wrapper.start++; return dimension == 0 ? (TypeBinding) parameterizedType : createArrayType(parameterizedType, dimension); 1132} 1133TypeBinding getTypeFromVariantTypeSignature( 1134 SignatureWrapper wrapper, 1135 TypeVariableBinding[] staticVariables, 1136 ReferenceBinding enclosingType, 1137 ReferenceBinding genericType, 1138 int rank) { 1139 switch (wrapper.signature[wrapper.start]) { 1144 case '-' : 1145 wrapper.start++; 1147 TypeBinding bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType); 1148 return createWildcard(genericType, rank, bound, null , Wildcard.SUPER); 1149 case '+' : 1150 wrapper.start++; 1152 bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType); 1153 return createWildcard(genericType, rank, bound, null , Wildcard.EXTENDS); 1154 case '*' : 1155 wrapper.start++; 1157 return createWildcard(genericType, rank, null, null , Wildcard.UNBOUND); 1158 default : 1159 return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType); 1160 } 1161} 1162 1163 1165boolean isPackage(char[][] compoundName, char[] name) { 1166 if (compoundName == null || compoundName.length == 0) 1167 return nameEnvironment.isPackage(null, name); 1168 return nameEnvironment.isPackage(compoundName, name); 1169} 1170 1172public MethodVerifier methodVerifier() { 1173 if (verifier == null) 1174 verifier = this.globalOptions.sourceLevel < ClassFileConstants.JDK1_5 1175 ? new MethodVerifier(this) 1176 : new MethodVerifier15(this); return verifier; 1178} 1179public void reset() { 1180 this.defaultPackage = new PackageBinding(this); this.defaultImports = null; 1182 this.knownPackages = new HashtableOfPackage(); 1183 this.accessRestrictions = new HashMap (3); 1184 1185 this.verifier = null; 1186 for (int i = this.uniqueArrayBindings.length; --i >= 0;) { 1187 ArrayBinding[] arrayBindings = this.uniqueArrayBindings[i]; 1188 if (arrayBindings != null) 1189 for (int j = arrayBindings.length; --j >= 0;) 1190 arrayBindings[j] = null; 1191 } 1192 this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3); 1193 this.uniqueRawTypeBindings = new SimpleLookupTable(3); 1194 this.uniqueWildcardBindings = new SimpleLookupTable(3); 1195 this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3); 1196 1197 for (int i = this.units.length; --i >= 0;) 1198 this.units[i] = null; 1199 this.lastUnitIndex = -1; 1200 this.lastCompletedUnitIndex = -1; 1201 this.unitBeingCompleted = null; 1203 this.classFilePool.reset(); 1204 } 1207 1211public void setAccessRestriction(ReferenceBinding type, AccessRestriction accessRestriction) { 1212 if (accessRestriction == null) return; 1213 type.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess; 1214 this.accessRestrictions.put(type, accessRestriction); 1215} 1216 1217void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) { 1218 if (this.uniqueParameterizedTypeBindings.get(unresolvedType) != null) { Object [] keys = this.uniqueParameterizedTypeBindings.keyTable; 1222 for (int i = 0, l = keys.length; i < l; i++) { 1223 if (keys[i] == unresolvedType) { 1224 keys[i] = resolvedType; break; 1226 } 1227 } 1228 } 1229 1230 if (this.uniqueWildcardBindings.get(unresolvedType) != null) { Object [] keys = this.uniqueWildcardBindings.keyTable; 1232 for (int i = 0, l = keys.length; i < l; i++) { 1233 if (keys[i] == unresolvedType) { 1234 keys[i] = resolvedType; break; 1236 } 1237 } 1238 } 1239} 1240} 1241 | Popular Tags |