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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (-3 / +3 lines)
Lines 680-692 Link Here
680
    		value.sourceEnd);
680
    		value.sourceEnd);
681
    }
681
    }
682
}
682
}
683
public void anonymousClassCannotExtendFinalClass(Expression expression, TypeBinding type) {
683
public void anonymousClassCannotExtendFinalClass(TypeReference reference, TypeBinding type) {
684
	this.handle(
684
	this.handle(
685
		IProblem.AnonymousClassCannotExtendFinalClass,
685
		IProblem.AnonymousClassCannotExtendFinalClass,
686
		new String[] {new String(type.readableName())},
686
		new String[] {new String(type.readableName())},
687
		new String[] {new String(type.shortReadableName())},
687
		new String[] {new String(type.shortReadableName())},
688
		expression.sourceStart,
688
		reference.sourceStart,
689
		expression.sourceEnd);
689
		reference.sourceEnd);
690
}
690
}
691
public void argumentTypeCannotBeVoid(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) {
691
public void argumentTypeCannotBeVoid(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, Argument arg) {
692
	String[] arguments = new String[] {new String(methodDecl.selector), new String(arg.name)};
692
	String[] arguments = new String[] {new String(methodDecl.selector), new String(arg.name)};
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java (-57 / +51 lines)
Lines 42-48 Link Here
42
	//qualification may be on both side
42
	//qualification may be on both side
43
	public Expression enclosingInstance;
43
	public Expression enclosingInstance;
44
	public TypeDeclaration anonymousType;
44
	public TypeDeclaration anonymousType;
45
	public ReferenceBinding superTypeBinding;
45
	public ReferenceBinding superclassBinding;
46
	
46
	
47
	public QualifiedAllocationExpression() {
47
	public QualifiedAllocationExpression() {
48
		// for subtypes
48
		// for subtypes
Lines 64-70 Link Here
64
		}
64
		}
65
		
65
		
66
		// check captured variables are initialized in current context (26134)
66
		// check captured variables are initialized in current context (26134)
67
		ReferenceBinding allocatedType = this.superTypeBinding == null ? this.binding.declaringClass : this.superTypeBinding;
67
		ReferenceBinding allocatedType = this.superclassBinding == null ? this.binding.declaringClass : this.superclassBinding; // TODO shouldn't it be #resolvedType ?
68
		checkCapturedLocalInitializationIfNecessary(
68
		checkCapturedLocalInitializationIfNecessary(
69
			(ReferenceBinding) allocatedType.erasure(),
69
			(ReferenceBinding) allocatedType.erasure(),
70
			currentScope, 
70
			currentScope, 
Lines 284-299 Link Here
284
		}
284
		}
285
		if (receiverType == null) {
285
		if (receiverType == null) {
286
			hasError = true;
286
			hasError = true;
287
		} else if (((ReferenceBinding) receiverType).isFinal()) {
288
			if (this.anonymousType != null) {
289
				if (!receiverType.isEnum()) {
290
					scope.problemReporter().anonymousClassCannotExtendFinalClass(this.type, receiverType);
291
					hasError = true;
292
				}
293
			} else if (!receiverType.canBeInstantiated()) {
294
				scope.problemReporter().cannotInstantiate(this.type, receiverType);
295
				return this.resolvedType = receiverType;
296
			}
297
		}
287
		}
298
		// resolve type arguments (for generic constructor call)
288
		// resolve type arguments (for generic constructor call)
299
		if (this.typeArguments != null) {
289
		if (this.typeArguments != null) {
Lines 331-343 Link Here
331
		// limit of fault-tolerance
321
		// limit of fault-tolerance
332
		if (hasError) {
322
		if (hasError) {
333
			if (receiverType instanceof ReferenceBinding) {
323
			if (receiverType instanceof ReferenceBinding) {
324
				ReferenceBinding referenceReceiver = (ReferenceBinding) receiverType;
334
				// record a best guess, for clients who need hint about possible contructor match
325
				// record a best guess, for clients who need hint about possible contructor match
335
				int length = this.arguments  == null ? 0 : this.arguments.length;
326
				int length = this.arguments  == null ? 0 : this.arguments.length;
336
				TypeBinding[] pseudoArgs = new TypeBinding[length];
327
				TypeBinding[] pseudoArgs = new TypeBinding[length];
337
				for (int i = length; --i >= 0;) {
328
				for (int i = length; --i >= 0;) {
338
					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
329
					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
339
				}
330
				}
340
				this.binding = scope.findMethod((ReferenceBinding) receiverType, TypeConstants.INIT, pseudoArgs, this);
331
				this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this);
341
				if (this.binding != null && !this.binding.isValidBinding()) {
332
				if (this.binding != null && !this.binding.isValidBinding()) {
342
					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
333
					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
343
					// record the closest match, for clients who may still need hint about possible method match
334
					// record the closest match, for clients who may still need hint about possible method match
Lines 354-360 Link Here
354
						}
345
						}
355
					}
346
					}
356
				}
347
				}
357
				
348
				if (this.anonymousType != null) {
349
					// insert anonymous type in scope (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210070)
350
					scope.addAnonymousType(this.anonymousType, referenceReceiver);
351
					this.anonymousType.resolve(scope);
352
					return this.resolvedType = this.anonymousType.binding;
353
				}
358
			}
354
			}
359
			return this.resolvedType = receiverType;
355
			return this.resolvedType = receiverType;
360
		}
