From bbde38a6dc4a2b0a4e33c74228cccb7c960fef78 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 31 Jan 2013 18:33:23 +0400 Subject: [PATCH] KT-1360 Vararg bug in front-end --- .../ValueArgumentsToParametersMapper.java | 51 ++++++++++--------- .../box/vararg/varargsAndFunctionLiterals.kt | 16 ++++++ .../varargs/varargsAndFunctionLiterals.kt | 13 +++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 ++ .../BlackBoxCodegenTestGenerated.java | 10 +++- 5 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt create mode 100644 compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java index bb5fb42409d..6b755c08154 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java @@ -20,6 +20,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.psi.impl.source.tree.LeafPsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; @@ -31,9 +32,7 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; @@ -102,6 +101,26 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap // We saw only positioned arguments so far private final ProcessorState positionedOnly = new ProcessorState() { + + private Queue valueParameterQueue; + + @Nullable + public ValueParameterDescriptor nextValueParameter() { + if (valueParameterQueue == null) { + valueParameterQueue = new LinkedList(candidateCall.getCandidateDescriptor().getValueParameters()); + } + + ValueParameterDescriptor head = valueParameterQueue.peek(); + if (head == null) return null; + + // If we found a vararg parameter, we are stuck with it forever + if (head.getVarargElementType() == null) { + valueParameterQueue.remove(); + } + + return head; + } + @Override public ProcessorState processNamedArgument(@NotNull ValueArgument argument) { return positionedThenNamed.processNamedArgument(argument); @@ -109,32 +128,16 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap @Override public ProcessorState processPositionedArgument(@NotNull ValueArgument argument, int index) { - D candidate = candidateCall.getCandidateDescriptor(); + ValueParameterDescriptor valueParameterDescriptor = nextValueParameter(); - List valueParameters = candidate.getValueParameters(); - - int parameterCount = valueParameters.size(); - if (index < parameterCount) { - ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(index); + if (valueParameterDescriptor != null) { usedParameters.add(valueParameterDescriptor); putVararg(valueParameterDescriptor, argument); } - else if (!valueParameters.isEmpty()) { - ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1); - if (valueParameterDescriptor.getVarargElementType() != null) { - putVararg(valueParameterDescriptor, argument); - usedParameters.add(valueParameterDescriptor); - } - else { - report(TOO_MANY_ARGUMENTS.on(argument.asElement(), candidate)); - unmappedArguments.add(argument); - setStatus(WEAK_ERROR); - } - } else { - report(TOO_MANY_ARGUMENTS.on(argument.asElement(), candidate)); + report(TOO_MANY_ARGUMENTS.on(argument.asElement(), candidateCall.getCandidateDescriptor())); unmappedArguments.add(argument); - setStatus(ERROR); + setStatus(WEAK_ERROR); } return positionedOnly; @@ -326,4 +329,4 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap } private ValueArgumentsToParametersMapper() {} -} +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt b/compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt new file mode 100644 index 00000000000..3c7dca68c44 --- /dev/null +++ b/compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt @@ -0,0 +1,16 @@ +fun foo(a: Int, vararg b: Int, f: (IntArray) -> String): String { + return "test" + a + " " + f(b) +} + +fun box(): String { + val test1 = foo(1) {a -> "" + a.size} + if (test1 != "test1 0") return test1 + + val test2 = foo(2, 2) {a -> "" + a.size} + if (test2 != "test2 1") return test2 + + val test3 = foo(3, 2, 3) {a -> "" + a.size} + if (test3 != "test3 2") return test3 + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt b/compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt new file mode 100644 index 00000000000..57bde281c46 --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt @@ -0,0 +1,13 @@ +fun f(vararg t : Int, f : ()->Unit) { +} + +fun test() { + f {} + f() {} + f(1) { + + } + f(1, 2) { + + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 32358d8882b..9ccce46684d 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4261,6 +4261,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/varargs/UnaryVsVararg.kt"); } + @TestMetadata("varargsAndFunctionLiterals.kt") + public void testVarargsAndFunctionLiterals() throws Exception { + doTest("compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt"); + } + } public static Test innerSuite() { diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index b91084927d8..b61e392488a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -16,13 +16,16 @@ package org.jetbrains.jet.codegen.generated; +import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; + +import java.io.File; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import java.io.File; +import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @@ -3249,6 +3252,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { blackBoxFileByFullPath("compiler/testData/codegen/box/vararg/kt796_797.kt"); } + @TestMetadata("varargsAndFunctionLiterals.kt") + public void testVarargsAndFunctionLiterals() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt"); + } + } @TestMetadata("compiler/testData/codegen/box/when")