View | Details | Raw Unified | Return to bug 220967
Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java (-1 / +63 lines)
Lines 3692-3695 Link Here
3692
				"}\n",//-----------------------------------------------------------------------
3692
				"}\n",//-----------------------------------------------------------------------
3693
			},
3693
			},
3694
			expected);
3694
			expected);
3695
}}
3695
}
3696
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220967
3697
public void test078() {
3698
	this.runNegativeTest(
3699
			new String[] {
3700
				"X.java", //-----------------------------------------------------------------------
3701
				"import java.util.List;\n" + 
3702
				"interface B {\n" + 
3703
				"  B m(String seq);\n" + 
3704
				"}\n" + 
3705
				"public class X implements B {\n" + 
3706
				"	public Zork m(String arg0) {\n" + 
3707
				"		return null;\n" + 
3708
				"	}\n" + 
3709
				"}\n",//-----------------------------------------------------------------------
3710
			},
3711
			"----------\n" + 
3712
			"1. ERROR in X.java (at line 6)\n" + 
3713
			"	public Zork m(String arg0) {\n" + 
3714
			"	       ^^^^\n" + 
3715
			"Zork cannot be resolved to a type\n" + 
3716
			"----------\n");
3717
}
3718
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220967 - variation
3719
public void test079() {
3720
	this.runNegativeTest(
3721
			new String[] {
3722
				"X.java", //-----------------------------------------------------------------------
3723
				"public class X {\n" + 
3724
				"	public Zork m(X x) {\n" + 
3725
				"		return x;\n" + 
3726
				"	}\n" + 
3727
				"}\n",//-----------------------------------------------------------------------
3728
			},
3729
			"----------\n" + 
3730
			"1. ERROR in X.java (at line 2)\n" + 
3731
			"	public Zork m(X x) {\n" + 
3732
			"	       ^^^^\n" + 
3733
			"Zork cannot be resolved to a type\n" + 
3734
			"----------\n");
3735
}
3736
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220967 - variation
3737
public void test080() {
3738
	this.runNegativeTest(
3739
			new String[] {
3740
				"X.java", //-----------------------------------------------------------------------
3741
				"import java.util.List;\n" + 
3742
				"interface B {\n" + 
3743
				"  void m() throws Exception;\n" + 
3744
				"}\n" + 
3745
				"public class X implements B {\n" + 
3746
				"	public void m() throws IOException {\n" + 
3747
				"	}\n" + 
3748
				"}\n",//-----------------------------------------------------------------------
3749
			},
3750
			"----------\n" + 
3751
			"1. ERROR in X.java (at line 6)\n" + 
3752
			"	public void m() throws IOException {\n" + 
3753
			"	                       ^^^^^^^^^^^\n" + 
3754
			"IOException cannot be resolved to a type\n" + 
3755
			"----------\n");
3756
}
3757
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-2 / +34 lines)
Lines 166-174 Link Here
166
				currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
166
				currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
167
			}
167
			}
168
	
168
	
169
			if (!areReturnTypesCompatible(currentMethod, inheritedMethod))
169
			if (!areReturnTypesCompatible(currentMethod, inheritedMethod)
170
					&& (currentMethod.returnType.tagBits & TagBits.HasMissingType) == 0) {
170
				if (reportIncompatibleReturnTypeError(currentMethod, inheritedMethod))
171
				if (reportIncompatibleReturnTypeError(currentMethod, inheritedMethod))
171
					continue nextMethod;
172
					continue nextMethod;
173
			}
172
	
174
	
173
			if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS)
175
			if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS)
174
				checkExceptions(currentMethod, inheritedMethod);
176
				checkExceptions(currentMethod, inheritedMethod);
Lines 192-197 Link Here
192
		checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
194
		checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
193
	}
195
	}
194
}
196
}
197
195
void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
198
void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
196
	// Remember that interfaces can only define public instance methods
199
	// Remember that interfaces can only define public instance methods
197
	if (concreteMethod.isStatic())