356
		}
Lines 392-448 Link Here
392
			scope.problemReporter().typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance);
388
			scope.problemReporter().typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance);
393
			return this.resolvedType = receiverType;
389
			return this.resolvedType = receiverType;
394
		}
390
		}
395
391
		ReferenceBinding superType = (ReferenceBinding) receiverType;
396
		if (receiverType.isTypeVariable()) {
392
		if (superType.isTypeVariable()) {
397
			receiverType = new ProblemReferenceBinding(receiverType.sourceName(), (ReferenceBinding)receiverType, ProblemReasons.IllegalSuperTypeVariable);
393
			superType = new ProblemReferenceBinding(superType.sourceName(), superType, ProblemReasons.IllegalSuperTypeVariable);
398
			scope.problemReporter().invalidType(this, receiverType);
394
			scope.problemReporter().invalidType(this, superType);
399
			return null;
395
			return null;
400
		} else if (this.type != null && receiverType.isEnum()) { // tolerate enum constant body
396
		} else if (this.type != null && superType.isEnum()) { // tolerate enum constant body
401
			scope.problemReporter().cannotInstantiate(this.type, receiverType);
397
			scope.problemReporter().cannotInstantiate(this.type, superType);
402
			return this.resolvedType = receiverType;
398
			return this.resolvedType = superType;
403
		}
399
		}
404
		// anonymous type scenario
400
		// anonymous type scenario
405
		// an anonymous class inherits from java.lang.Object when declared "after" an interface
401
		// an anonymous class inherits from java.lang.Object when declared "after" an interface
406
		this.superTypeBinding = receiverType.isInterface() ? scope.getJavaLangObject() : (ReferenceBinding) receiverType;
402
		this.superclassBinding = superType.isInterface() ? scope.getJavaLangObject() : superType;
407
		// insert anonymous type in scope
403
		// insert anonymous type in scope
408
		scope.addAnonymousType(this.anonymousType, (ReferenceBinding) receiverType);
404
		scope.addAnonymousType(this.anonymousType, superType);
409
		this.anonymousType.resolve(scope);		
405
		this.anonymousType.resolve(scope);	
410
		if (this.superTypeBinding.erasure().id == TypeIds.T_JavaLangEnum) {
406
			
411
			scope.problemReporter().cannotExtendEnum(this.anonymousType.binding, this.type, this.superTypeBinding);
412
		}
413
		
414
		if ((receiverType.tagBits & TagBits.HasDirectWildcard) != 0) {
415
			scope.problemReporter().superTypeCannotUseWildcard(this.anonymousType.binding, this.type, receiverType);
416
		}		
417
		// find anonymous super constructor
407
		// find anonymous super constructor
418
		MethodBinding inheritedBinding = scope.getConstructor(this.superTypeBinding, argumentTypes, this);
408
		this.resolvedType = this.anonymousType.binding; // 1.2 change
