diff options
| author | Stephan Herrmann | 2013-02-22 18:48:36 +0000 |
|---|---|---|
| committer | Jayaprakash Arthanareeswaran | 2013-04-03 09:02:14 +0000 |
| commit | 7f149cbd31a29082f285cf448e823f215f36990d (patch) | |
| tree | c16cbb92231cbfc21b4686b4868c7adf131f64f7 | |
| parent | 43e6a1aaf95a700a23727644400d8055e7261c91 (diff) | |
| download | eclipse.jdt.core-7f149cbd31a29082f285cf448e823f215f36990d.tar.gz eclipse.jdt.core-7f149cbd31a29082f285cf448e823f215f36990d.tar.xz eclipse.jdt.core-7f149cbd31a29082f285cf448e823f215f36990d.zip | |
Bug 401456 - Code compiles from javac/intellij, but fails from eclipse
3 files changed, 74 insertions, 12 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java index 1b1042d2b6..f83ec1fab9 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java @@ -38788,8 +38788,7 @@ public void test1132() { " X myThing = new X<Object>();\n" + " Integer i = myThing.getList().get(0); // Type Mismatch error - Since\n" + " // myThing is unbounded, return\n" + - " // type List<Integer>\n" + - " // incorrectly becomes unbounded\n" + + " // type List<Integer> becomes unbounded\n" + " }\n" + "\n" + " public List<Integer> getList() {\n" + @@ -38821,12 +38820,12 @@ public void test1132() { " ^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Type mismatch: cannot convert from Object to Integer\n" + "----------\n" + - "3. WARNING in X.java (at line 25)\n" + + "3. WARNING in X.java (at line 24)\n" + " X myThing = new X<Object>();\n" + " ^\n" + "X is a raw type. References to generic type X<T> should be parameterized\n" + "----------\n" + - "4. WARNING in X.java (at line 26)\n" + + "4. WARNING in X.java (at line 25)\n" + " List<Integer> l = myThing.getList();\n" + " ^^^^^^^^^^^^^^^^^\n" + "Type safety: The expression of type List needs unchecked conversion to conform to List<Integer>\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java index 8721046913..6b769ebdf7 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java @@ -10,6 +10,7 @@ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for * bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation. + * bug 401456 - Code compiles from javac/intellij, but fails from eclipse *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -30,7 +31,7 @@ public class GenericsRegressionTest extends AbstractComparableTest { // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which does not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "testBug395002_combined" }; +// TESTS_NAMES = new String[] { "test401456" }; // TESTS_NAMES = new String[] { "test1464" }; // TESTS_NUMBERS = new int[] { 1465 }; // TESTS_RANGE = new int[] { 1097, -1 }; @@ -2817,4 +2818,43 @@ public void test397888b() { "----------\n", null, true, customOptions); } +// Bug 401456 - Code compiles from javac/intellij, but fails from eclipse +public void test401456() { + runConformTest( + new String[] { + "App.java", + "import java.util.List;\n" + + "\n" + + "public class App {\n" + + "\n" + + " public interface Command_1<T> {\n" + + " public void execute(T o);\n" + + " }\n" + + " public static class ObservableEventWithArg<T> {\n" + + " public class Monitor {\n" + + " public Object addListener(final Command_1<T> l) {\n" + + " return null;\n" + + " }\n" + + " }\n" + + " }\n" + + " public static class Context<T> {\n" + + " public ObservableEventWithArg<String>.Monitor getSubmissionErrorEventMonitor() {\n" + + " return new ObservableEventWithArg<String>().new Monitor();\n" + + " }\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " compileError(new Context<List<String>>());\n" + + " }\n" + + "\n" + + " private static void compileError(Context context) {\n" + + " context.getSubmissionErrorEventMonitor().addListener(\n" + // here the inner message send bogusly resolved to ObservableEventWithArg#RAW.Monitor + " new Command_1<String>() {\n" + + " public void execute(String o) {\n" + + " }\n" + + " });\n" + + " }\n" + + "}\n" + }); +} }
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java index 641d61fc6e..80a1b6a431 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -15,8 +15,12 @@ * bug 186342 - [compiler][null] Using annotations for null checking * bug 387612 - Unreachable catch block...exception is never thrown from the try * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation. +<<<<<<< BETA_JAVA8 * Jesper S Moller - Contributions for * bug 382721 - [1.8][compiler] Effectively final variables needs special treatment +======= + * bug 401456 - Code compiles from javac/intellij, but fails from eclipse +>>>>>>> 8200b6c Bug 401456 - Code compiles from javac/intellij, but fails from eclipse *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -359,13 +363,12 @@ public abstract class Scope { /** * Returns a type, where original type was substituted using the receiver * parameterized type. - * In raw mode, all parameterized type denoting same original type are converted - * to raw types. e.g. - * class X <T> { - * X<T> foo; - * X<String> bar; - * } when used in raw fashion, then type of both foo and bar is raw type X. - * + * In raw mode (see {@link Substitution#isRawSubstitution()}), + * all parameterized types are converted to raw types. + * Cf. 4.8: "The type of a constructor (8.8), instance method (8.4, 9.4), + * or non-static field (8.3) M of a raw type C that is not inherited from its + * superclasses or superinterfaces is the raw type that corresponds to the erasure + * of its type in the generic declaration corresponding to C." */ public static TypeBinding substitute(Substitution substitution, TypeBinding originalType) { if (originalType == null) return null; @@ -380,6 +383,9 @@ public abstract class Scope { ReferenceBinding substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return originalParameterizedType.environment.createRawType( + originalParameterizedType.genericType(), substitutedEnclosing); } TypeBinding[] originalArguments = originalParameterizedType.arguments; TypeBinding[] substitutedArguments = originalArguments; @@ -443,6 +449,8 @@ public abstract class Scope { substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing); } // treat as if parameterized with its type variables (non generic type gets 'null' arguments) @@ -458,6 +466,8 @@ public abstract class Scope { substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing); } if (substitution.isRawSubstitution()) { @@ -471,6 +481,19 @@ public abstract class Scope { return originalType; } + private static boolean isMemberTypeOfRaw(TypeBinding originalType, ReferenceBinding substitutedEnclosing) { + // 4.8: + // "a raw type is defined to be one of: + // ... + // * A non-static member type of a raw type R that is not + // inherited from a superclass or superinterface of R." + + // Due to staticness, e.g., Map.Entry<String,Object> is *not* considered as a raw type + + return (substitutedEnclosing != null && substitutedEnclosing.isRawType()) + && ((originalType instanceof ReferenceBinding) && !((ReferenceBinding)originalType).isStatic()); + } + /** * Returns an array of types, where original types got substituted given a substitution. * Only allocate an array if anything is different. |