200
	if (concreteMethod.isStatic())
Lines 213-218 Link Here
213
		for (int i = abstractMethods.length; --i >= 0;)
216
		for (int i = abstractMethods.length; --i >= 0;)
214
			checkExceptions(concreteMethod, abstractMethods[i]);
217
			checkExceptions(concreteMethod, abstractMethods[i]);
215
}
218
}
219
216
/*
220
/*
217
"8.4.4"
221
"8.4.4"
218
Verify that newExceptions are all included in inheritedExceptions.
222
Verify that newExceptions are all included in inheritedExceptions.
Lines 227-239 Link Here
227
		int j = inheritedExceptions.length;
231
		int j = inheritedExceptions.length;
228
		while (--j > -1 && !isSameClassOrSubclassOf(newException, inheritedExceptions[j])){/*empty*/}
232
		while (--j > -1 && !isSameClassOrSubclassOf(newException, inheritedExceptions[j])){/*empty*/}
229
		if (j == -1)
233
		if (j == -1)
230
			if (!newException.isUncheckedException(false))
234
			if (!newException.isUncheckedException(false)
235
					&& (newException.tagBits & TagBits.HasMissingType) == 0) {
231
				problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
236
				problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
237
			}
232
	}
238
	}
233
}
239
}
240
234
void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) {
241
void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) {
235
	// no op before 1.5
242
	// no op before 1.5
236
}
243
}
244
237
void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
245
void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
238
	if (superInterfaces == Binding.NO_SUPERINTERFACES) return;
246
	if (superInterfaces == Binding.NO_SUPERINTERFACES) return;
239
247
Lines 295-300 Link Here
295
		}
303
		}
296
	}
304
	}
297
}
305
}
306
298
void checkInheritedMethods(MethodBinding[] methods, int length) {
307
void checkInheritedMethods(MethodBinding[] methods, int length) {
299
	if (length > 1) {
308
	if (length > 1) {
300
		int[] overriddenInheritedMethods = findOverriddenInheritedMethods(methods, length);
309
		int[] overriddenInheritedMethods = findOverriddenInheritedMethods(methods, length);
Lines 349-354 Link Here
349
		checkConcreteInheritedMethod(concreteMethod, abstractMethods);
358
		checkConcreteInheritedMethod(concreteMethod, abstractMethods);
350
	}
359
	}
351
}
360
}
361
352
boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) {
362
boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) {
353
	MethodBinding first = methods[0];
363
	MethodBinding first = methods[0];
354
	int index = length;
364
	int index = length;
Lines 447-452 Link Here
447
		}
457
		}
448
	}
458
	}
