Lines 447-457
Link Here
|
447 |
return null; // incompatible |
447 |
return null; // incompatible |
448 |
} |
448 |
} |
449 |
|
449 |
|
|
|
450 |
/** |
451 |
* Connect type variable supertypes, and returns true if no problem was detected |
452 |
* @param typeParameters |
453 |
* @param checkForErasedCandidateCollisions |
454 |
*/ |
450 |
protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) { |
455 |
protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) { |
451 |
if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true; |
456 |
if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true; |
452 |
boolean noProblems = true; |
|
|
453 |
Map invocations = new HashMap(2); |
457 |
Map invocations = new HashMap(2); |
454 |
nextVariable : for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { |
458 |
boolean noProblems = true; |
|
|
459 |
nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { |
455 |
TypeParameter typeParameter = typeParameters[i]; |
460 |
TypeParameter typeParameter = typeParameters[i]; |
456 |
TypeVariableBinding typeVariable = typeParameter.binding; |
461 |
TypeVariableBinding typeVariable = typeParameter.binding; |
457 |
if (typeVariable == null) return false; |
462 |
if (typeVariable == null) return false; |
Lines 464-556
Link Here
|
464 |
TypeReference typeRef = typeParameter.type; |
469 |
TypeReference typeRef = typeParameter.type; |
465 |
if (typeRef == null) |
470 |
if (typeRef == null) |
466 |
continue nextVariable; |
471 |
continue nextVariable; |
|
|
472 |
boolean isFirstBoundTypeVariable = false; |
467 |
TypeBinding superType = this.kind == METHOD_SCOPE |
473 |
TypeBinding superType = this.kind == METHOD_SCOPE |
468 |
? typeRef.resolveType((BlockScope)this, false/*no bound check*/) |
474 |
? typeRef.resolveType((BlockScope)this, false/*no bound check*/) |
469 |
: typeRef.resolveType((ClassScope)this); |
475 |
: typeRef.resolveType((ClassScope)this); |
470 |
if (superType == null) { |
476 |
if (superType == null) { |
471 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
477 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
472 |
noProblems = false; |
|
|
473 |
continue nextVariable; |
474 |
} |
475 |
typeRef.resolvedType = superType; // hold onto the problem type |
476 |
if (superType.isArrayType()) { |
477 |
problemReporter().boundCannotBeArray(typeRef, superType); |
478 |
continue nextVariable; |
479 |
} |
480 |
boolean isTypeVariableFirstBound = superType.isTypeVariable(); |
481 |
if (isTypeVariableFirstBound) { |
482 |
TypeVariableBinding varSuperType = (TypeVariableBinding) superType; |
483 |
if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) { |
484 |
problemReporter().forwardTypeVariableReference(typeParameter, varSuperType); |
485 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
486 |
noProblems = false; |
487 |
continue nextVariable; |
488 |
} |
489 |
} |
490 |
ReferenceBinding superRefType = (ReferenceBinding) superType; |
491 |
if (superRefType.isFinal()) |
492 |
problemReporter().finalVariableBound(typeVariable, typeRef); |
493 |
if (!superType.isInterface()) { |
494 |
typeVariable.superclass = superRefType; |
495 |
} else { |
478 |
} else { |
496 |
typeVariable.superInterfaces = new ReferenceBinding[] {superRefType}; |
479 |
typeRef.resolvedType = superType; // hold onto the problem type |
|
|
480 |
firstBound: { |
481 |
switch (superType.kind()) { |
482 |
case Binding.ARRAY_TYPE : |
483 |
problemReporter().boundCannotBeArray(typeRef, superType); |
484 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
485 |
break firstBound; // do not keep first bound |
486 |
case Binding.TYPE_PARAMETER : |
487 |
isFirstBoundTypeVariable = true; |
488 |
TypeVariableBinding varSuperType = (TypeVariableBinding) superType; |
489 |
if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) { |
490 |
problemReporter().forwardTypeVariableReference(typeParameter, varSuperType); |
491 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
492 |
break firstBound; // do not keep first bound |
493 |
} |
494 |
break; |
495 |
default : |
496 |
if (((ReferenceBinding) superType).isFinal()) { |
497 |
problemReporter().finalVariableBound(typeVariable, typeRef); |
498 |
} |
499 |
break; |
500 |
} |
501 |
ReferenceBinding superRefType = (ReferenceBinding) superType; |
502 |
if (!superType.isInterface()) { |
503 |
typeVariable.superclass = superRefType; |
504 |
} else { |
505 |
typeVariable.superInterfaces = new ReferenceBinding[] {superRefType}; |
506 |
} |
507 |
typeVariable.firstBound = superRefType; // first bound used to compute erasure |
508 |
} |
497 |
} |
509 |
} |
498 |
typeVariable.firstBound = superRefType; // first bound used to compute erasure |
|
|
499 |
TypeReference[] boundRefs = typeParameter.bounds; |
510 |
TypeReference[] boundRefs = typeParameter.bounds; |
500 |
if (boundRefs != null) { |
511 |
if (boundRefs != null) { |
501 |
for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) { |
512 |
nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) { |
502 |
typeRef = boundRefs[j]; |
513 |
typeRef = boundRefs[j]; |
503 |
superType = this.kind == METHOD_SCOPE |
514 |
superType = this.kind == METHOD_SCOPE |
504 |
? typeRef.resolveType((BlockScope)this, false) |
515 |
? typeRef.resolveType((BlockScope)this, false) |
505 |
: typeRef.resolveType((ClassScope)this); |
516 |
: typeRef.resolveType((ClassScope)this); |
506 |
if (superType == null) { |
517 |
if (superType == null) { |
507 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
518 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
508 |
noProblems = false; |
519 |
continue nextBound; |
509 |
continue nextVariable; |
520 |
} else { |
510 |
} |
521 |
typeRef.resolvedType = superType; // hold onto the problem type |
511 |
typeRef.resolvedType = superType; // hold onto the problem type |
522 |
boolean didAlreadyComplain = false; |
512 |
if (isTypeVariableFirstBound && j == 0) { |
523 |
if (isFirstBoundTypeVariable && j == 0) { |
513 |
problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); |
524 |
problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); |
514 |
} |
|
|
515 |
if (superType.isArrayType()) { |
516 |
problemReporter().boundCannotBeArray(typeRef, superType); |
517 |
continue nextVariable; |
518 |
} |
519 |
superRefType = (ReferenceBinding) superType; |
520 |
if (!superType.isInterface()) { |
521 |
problemReporter().boundMustBeAnInterface(typeRef, superType); |
522 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
523 |
noProblems = false; |
524 |
continue nextVariable; |
525 |
} |
526 |
// check against superclass |
527 |
if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) { |
528 |
if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) { |
529 |
noProblems = false; |
530 |
continue nextVariable; |
531 |
} |
532 |
} |
533 |
// check against superinterfaces |
534 |
for (int index = typeVariable.superInterfaces.length; --index >= 0;) { |
535 |
ReferenceBinding previousInterface = typeVariable.superInterfaces[index]; |
536 |
if (previousInterface == superRefType) { |
537 |
problemReporter().duplicateBounds(typeRef, superType); |
538 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
525 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
539 |
noProblems = false; |
526 |
didAlreadyComplain = true; |
540 |
continue nextVariable; |
527 |
//continue nextBound; - keep these bounds to minimize secondary errors |
|
|
528 |
} else if (superType.isArrayType()) { |
529 |
if (!didAlreadyComplain) { |
530 |
problemReporter().boundCannotBeArray(typeRef, superType); |
531 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
532 |
} |
533 |
continue nextBound; |
534 |
} else { |
535 |
if (!superType.isInterface()) { |
536 |
if (!didAlreadyComplain) { |
537 |
problemReporter().boundMustBeAnInterface(typeRef, superType); |
538 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
539 |
} |
540 |
continue nextBound; |
541 |
} |
541 |
} |
542 |
} |
542 |
if (checkForErasedCandidateCollisions) { |
543 |
// check against superclass |
543 |
if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) { |
544 |
if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) { |
544 |
noProblems = false; |
545 |
if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) { |
545 |
continue nextVariable; |
546 |
continue nextBound; |
|
|
547 |
} |
548 |
} |
549 |
// check against superinterfaces |
550 |
ReferenceBinding superRefType = (ReferenceBinding) superType; |
551 |
for (int index = typeVariable.superInterfaces.length; --index >= 0;) { |
552 |
ReferenceBinding previousInterface = typeVariable.superInterfaces[index]; |
553 |
if (previousInterface == superRefType) { |
554 |
problemReporter().duplicateBounds(typeRef, superType); |
555 |
typeVariable.tagBits |= TagBits.HierarchyHasProblems; |
556 |
continue nextBound; |
557 |
} |
558 |
if (checkForErasedCandidateCollisions) { |
559 |
if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) { |
560 |
continue nextBound; |
561 |
} |
546 |
} |
562 |
} |
547 |
} |
563 |
} |
|
|
564 |
int size = typeVariable.superInterfaces.length; |
565 |
System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size); |
566 |
typeVariable.superInterfaces[size] = superRefType; |
548 |
} |
567 |
} |
549 |
int size = typeVariable.superInterfaces.length; |
|
|
550 |
System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size); |
551 |
typeVariable.superInterfaces[size] = superRefType; |
552 |
} |
568 |
} |
553 |
} |
569 |
} |
|
|
570 |
noProblems &= (typeVariable.tagBits & TagBits.HierarchyHasProblems) == 0; |
554 |
} |
571 |
} |
555 |
return noProblems; |
572 |
return noProblems; |
556 |
} |
573 |
} |