diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java index 36020c5972..2b78560cea 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java @@ -437,6 +437,41 @@ public void testTypeChecked7945() { "----------\n"); } + @Test + public void testTypeChecked8034() { + //@formatter:off + String[] sources = { + "Test.groovy", + "class A {\n" + + " def > IO andThen(IO next) {\n" + + " next\n" + + " }\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "void test() {\n" + + " def a1 = new A()\n" + + " def a2 = new A()\n" + + " def a3 = new A()\n" + + " def a4 = new A()\n" + + " def a5 = new A()\n" + + " \n" + + " a1.andThen(a2)\n" + + " a2.andThen(a3)\n" + + " a3.andThen(a4)\n" + + " a4.andThen(a5)\n" + + " \n" + + " a1.andThen(a2)\n" + + " .andThen(a3)\n" + + " .andThen(a4)\n" + + " .andThen(a5)\n" + + "}\n" + + "test()\n", + }; + //@formatter:on + + runNegativeTest(sources, ""); + } + @Test public void testTypeChecked8103() { //@formatter:off @@ -468,7 +503,7 @@ public void testTypeChecked8103() { " Ours isSimilarTo(String json) { return this }\n" + " }\n" + " static Ours factory(String json) { new Ours() }\n" + - "}", + "}\n", }; //@formatter:on diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index ec2804bd28..63f2cf7486 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1456,9 +1456,18 @@ protected static boolean typeCheckMethodArgumentWithGenerics(ClassNode parameter } static void addMethodLevelDeclaredGenerics(MethodNode method, Map resolvedPlaceholders) { + /* GRECLIPSE edit ClassNode dummy = OBJECT_TYPE.getPlainNodeReference(); dummy.setGenericsTypes(method.getGenericsTypes()); GenericsUtils.extractPlaceholders(dummy, resolvedPlaceholders); + */ + GenericsType[] generics = method.getGenericsTypes(); + if (!method.isStatic() && !resolvedPlaceholders.isEmpty()) { + // GROOVY-8034: non-static method may use class generics + generics = applyGenericsContext(resolvedPlaceholders, generics); + } + GenericsUtils.extractPlaceholders(GenericsUtils.makeClassSafe0(OBJECT_TYPE, generics), resolvedPlaceholders); + // GRECLIPSE end } protected static boolean typeCheckMethodsWithGenerics(ClassNode receiver, ClassNode[] arguments, MethodNode candidateMethod) { diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index a00409006a..1fd9694465 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1387,9 +1387,18 @@ protected static boolean typeCheckMethodArgumentWithGenerics(final ClassNode par } static void addMethodLevelDeclaredGenerics(final MethodNode method, final Map resolvedPlaceholders) { + /* GRECLIPSE edit ClassNode dummy = OBJECT_TYPE.getPlainNodeReference(); dummy.setGenericsTypes(method.getGenericsTypes()); GenericsUtils.extractPlaceholders(dummy, resolvedPlaceholders); + */ + GenericsType[] generics = method.getGenericsTypes(); + if (!method.isStatic() && !resolvedPlaceholders.isEmpty()) { + // GROOVY-8034: non-static method may use class generics + generics = applyGenericsContext(resolvedPlaceholders, generics); + } + GenericsUtils.extractPlaceholders(GenericsUtils.makeClassSafe0(OBJECT_TYPE, generics), resolvedPlaceholders); + // GRECLIPSE end } protected static boolean typeCheckMethodsWithGenerics(final ClassNode receiver, final ClassNode[] argumentTypes, final MethodNode candidateMethod) { diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index fe9ad036e6..95d00b0bd8 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1386,7 +1386,16 @@ protected static boolean typeCheckMethodArgumentWithGenerics(final ClassNode par } static void addMethodLevelDeclaredGenerics(final MethodNode method, final Map placeholders) { + /* GRECLIPSE edit ClassNode dummy = GenericsUtils.makeClassSafe0(OBJECT_TYPE, method.getGenericsTypes()); + */ + GenericsType[] generics = method.getGenericsTypes(); + if (!method.isStatic() && !placeholders.isEmpty()) { + // GROOVY-8034: non-static method may use class generics + generics = applyGenericsContext(placeholders, generics); + } + ClassNode dummy = GenericsUtils.makeClassSafe0(OBJECT_TYPE, generics); + // GRECLIPSE end GenericsUtils.extractPlaceholders(dummy, placeholders); }