449
}
459
}
460
450
void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) {
461
void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) {
451
	// check that the inherited abstract method (package private visibility) is implemented within the same package
462
	// check that the inherited abstract method (package private visibility) is implemented within the same package
452
	PackageBinding necessaryPackage = abstractMethod.declaringClass.fPackage;
463
	PackageBinding necessaryPackage = abstractMethod.declaringClass.fPackage;
Lines 473-478 Link Here
473
	// non visible abstract methods cannot be overridden so the type must be defined abstract
484
	// non visible abstract methods cannot be overridden so the type must be defined abstract
474
	problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
485
	problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
475
}
486
}
487
476
void computeInheritedMethods() {
488
void computeInheritedMethods() {
477
	ReferenceBinding superclass = this.type.isInterface()
489
	ReferenceBinding superclass = this.type.isInterface()
478
		? this.type.scope.getJavaLangObject() // check interface methods against Object
490
		? this.type.scope.getJavaLangObject() // check interface methods against Object
Lines 480-485 Link Here
480
	computeInheritedMethods(superclass, type.superInterfaces());
492
	computeInheritedMethods(superclass, type.superInterfaces());
481
	checkForRedundantSuperinterfaces(superclass, type.superInterfaces());
493
	checkForRedundantSuperinterfaces(superclass, type.superInterfaces());
482
}
494
}
495
483
/*
496
/*
484
Binding creation is responsible for reporting:
497
Binding creation is responsible for reporting:
485
	- all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations)
498
	- all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations)
Lines 629-634 Link Here
629
		}
642
		}
630
	}
643
	}
631
}
644
}
645
632
void computeMethods() {
646
void computeMethods() {
633
	MethodBinding[] methods = type.methods();
647
	MethodBinding[] methods = type.methods();
634
	int size = methods.length;
648
	int size = methods.length;
Lines 647-657 Link Here
647
		}
661
		}
648
	}
662
	}
649
}
663
}
664
650
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
665
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
651
	if (inheritedMethod == null) return null;
666
	if (inheritedMethod == null) return null;
652
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
667
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
653
	return inheritedMethod;
668
	return inheritedMethod;
654
}
669
}
670
655
boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
671
boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
656
	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
672
	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
657
		return false;
673
		return false;
Lines 669-674 Link Here
669
	}
685
	}
670
	return true;
686
	return true;
671
}
687
}
688
672
// Answer whether the method overrides the inheritedMethod
689
// Answer whether the method overrides the inheritedMethod
673
// Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass
690
// Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass
674
// See isMethodSubsignature() for parameter comparisons
691
// See isMethodSubsignature() for parameter comparisons
Lines 683-691 Link Here
683
700
684
	return isParameterSubsignature(method, inheritedMethod);
701
	return isParameterSubsignature(method, inheritedMethod);
685
}
702
}
703
686
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
704
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
687
	return null; // noop in 1.4
705
	return null; // noop in 1.4
688
}
706
}
707
689
int[] findOverriddenInheritedMethods(MethodBinding[] methods, int length) {
708
int[] findOverriddenInheritedMethods(MethodBinding[] methods, int length) {
690
	// NOTE assumes length > 1
709
	// NOTE assumes length > 1
691
	// inherited methods are added as we walk up the superclass hierarchy, then each superinterface
710
	// inherited methods are added as we walk up the superclass hierarchy, then each superinterface
Lines 736-741 Link Here
736
	}
755
	}
737
	return toSkip;
756
	return toSkip;
738
}
757
}
758
739
boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) {
759
boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) {
740
	if (inheritedMethod.modifiers == newMethod.modifiers) return true;
760
	if (inheritedMethod.modifiers == newMethod.modifiers) return true;
741
761
Lines 747-769 Link Here
747
767
748
	return !newMethod.isPrivate();		// The inheritedMethod cannot be private since it would not be visible
768
	return !newMethod.isPrivate();		// The inheritedMethod cannot be private since it would not be visible
749
}
769
}
770
750
boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
771
boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
751
	// skip interface method with the same signature if visible to its declaringClass
772
	// skip interface method with the same signature if visible to its declaringClass
752
	return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true);
773
	return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true);
753
}
774
}
775
754
public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
776
public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
755
	return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
777
	return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
756
		&& isParameterSubsignature(method, inheritedMethod);
778
		&& isParameterSubsignature(method, inheritedMethod);
757
}
779
}
780
758
boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
781
boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
759
	return areParametersEqual(method, inheritedMethod);
782
	return areParametersEqual(method, inheritedMethod);
760
}
783
}
784
761
boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
785
boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
762
	do {
786
	do {
763
		if (testClass == superclass) return true;
787
		if (testClass == superclass) return true;
764
	} while ((testClass = testClass.superclass()) != null);
788
	} while ((testClass = testClass.superclass()) != null);
765
	return false;
789
	return false;
766
}
790
}
791
767
boolean mustImplementAbstractMethod(ReferenceBinding declaringClass) {
792
boolean mustImplementAbstractMethod(ReferenceBinding declaringClass) {
768
	// if the type's superclass is an abstract class, then all abstract methods must be implemented
793
	// if the type's superclass is an abstract class, then all abstract methods must be implemented
769
	// otherwise, skip it if the type's superclass must implement any of the inherited methods
794
	// otherwise, skip it if the type's superclass must implement any of the inherited methods
Lines 782-799 Link Here
782
	}
807
	}
783
	return superclass.isAbstract();		// if it is a concrete class then we have already reported problem against it
808
	return superclass.isAbstract();		// if it is a concrete class then we have already reported problem against it
784
}
809
}
810
785
boolean mustImplementAbstractMethods() {
811
boolean mustImplementAbstractMethods() {
786
	return !this.type.isInterface() && !this.type.isAbstract();
812
	return !this.type.isInterface() && !this.type.isAbstract();
787
}
813
}
814
788
ProblemReporter problemReporter() {
815
ProblemReporter problemReporter() {
789
	return this.type.scope.problemReporter();
816
	return this.type.scope.problemReporter();
790
}
817
}
818
791
ProblemReporter problemReporter(MethodBinding currentMethod) {
819
ProblemReporter problemReporter(MethodBinding currentMethod) {
792
	ProblemReporter reporter = problemReporter();
820
	ProblemReporter reporter = problemReporter();
793
	if (currentMethod.declaringClass == type && currentMethod.sourceMethod() != null)	// only report against the currentMethod if its implemented by the type
821
	if (currentMethod.declaringClass == type && currentMethod.sourceMethod() != null)	// only report against the currentMethod if its implemented by the type
794
		reporter.referenceContext = currentMethod.sourceMethod();
822
		reporter.referenceContext = currentMethod.sourceMethod();
795
	return reporter;
823
	return reporter;
796
}
824
}
825
797
/**
826
/**
798
 * Return true and report an incompatibleReturnType error if currentMethod's
827
 * Return true and report an incompatibleReturnType error if currentMethod's
799
 * return type is strictly incompatible with inheritedMethod's, else return 
828
 * return type is strictly incompatible with inheritedMethod's, else return 
Lines 808-813 Link Here
808
	problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
837
	problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
809
	return true;
838
	return true;
810
}
839
}
840
811
ReferenceBinding[] resolvedExceptionTypesFor(MethodBinding method) {
841
ReferenceBinding[] resolvedExceptionTypesFor(MethodBinding method) {
812
	ReferenceBinding[] exceptions = method.thrownExceptions;
842
	ReferenceBinding[] exceptions = method.thrownExceptions;
813
	if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
843
	if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
Lines 820-831 Link Here
820
		exceptions[i] = BinaryTypeBinding.resolveType(exceptions[i], this.environment, true);
850
		exceptions[i] = BinaryTypeBinding.resolveType(exceptions[i], this.environment, true);
821
	return exceptions;
851
	return exceptions;
822
}
852
}
853
823
void verify(SourceTypeBinding someType) {
854
void verify(SourceTypeBinding someType) {
824
	this.type = someType;
855
	this.type = someType;
825
	computeMethods();
856
	computeMethods();
826
	computeInheritedMethods();
857
	computeInheritedMethods();
827
	checkMethods();
858
	checkMethods();
828
}
859
}
860
829
public String toString() {
861
public String toString() {
830
	StringBuffer buffer = new StringBuffer(10);
862
	StringBuffer buffer = new StringBuffer(10);
831
	buffer.append("MethodVerifier for type: "); //$NON-NLS-1$
863
	buffer.append("MethodVerifier for type: "); //$NON-NLS-1$
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-1 / +4 lines)
Lines 250-256 Link Here
250
			CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
250
			CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
251
		}			return;
251
		}			return;
252
	}
252
	}
253
	scope.problemReporter().typeMismatchError(expressionType, methodType, this.expression, null);
253
	if ((methodType.tagBits & TagBits.HasMissingType) == 0) {
254
		// no need to complain if return type was missing (avoid secondary error : 220967)
255
		scope.problemReporter().typeMismatchError(expressionType, methodType, this.expression, null);
256
	}
254
}
257
}
255
258
256
public void traverse(ASTVisitor visitor, BlockScope scope) {
259
public void traverse(ASTVisitor visitor, BlockScope scope) {

Return to bug 220967