419
		if (!inheritedBinding.isValidBinding()) {
409
		if ((this.resolvedType.tagBits & TagBits.HierarchyHasProblems) == 0) {
420
			if (inheritedBinding.declaringClass == null) {
410
			MethodBinding inheritedBinding = scope.getConstructor(this.superclassBinding, argumentTypes, this);
421
				inheritedBinding.declaringClass = this.superTypeBinding;
411
			if (!inheritedBinding.isValidBinding()) {
412
				if (inheritedBinding.declaringClass == null) {
413
					inheritedBinding.declaringClass = this.superclassBinding;
414
				}
415
				scope.problemReporter().invalidConstructor(this, inheritedBinding);
416
				return this.resolvedType;
417
			}
418
			if (this.enclosingInstance != null) {
419
				ReferenceBinding targetEnclosing = inheritedBinding.declaringClass.enclosingType();
420
				if (targetEnclosing == null) {
421
					scope.problemReporter().unnecessaryEnclosingInstanceSpecification(this.enclosingInstance, superType);
422
					return this.resolvedType;
423
				} else if (!enclosingInstanceType.isCompatibleWith(targetEnclosing) && !scope.isBoxingCompatibleWith(enclosingInstanceType, targetEnclosing)) {
424
					scope.problemReporter().typeMismatchError(enclosingInstanceType, targetEnclosing, this.enclosingInstance);
425
					return this.resolvedType;
426
				}
427
				this.enclosingInstance.computeConversion(scope, targetEnclosing, enclosingInstanceType);
428
			}
429
			if (this.arguments != null) {
430
				// TODO shouldn't this.superclassBinding be replaced with superType ?
431
				checkInvocationArguments(scope, null, this.superclassBinding, inheritedBinding, this.arguments, argumentTypes, argsContainCast, this);
422
			}
432
			}
423
			scope.problemReporter().invalidConstructor(this, inheritedBinding);
433
			if (this.typeArguments != null && inheritedBinding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
424
			return this.resolvedType = this.anonymousType.binding;
434
				scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(inheritedBinding, this.genericTypeArguments, this.typeArguments);
435
			}		
436
			// Update the anonymous inner class : superclass, interface  
437
			this.binding = this.anonymousType.createDefaultConstructorWithBinding(inheritedBinding);
425
		}
438
		}
426
		if (this.enclosingInstance != null) {
439
		return this.resolvedType;
427
			ReferenceBinding targetEnclosing = inheritedBinding.declaringClass.enclosingType();
428
			if (targetEnclosing == null) {
429
				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(this.enclosingInstance, (ReferenceBinding)receiverType);
430
				return this.resolvedType = this.anonymousType.binding;
431
			} else if (!enclosingInstanceType.isCompatibleWith(targetEnclosing) && !scope.isBoxingCompatibleWith(enclosingInstanceType, targetEnclosing)) {
432
				scope.problemReporter().typeMismatchError(enclosingInstanceType, targetEnclosing, this.enclosingInstance);
433
				return this.resolvedType = this.anonymousType.binding;
434
			}
435
			this.enclosingInstance.computeConversion(scope, targetEnclosing, enclosingInstanceType);
436
		}
437
		if (this.arguments != null)
438
			checkInvocationArguments(scope, null, this.superTypeBinding, inheritedBinding, this.arguments, argumentTypes, argsContainCast, this);
439
440
		if (this.typeArguments != null && inheritedBinding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
441
			scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(inheritedBinding, this.genericTypeArguments, this.typeArguments);
442
		}		
443
		// Update the anonymous inner class : superclass, interface  
444
		this.binding = this.anonymousType.createDefaultConstructorWithBinding(inheritedBinding);
445
		return this.resolvedType = this.anonymousType.binding; // 1.2 change
446
	}
440
	}
447
	
441
	
448
	public void traverse(ASTVisitor visitor, BlockScope scope) {
442
	public void traverse(ASTVisitor visitor, BlockScope scope) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (-6 / +20 lines)
Lines 38-50 Link Here
38
	}
38
	}
39
	
39
	
