Lines 25-30
Link Here
|
25 |
public char[][] currentPackageName; |
25 |
public char[][] currentPackageName; |
26 |
public PackageBinding fPackage; |
26 |
public PackageBinding fPackage; |
27 |
public ImportBinding[] imports; |
27 |
public ImportBinding[] imports; |
|
|
28 |
public int importPtr; |
28 |
public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage() |
29 |
public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage() |
29 |
|
30 |
|
30 |
public SourceTypeBinding[] topLevelTypes; |
31 |
public SourceTypeBinding[] topLevelTypes; |
Lines 37-42
Link Here
|
37 |
|
38 |
|
38 |
HashtableOfType constantPoolNameUsage; |
39 |
HashtableOfType constantPoolNameUsage; |
39 |
private int captureID = 1; |
40 |
private int captureID = 1; |
|
|
41 |
|
42 |
private ImportBinding[] tempImports; // to keep a record of resolved imports while traversing all in faultInImports() |
40 |
|
43 |
|
41 |
public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) { |
44 |
public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) { |
42 |
super(COMPILATION_UNIT_SCOPE, null); |
45 |
super(COMPILATION_UNIT_SCOPE, null); |
Lines 328-337
Link Here
|
328 |
break; |
331 |
break; |
329 |
} |
332 |
} |
330 |
} |
333 |
} |
331 |
ImportBinding[] resolvedImports = new ImportBinding[numberOfImports]; |
334 |
this.tempImports = new ImportBinding[numberOfImports]; |
332 |
resolvedImports[0] = getDefaultImports()[0]; |
335 |
this.tempImports[0] = getDefaultImports()[0]; |
333 |
int index = 1; |
336 |
this.importPtr = 1; |
334 |
|
337 |
|
335 |
// keep static imports with normal imports until there is a reason to split them up |
338 |
// keep static imports with normal imports until there is a reason to split them up |
336 |
// on demand imports continue to be packages & types. need to check on demand type imports for fields/methods |
339 |
// on demand imports continue to be packages & types. need to check on demand type imports for fields/methods |
337 |
// single imports change from being just types to types or fields |
340 |
// single imports change from being just types to types or fields |
Lines 340-347
Link Here
|
340 |
char[][] compoundName = importReference.tokens; |
343 |
char[][] compoundName = importReference.tokens; |
341 |
|
344 |
|
342 |
// skip duplicates or imports of the current package |
345 |
// skip duplicates or imports of the current package |
343 |
for (int j = 0; j < index; j++) { |
346 |
for (int j = 0; j < this.importPtr; j++) { |
344 |
ImportBinding resolved = resolvedImports[j]; |
347 |
ImportBinding resolved = this.tempImports[j]; |
345 |
if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) { |
348 |
if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) { |
346 |
if (CharOperation.equals(compoundName, resolved.compoundName)) { |
349 |
if (CharOperation.equals(compoundName, resolved.compoundName)) { |
347 |
problemReporter().unusedImport(importReference); // since skipped, must be reported now |
350 |
problemReporter().unusedImport(importReference); // since skipped, must be reported now |
Lines 364-370
Link Here
|
364 |
problemReporter().cannotImportPackage(importReference); |
367 |
problemReporter().cannotImportPackage(importReference); |
365 |
continue nextImport; |
368 |
continue nextImport; |
366 |
} |
369 |
} |
367 |
resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference); |
370 |
recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference)); |
368 |
} else { |
371 |
} else { |
369 |
Binding importBinding = findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic()); |
372 |
Binding importBinding = findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic()); |
370 |
if (!importBinding.isValidBinding()) { |
373 |
if (!importBinding.isValidBinding()) { |
Lines 379-459
Link Here
|
379 |
problemReporter().cannotImportPackage(importReference); |
382 |
problemReporter().cannotImportPackage(importReference); |
380 |
continue nextImport; |
383 |
continue nextImport; |
381 |
} |
384 |
} |
382 |
ReferenceBinding conflictingType = null; |
385 |
if(checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName) == -1) |
383 |
if (importBinding instanceof MethodBinding) { |
386 |
continue nextImport; |
384 |
conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length); |
387 |
if (importReference.isStatic()) { |
385 |
if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic())) |
388 |
// look for more bindings being imported |
386 |
conflictingType = null; |
389 |
// static imports are checked for fields first, followed by method and then type |
387 |
} |
390 |
// So if a type is found, no fields and methods are available anyway |
388 |
// collisions between an imported static field & a type should be checked according to spec... but currently not by javac |
391 |
// similarly when method is found, type may be available but no field available for sure |
389 |
if (importBinding instanceof ReferenceBinding || conflictingType != null) { |
392 |
if (importBinding.kind() == Binding.FIELD) { |
390 |
ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType; |
393 |
if (checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference) == -1) |
391 |
ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous |
|
|
392 |
? ((ProblemReferenceBinding) referenceBinding).closestMatch |
393 |
: referenceBinding; |
394 |
if (importReference.isTypeUseDeprecated(typeToCheck, this)) |
395 |
problemReporter().deprecatedType(typeToCheck, importReference); |
396 |
|
397 |
ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]); |
398 |
if (existingType != null) { |
399 |
// duplicate test above should have caught this case, but make sure |
400 |
if (existingType == referenceBinding) { |
401 |
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865 |
402 |
// Check all resolved imports to see if this import qualifies as a duplicate |
403 |
for (int j = 0; j < index; j++) { |
404 |
ImportBinding resolved = resolvedImports[j]; |
405 |
if (resolved instanceof ImportConflictBinding) { |
406 |
ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved; |
407 |
if (importConflictBinding.conflictingTypeBinding == referenceBinding) { |
408 |
if (!importReference.isStatic()) { |
409 |
// resolved is implicitly static |
410 |
problemReporter().duplicateImport(importReference); |
411 |
resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference); |
412 |
} |
413 |
} |
414 |
} else if (resolved.resolvedImport == referenceBinding) { |
415 |
if (importReference.isStatic() != resolved.isStatic()) { |
416 |
problemReporter().duplicateImport(importReference); |
417 |
resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference); |
418 |
} |
419 |
} |
420 |
} |
421 |
continue nextImport; |
394 |
continue nextImport; |
422 |
} |
395 |
} else if (importBinding.kind() == Binding.METHOD) { |
423 |
// either the type collides with a top level type or another imported type |
396 |
if (checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE, importReference) == -1) |
424 |
for (int j = 0, length = this.topLevelTypes.length; j < length; j++) { |
397 |
continue nextImport; |
425 |
if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) { |
|
|
426 |
problemReporter().conflictingImport(importReference); |
427 |
continue nextImport; |
428 |
} |
429 |
} |
430 |
problemReporter().duplicateImport(importReference); |
431 |
continue nextImport; |
432 |
} |
398 |
} |
433 |
typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding); |
399 |
// Binding importBinding = findSingleStaticImport(compoundName, Binding.TYPE); |
434 |
} else if (importBinding instanceof FieldBinding) { |
400 |
// if (importBinding.isValidBinding()) { |
435 |
for (int j = 0; j < index; j++) { |
401 |
// temp = checkAndAddImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
436 |
ImportBinding resolved = resolvedImports[j]; |
402 |
// if (temp == -1) continue nextImport; |
437 |
// find other static fields with the same name |
403 |
// } |
438 |
if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) { |
404 |
// importBinding = findSingleStaticImport(compoundName, Binding.FIELD); |
439 |
if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) { |
405 |
// if (importBinding.isValidBinding()) { |
440 |
problemReporter().duplicateImport(importReference); |
406 |
// temp = checkAndAddImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
441 |
continue nextImport; |
407 |
// if (temp == -1) continue nextImport; |
442 |
} |
408 |
// } |
443 |
} |
409 |
// importBinding = findSingleStaticImport(compoundName, Binding.METHOD); |
444 |
} |
410 |
// if (importBinding.isValidBinding()) { |
|
|
411 |
// temp = checkAndAddImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
412 |
// if (temp == -1) continue nextImport; |
413 |
// } |
445 |
} |
414 |
} |
446 |
resolvedImports[index++] = conflictingType == null |
|
|
447 |
? new ImportBinding(compoundName, false, importBinding, importReference) |
448 |
: new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference); |
449 |
} |
415 |
} |
450 |
} |
416 |
} |
451 |
|
417 |
|
452 |
// shrink resolvedImports... only happens if an error was reported |
418 |
// shrink resolvedImports... only happens if an error was reported |
453 |
if (resolvedImports.length > index) |
419 |
if (this.tempImports.length > this.importPtr) |
454 |
System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index); |
420 |
System.arraycopy(this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr); |
455 |
this.imports = resolvedImports; |
421 |
this.imports = this.tempImports; |
456 |
|
|
|
457 |
int length = this.imports.length; |
422 |
int length = this.imports.length; |
458 |
this.typeOrPackageCache = new HashtableOfObject(length); |
423 |
this.typeOrPackageCache = new HashtableOfObject(length); |
459 |
for (int i = 0; i < length; i++) { |
424 |
for (int i = 0; i < length; i++) { |
Lines 840-843
Link Here
|
840 |
for (int i = 0, length = this.topLevelTypes.length; i < length; i++) |
805 |
for (int i = 0, length = this.topLevelTypes.length; i < length; i++) |
841 |
this.topLevelTypes[i].verifyMethods(verifier); |
806 |
this.topLevelTypes[i].verifyMethods(verifier); |
842 |
} |
807 |
} |
|
|
808 |
private void recordImportBinding(ImportBinding bindingToAdd) { |
809 |
if (this.tempImports.length == this.importPtr) { |
810 |
System.arraycopy(this.tempImports, 0, (this.tempImports = new ImportBinding[this.importPtr + 1]), 0, this.importPtr); |
811 |
} |
812 |
this.tempImports[this.importPtr++] = bindingToAdd; |
813 |
} |
814 |
/** |
815 |
* Checks additional bindings (methods or types) imported from a single static import. |
816 |
* Method is tried first, followed by type. If found, records them. |
817 |
* If in the process, import is flagged as duplicate, -1 is returned. |
818 |
* @param compoundName |
819 |
* @param typesBySimpleNames |
820 |
* @param mask |
821 |
* @param importReference |
822 |
* @return -1 when this import is flagged as duplicate, 0 otherwise. |
823 |
*/ |
824 |
private int checkMoreStaticBindings( |
825 |
char[][] compoundName, |
826 |
HashtableOfType typesBySimpleNames, |
827 |
int mask, |
828 |
ImportReference importReference) { |
829 |
Binding importBinding = findSingleStaticImport(compoundName, mask); |
830 |
|
831 |
int temp; |
832 |
if (!importBinding.isValidBinding()) { |
833 |
// only continue of the same kind's ambiguous binding is returned |
834 |
// may have found an ambiguous type when looking for field or method. Don't continue in that case |
835 |
if (importBinding.problemId() == ProblemReasons.Ambiguous) { |
836 |
// keep it unless a duplicate can be found below |
837 |
temp = checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
838 |
if (temp == -1) return -1; |
839 |
} |
840 |
} else { |
841 |
temp = checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
842 |
if (temp == -1) return -1; |
843 |
} |
844 |
if (importBinding.kind() == Binding.METHOD) { |
845 |
// found method |
846 |
// type is left to be looked for |
847 |
// reset METHOD bit to enable lookup for only type |
848 |
mask &= ~Binding.METHOD; |
849 |
// now search for a type binding |
850 |
importBinding = findSingleStaticImport(compoundName, mask); |
851 |
if (!importBinding.isValidBinding()) { |
852 |
// only continue of the same kind's ambiguous binding is returned |
853 |
// may have found,say, an ambiguous type when looking for field or method. Don't continue in that case |
854 |
if (importBinding.problemId() == ProblemReasons.Ambiguous) { |
855 |
// keep it unless a duplicate can be found below |
856 |
temp = checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
857 |
if (temp == -1) return -1; |
858 |
} |
859 |
} else { |
860 |
temp = checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); |
861 |
if (temp == -1) return -1; |
862 |
} |
863 |
} |
864 |
return 0; |
865 |
} |
866 |
/** |
867 |
* Checks for duplicates. If all ok, records the importBinding |
868 |
* returns -1 when this import is flagged as duplicate. |
869 |
* @param importBinding |
870 |
* @param typesBySimpleNames |
871 |
* @param importReference |
872 |
* @param compoundName |
873 |
* @return -1 when this import is flagged as duplicate, importPtr otherwise. |
874 |
*/ |
875 |
private int checkAndRecordImportBinding( |
876 |
Binding importBinding, |
877 |
HashtableOfType typesBySimpleNames, |
878 |
ImportReference importReference, |
879 |
char[][] compoundName) { |
880 |
ReferenceBinding conflictingType = null; |
881 |
if (importBinding instanceof MethodBinding) { |
882 |
conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length); |
883 |
if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic())) |
884 |
conflictingType = null; |
885 |
} |
886 |
// collisions between an imported static field & a type should be checked according to spec... but currently not by javac |
887 |
if (importBinding instanceof ReferenceBinding || conflictingType != null) { |
888 |
ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType; |
889 |
ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous |
890 |
? ((ProblemReferenceBinding) referenceBinding).closestMatch |
891 |
: referenceBinding; |
892 |
if (importReference.isTypeUseDeprecated(typeToCheck, this)) |
893 |
problemReporter().deprecatedType(typeToCheck, importReference); |
894 |
|
895 |
ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]); |
896 |
if (existingType != null) { |
897 |
// duplicate test above should have caught this case, but make sure |
898 |
if (existingType == referenceBinding) { |
899 |
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865 |
900 |
// Check all resolved imports to see if this import qualifies as a duplicate |
901 |
for (int j = 0; j < this.importPtr; j++) { |
902 |
ImportBinding resolved = this.tempImports[j]; |
903 |
if (resolved instanceof ImportConflictBinding) { |
904 |
ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved; |
905 |
if (importConflictBinding.conflictingTypeBinding == referenceBinding) { |
906 |
if (!importReference.isStatic()) { |
907 |
// resolved is implicitly static |
908 |
problemReporter().duplicateImport(importReference); |
909 |
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); |
910 |
} |
911 |
} |
912 |
} else if (resolved.resolvedImport == referenceBinding) { |
913 |
if (importReference.isStatic() != resolved.isStatic()) { |
914 |
problemReporter().duplicateImport(importReference); |
915 |
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); |
916 |
} |
917 |
} |
918 |
} |
919 |
return -1; |
920 |
} |
921 |
// either the type collides with a top level type or another imported type |
922 |
for (int j = 0, length = this.topLevelTypes.length; j < length; j++) { |
923 |
if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) { |
924 |
problemReporter().conflictingImport(importReference); |
925 |
return -1; |
926 |
} |
927 |
} |
928 |
problemReporter().duplicateImport(importReference); |
929 |
return -1; |
930 |
} |
931 |
typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding); |
932 |
} else if (importBinding instanceof FieldBinding) { |
933 |
for (int j = 0; j < this.importPtr; j++) { |
934 |
ImportBinding resolved = this.tempImports[j]; |
935 |
// find other static fields with the same name |
936 |
if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) { |
937 |
if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) { |
938 |
problemReporter().duplicateImport(importReference); |
939 |
return -1; |
940 |
} |
941 |
} |
942 |
} |
943 |
} |
944 |
if (conflictingType == null) { |
945 |
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); |
946 |
} else { |
947 |
recordImportBinding(new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference)); |
948 |
} |
949 |
return this.importPtr; |
950 |
} |
843 |
} |
951 |
} |