View | Details | Raw Unified | Return to bug 202404 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java (-3 / +6 lines)
Lines 66-73 Link Here
66
			boolean hasErrors = false;
66
			boolean hasErrors = false;
67
			TypeVariableBinding[] typeVariables = this.type.typeVariables();
67
			TypeVariableBinding[] typeVariables = this.type.typeVariables();
68
			if (this.arguments != null && typeVariables != null) { // arguments may be null in error cases
68
			if (this.arguments != null && typeVariables != null) { // arguments may be null in error cases
69
				// JLS 4.5 - need to perform capture conversion before attempting to check bound compatibility
70
				ParameterizedTypeBinding capturedParamType = (ParameterizedTypeBinding) this.capture(null /* no scope */, 0 /*use rank as a dummy position*/);
69
				for (int i = 0, length = typeVariables.length; i < length; i++) {
71
				for (int i = 0, length = typeVariables.length; i < length; i++) {
70
				    if (typeVariables[i].boundCheck(this, this.arguments[i])  != TypeConstants.OK) {
72
				    if (typeVariables[i].boundCheck(capturedParamType, capturedParamType.arguments[i])  != TypeConstants.OK) {
71
				    	hasErrors = true;
73
				    	hasErrors = true;
72
						scope.problemReporter().typeMismatchError(this.arguments[i], typeVariables[i], this.type, argumentReferences[i]);
74
						scope.problemReporter().typeMismatchError(this.arguments[i], typeVariables[i], this.type, argumentReferences[i]);
73
				    }
75
				    }
Lines 85-90 Link Here
85
	/**
87
	/**
86
	 * Perform capture conversion for a parameterized type with wildcard arguments
88
	 * Perform capture conversion for a parameterized type with wildcard arguments
87
	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture(Scope,int)
89
	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture(Scope,int)
90
	 * @param scope - may be null
88
	 */
91
	 */
89
	public TypeBinding capture(Scope scope, int position) {
92
	public TypeBinding capture(Scope scope, int position) {
90
		if ((this.tagBits & TagBits.HasDirectWildcard) == 0) 
93
		if ((this.tagBits & TagBits.HasDirectWildcard) == 0) 
Lines 95-107 Link Here
95
		TypeBinding[] capturedArguments = new TypeBinding[length];
98
		TypeBinding[] capturedArguments = new TypeBinding[length];
96
		
99
		
97
		// Retrieve the type context for capture bindingKey
100
		// Retrieve the type context for capture bindingKey
98
		ReferenceBinding contextType = scope.enclosingSourceType();
101
		ReferenceBinding contextType = scope == null ? null : scope.enclosingSourceType();
99
		if (contextType != null) contextType = contextType.outermostEnclosingType(); // maybe null when used programmatically by DOM
102
		if (contextType != null) contextType = contextType.outermostEnclosingType(); // maybe null when used programmatically by DOM
100
		
103
		
101
		for (int i = 0; i < length; i++) {
104
		for (int i = 0; i < length; i++) {
102
			TypeBinding argument = originalArguments[i];
105
			TypeBinding argument = originalArguments[i];
103
			if (argument.kind() == Binding.WILDCARD_TYPE && ((WildcardBinding)argument).otherBounds == null) { // no capture for intersection types
106
			if (argument.kind() == Binding.WILDCARD_TYPE && ((WildcardBinding)argument).otherBounds == null) { // no capture for intersection types
104
				capturedArguments[i] = new CaptureBinding((WildcardBinding) argument, contextType, position, scope.compilationUnitScope().nextCaptureID());
107
				capturedArguments[i] = new CaptureBinding((WildcardBinding) argument, contextType, position, scope == null ? position : scope.compilationUnitScope().nextCaptureID());
105
			} else {
108
			} else {
106
				capturedArguments[i] = argument;
109
				capturedArguments[i] = argument;
107
			}
110
			}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java (-12 / +11 lines)
Lines 228-233 Link Here
228
		switch (originalType.kind()) {
228
		switch (originalType.kind()) {
229
			
229
			
230
			case Binding.TYPE_PARAMETER:
230
			case Binding.TYPE_PARAMETER:
231
				if (originalType.isCapture()) {
232
//			        CaptureBinding capture = (CaptureBinding) originalType;
233
//			        WildcardBinding originalWildcard = capture.wildcard;
234
//			        TypeBinding substitutedWildcard = substitute(substitution, originalWildcard);
235
//			        if (substitutedWildcard != originalWildcard) {
236
//			        	CaptureBinding substitutedCapture = new CaptureBinding((WildcardBinding)substitutedWildcard, capture.sourceType, capture.position, capture.captureID);
237
//			        	substitutedCapture.initializeBounds(((SourceTypeBinding)capture.sourceType).scope, (ParameterizedTypeBinding)substitution);
238
//			        	return substitutedCapture;
239
//			        }
240
			        break;   
241
				}
231
				return substitution.substitute((TypeVariableBinding) originalType);
242
				return substitution.substitute((TypeVariableBinding) originalType);
232
				
243
				
233
			case Binding.PARAMETERIZED_TYPE:
244
			case Binding.PARAMETERIZED_TYPE:
Lines 246-263 Link Here
246
					substitutedArguments = substitute(substitution, originalArguments);
257
					substitutedArguments = substitute(substitution, originalArguments);
247
				}
258
				}
248
				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
259
				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
249
//					identicalVariables: { // if substituted with original variables, then answer the generic type itself
250
//						if (substitutedEnclosing != null) {
251
//							//if (!(substitutedEnclosing instanceof SourceTypeBinding)) break identicalVariables;
252
//							if (substitutedEnclosing != originalEnclosing) break identicalVariables;						
253
//						}
254
//						if (originalParameterizedType.type.isBinaryBinding()) break identicalVariables; // generic binary is never used as is, see 85262
255
//						TypeVariableBinding[] originalVariables = originalParameterizedType.type.typeVariables();
256
//						for (int i = 0, length = originalVariables.length; i < length; i++) {
257
//							if (substitutedArguments[i] != originalVariables[i]) break identicalVariables;
258
//						}
259
//						return originalParameterizedType.type;
260
//					}
261
					return originalParameterizedType.environment.createParameterizedType(
260
					return originalParameterizedType.environment.createParameterizedType(
262
							originalParameterizedType.genericType(), substitutedArguments, substitutedEnclosing);
261
							originalParameterizedType.genericType(), substitutedArguments, substitutedEnclosing);
263
				}
262
				}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java (+1 lines)
Lines 98-103 Link Here
98
98
99
/**
99
/**
100
 * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
100
 * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
101
 * @param scope - may be null
101
 */
102
 */
102
public TypeBinding capture(Scope scope, int position) {
103
public TypeBinding capture(Scope scope, int position) {
103
	return this;
104
	return this;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java (-48 / +62 lines)
Lines 60-121 Link Here
60
		if (this.superclass == null)
60
		if (this.superclass == null)
61
			return TypeConstants.OK;
61
			return TypeConstants.OK;
62
62
63
		if (argumentType.isWildcard() && !argumentType.isIntersectionType()) {
63
		switch(argumentType.kind()) {
64
			WildcardBinding wildcard = (WildcardBinding) argumentType;
64
			case Binding.TYPE_PARAMETER :
65
			switch(wildcard.boundKind) {
65
				if (argumentType.isCapture()) {
66
				case Wildcard.EXTENDS :
66
					CaptureBinding capture = (CaptureBinding) argumentType;
67
					TypeBinding wildcardBound = wildcard.bound;
67
					if (capture.lowerBound != null) {
68
					if (wildcardBound == this) 
68
						return boundCheck(substitution, capture.lowerBound);
69
					} else if (capture.wildcard.boundKind == Wildcard.UNBOUND) {
69
						return TypeConstants.OK;
70
						return TypeConstants.OK;
70
					ReferenceBinding superclassBound = hasSubstitution ? (ReferenceBinding)Scope.substitute(substitution, this.superclass) : this.superclass;
71
					}
71
					boolean isArrayBound = wildcardBound.isArrayType();
72
				}
72
					if (!wildcardBound.isInterface()) {
73
				break;
73
						if (superclassBound.id != TypeIds.T_JavaLangObject) {
74
			case Binding.WILDCARD_TYPE :
74
							if (isArrayBound) {
75
				if (!argumentType.isIntersectionType()) {
75
								if (!wildcardBound.isCompatibleWith(superclassBound))
76
					WildcardBinding wildcard = (WildcardBinding) argumentType;
76
									return TypeConstants.MISMATCH;
77
					switch(wildcard.boundKind) {
77
							} else {
78
						case Wildcard.EXTENDS :
78
								TypeBinding match = ((ReferenceBinding)wildcardBound).findSuperTypeWithSameErasure(superclassBound);
79
							TypeBinding wildcardBound = wildcard.bound;
79
								if (match != null) {
80
							if (wildcardBound == this) 
80
									if (!match.isIntersectingWith(superclassBound)) {
81
								return TypeConstants.OK;
81
										return TypeConstants.MISMATCH;
82
							ReferenceBinding superclassBound = hasSubstitution ? (ReferenceBinding)Scope.substitute(substitution, this.superclass) : this.superclass;
83
							boolean isArrayBound = wildcardBound.isArrayType();
84
							if (!wildcardBound.isInterface()) {
85
								if (superclassBound.id != TypeIds.T_JavaLangObject) {
86
									if (isArrayBound) {
87
										if (!wildcardBound.isCompatibleWith(superclassBound))
88
											return TypeConstants.MISMATCH;
89
									} else {
90
										TypeBinding match = ((ReferenceBinding)wildcardBound).findSuperTypeWithSameErasure(superclassBound);
91
										if (match != null) {
92
											if (!match.isIntersectingWith(superclassBound)) {
93
												return TypeConstants.MISMATCH;
94
											}
95
										} else {
96
											return TypeConstants.MISMATCH;
97
										}
82
									}
98
									}
83
								} else {
84
									return TypeConstants.MISMATCH;
85
								}
99
								}
86
							}
100
							}
87
						}
101
							ReferenceBinding[] superInterfaceBounds = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces) : this.superInterfaces;
88
					}
102
							int length = superInterfaceBounds.length;
89
					ReferenceBinding[] superInterfaceBounds = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces) : this.superInterfaces;
103
							boolean mustImplement = isArrayBound || ((ReferenceBinding)wildcardBound).isFinal();
90
					int length = superInterfaceBounds.length;
104
							for (int i = 0; i < length; i++) {
91
					boolean mustImplement = isArrayBound || ((ReferenceBinding)wildcardBound).isFinal();
105
								TypeBinding superInterfaceBound = superInterfaceBounds[i];
92
					for (int i = 0; i < length; i++) {
106
								if (isArrayBound) {
93
						TypeBinding superInterfaceBound = superInterfaceBounds[i];
107
									if (!wildcardBound.isCompatibleWith(superInterfaceBound))
94
						if (isArrayBound) {
108
											return TypeConstants.MISMATCH;
95
							if (!wildcardBound.isCompatibleWith(superInterfaceBound))
109
								} else {
96
									return TypeConstants.MISMATCH;
110
									TypeBinding match = wildcardBound.findSuperTypeWithSameErasure(superInterfaceBound);
97
						} else {
111
									if (match != null) {
98
							TypeBinding match = wildcardBound.findSuperTypeWithSameErasure(superInterfaceBound);
112
										if (!match.isIntersectingWith(superInterfaceBound)) {
99
							if (match != null) {
113
											return TypeConstants.MISMATCH;
100
								if (!match.isIntersectingWith(superInterfaceBound)) {
114
										}
101
									return TypeConstants.MISMATCH;
115
									} else if (mustImplement) {
116
											return TypeConstants.MISMATCH; // cannot be extended further to satisfy missing bounds
117
									}
102
								}
118
								}
103
							} else if (mustImplement) {
104
									return TypeConstants.MISMATCH; // cannot be extended further to satisfy missing bounds
105
							}
106
						}
107
119
120
							}
121
							break;
122
							
123
						case Wildcard.SUPER :
124
							return boundCheck(substitution, wildcard.bound);
125
							
126
						case Wildcard.UNBOUND :
127
							break;
108
					}
128
					}
109
					break;
129
					return TypeConstants.OK;
110
					
130
				}
111
				case Wildcard.SUPER :
112
					return boundCheck(substitution, wildcard.bound);
113
					
114
				case Wildcard.UNBOUND :
115
					break;
116
			}
117
			return TypeConstants.OK;
118
		}
131
		}
132
119
		boolean unchecked = false;
133
		boolean unchecked = false;
120
		if (this.superclass.id != TypeIds.T_JavaLangObject) {
134
		if (this.superclass.id != TypeIds.T_JavaLangObject) {
121
			TypeBinding superType = this.superclass;
135
			TypeBinding superType = this.superclass;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java (-3 / +13 lines)
Lines 79-84 Link Here
79
	/**
79
	/**
80
	 * Initialize capture bounds using substituted supertypes
80
	 * Initialize capture bounds using substituted supertypes
81
	 * e.g. given X<U, V extends X<U, V>>,     capture(X<E,?>) = X<E,capture>, where capture extends X<E,capture>
81
	 * e.g. given X<U, V extends X<U, V>>,     capture(X<E,?>) = X<E,capture>, where capture extends X<E,capture>
82
	 * @param scope - may be null
82
	 */
83
	 */
83
	public void initializeBounds(Scope scope, ParameterizedTypeBinding capturedParameterizedType) {
84
	public void initializeBounds(Scope scope, ParameterizedTypeBinding capturedParameterizedType) {
84
		TypeVariableBinding wildcardVariable = wildcard.typeVariable();
85
		TypeVariableBinding wildcardVariable = wildcard.typeVariable();
Lines 101-107 Link Here
101
		switch (wildcard.boundKind) {
102
		switch (wildcard.boundKind) {
102
			case Wildcard.EXTENDS :
103
			case Wildcard.EXTENDS :
103
				// still need to capture bound supertype as well so as not to expose wildcards to the outside (111208)
104
				// still need to capture bound supertype as well so as not to expose wildcards to the outside (111208)
104
				TypeBinding substitutedWildcardBound = originalWildcardBound.capture(scope, this.position);
105
				TypeBinding capturedWildcardBound = originalWildcardBound.capture(scope, this.position);
106
				TypeBinding substitutedWildcardBound = Scope.substitute(capturedParameterizedType, capturedWildcardBound);
105
				if (wildcard.bound.isInterface()) {
107
				if (wildcard.bound.isInterface()) {
106
					this.superclass = substitutedVariableSuperclass;
108
					this.superclass = substitutedVariableSuperclass;
107
					// merge wildcard bound into variable superinterfaces using glb
109
					// merge wildcard bound into variable superinterfaces using glb
Lines 114-121 Link Here
114
						this.superInterfaces = Scope.greaterLowerBound(substitutedVariableInterfaces);
116
						this.superInterfaces = Scope.greaterLowerBound(substitutedVariableInterfaces);
115
					}
117
					}
116
				} else {
118
				} else {
117
					// per construction the wildcard bound is a subtype of variable superclass
119
					// the wildcard bound should be a subtype of variable superclass
118
					this.superclass = wildcard.bound.isArrayType() ? substitutedVariableSuperclass : (ReferenceBinding) substitutedWildcardBound;
120
					// it may occur that the bound is less specific, then consider glb (202404)
121
					if (substitutedWildcardBound.isArrayType() || substitutedWildcardBound == this) {
122
						this.superclass = substitutedVariableSuperclass;
123
					} else {
124
						this.superclass = (ReferenceBinding) substitutedWildcardBound;
125
						if (this.superclass.isSuperclassOf(substitutedVariableSuperclass)) {
126
							this.superclass = substitutedVariableSuperclass;
127
						}
128
					}
119
					this.superInterfaces = substitutedVariableInterfaces;
129
					this.superInterfaces = substitutedVariableInterfaces;
120
				}
130
				}
121
				this.firstBound =  substitutedWildcardBound;
131
				this.firstBound =  substitutedWildcardBound;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (-2 / +2 lines)
Lines 111-118 Link Here
111
	this.subscopes[this.subscopeCount++] = childScope;
111
	this.subscopes[this.subscopeCount++] = childScope;
112
}
112
}
113
113
114
/* Answer true if the receiver is suitable for assigning final blank fields.
114
/* 
115
 *
115
 * Answer true if the receiver is suitable for assigning final blank fields.
116
 * in other words, it is inside an initializer, a constructor or a clinit 
116
 * in other words, it is inside an initializer, a constructor or a clinit 
117
 */
117
 */
118
public final boolean allowBlankFinalFieldAssignment(FieldBinding binding) {
118
public final boolean allowBlankFinalFieldAssignment(FieldBinding binding) {

Return to bug 202404