40
	void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) {
40
	void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) {
41
		LocalTypeBinding anonymousType = buildLocalType(enclosingType, enclosingType.fPackage);
41
		LocalTypeBinding anonymousType = buildLocalType(enclosingType, supertype, enclosingType.fPackage);
42
		SourceTypeBinding sourceType = referenceContext.binding;
42
		SourceTypeBinding sourceType = referenceContext.binding;
43
		if (supertype.isInterface()) {
43
		if (supertype.isInterface()) {
44
			sourceType.superclass = getJavaLangObject();
44
			sourceType.superclass = getJavaLangObject();
45
			sourceType.superInterfaces = new ReferenceBinding[] { supertype };
45
			sourceType.superInterfaces = new ReferenceBinding[] { supertype };
46
		} else {
46
		} else {
47
			sourceType.superclass = supertype;
47
			if (supertype.erasure().id == TypeIds.T_JavaLangEnum) {
48
				problemReporter().cannotExtendEnum(anonymousType, referenceContext.allocation.type, supertype);
49
				sourceType.tagBits |= TagBits.HierarchyHasProblems;		
50
				sourceType.superclass = getJavaLangObject();
51
			} else if (supertype.isFinal()) {
52
				problemReporter().anonymousClassCannotExtendFinalClass(referenceContext.allocation.type, supertype);
53
				sourceType.tagBits |= TagBits.HierarchyHasProblems;		
54
				sourceType.superclass = getJavaLangObject();
55
			} else if ((supertype.tagBits & TagBits.HasDirectWildcard) != 0) {
56
				problemReporter().superTypeCannotUseWildcard(anonymousType, referenceContext.allocation.type, supertype);
57
				sourceType.tagBits |= TagBits.HierarchyHasProblems;		
58
				sourceType.superclass = getJavaLangObject();
59
			} else {
60
				sourceType.superclass = supertype;
61
			}
48
			sourceType.superInterfaces = Binding.NO_SUPERINTERFACES;
62
			sourceType.superInterfaces = Binding.NO_SUPERINTERFACES;
49
		}
63
		}
50
		connectMemberTypes();
64
		connectMemberTypes();
Lines 144-157 Link Here
144
			 ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods();
158
			 ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods();
145
	}
159
	}
146
	
160
	
147
	private LocalTypeBinding buildLocalType(SourceTypeBinding enclosingType, PackageBinding packageBinding) {
161
	private LocalTypeBinding buildLocalType(SourceTypeBinding enclosingType, ReferenceBinding anonymousOriginalSuperType, PackageBinding packageBinding) {
148
	    
162
	    
149
		referenceContext.scope = this;
163
		referenceContext.scope = this;
150
		referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true);
164
		referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true);
151
		referenceContext.initializerScope = new MethodScope(this, referenceContext, false);
165
		referenceContext.initializerScope = new MethodScope(this, referenceContext, false);
152
166
153
		// build the binding or the local type
167
		// build the binding or the local type
154
		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, this.innermostSwitchCase());
168
		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, this.innermostSwitchCase(), anonymousOriginalSuperType);
155
		referenceContext.binding = localType;
169
		referenceContext.binding = localType;
156
		checkAndSetModifiers();
170
		checkAndSetModifiers();
157
		buildTypeVariables();
171
		buildTypeVariables();
Lines 187-193 Link Here
187
					}
201
					}
188
				}
202
				}
189
				ClassScope memberScope = new ClassScope(this, referenceContext.memberTypes[i]);
203
				ClassScope memberScope = new ClassScope(this, referenceContext.memberTypes[i]);
190
				LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, packageBinding);
204
				LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, null /* anonymous super type*/, packageBinding);
191
				memberBinding.setAsMemberType();
205
				memberBinding.setAsMemberType();
192
				memberTypeBindings[count++] = memberBinding;
206
				memberTypeBindings[count++] = memberBinding;
193
			}
207
			}
Lines 200-206 Link Here
200
	
214
	
201
	void buildLocalTypeBinding(SourceTypeBinding enclosingType) {
215
	void buildLocalTypeBinding(SourceTypeBinding enclosingType) {
202
216
203
		LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage);
217
		LocalTypeBinding localType = buildLocalType(enclosingType, null /* anonymous super type*/, enclosingType.fPackage);
204
		connectTypeHierarchy();
218
		connectTypeHierarchy();
205
		buildFieldsAndMethods();
219
		buildFieldsAndMethods();
206
		localType.faultInTypesForFieldsAndMethods();
220
		localType.faultInTypesForFieldsAndMethods();
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java (-19 / +12 lines)
Lines 22-44 Link Here
22
	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
22
	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
23
	public int sourceStart; // used by computeUniqueKey to uniquely identify this binding
23
	public int sourceStart; // used by computeUniqueKey to uniquely identify this binding
24
	public MethodBinding enclosingMethod;
24
	public MethodBinding enclosingMethod;
25
	public ReferenceBinding anonymousOriginalSuperType;
25
	
26
	
26
public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase) {
27
public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase, ReferenceBinding anonymousOriginalSuperType) {
27
	super(
28
	super(
28
		new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)},
29
		new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)},
