Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 65087 Details for
Bug 184293
Unnecessary inherited method errors reported against subtypes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Proposed patch
patch.txt (text/plain), 30.15 KB, created by
Kent Johnson
on 2007-04-26 14:45:11 EDT
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Kent Johnson
Created:
2007-04-26 14:45:11 EDT
Size:
30.15 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core.tests.compiler >Index: src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java,v >retrieving revision 1.617 >diff -u -r1.617 GenericTypeTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 25 Apr 2007 13:38:39 -0000 1.617 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 26 Apr 2007 18:42:09 -0000 >@@ -31605,12 +31605,7 @@ > "}", // ================= > }, > "----------\n" + >- "1. ERROR in X.java (at line 7)\n" + >- " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + >- " ^^^^^^^^^^^^^^^^\n" + >- "The return type is incompatible with ILinkViewElement.getViewer(), AbstractEditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + >- "----------\n" + >- "2. ERROR in X.java (at line 11)\n" + >+ "1. ERROR in X.java (at line 11)\n" + > " public SheetViewer getViewer() { return null; } \n" + > " ^^^^^^^^^^^\n" + > "The return type is incompatible with AbstractEditPart.getViewer()\n" + >Index: src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java,v >retrieving revision 1.126 >diff -u -r1.126 MethodVerifyTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 24 Apr 2007 15:14:02 -0000 1.126 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 26 Apr 2007 18:42:10 -0000 >@@ -708,27 +708,16 @@ > new String[] { > "A.java", > "abstract class A implements I {}\n" + >- "interface I extends J { Object foo(); }\n" + >+ "interface I extends J { Object foo(); }\n" + // with javac only this type gets an error > "interface J { String foo(); }\n", > "X.java", > "abstract class X2 extends A implements J {}\n" > }, > "----------\n" + >- "1. ERROR in A.java (at line 1)\n" + >- " abstract class A implements I {}\n" + >- " ^\n" + >- "The return type is incompatible with J.foo(), I.foo()\n" + >- "----------\n" + >- "2. ERROR in A.java (at line 2)\n" + >+ "1. ERROR in A.java (at line 2)\n" + > " interface I extends J { Object foo(); }\n" + > " ^^^^^^\n" + > "The return type is incompatible with J.foo()\n" + >- "----------\n" + >- "----------\n" + >- "1. ERROR in X.java (at line 1)\n" + >- " abstract class X2 extends A implements J {}\n" + >- " ^^\n" + >- "The return type is incompatible with I.foo(), J.foo()\n" + > "----------\n" > ); > } >@@ -7592,4 +7581,180 @@ > "----------\n" > ); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test134() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "interface I {\n" + >+ " <T extends Exception & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " A foo(Number n);\n" + // warning: overrides <T>foo(java.lang.Number) in I; return type requires unchecked conversion >+ "}\n" + >+ "abstract class A extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 5)\n" + >+ " A foo(Number n);\n" + >+ " ^\n" + >+ "Type safety: The return type A for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >+ "----------\n" >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test135() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "abstract class X implements J {}\n" + >+ "class X2 implements J {\n" + >+ " public A foo(Number n) { return null; }\n" + >+ "}\n" + >+ "abstract class Y extends X {}\n" + >+ "interface I {\n" + >+ " <T extends Exception & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " A foo(Number n);\n" + // warning: overrides <T>foo(java.lang.Number) in I; return type requires unchecked conversion >+ "}\n" + >+ "abstract class A extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 10)\n" + >+ " A foo(Number n);\n" + >+ " ^\n" + >+ "Type safety: The return type A for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >+ "----------\n" >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test136() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public abstract class X extends E {}\n" + >+ "class X2 extends E {\n" + >+ " @Override public A foo(Number n) { return null; }\n" + >+ "}\n" + >+ "abstract class Y extends X {}\n" + >+ "abstract class D {\n" + >+ " abstract <T extends Exception & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "abstract class E extends D {\n" + >+ " @Override abstract A foo(Number n);\n" + // warning: overrides <T>foo(java.lang.Number) in I; return type requires unchecked conversion >+ "}\n" + >+ "abstract class A extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 10)\n" + >+ " @Override abstract A foo(Number n);\n" + >+ " ^\n" + >+ "Type safety: The return type A for foo(Number) from the type E needs unchecked conversion to conform to T from the type D\n" + >+ "----------\n" >+ // javac reports warnings against X AND Y about E.foo(), as well as reporting the warning on E.foo() twice >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test137() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public abstract class X implements J {}\n" + >+ "interface I {\n" + >+ " <T extends Y<T> & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " XX foo(Number n);\n" + >+ "}\n" + >+ "class Z { }\n" + >+ "class Y <U> extends Z { }" + >+ "abstract class XX extends Y<XX> implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 6)\n" + >+ " XX foo(Number n);\n" + >+ " ^^\n" + >+ "Type safety: The return type XX for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >+ "----------\n" >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test138() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public abstract class X implements J {}\n" + >+ "interface I {\n" + >+ " <T extends Exception & Cloneable> A<T> foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " A<XX> foo(Number n);\n" + >+ "}\n" + >+ "class A<T> { }" + >+ "abstract class XX extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 6)\n" + >+ " A<XX> foo(Number n);\n" + >+ " ^\n" + >+ "Type safety: The return type A<XX> for foo(Number) from the type J needs unchecked conversion to conform to A<T> from the type I\n" + >+ "----------\n" >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test139() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public abstract class X implements J {\n" + >+ " void foo() {}\n" + >+ " public XX foo(Number n) { return null; }\n" + >+ "}\n" + >+ "interface I {\n" + >+ " <T extends Exception & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " XX foo(Number n);\n" + >+ "}\n" + >+ "abstract class XX extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 9)\n" + >+ " XX foo(Number n);\n" + >+ " ^^\n" + >+ "Type safety: The return type XX for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >+ "----------\n" >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >+public void test140() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public abstract class X implements J, K {}\n" + >+ "interface I {\n" + >+ " <T extends Exception & Cloneable> T foo(Number n);\n" + >+ "}\n" + >+ "interface J extends I {\n" + >+ " XX foo(Number n);\n" + >+ "}\n" + >+ "interface K {\n" + >+ " NullPointerException foo(Number n);\n" + >+ "}\n" + >+ "abstract class XX extends Exception implements Cloneable {}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 1)\n" + >+ " public abstract class X implements J, K {}\n" + >+ " ^\n" + >+ "The return type is incompatible with K.foo(Number), J.foo(Number)\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 6)\n" + >+ " XX foo(Number n);\n" + >+ " ^^\n" + >+ "Type safety: The return type XX for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >+ "----------\n" >+ ); >+} > } >Index: src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java,v >retrieving revision 1.41 >diff -u -r1.41 AmbiguousMethodTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 26 Apr 2007 12:33:58 -0000 1.41 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 26 Apr 2007 18:42:05 -0000 >@@ -1456,155 +1456,8 @@ > }, > ""); > } >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-public void test032() { >- this.runConformTest( >- new String[] { >- "X.java", >- "interface I {\n" + >- " <T extends Exception & Cloneable> T foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " XX foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant that shows that the use of a substitution is needed during the bounds >-// check >-public void test032a() { >- this.runConformTest( >- new String[] { >- "X.java", >- "class Z { }\n" + >- "class Y <U> extends Z { }" + >- "interface I {\n" + >- " <T extends Y<T> & Cloneable> T foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " XX foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- "}\n" + >- "abstract class XX extends Y<XX> implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant >-public void test032b() { >- this.runConformTest( >- new String[] { >- "X.java", >- "class A<T> { }" + >- "interface I {\n" + >- " <T extends Exception & Cloneable> A<T> foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " A<XX> foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant >-public void test032c() { >- this.runConformTest( >- new String[] { >- "X.java", >- "class A<T> { }" + >- "interface I {\n" + >- " <T extends Exception & Cloneable> A<T> foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " <S extends XX> A<S> foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant >-public void test032d() { >- this.runConformTest( >- new String[] { >- "X.java", >- "class A<T> { }" + >- "interface I {\n" + >- " A<XX> foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " <T extends Exception & Cloneable> A<T> foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant >-public void test033() { >- this.runConformTest( >- new String[] { >- "X.java", >- "interface I {\n" + >- " <T extends Exception & Cloneable> T foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " XX foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J {\n" + >- " void foo() {\n" + >- " }\n" + >- " public XX foo(Number n) {\n" + >- " return null;\n" + >- " }\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- ""); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162073 >-// variant that rightly complains >-public void test034() { >- this.runNegativeTest( >- new String[] { >- "X.java", >- "interface I {\n" + >- " <T extends Exception & Cloneable> T foo(Number n);\n" + >- "}\n" + >- "interface J extends I {\n" + >- " XX foo(Number n);\n" + >- "}\n" + >- "interface K {\n" + >- " NullPointerException foo(Number n);\n" + >- "}\n" + >- "public abstract class X implements J, K {\n" + >- "}\n" + >- "abstract class XX extends Exception implements Cloneable {}" >- }, >- "----------\n" + >- "1. WARNING in X.java (at line 5)\n" + >- " XX foo(Number n);\n" + >- " ^^\n" + >- "Type safety: The return type XX for foo(Number) from the type J needs unchecked conversion to conform to T from the type I\n" + >- "----------\n" + >- "2. ERROR in X.java (at line 10)\n" + >- " public abstract class X implements J, K {\n" + >- " ^\n" + >- "The return type is incompatible with K.foo(Number), J.foo(Number)\n" + >- "----------\n"); >-} >+//tests 32-34 were moved to MethodVerityTest 134-140 >+ > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=162065 > // variant - the inheriting class implements foo > public void test035() { >#P org.eclipse.jdt.core >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java,v >retrieving revision 1.75 >diff -u -r1.75 MethodVerifier15.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 23 Apr 2007 06:51:39 -0000 1.75 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 26 Apr 2007 18:42:12 -0000 >@@ -344,56 +344,16 @@ > boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) { > if (methods[0].declaringClass.isClass()) > return super.checkInheritedReturnTypes(methods, length); >- if (length <= 1) { >- return true; // no need to continue since only 1 inherited method is left >- } >- // get rid of overriden methods coming from interfaces - if any >- MethodBinding methodsToCheck[] = new MethodBinding[length]; // must not nullify methods slots in place >- int count = length; >- for (int i = 0; i < length; i++) { >- methodsToCheck[i] = methods[i]; >- } >- for (int i = 0; i < length; i++) { >- MethodBinding existingMethod; >- if ((existingMethod = methodsToCheck[i]) != null) { >- for (int j = 0; j < length; j++) { >- MethodBinding inheritedMethod; >- if (i != j && (inheritedMethod = methodsToCheck[j]) != null && >- existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { >- MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod); >- if (substitute != null && >- doesSubstituteMethodOverride(existingMethod, substitute) && >- (existingMethod.returnType.isCompatibleWith(substitute.returnType) || >- isReturnTypeSubstituable(substitute, existingMethod))) { >- count--; >- methodsToCheck[j] = null; >- } >- } >- } >- } >- } >- if (count < length) { >- if (count == 1) { >- return true; // no need to continue since only 1 inherited method is left >- } >- for (int i = 0, j = 0; j < count; i++) { >- if (methodsToCheck[i] != null) { >- methodsToCheck[j++] = methodsToCheck[i]; >- } >- } >- methods = methodsToCheck; >- length = count; >- } // else keep methods unchanged for further checks > > // its possible in 1.5 that A is compatible with B & C, but B is not compatible with C > for (int i = 0, l = length - 1; i < l;) { > MethodBinding method = methods[i++]; >- for (int j = i; j <= l; j++) { >+ nextMethod : for (int j = i; j <= l; j++) { > if (!areReturnTypesCompatible(method, methods[j])) { > if (this.type.isInterface()) > for (int m = length; --m >= 0;) > if (methods[m].declaringClass.id == TypeIds.T_JavaLangObject) >- return false; // do not complain since the super interface already got blamed >+ continue nextMethod; // do not complain since the super interface already got blamed > problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); > return false; > } >@@ -621,84 +581,16 @@ > // one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod() > return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding); > } >-// caveat: returns false if a method is implemented but needs that a bridge >-// method be generated >+// caveat: returns false if a method is implemented that needs a bridge method > boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) { > if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) > return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary > > inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); > return inheritedMethod != null >- && inheritedMethod.returnType == existingMethod.returnType >+ && inheritedMethod.returnType == existingMethod.returnType // keep around to produce bridge methods > && super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); > } >-/** >- * Return true iff the return type of existingMethod is a valid replacement for >- * the one of substituteMethod in a method declaration, in the context specified >- * thereafter. It is expected that substituteMethod is the result of the >- * substitution of the type parameters of an inheritedMethod method according to >- * the type parameters of existingMethod and the inheritance relationship >- * between existingMethod's declaring type and inheritedMethod's declaring type, >- * where inheritedMethod is a method inherited by existingMethod's declaring >- * type which is override compatible with existingMethod, except maybe for >- * their respective return types. If those conditions are not met, the result is >- * unspecified. >- * @param substituteMethod a proper substitute of a method inherited by existingMethod >- * @param existingMethod the existing method under examination >- * @return true if the return type of existingMethod is a valid substitute for >- * the one of substituteMethod >- */ >-boolean isReturnTypeSubstituable(MethodBinding substituteMethod, MethodBinding existingMethod) { >- class ReturnTypeSubstitution implements Substitution { >- TypeBinding replaced, replacer; >- ReturnTypeSubstitution(TypeBinding replaced, TypeBinding replacer) { >- this.replaced = replaced; >- this.replacer = replacer; >- } >- public LookupEnvironment environment() { >- return environment; >- } >- public boolean isRawSubstitution() { >- return false; >- } >- public TypeBinding substitute(TypeVariableBinding typeVariable) { >- return typeVariable == replaced ? replacer : typeVariable; >- } >- } >- if (substituteMethod.returnType instanceof TypeVariableBinding) { >- return ((TypeVariableBinding) substituteMethod.returnType). >- boundCheck( >- new ReturnTypeSubstitution(substituteMethod.returnType, existingMethod.returnType), >- existingMethod.returnType) == TypeConstants.OK; >- } else if (substituteMethod.returnType instanceof ParameterizedTypeBinding) { >- if (! (existingMethod.returnType instanceof ParameterizedTypeBinding)) { >- return false; >- } >- ParameterizedTypeBinding substituteReturnType = (ParameterizedTypeBinding) substituteMethod.returnType, >- existingReturnType = (ParameterizedTypeBinding) existingMethod.returnType; >- if (substituteReturnType.actualType() != existingReturnType.actualType()) >- return false; >- for (int i = 0; i < substituteReturnType.arguments.length; i++) { >- TypeBinding substituteArgumentType, existingArgumentType; >- if (! (existingArgumentType = existingReturnType.arguments[i]).isCompatibleWith( >- substituteArgumentType = substituteReturnType.arguments[i])) { >- if (substituteArgumentType instanceof TypeVariableBinding) { >- if (((TypeVariableBinding) substituteArgumentType). >- boundCheck( >- new ReturnTypeSubstitution(substituteArgumentType, existingArgumentType), >- // we do not address the most general pattern of multiple type variables, nor the recursive case either >- existingArgumentType) != TypeConstants.OK) { >- return false; >- } >- } else { >- return false; >- } >- } >- } >- return true; >- } >- return false; >-} > SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { > ReferenceBinding[] interfacesToVisit = null; > int nextPosition = 0; >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java,v >retrieving revision 1.84 >diff -u -r1.84 MethodVerifier.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 23 Apr 2007 06:51:39 -0000 1.84 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 26 Apr 2007 18:42:12 -0000 >@@ -141,48 +141,53 @@ > return; // do not repoort against subsequent inherited methods > } > CompilerOptions options = type.scope.compilerOptions(); >+ // need to find the overridden methods to avoid blaming this type for issues which are already reported against a supertype >+ // but cannot ignore an overridden inherited method completely when it comes to checking for bridge methods >+ int[] overriddenInheritedMethods = findOverriddenInheritedMethods(methods, length); > nextMethod : for (int i = length; --i >= 0;) { > MethodBinding inheritedMethod = methods[i]; >- if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot override a static method or hide an instance method >- problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod); >- continue nextMethod; >- } >- >- // want to tag currentMethod even if return types are not equal >- if (inheritedMethod.isAbstract()) { >- if (inheritedMethod.declaringClass.isInterface()) { >- currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing; >+ if (overriddenInheritedMethods == null || overriddenInheritedMethods[i] == 0) { >+ if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot override a static method or hide an instance method >+ problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod); >+ continue nextMethod; >+ } >+ >+ // want to tag currentMethod even if return types are not equal >+ if (inheritedMethod.isAbstract()) { >+ if (inheritedMethod.declaringClass.isInterface()) { >+ currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing; >+ } else { >+ currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding; >+ } >+// with the above change an abstract method is tagged as implementing the inherited abstract method >+// if (!currentMethod.isAbstract() && inheritedMethod.isAbstract()) { >+// if ((currentMethod.modifiers & CompilerModifiers.AccOverriding) == 0) >+// currentMethod.modifiers |= CompilerModifiers.AccImplementing; > } else { >- currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding; >+ currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding; > } >-// with the above change an abstract method is tagged as implementing the inherited abstract method >-// if (!currentMethod.isAbstract() && inheritedMethod.isAbstract()) { >-// if ((currentMethod.modifiers & CompilerModifiers.AccOverriding) == 0) >-// currentMethod.modifiers |= CompilerModifiers.AccImplementing; >- } else { >- currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding; >- } >- >- if (!areReturnTypesCompatible(currentMethod, inheritedMethod)) >- if (reportIncompatibleReturnTypeError(currentMethod, inheritedMethod)) >- continue nextMethod; >- >- if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS) >- checkExceptions(currentMethod, inheritedMethod); >- if (inheritedMethod.isFinal()) >- problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); >- if (!isAsVisible(currentMethod, inheritedMethod)) >- problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod); >- if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) { >- if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) { >- // check against the other inherited methods to see if they hide this inheritedMethod >- ReferenceBinding declaringClass = inheritedMethod.declaringClass; >- if (declaringClass.isInterface()) >- for (int j = length; --j >= 0;) >- if (i != j && methods[j].declaringClass.implementsInterface(declaringClass, false)) >- continue nextMethod; >- >- problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod); >+ >+ if (!areReturnTypesCompatible(currentMethod, inheritedMethod)) >+ if (reportIncompatibleReturnTypeError(currentMethod, inheritedMethod)) >+ continue nextMethod; >+ >+ if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS) >+ checkExceptions(currentMethod, inheritedMethod); >+ if (inheritedMethod.isFinal()) >+ problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); >+ if (!isAsVisible(currentMethod, inheritedMethod)) >+ problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod); >+ if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) { >+ if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) { >+ // check against the other inherited methods to see if they hide this inheritedMethod >+ ReferenceBinding declaringClass = inheritedMethod.declaringClass; >+ if (declaringClass.isInterface()) >+ for (int j = length; --j >= 0;) >+ if (i != j && methods[j].declaringClass.implementsInterface(declaringClass, false)) >+ continue nextMethod; >+ >+ problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod); >+ } > } > } > checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods); >@@ -231,6 +236,18 @@ > // no op before 1.5 > } > void checkInheritedMethods(MethodBinding[] methods, int length) { >+ int[] overriddenInheritedMethods = findOverriddenInheritedMethods(methods, length); >+ if (overriddenInheritedMethods != null) { >+ // detected some overridden methods that can be ignored when checking return types >+ int index = 0; >+ MethodBinding[] closestMethods = new MethodBinding[length]; >+ for (int i = 0; i < length; i++) >+ if (overriddenInheritedMethods[i] == 0) >+ closestMethods[index++] = methods[i]; >+ methods = closestMethods; >+ length = index; >+ } >+ > if (!checkInheritedReturnTypes(methods, length)) > return; > >@@ -573,6 +590,42 @@ > public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { > return areParametersEqual(method, inheritedMethod); > } >+SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { >+ return null; // noop in 1.4 >+} >+int[] findOverriddenInheritedMethods(MethodBinding[] methods, int length) { >+ int[] toSkip = null; >+ if (length > 1) { >+ nextMethod : for (int i = 0; i < length; i++) { >+ if (toSkip != null && toSkip[i] == -1) continue nextMethod; >+ ReferenceBinding declaringClass = methods[i].declaringClass; >+ if (declaringClass.isInterface()) { >+ for (int j = 0; j < length; j++) { >+ if (i == j) continue; >+ ReferenceBinding declaringClass2 = methods[j].declaringClass; >+ if (declaringClass2.isInterface() && declaringClass2.implementsInterface(declaringClass, true)) { >+ if (toSkip == null) >+ toSkip = new int[length]; >+ toSkip[i] = -1; >+ continue nextMethod; >+ } >+ } >+ } else { >+ for (int j = 0; j < length; j++) { >+ if (i == j) continue; >+ ReferenceBinding declaringClass2 = methods[j].declaringClass; >+ if (!declaringClass2.isInterface() && declaringClass.isSuperclassOf(declaringClass2)) { >+ if (toSkip == null) >+ toSkip = new int[length]; >+ toSkip[i] = -1; >+ continue nextMethod; >+ } >+ } >+ } >+ } >+ } >+ return toSkip; >+} > boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) { > if (inheritedMethod.modifiers == newMethod.modifiers) return true; > >@@ -624,9 +677,6 @@ > reporter.referenceContext = currentMethod.sourceMethod(); > return reporter; > } >-SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { >- return null; // noop in 1.4 >-} > /** > * Return true and report an incompatibleReturnType error if currentMethod's > * return type is strictly incompatible with inheritedMethod's, else return
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 184293
: 65087