Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v retrieving revision 1.94 diff -u -r1.94 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 22 Apr 2006 17:45:42 -0000 1.94 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 2 May 2006 16:55:00 -0000 @@ -500,13 +500,9 @@ int[] toSkip = null; if (iMethods != null) { total = initialTotal = iMethods.length; - boolean keepBridgeMethods = sourceLevel < ClassFileConstants.JDK1_5 - && this.environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5; for (int i = total; --i >= 0;) { IBinaryMethod method = iMethods[i]; if ((method.getModifiers() & ClassFileConstants.AccSynthetic) != 0) { - if (keepBridgeMethods && (method.getModifiers() & ClassFileConstants.AccBridge) != 0) - continue; // want to see bridge methods as real methods // discard synthetics methods if (toSkip == null) toSkip = new int[iMethods.length]; toSkip[i] = -1; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java,v retrieving revision 1.58 diff -u -r1.58 MethodVerifier15.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 28 Apr 2006 14:53:28 -0000 1.58 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 2 May 2006 16:55:00 -0000 @@ -41,30 +41,7 @@ return true; } boolean areReturnTypesEqual(MethodBinding one, MethodBinding substituteTwo) { - if (one.returnType == substituteTwo.returnType) return true; - - // short is compatible with int, but as far as covariance is concerned, its not - if (one.returnType.isBaseType()) return false; - - if (!one.declaringClass.isInterface()) { - if (one.declaringClass.id == TypeIds.T_JavaLangObject) - return substituteTwo.returnType.isCompatibleWith(one.returnType); // interface methods inherit from Object - return one.returnType.isCompatibleWith(substituteTwo.returnType); - } - - // check for methods from Object, every interface inherits from Object - if (substituteTwo.declaringClass.id == TypeIds.T_JavaLangObject) - return one.returnType.isCompatibleWith(substituteTwo.returnType); - - // both are interfaces, see if they're related - if (one.declaringClass.implementsInterface(substituteTwo.declaringClass, true)) - return one.returnType.isCompatibleWith(substituteTwo.returnType); - if (substituteTwo.declaringClass.implementsInterface(one.declaringClass, true)) - return substituteTwo.returnType.isCompatibleWith(one.returnType); - - // unrelated interfaces... one must be a subtype of the other - return one.returnType.isCompatibleWith(substituteTwo.returnType) - || substituteTwo.returnType.isCompatibleWith(one.returnType); + return areReturnTypesCompatible(one, substituteTwo); } boolean areTypesEqual(TypeBinding one, TypeBinding two) { if (one == two) return true; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java,v retrieving revision 1.76 diff -u -r1.76 MethodVerifier.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 28 Apr 2006 14:53:28 -0000 1.76 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 2 May 2006 16:55:00 -0000 @@ -23,6 +23,7 @@ ReferenceBinding runtimeException; ReferenceBinding errorException; LookupEnvironment environment; + boolean allowCompatibleReturnTypes; /* Binding creation is responsible for reporting all problems with types: - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final) @@ -47,6 +48,9 @@ this.runtimeException = null; this.errorException = null; this.environment = environment; + this.allowCompatibleReturnTypes = + environment.globalOptions.complianceLevel >= org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5 + && environment.globalOptions.sourceLevel < org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5; } boolean areMethodsEqual(MethodBinding one, MethodBinding two) { return doesMethodOverride(one, two) && areReturnTypesEqual(one, two); @@ -63,8 +67,41 @@ if (!areTypesEqual(oneArgs[i], twoArgs[i])) return false; return true; } +boolean areReturnTypesCompatible(MethodBinding one, MethodBinding substituteTwo) { + if (one.returnType == substituteTwo.returnType) return true; + + // short is compatible with int, but as far as covariance is concerned, its not + if (one.returnType.isBaseType()) return false; + + if (!one.declaringClass.isInterface()) { + if (one.declaringClass.id == TypeIds.T_JavaLangObject) + return substituteTwo.returnType.isCompatibleWith(one.returnType); // interface methods inherit from Object + return one.returnType.isCompatibleWith(substituteTwo.returnType); + } + + // check for methods from Object, every interface inherits from Object + if (substituteTwo.declaringClass.id == TypeIds.T_JavaLangObject) + return one.returnType.isCompatibleWith(substituteTwo.returnType); + + // both are interfaces, see if they're related + if (one.declaringClass.implementsInterface(substituteTwo.declaringClass, true)) + return one.returnType.isCompatibleWith(substituteTwo.returnType); + if (substituteTwo.declaringClass.implementsInterface(one.declaringClass, true)) + return substituteTwo.returnType.isCompatibleWith(one.returnType); + + // unrelated interfaces... one must be a subtype of the other + return one.returnType.isCompatibleWith(substituteTwo.returnType) + || substituteTwo.returnType.isCompatibleWith(one.returnType); +} boolean areReturnTypesEqual(MethodBinding one, MethodBinding two) { - return areTypesEqual(one.returnType, two.returnType); + if (areTypesEqual(one.returnType, two.returnType)) return true; + + // when sourceLevel < 1.5 but compliance >= 1.5, allow return types in binaries to be compatible instead of just equal + if (this.allowCompatibleReturnTypes) + if (one.declaringClass instanceof BinaryTypeBinding && two.declaringClass instanceof BinaryTypeBinding) + if (areReturnTypesCompatible(one, two)) + return true; + return false; } boolean areTypesEqual(TypeBinding one, TypeBinding two) { if (one == two) return true;