29
		scope,
30
		scope,
30
		enclosingType);
31
		enclosingType);
31
	
32
	
32
	if (this.sourceName == CharOperation.NO_CHAR)
33
	if (anonymousOriginalSuperType != null) {
33
		this.tagBits |= TagBits.AnonymousTypeMask;
34
		this.tagBits |= TagBits.AnonymousTypeMask;
34
	else
35
		this.anonymousOriginalSuperType = anonymousOriginalSuperType;
36
	} else {
35
		this.tagBits |= TagBits.LocalTypeMask;
37
		this.tagBits |= TagBits.LocalTypeMask;
38
	}
36
	this.enclosingCase = switchCase;
39
	this.enclosingCase = switchCase;
37
	this.sourceStart = scope.referenceContext.sourceStart;
40
	this.sourceStart = scope.referenceContext.sourceStart;
38
	MethodScope methodScope = scope.enclosingMethodScope();
41
	MethodScope methodScope = scope.enclosingMethodScope();
39
	AbstractMethodDeclaration declaration = methodScope.referenceMethod();
42
	AbstractMethodDeclaration methodDeclaration = methodScope.referenceMethod();
40
	if (declaration != null) {
43
	if (methodDeclaration != null) {
41
		this.enclosingMethod = declaration.binding;
44
		this.enclosingMethod = methodDeclaration.binding;
42
	}
45
	}
43
}
46
}
44
/* Record a dependency onto a source target type which may be altered
47
/* Record a dependency onto a source target type which may be altered
Lines 126-135 Link Here
126
public char[] readableName() /*java.lang.Object,  p.X<T> */ {
129
public char[] readableName() /*java.lang.Object,  p.X<T> */ {
127
    char[] readableName;
130
    char[] readableName;
128
	if (isAnonymousType()) {
131
	if (isAnonymousType()) {
129
		if (superInterfaces == Binding.NO_SUPERINTERFACES)
132
		readableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType.readableName(), TypeConstants.ANONYM_SUFFIX);
130
			readableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, superclass.readableName(), TypeConstants.ANONYM_SUFFIX);
131
		else
132
			readableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, superInterfaces[0].readableName(), TypeConstants.ANONYM_SUFFIX);
133
	} else if (isMemberType()) {
133
	} else if (isMemberType()) {
134
		readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
134
		readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
135
	} else {
135
	} else {
Lines 154-163 Link Here
154
public char[] shortReadableName() /*Object*/ {
154
public char[] shortReadableName() /*Object*/ {
155
    char[] shortReadableName;
155
    char[] shortReadableName;
156
	if (isAnonymousType()) {
156
	if (isAnonymousType()) {
157
		if (superInterfaces == Binding.NO_SUPERINTERFACES)
157
		shortReadableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType.shortReadableName(), TypeConstants.ANONYM_SUFFIX);
158
			shortReadableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, superclass.shortReadableName(), TypeConstants.ANONYM_SUFFIX);
159
		else
160
			shortReadableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, superInterfaces[0].shortReadableName(), TypeConstants.ANONYM_SUFFIX);
161
	} else if (isMemberType()) {
158
	} else if (isMemberType()) {
162
		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
159
		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
163
	} else {
160
	} else {
Lines 203-213 Link Here
203
}
200
}
204
public char[] sourceName() {
201
public char[] sourceName() {
205
	if (isAnonymousType()) {
202
	if (isAnonymousType()) {
206
		if (superInterfaces == Binding.NO_SUPERINTERFACES)
203
		return CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType.sourceName(), TypeConstants.ANONYM_SUFFIX);
207
			return CharOperation.concat(TypeConstants.ANONYM_PREFIX, superclass.sourceName(), TypeConstants.ANONYM_SUFFIX);
208
		else
209
			return CharOperation.concat(TypeConstants.ANONYM_PREFIX, superInterfaces[0].sourceName(), TypeConstants.ANONYM_SUFFIX);
210
			
211
	} else
204
	} else
212
		return sourceName;
205
		return sourceName;
213
}
206
}

Return to bug 210422