Index: .cvsignore =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/.cvsignore,v retrieving revision 1.4 diff -u -r1.4 .cvsignore --- .cvsignore 28 Jul 2003 13:20:34 -0000 1.4 +++ .cvsignore 18 Feb 2005 00:33:36 -0000 @@ -1,2 +1,4 @@ bin -antbin \ No newline at end of file +antbin +*.ipr +*.iws Index: .settings/org.eclipse.jdt.core.prefs =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs,v retrieving revision 1.4 diff -u -r1.4 org.eclipse.jdt.core.prefs --- .settings/org.eclipse.jdt.core.prefs 12 Oct 2004 11:49:13 -0000 1.4 +++ .settings/org.eclipse.jdt.core.prefs 18 Feb 2005 00:33:36 -0000 @@ -1,9 +1,10 @@ -#Fri Sep 03 12:55:26 CEST 2004 +#Thu Feb 03 14:27:11 PST 2005 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.unusedImport=warning org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore @@ -23,6 +24,7 @@ org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.compliance=1.4 org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning org.eclipse.jdt.core.builder.cleanOutputFolder=clean @@ -32,25 +34,25 @@ org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning org.eclipse.jdt.core.compiler.problem.fieldHiding=warning org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.incompatibleJDKLevel=ignore eclipse.preferences.version=1 org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled @@ -58,8 +60,7 @@ org.eclipse.jdt.core.incompleteClasspath=error org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.builder.duplicateResourceTask=warning org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning \ No newline at end of file Index: compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java,v retrieving revision 1.32 diff -u -r1.32 ArrayReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java 9 Dec 2004 18:24:26 -0000 1.32 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java 18 Feb 2005 00:33:37 -0000 @@ -203,7 +203,10 @@ if (positionType != null) { position.computeConversion(scope, IntBinding, positionType); } - return this.resolvedType; + + // The type of this expression needs to be captured, unless it is being assigned to. + return (this.bits & IsStrictlyAssignedMASK) != 0 ? + this.resolvedType : captureResolvedType(); } public void traverse(ASTVisitor visitor, BlockScope scope) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java,v retrieving revision 1.53 diff -u -r1.53 Assignment.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java 14 Jan 2005 09:33:12 -0000 1.53 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java 18 Feb 2005 00:33:37 -0000 @@ -173,12 +173,13 @@ scope.problemReporter().expressionShouldBeAVariable(this.lhs); return null; } - TypeBinding lhsType = this.resolvedType = lhs.resolveType(scope); + TypeBinding lhsType = lhs.resolveType(scope); expression.setExpectedType(lhsType); // needed in case of generic method invocation TypeBinding rhsType = expression.resolveType(scope); if (lhsType == null || rhsType == null) { return null; } + this.resolvedType = lhsType.capture(); checkAssignmentEffect(scope); // Compile-time conversion of base-types : implicit narrowing integer into byte/short/character Index: compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java,v retrieving revision 1.72 diff -u -r1.72 CastExpression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java 3 Feb 2005 09:34:46 -0000 1.72 +++ compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java 18 Feb 2005 00:33:37 -0000 @@ -381,7 +381,7 @@ scope.problemReporter().typeCastError(this, this.resolvedType, expressionType); } } - return this.resolvedType; + return captureResolvedType(); } else { // expression as a cast TypeBinding expressionType = expression.resolveType(scope); if (expressionType == null) return null; Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java,v retrieving revision 1.58 diff -u -r1.58 ConditionalExpression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 2 Feb 2005 20:45:05 -0000 1.58 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 18 Feb 2005 00:33:38 -0000 @@ -411,7 +411,7 @@ if (commonType != null) { valueIfTrue.computeConversion(scope, commonType, valueIfTrueType); valueIfFalse.computeConversion(scope, commonType, valueIfFalseType); - return this.resolvedType = commonType; + return this.resolvedType = commonType.capture(); } } scope.problemReporter().conditionalArgumentsIncompatibleTypes( Index: compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java,v retrieving revision 1.61 diff -u -r1.61 Expression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java 2 Feb 2005 23:15:36 -0000 1.61 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java 18 Feb 2005 00:33:38 -0000 @@ -848,4 +848,10 @@ public LocalVariableBinding localVariableBinding() { return null; } + + public final TypeBinding captureResolvedType() { + if (this.resolvedType != null) + this.resolvedType = this.resolvedType.capture(); + return this.resolvedType; + } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java,v retrieving revision 1.74 diff -u -r1.74 FieldReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 15 Dec 2004 20:30:24 -0000 1.74 +++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 18 Feb 2005 00:33:38 -0000 @@ -523,7 +523,9 @@ scope.problemReporter().indirectAccessToStaticField(this, binding); } } - return this.resolvedType = binding.type; + + // The type of this expression needs to be captured, unless it is being assigned to. + return this.resolvedType = (this.bits & IsStrictlyAssignedMASK) == 0 ? binding.type.capture() : binding.type; } public void setActualReceiverType(ReferenceBinding receiverType) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java,v retrieving revision 1.82 diff -u -r1.82 MessageSend.java --- compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 13 Dec 2004 14:27:25 -0000 1.82 +++ compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 18 Feb 2005 00:33:38 -0000 @@ -259,7 +259,7 @@ // resolve type arguments (for generic constructor call) if (this.typeArguments != null) { int length = this.typeArguments.length; - boolean argHasError = false; // typeChecks all arguments + boolean argHasError = false; // typeChecks all aFrguments this.genericTypeArguments = new TypeBinding[length]; for (int i = 0; i < length; i++) { if ((this.genericTypeArguments[i] = this.typeArguments[i].resolveType(scope, true /* check bounds*/)) == null) { @@ -336,7 +336,7 @@ closestMatch.original().modifiers |= AccPrivateUsed; } } - return this.resolvedType; + return captureResolvedType(); } if (!binding.isStatic()) { // the "receiver" must not be a type, in other words, a NameReference that the TC has bound to a Type @@ -385,7 +385,7 @@ } else { this.resolvedType = this.binding.returnType; } - return this.resolvedType; + return captureResolvedType(); } public void setActualReceiverType(ReferenceBinding receiverType) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v retrieving revision 1.77 diff -u -r1.77 QualifiedNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 9 Dec 2004 22:09:27 -0000 1.77 +++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 18 Feb 2005 00:33:38 -0000 @@ -607,6 +607,8 @@ field = null; } TypeBinding type = ((VariableBinding) binding).type; + if (type != null) type = type.capture(); + int index = indexOfFirstFieldBinding; if (index == length) { // restrictiveFlag == FIELD this.constant = FieldReference.getConstantFor((FieldBinding) binding, this, false, scope); @@ -673,7 +675,9 @@ } } setDepth(firstDepth); - return (otherBindings[otherBindingsLength - 1]).type; + final TypeBinding result = (otherBindings[otherBindingsLength - 1]).type; + // The type of this expression needs to be captured, unless it is being assigned to. + return (this.bits & IsStrictlyAssignedMASK) != 0 ? result : result.capture(); } public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { if (!flowInfo.isReachable()) return; Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v retrieving revision 1.62 diff -u -r1.62 SingleNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 9 Dec 2004 22:09:27 -0000 1.62 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 18 Feb 2005 00:33:38 -0000 @@ -661,14 +661,22 @@ if (!variable.isFinal() && (bits & DepthMASK) != 0) { scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this); } - return this.resolvedType = variable.type; + // If assigning to this variable, it's type is not captured. + this.resolvedType = variable.type; } - // a field - FieldBinding field = (FieldBinding) this.binding; - if (!field.isStatic() && scope.environment().options.getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { - scope.problemReporter().unqualifiedFieldAccess(this, field); - } - return this.resolvedType = checkFieldAccess(scope); + else { + // a field + FieldBinding field = (FieldBinding) this.binding; + if (!field.isStatic() && scope.environment().options.getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { + scope.problemReporter().unqualifiedFieldAccess(this, field); + } + this.resolvedType = checkFieldAccess(scope); + } + + // The type of this expression needs to be captured, unless it is being assigned to. + if (((this.bits & IsStrictlyAssignedMASK) == 0)) + captureResolvedType(); + return this.resolvedType; } // thus it was a type Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java,v retrieving revision 1.36 diff -u -r1.36 ParameterizedTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 24 Jan 2005 16:01:13 -0000 1.36 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 18 Feb 2005 00:33:39 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.compiler.lookup; import java.util.Map; + import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ast.Wildcard; @@ -187,6 +188,110 @@ */ public TypeBinding erasure() { return this.type.erasure(); // erasure + } + + /** + * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture() + */ + public TypeBinding capture() { + final TypeBinding[] oldArgs = this.arguments; + if (oldArgs == null) return this; + final TypeBinding[] newArgs = new TypeBinding[oldArgs.length]; + final TypeVariableBinding[] typeParams = this.type.typeVariables(); + boolean hasWildcard = false; + + // Perform capture in two passes. First construct a fresh type variable for each + // wildcard type argument + for (int i = 0, len = newArgs.length ; i < len ; i++) { + final TypeBinding oldArg = oldArgs[i]; + if (! oldArg.isWildcard()) + newArgs[i] = oldArg; + else { + TypeVariableBinding newArg = new TypeVariableBinding( + CharOperation.concat(TypeConstants.CAPTURE_OF, oldArg.readableName()), + null, ((WildcardBinding)oldArg).rank); + newArg.fPackage = ((WildcardBinding)oldArg).fPackage; + newArgs[i] = newArg; + hasWildcard = true; + } + } + + if (! hasWildcard) return this; + + // Construct a substitution from the Type Parameters of the generic type that is being captured + // to the new captured wildcards. This is used below in setting the bounds of the captured wildcards. + Substitution sub = new Substitution() { + public LookupEnvironment environment() { return ParameterizedTypeBinding.this.environment(); } + public boolean isRawSubstitution() { return false; } + + public TypeBinding substitute(TypeVariableBinding typeVariable) { + for (int i = 0, len = typeParams.length ; i < len ; i++) + if (typeVariable == typeParams[i]) + return newArgs[i]; + return typeVariable; + } + }; + + // Second. Set the bounds of the new type variables + for (int i = 0, len = newArgs.length; i < len; i++) { + final TypeBinding oldArg = oldArgs[i]; + if (oldArg.isWildcard()) { + final WildcardBinding wildcard = (WildcardBinding) oldArg; + final TypeVariableBinding capture = (TypeVariableBinding) newArgs[i]; + + // unbounded wildcards and lower bounded wildcards generate a type variable with + // whose upper bound is the same as the upper bounds of the corresponding type variable + if (wildcard.kind == Wildcard.UNBOUND || wildcard.kind == Wildcard.SUPER) { + final TypeBinding bound = Scope.substitute(sub, typeParams[i].superclass()); + capture.superclass = bound.isClass() ? (ReferenceBinding) bound : environment.getType(JAVA_LANG_OBJECT); + + final ReferenceBinding[] intfs = typeParams[i].superInterfaces; + final ReferenceBinding[] bounds = new ReferenceBinding[intfs.length]; + for (int j = 0, len2 = bounds.length; j < len2; j++) { + bounds[j] = (ReferenceBinding)Scope.substitute(sub, intfs[j]); + } + capture.superInterfaces = bounds; + } + + // The upper bound has already been set. Now set the lower bound. + if (wildcard.kind == Wildcard.SUPER) { + capture.lowerBound = wildcard.bound; + } + else if (wildcard.kind == Wildcard.EXTENDS) { + if (wildcard.bound.isArrayType()) + capture.arrayBound = wildcard.bound; + + if (wildcard.bound.isClass()) + capture.firstBound = capture.superclass = (ReferenceBinding)wildcard.bound; + else if (typeParams[i].firstBound != null && typeParams[i].firstBound.isClass()) + capture.firstBound = capture.superclass = typeParams[i].firstBound; + else + capture.superclass = environment.getType(JAVA_LANG_OBJECT); + + int intfs = (wildcard.bound.isInterface() ? 1 : 0) + + typeParams[i].superInterfaces().length; + + if (intfs == 0) + capture.superInterfaces = NoSuperInterfaces; + else { + ReferenceBinding[] interfaces = + Scope.substitute(sub, typeParams[i].superInterfaces); + if (wildcard.bound.isInterface()) { + System.arraycopy(interfaces, 0, interfaces = new ReferenceBinding[intfs], 0, intfs - 1); + interfaces[intfs - 1] = (ReferenceBinding) wildcard.bound; + } + interfaces = Scope.greaterLowerBound(interfaces); + + capture.superInterfaces = interfaces; + if (capture.firstBound == null) + capture.firstBound = interfaces[0]; + } + + } + } + } + + return this.environment().createParameterizedType(this.type, newArgs, this.enclosingType); } /** * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#fieldCount() Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java,v retrieving revision 1.59 diff -u -r1.59 ReferenceBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 2 Feb 2005 11:51:42 -0000 1.59 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 18 Feb 2005 00:33:39 -0000 @@ -625,6 +625,15 @@ } if (otherReferenceType.isInterface()) return implementsInterface(otherReferenceType, true); + + if (otherReferenceType.isTypeVariable()) { + // This handles the case for captured wildcards, For example: + // is assignable from Integer + TypeVariableBinding otherTypeVariable = (TypeVariableBinding) otherReferenceType; + if (otherTypeVariable.lowerBound != null) + return this.isCompatibleWith(otherTypeVariable.lowerBound); + } + if (isInterface()) // Explicit conversion from an interface to a class is not allowed return false; return otherReferenceType.isSuperclassOf(this); Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.172 diff -u -r1.172 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 2 Feb 2005 16:35:11 -0000 1.172 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 18 Feb 2005 00:33:40 -0000 @@ -675,8 +675,26 @@ CompilationUnitScope unitScope = compilationUnitScope(); unitScope.recordTypeReference(receiverType); - if (receiverType.isArrayType()) { - TypeBinding leafType = receiverType.leafComponentType(); + checkArrayField: { + TypeBinding leafType; + switch (receiverType.kind()) { + case Binding.WILDCARD_TYPE : + TypeBinding receiverErasure = receiverType.erasure(); + if (!receiverErasure.isArrayType()) + break checkArrayField; + leafType =receiverErasure.leafComponentType(); + break; + case Binding.ARRAY_TYPE : + leafType = receiverType.leafComponentType(); + break; + case Binding.TYPE_PARAMETER: + leafType = ((TypeVariableBinding)receiverType).arrayBound; + if (leafType == null) + break checkArrayField; + break; + default: + break checkArrayField; + } if (leafType instanceof ReferenceBinding) if (!((ReferenceBinding) leafType).canBeSeenBy(this)) return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ReceiverTypeNotVisible); @@ -2467,11 +2485,44 @@ return qualifiedType; } + + // 5.1.10 + static public TypeBinding[] greaterLowerBound(TypeBinding[] types) { + if (types == null) return null; + int length = types.length; + TypeBinding[] result = types; + int removed = 0; + for (int i = 0; i < length; i++) { + TypeBinding iType = result[i]; + for (int j = 0; j < length; j++) { + if (i == j) continue; + TypeBinding jType = result[j]; + if (jType == null) continue; + if (iType.isCompatibleWith(jType)) { // if Vi <: Vj, Vj is removed + if (result == types) { // defensive copy + System.arraycopy(result, 0, result = new TypeBinding[length], 0, length); + } + result[j] = null; + removed ++; + } + } + } + if (removed == 0) return result; + TypeBinding[] trimmedResult = new TypeBinding[length - removed]; + for (int i = 0, index = 0; i < length; i++) { + TypeBinding iType = result[i]; + if (iType != null) { + trimmedResult[index++] = iType; + } + } + return trimmedResult; + } + // 5.1.10 - public TypeBinding[] greaterLowerBound(TypeBinding[] types) { + static public ReferenceBinding[] greaterLowerBound(ReferenceBinding[] types) { if (types == null) return null; int length = types.length; - TypeBinding[] result = types; + ReferenceBinding[] result = types; int removed = 0; for (int i = 0; i < length; i++) { TypeBinding iType = result[i]; @@ -2481,7 +2532,7 @@ if (jType == null) continue; if (iType.isCompatibleWith(jType)) { // if Vi <: Vj, Vj is removed if (result == types) { // defensive copy - System.arraycopy(result, 0, result = new TypeBinding[length], 0, length); + System.arraycopy(result, 0, result = new ReferenceBinding[length], 0, length); } result[j] = null; removed ++; @@ -2489,9 +2540,9 @@ } } if (removed == 0) return result; - TypeBinding[] trimmedResult = new TypeBinding[length - removed]; + ReferenceBinding[] trimmedResult = new ReferenceBinding[length - removed]; for (int i = 0, index = 0; i < length; i++) { - TypeBinding iType = result[i]; + ReferenceBinding iType = result[i]; if (iType != null) { trimmedResult[index++] = iType; } @@ -2801,7 +2852,7 @@ case 0: return NoTypes; case 1: return types; } - + // record all supertypes of type // intersect with all supertypes of otherType TypeBinding firstType = types[indexOfFirst]; @@ -2824,15 +2875,25 @@ }; } else { ArrayList typesToVisit = new ArrayList(5); - if (firstType.erasure() != firstType) { + TypeBinding firstErasure = firstType.erasure(); + if (firstErasure != firstType) { Set someInvocations = new HashSet(1); someInvocations.add(firstType); - allInvocations.put(firstType.erasure(), someInvocations); - } - typesToVisit.add(firstType.erasure()); + allInvocations.put(firstErasure, someInvocations); + } + typesToVisit.add(firstErasure); + int max = 1; + if (firstErasure.isArrayType()) { + typesToVisit.add(getJavaIoSerializable()); + typesToVisit.add(getJavaLangCloneable()); + typesToVisit.add(getJavaLangObject()); + max += 3; + } ReferenceBinding currentType = (ReferenceBinding)firstType; - for (int i = 0, max = 1; i < max; i++) { - currentType = (ReferenceBinding) typesToVisit.get(i); + for (int i = 0; i < max; i++) { + TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i); + if (typeToVisit.isArrayType()) continue; + currentType = (ReferenceBinding) typeToVisit; // inject super interfaces prior to superclass ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); for (int j = 0, count = itsInterfaces.length; j < count; j++) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java,v retrieving revision 1.41 diff -u -r1.41 TypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java 28 Jan 2005 15:44:53 -0000 1.41 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java 18 Feb 2005 00:33:40 -0000 @@ -106,6 +106,12 @@ public TypeBinding erasure() { return this; } + +/** Returns the type of this type after performing Capture Conversion(5.1.10) */ +public TypeBinding capture() { + return this; +} + /** * Returns the type to use for generic cast, or null if none required */ Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java,v retrieving revision 1.33 diff -u -r1.33 TypeConstants.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 27 Jan 2005 10:46:40 -0000 1.33 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 18 Feb 2005 00:33:40 -0000 @@ -67,6 +67,7 @@ char[] UPPER_LOCAL_VARIABLE = "LOCAL_VARIABLE".toCharArray(); //$NON-NLS-1$ char[] UPPER_ANNOTATION_TYPE = "ANNOTATION_TYPE".toCharArray(); //$NON-NLS-1$ char[] UPPER_PACKAGE = "PACKAGE".toCharArray(); //$NON-NLS-1$ + char[] CAPTURE_OF = "capture of ".toCharArray(); //$NON-NLS-1$ // Constant compound names char[][] JAVA_LANG = {JAVA, LANG}; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java,v retrieving revision 1.21 diff -u -r1.21 TypeVariableBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 14 Jan 2005 12:30:11 -0000 1.21 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 18 Feb 2005 00:33:40 -0000 @@ -33,6 +33,19 @@ public ReferenceBinding[] superInterfaces; public char[] genericTypeSignature; + /** + * The lower bound of this type variable. Declared type variables never have + * lower bounds. Only wildcard captures have lower bounds. + */ + public TypeBinding lowerBound; + + /** + * The upper array bound of this type variable. Only captured wildcards + * can have an array type as an upper bound. + */ + public TypeBinding arrayBound; + + public TypeVariableBinding(char[] sourceName, Binding declaringElement, int rank) { this.sourceName = sourceName; this.declaringElement = declaringElement; @@ -133,6 +146,9 @@ * p.X { ... } --> Lp/X;:TT; */ public char[] computeUniqueKey() { + // TODO: for captured wildcards declaring element is null. Is this the right thing to do? + if (this.declaringElement == null) return genericTypeSignature(); + char[] declaringKey = this.declaringElement.computeUniqueKey(); int declaringLength = declaringKey.length; char[] sig = genericTypeSignature(); @@ -290,6 +306,14 @@ return true; } + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isCompatibleWith(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) + */ + public boolean isCompatibleWith(TypeBinding otherType) { + return (this.arrayBound != null && this.arrayBound.isCompatibleWith(otherType)) || + super.isCompatibleWith(otherType); + } + /** * Returns the original type variable for a given variable. * Only different from receiver for type variables of generic methods of parameterized types @@ -352,7 +376,8 @@ } public ReferenceBinding[] superInterfaces() { return superInterfaces; - } + } + /** * @see java.lang.Object#toString() */