KT-4348: Array access operator overloading doesn't work with vararg's

#KT-4348 Fixed
This commit is contained in:
Mikhael Bogdanov
2013-12-26 11:17:15 +04:00
parent 2daf6961b2
commit c9c50e4107
3 changed files with 44 additions and 9 deletions
@@ -2288,17 +2288,28 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
private int pushMethodArguments(@NotNull ResolvedCall resolvedCall, List<Type> valueParameterTypes) { private int pushMethodArguments(@NotNull ResolvedCall resolvedCall, List<Type> valueParameterTypes) {
return pushMethodArguments(resolvedCall, valueParameterTypes, false);
}
private int pushMethodArguments(@NotNull ResolvedCall resolvedCall, List<Type> valueParameterTypes, boolean skipLast) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex(); List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
CallableDescriptor fd = resolvedCall.getResultingDescriptor(); CallableDescriptor fd = resolvedCall.getResultingDescriptor();
List<ValueParameterDescriptor> valueParameters = fd.getValueParameters();
if (fd.getValueParameters().size() != valueArguments.size()) { if (valueParameters.size() != valueArguments.size()) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
int mask = 0; int mask = 0;
for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) {
for (Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator(); iterator.hasNext(); ) {
ValueParameterDescriptor valueParameter = iterator.next();
if (skipLast && !iterator.hasNext()) {
continue;
}
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex()); ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
Type parameterType = valueParameterTypes.get(valueParameter.getIndex()); Type parameterType = valueParameterTypes.get(valueParameter.getIndex());
if (resolvedValueArgument instanceof ExpressionValueArgument) { if (resolvedValueArgument instanceof ExpressionValueArgument) {
@@ -3380,20 +3391,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText(); assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
Callable callable = resolveToCallable(operationDescriptor, false); Callable callable = resolveToCallable(operationDescriptor, false);
Method asmMethod = resolveToCallableMethod(operationDescriptor, false, context).getSignature().getAsmMethod();
Type[] argumentTypes = asmMethod.getArgumentTypes();
if (callable instanceof CallableMethod) { if (callable instanceof CallableMethod) {
genThisAndReceiverFromResolvedCall(receiver, resolvedCall, (CallableMethod) callable); genThisAndReceiverFromResolvedCall(receiver, resolvedCall, (CallableMethod) callable);
pushMethodArguments(resolvedCall, ((CallableMethod) callable).getValueParameterTypes(), !isGetter);
} }
else { else {
gen(array, arrayType); // intrinsic method gen(array, arrayType); // intrinsic method
}
int index = operationDescriptor.getReceiverParameter() != null ? 1 : 0; int index = operationDescriptor.getReceiverParameter() != null ? 1 : 0;
Method asmMethod = resolveToCallableMethod(operationDescriptor, false, context).getSignature().getAsmMethod(); for (JetExpression jetExpression : expression.getIndexExpressions()) {
Type[] argumentTypes = asmMethod.getArgumentTypes(); gen(jetExpression, argumentTypes[index]);
for (JetExpression jetExpression : expression.getIndexExpressions()) { index++;
gen(jetExpression, argumentTypes[index]); }
index++;
} }
Type elementType = isGetter ? asmMethod.getReturnType() : ArrayUtil.getLastElement(argumentTypes); Type elementType = isGetter ? asmMethod.getReturnType() : ArrayUtil.getLastElement(argumentTypes);
@@ -0,0 +1,17 @@
fun String.get(vararg value: Any) : String {
return if (value[0] == 44 && value[1] == "example") "OK" else "fail"
}
fun Int.get(vararg value: Any) : Int {
return if (value[0] == 44 && value[1] == "example") 1 else 0
}
fun main(args: Array<String>) {
12 [44, "example"]
}
fun box(): String {
if ("foo" [44, "example"] != "OK") return "fail1"
if (11 [44, "example"] != 1) return "fail2"
return "OK"
}
@@ -193,6 +193,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/arrays/kt33.kt"); doTest("compiler/testData/codegen/box/arrays/kt33.kt");
} }
@TestMetadata("kt4348.kt")
public void testKt4348() throws Exception {
doTest("compiler/testData/codegen/box/arrays/kt4348.kt");
}
@TestMetadata("kt503.kt") @TestMetadata("kt503.kt")
public void testKt503() throws Exception { public void testKt503() throws Exception {
doTest("compiler/testData/codegen/box/arrays/kt503.kt"); doTest("compiler/testData/codegen/box/arrays/kt503.kt");