KT-1360 Vararg bug in front-end

This commit is contained in:
Andrey Breslav
2013-01-31 18:33:23 +04:00
parent 1fcbf1721b
commit bbde38a6dc
5 changed files with 70 additions and 25 deletions
@@ -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<ValueParameterDescriptor> valueParameterQueue;
@Nullable
public ValueParameterDescriptor nextValueParameter() {
if (valueParameterQueue == null) {
valueParameterQueue = new LinkedList<ValueParameterDescriptor>(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<ValueParameterDescriptor> 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() {}
}
}
@@ -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"
}
@@ -0,0 +1,13 @@
fun f(vararg <!UNUSED_PARAMETER!>t<!> : Int, <!UNUSED_PARAMETER!>f<!> : ()->Unit) {
}
fun test() {
f {}
f() {}
f(1) {
}
f(1, 2) {
}
}
@@ -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() {
@@ -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")