diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java index e0f4746f37..1556886306 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java @@ -6288,6 +6288,9 @@ public void testCompileStatic10072() { " c = { p, q = 'baz' -> '' + p + q }\n" + " assert c('foo', 'bar') == 'foobar'\n" + " assert c('foo') == 'foobaz'\n" + + " c = { p, q = p.toString() -> '' + p + q }\n" + + " assert c('foo', 'bar') == 'foobar'\n" + + " assert c('foo') == 'foofoo'\n" + "}\n" + "test()\n", }; 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 20a311f195..3ddec80e99 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 @@ -3000,6 +3000,26 @@ public void testTypeChecked10091() { "----------\n"); } + @Test + public void testTypeChecked10094() { + //@formatter:off + String[] sources = { + "Main.groovy", + "@groovy.transform.TypeChecked\n" + + "void test(int i = 'error') {}\n" + + "test()\n", + }; + //@formatter:on + + runNegativeTest(sources, + "----------\n" + + "1. ERROR in Main.groovy (at line 2)\n" + + "\tvoid test(int i = 'error') {}\n" + + "\t ^^^^^^^\n" + + "Groovy:[Static type checking] - Cannot assign value of type java.lang.String to variable of type int\n" + + "----------\n"); + } + @Test public void testTypeChecked10098() { //@formatter:off diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 5693db2a49..14b4dc1c5f 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -36,6 +36,7 @@ import org.codehaus.groovy.ast.ClassCodeVisitorSupport; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.CodeVisitorSupport; import org.codehaus.groovy.ast.ConstructorNode; import org.codehaus.groovy.ast.DynamicVariable; import org.codehaus.groovy.ast.FieldNode; @@ -2611,6 +2612,21 @@ protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) typeCheckingContext.pushEnclosingMethod(node); if (!isSkipMode(node) && !shouldSkipMethodNode(node)) { super.visitConstructorOrMethod(node, isConstructor); + // GRECLIPSE add + if (node.hasDefaultValue()) + for (Parameter parameter : node.getParameters()) { + if (!parameter.hasInitialExpression()) continue; + // GROOVY-10094: visit param default argument expression + visitInitialExpression(parameter.getInitialExpression(), varX(parameter), parameter); + // GROOVY-10104: remove direct target setting to prevent errors + parameter.getInitialExpression().visit(new CodeVisitorSupport() { + @Override + public void visitMethodCallExpression(final MethodCallExpression mce) { + mce.setMethodTarget(null); super.visitMethodCallExpression(mce); + } + }); + } + // GRECLIPSE end } if (!isConstructor) { returnAdder.visitMethod(node); // return statement added after visitConstructorOrMethod finished... we can not count these auto-generated return statements(GROOVY-7753), see `typeCheckingContext.pushEnclosingReturnStatement` diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 1aa145f8be..830330eb2e 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -36,6 +36,7 @@ import org.codehaus.groovy.ast.ClassCodeVisitorSupport; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.CodeVisitorSupport; import org.codehaus.groovy.ast.ConstructorNode; import org.codehaus.groovy.ast.DynamicVariable; import org.codehaus.groovy.ast.FieldNode; @@ -2344,6 +2345,21 @@ protected void visitConstructorOrMethod(final MethodNode node, final boolean isC typeCheckingContext.pushEnclosingMethod(node); if (!isSkipMode(node) && !shouldSkipMethodNode(node)) { super.visitConstructorOrMethod(node, isConstructor); + // GRECLIPSE add + if (node.hasDefaultValue()) + for (Parameter parameter : node.getParameters()) { + if (!parameter.hasInitialExpression()) continue; + // GROOVY-10094: visit param default argument expression + visitInitialExpression(parameter.getInitialExpression(), varX(parameter), parameter); + // GROOVY-10104: remove direct target setting to prevent errors + parameter.getInitialExpression().visit(new CodeVisitorSupport() { + @Override + public void visitMethodCallExpression(final MethodCallExpression mce) { + mce.setMethodTarget(null); super.visitMethodCallExpression(mce); + } + }); + } + // GRECLIPSE end } if (!isConstructor) { returnAdder.visitMethod(node); // return statement added after visitConstructorOrMethod finished... we can not count these auto-generated return statements(GROOVY-7753), see `typeCheckingContext.pushEnclosingReturnStatement` diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 3983157146..4d43304219 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -2176,6 +2176,21 @@ protected void visitConstructorOrMethod(final MethodNode node, final boolean isC typeCheckingContext.pushEnclosingMethod(node); if (!isSkipMode(node) && !shouldSkipMethodNode(node)) { super.visitConstructorOrMethod(node, isConstructor); + // GRECLIPSE add + if (node.hasDefaultValue()) + for (Parameter parameter : node.getParameters()) { + if (!parameter.hasInitialExpression()) continue; + // GROOVY-10094: visit param default argument expression + visitInitialExpression(parameter.getInitialExpression(), varX(parameter), parameter); + // GROOVY-10104: remove direct target setting to prevent errors + parameter.getInitialExpression().visit(new CodeVisitorSupport() { + @Override + public void visitMethodCallExpression(final MethodCallExpression mce) { + mce.setMethodTarget(null); super.visitMethodCallExpression(mce); + } + }); + } + // GRECLIPSE end } if (!isConstructor) { returnAdder.visitMethod(node); // return statement added after visitConstructorOrMethod finished... we can not count these auto-generated return statements(GROOVY-7753), see `typeCheckingContext.pushEnclosingReturnStatement`