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 281982c4bc..e15c25ca36 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 @@ -425,9 +425,6 @@ public void testTypeChecked18() { //@formatter:off String[] sources = { "Main.groovy", - "class C {\n" + - " boolean b\n" + - "}\n" + "@groovy.transform.TypeChecked\n" + "void test() {\n" + " print(new Pogo().isFlag())\n" + @@ -481,6 +478,28 @@ public void testTypeChecked19() { runConformTest(sources, "test"); } + @Test + public void testTypeChecked20() { + //@formatter:off + String[] sources = { + "Main.groovy", + "def T m(java.util.function.Consumer c) {\n" + + " c.accept(null)\n" + + " null\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "void test() {\n" + + " this.m { n ->\n" + + " n?.toBigInteger()\n" + + " }\n" + + "}\n" + + "test()\n", + }; + //@formatter:on + + runConformTest(sources); + } + @Test public void testTypeChecked5450() { //@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 0f4a81a751..486b324ff1 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 @@ -3416,7 +3416,8 @@ protected void silentlyVisitMethodNode(final MethodNode directMethodCallCandidat startMethodInference(directMethodCallCandidate, collector); } - protected void visitMethodCallArguments(final ClassNode receiver, ArgumentListExpression arguments, boolean visitClosures, final MethodNode selectedMethod) { + protected void visitMethodCallArguments(final ClassNode receiver, final ArgumentListExpression arguments, final boolean visitClosures, final MethodNode selectedMethod) { + /* GRECLIPSE edit Parameter[] params = selectedMethod != null ? selectedMethod.getParameters() : Parameter.EMPTY_ARRAY; List expressions = new LinkedList(arguments.getExpressions()); if (selectedMethod instanceof ExtensionMethodNode) { @@ -3424,20 +3425,31 @@ protected void visitMethodCallArguments(final ClassNode receiver, ArgumentListEx expressions.add(0, varX("$self", receiver)); } ArgumentListExpression newArgs = args(expressions); - - for (int i = 0, expressionsSize = expressions.size(); i < expressionsSize; i++) { + */ + Parameter[] params; + List expressions = new ArrayList<>(); + if (selectedMethod instanceof ExtensionMethodNode) { + params = ((ExtensionMethodNode) selectedMethod).getExtensionMethodNode().getParameters(); + expressions.add(varX("$self", receiver)); + } else { + params = selectedMethod != null ? selectedMethod.getParameters() : Parameter.EMPTY_ARRAY; + } + expressions.addAll(arguments.getExpressions()); + if (expressions.isEmpty()) return; + // GRECLIPSE end + for (int i = 0, n = expressions.size(); i < n; i++) { final Expression expression = expressions.get(i); if (visitClosures && expression instanceof ClosureExpression || !visitClosures && !(expression instanceof ClosureExpression)) { if (i < params.length && visitClosures) { Parameter param = params[i]; - checkClosureWithDelegatesTo(receiver, selectedMethod, newArgs, params, expression, param); + checkClosureWithDelegatesTo(receiver, selectedMethod, args(expressions), params, expression, param); if (selectedMethod instanceof ExtensionMethodNode) { if (i > 0) { inferClosureParameterTypes(receiver, arguments, (ClosureExpression) expression, param, selectedMethod); } } else { - inferClosureParameterTypes(receiver, newArgs, (ClosureExpression) expression, param, selectedMethod); + inferClosureParameterTypes(receiver, arguments, (ClosureExpression) expression, param, selectedMethod); } // GRECLIPSE add -- GROOVY-9971 ClassNode targetType = param.getType(); @@ -3449,12 +3461,10 @@ protected void visitMethodCallArguments(final ClassNode receiver, ArgumentListEx // GRECLIPSE end } expression.visit(this); - if (expression.getNodeMetaData(StaticTypesMarker.DELEGATION_METADATA) != null) { - expression.removeNodeMetaData(StaticTypesMarker.DELEGATION_METADATA); - } + expression.removeNodeMetaData(StaticTypesMarker.DELEGATION_METADATA); } } - if (expressions.size() > 0 && expressions.get(0) instanceof MapExpression && params.length > 0) { + if (params.length > 0 && expressions.get(0) instanceof MapExpression) { checkNamedParamsAnnotation(params[0], (MapExpression) expressions.get(0)); } } 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 84768bf143..3c30c47133 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 @@ -3119,6 +3119,7 @@ protected void silentlyVisitMethodNode(final MethodNode directMethodCallCandidat } protected void visitMethodCallArguments(final ClassNode receiver, final ArgumentListExpression arguments, final boolean visitClosures, final MethodNode selectedMethod) { + /* GRECLIPSE edit Parameter[] params = selectedMethod != null ? selectedMethod.getParameters() : Parameter.EMPTY_ARRAY; List expressions = new LinkedList<>(arguments.getExpressions()); if (selectedMethod instanceof ExtensionMethodNode) { @@ -3126,7 +3127,17 @@ protected void visitMethodCallArguments(final ClassNode receiver, final Argument expressions.add(0, varX("$self", receiver)); } ArgumentListExpression newArgs = args(expressions); - + */ + Parameter[] params; + List expressions = new ArrayList<>(); + if (selectedMethod instanceof ExtensionMethodNode) { + params = ((ExtensionMethodNode) selectedMethod).getExtensionMethodNode().getParameters(); + expressions.add(varX("$self", receiver)); + } else { + params = selectedMethod != null ? selectedMethod.getParameters() : Parameter.EMPTY_ARRAY; + } + expressions.addAll(arguments.getExpressions()); + // GRECLIPSE end int nExpressions = expressions.size(); for (int i = 0; i < nExpressions; i += 1) { Expression expression = expressions.get(i); @@ -3136,13 +3147,13 @@ protected void visitMethodCallArguments(final ClassNode receiver, final Argument Parameter target = params[i]; ClassNode targetType = target.getType(); ClosureExpression source = (ClosureExpression) expression; - checkClosureWithDelegatesTo(receiver, selectedMethod, newArgs, params, source, target); + checkClosureWithDelegatesTo(receiver, selectedMethod, args(expressions), params, source, target); if (selectedMethod instanceof ExtensionMethodNode) { if (i > 0) { inferClosureParameterTypes(receiver, arguments, source, target, selectedMethod); } } else { - inferClosureParameterTypes(receiver, newArgs, source, target, selectedMethod); + inferClosureParameterTypes(receiver, arguments, source, target, selectedMethod); } if (isFunctionalInterface(targetType)) { storeInferredReturnType(source, GenericsUtils.parameterizeSAM(targetType).getV2());