diff options
author | Stephan Herrmann | 2013-08-22 19:53:11 +0000 |
---|---|---|
committer | Stephan Herrmann | 2013-08-27 07:50:35 +0000 |
commit | 288e8d99c513639a6f3fdf977634474ff458e3aa (patch) | |
tree | de9a20be67089a9605c465be15308872cfd97188 | |
parent | c005efbda8be0db83712eb14294777155c3ab919 (diff) | |
download | eclipse.jdt.core-288e8d99c513639a6f3fdf977634474ff458e3aa.tar.gz eclipse.jdt.core-288e8d99c513639a6f3fdf977634474ff458e3aa.tar.xz eclipse.jdt.core-288e8d99c513639a6f3fdf977634474ff458e3aa.zip |
Bug 410325 - [1.7][compiler] Generified method override different
between javac and eclipse compiler
2 files changed, 114 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java index be44bb3cc8..c77b67b2fb 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java @@ -11,6 +11,7 @@ * bug 388795 - [compiler] detection of name clash depends on order of super interfaces * bug 395681 - [compiler] Improve simulation of javac6 behavior from bug 317719 after fixing bug 388795 * bug 409473 - [compiler] JDT cannot compile against JRE 1.8 + * Bug 410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler * Andy Clement - Contribution for * bug 406928 - computation of inherited methods seems damaged (affecting @Overrides) *******************************************************************************/ @@ -13839,4 +13840,94 @@ public void testBug409473() { "public abstract class Foo<E> implements java.util.List<E> { } " }); } +// https://bugs.eclipse.org/410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler +public void testBug410325() { + runConformTest( + new String[] { + "Main.java", + "public class Main {\n" + + " public static void main(String[] args) {\n" + + " F3 f3 = new F3();\n" + + " SubSub sub = new SubSub();\n" + + " sub.foo(f3);\n" + + "\n" + + " Sub<F3> sub2 = sub;\n" + + " Base<F3> base = sub;\n" + + " sub2.foo(f3);\n" + + " base.foo(f3);\n" + + "\n" + + " F2 f2 = new F2();\n" + + " sub2.foo(f2);\n" + + " }\n" + + "\n" + + " public static class F1 {\n" + + " }\n" + + "\n" + + " public static class F2 extends F1 {\n" + + " }\n" + + "\n" + + " public static class F3 extends F2 {\n" + + " public void bar() {\n" + + " System.out.println(\"bar in F3\");\n" + + " }\n" + + " }\n" + + "\n" + + " public static abstract class Base<T extends F1> {\n" + + " public abstract void foo(T bar);\n" + + " }\n" + + "\n" + + " public static abstract class Sub<T extends F2> extends Base<T> {\n" + + " @Override\n" + + " public void foo(F2 bar) {\n" + + " System.out.println(getClass().getSimpleName() + \": F2 + \"\n" + + " + bar.getClass().getSimpleName());\n" + + " }\n" + + " }\n" + + "\n" + + " public static class SubSub extends Sub<F3> {\n" + + " }\n" + + "}" + }); +} +// https://bugs.eclipse.org/410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler +// test from duplicate bug 411811 +public void testBug411811() { + runConformTest( + new String[] { + "FaultyType.java", + " class ParamType {}\n" + + "\n" + + " abstract class AbstractType<T extends ParamType> {\n" + + " public abstract void foo(T t);\n" + + " }\n" + + "\n" + + " abstract class SubAbstractType<T extends ParamType> extends AbstractType<T> {\n" + + " @Override public void foo(ParamType t) {}\n" + + " }\n" + + "\n" + + " class SubParamType extends ParamType {}\n" + + " \n" + + "public class FaultyType extends SubAbstractType<SubParamType> {}" + }); +} +// https://bugs.eclipse.org/410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler +// test from duplicate bug 415600 +public void testBug415600() { + runConformTest( + new String[] { + "A.java", + "import java.io.Reader;\n" + + "import java.io.StringReader;\n" + + "\n" + + "public abstract class A<E extends Reader> {\n" + + " protected abstract void create(E element);\n" + + "}\n" + + "\n" + + "abstract class B<T extends Reader> extends A<T> {\n" + + " public void create(Reader element) { }\n" + + "}\n" + + "\n" + + "class C extends B<StringReader> { }\n" + }); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java index caa0c2c88b..1b7b1f2a78 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java @@ -15,6 +15,7 @@ * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation. * bug 395681 - [compiler] Improve simulation of javac6 behavior from bug 317719 after fixing bug 388795 * bug 409473 - [compiler] JDT cannot compile against JRE 1.8 + * Bug 410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -275,6 +276,23 @@ void checkInheritedMethods(MethodBinding[] methods, int length, boolean[] isOver boolean isAbstract = methods[i].isAbstract() || methods[i].declaringClass.isInterface(); if (!isAbstract) { if (concreteMethod != null) { + // https://bugs.eclipse.org/195802 with https://bugs.eclipse.org/410325 + // If a replace method (from findReplacedMethod()) is the rawified version of another + // don't count this as duplicates: + // (Not asking ParameterizedGenericMethodBinding.isRawMethod(), + // because that is true only for methods of a RawTypeBinding, + // but here we look for rawness regarding the method's type variables). + if (concreteMethod.declaringClass == methods[i].declaringClass + && concreteMethod.typeVariables.length != methods[i].typeVariables.length) + { + if (concreteMethod.typeVariables == Binding.NO_TYPE_VARIABLES + && concreteMethod.original() == methods[i]) + continue; + if (methods[i].typeVariables == Binding.NO_TYPE_VARIABLES + && methods[i].original() == concreteMethod) + continue; + } + problemReporter().duplicateInheritedMethods(this.type, concreteMethod, methods[i]); continueInvestigation = false; } @@ -584,6 +602,8 @@ void checkMethods() { * mark as isOverridden * - any skippable method as defined above iff it is actually overridden by the specific method (disregarding visibility etc.) * Note, that 'idx' corresponds to the position of 'general' in the arrays 'skip' and 'isOverridden' + * TODO(stephan) currently (as of Bug 410325), the boarder between skip and isOverridden is blurred, + * should reassess after more experience with this patch. */ boolean isSkippableOrOverridden(MethodBinding specific, MethodBinding general, boolean[] skip, boolean[] isOverridden, int idx) { boolean specificIsInterface = specific.declaringClass.isInterface(); @@ -594,10 +614,10 @@ boolean isSkippableOrOverridden(MethodBinding specific, MethodBinding general, b isOverridden[idx] = true; return true; } - } else if (specificIsInterface == generalIsInterface) { - if (isParameterSubsignature(specific, general)) { + } else if (specificIsInterface == generalIsInterface) { + if (specific.declaringClass.isCompatibleWith(general.declaringClass) && isMethodSubsignature(specific, general)) { skip[idx] = true; - isOverridden[idx] = specific.declaringClass.isCompatibleWith(general.declaringClass); + isOverridden[idx] = true; return true; } } |