Supported creating varargs of reified type parameter
This commit is contained in:
committed by
Andrey Breslav
parent
29b4ba9b3d
commit
a8ca39754c
@@ -373,10 +373,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@NotNull
|
||||
public Type expressionType(JetExpression expression) {
|
||||
JetType type = bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
JetType type = expressionJetType(expression);
|
||||
return type == null ? Type.VOID_TYPE : asmType(type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetType expressionJetType(JetExpression expression) {
|
||||
return bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, StackValue receiver) {
|
||||
return genQualified(receiver, expression.getExpression());
|
||||
@@ -2525,14 +2530,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
v.dup();
|
||||
v.invokevirtual(owner, "size", "()I", false);
|
||||
v.newarray(elementType);
|
||||
newArrayInstruction(outType);
|
||||
v.invokevirtual(owner, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
|
||||
v.checkcast(type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.iconst(arguments.size());
|
||||
v.newarray(elementType);
|
||||
newArrayInstruction(outType);
|
||||
for (int i = 0; i != size; ++i) {
|
||||
v.dup();
|
||||
v.iconst(i);
|
||||
@@ -3460,19 +3465,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
throw new CompilationException("primitive array constructor requires one argument", null, expression);
|
||||
}
|
||||
|
||||
if (isArray) {
|
||||
gen(args.get(0), Type.INT_TYPE);
|
||||
putReifierMarkerIfTypeIsReifiedParameter(
|
||||
arrayType.getArguments().get(0).getType(),
|
||||
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
|
||||
);
|
||||
v.newarray(boxType(asmType(arrayType.getArguments().get(0).getType())));
|
||||
}
|
||||
else {
|
||||
Type type = typeMapper.mapType(arrayType);
|
||||
gen(args.get(0), Type.INT_TYPE);
|
||||
v.newarray(correctElementType(type));
|
||||
}
|
||||
gen(args.get(0), Type.INT_TYPE);
|
||||
newArrayInstruction(arrayType);
|
||||
|
||||
if (args.size() == 2) {
|
||||
int sizeIndex = myFrameMap.enterTemp(Type.INT_TYPE);
|
||||
@@ -3512,6 +3506,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
}
|
||||
|
||||
public void newArrayInstruction(@NotNull JetType arrayType) {
|
||||
if (KotlinBuiltIns.getInstance().isArray(arrayType)) {
|
||||
JetType elementJetType = arrayType.getArguments().get(0).getType();
|
||||
putReifierMarkerIfTypeIsReifiedParameter(
|
||||
elementJetType,
|
||||
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
|
||||
);
|
||||
v.newarray(boxType(asmType(elementJetType)));
|
||||
}
|
||||
else {
|
||||
Type type = typeMapper.mapType(arrayType);
|
||||
v.newarray(correctElementType(type));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression, StackValue receiver) {
|
||||
JetExpression array = expression.getArrayExpression();
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
@@ -45,7 +46,11 @@ public class CopyToArray extends IntrinsicMethod {
|
||||
v.dup();
|
||||
v.invokeinterface("java/util/Collection", "size", "()I");
|
||||
|
||||
v.newarray(returnType.getElementType());
|
||||
assert element instanceof JetExpression;
|
||||
JetType arrayType = codegen.expressionJetType((JetExpression) element);
|
||||
assert arrayType != null;
|
||||
|
||||
codegen.newArrayInstruction(arrayType);
|
||||
v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;");
|
||||
|
||||
return getType(Object[].class);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
inline fun <reified T> copy(c: Collection<T>): Array<T> {
|
||||
return c.copyToArray()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a: Array<String> = copy(listOf("a", "b", "c"))
|
||||
assertEquals("abc", a.join(""))
|
||||
|
||||
val b: Array<Int> = copy(listOf(1,2,3))
|
||||
assertEquals("123", b.map { it.toString() }.join(""))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun <T> foo(vararg a: T) = a.size
|
||||
|
||||
inline fun <reified T> bar(a: Array<T>, block: () -> T): Array<T> {
|
||||
assertEquals(4, foo(*a, block(), block()))
|
||||
|
||||
return array(*a, block(), block())
|
||||
}
|
||||
|
||||
inline fun <reified T> empty() = array<T>()
|
||||
|
||||
fun box(): String {
|
||||
|
||||
var i = 0
|
||||
val a: Array<String> = bar(array("1", "2")) { i++; i.toString() }
|
||||
assertEquals("1234", a.join(""))
|
||||
|
||||
i = 0
|
||||
val b: Array<Int> = bar(array(0, 1)) { i++ }
|
||||
assertEquals("0123", b.map { it.toString() }.join(""))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun <T> foo(vararg a: T) = a.size
|
||||
|
||||
inline fun <reified T> bar(block: () -> T): Array<T> {
|
||||
assertEquals(2, foo(block(), block()))
|
||||
|
||||
return array(block(), block(), block())
|
||||
}
|
||||
|
||||
inline fun <reified T> empty() = array<T>()
|
||||
|
||||
fun box(): String {
|
||||
var i = 0
|
||||
val a: Array<String> = bar() { i++; i.toString() }
|
||||
assertEquals("345", a.join(""))
|
||||
|
||||
i = 0
|
||||
val b: Array<Int> = bar() { i++ }
|
||||
assertEquals("234", b.map { it.toString() }.join(""))
|
||||
|
||||
val c: Array<String> = empty()
|
||||
assertEquals(0, c.size)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+18
@@ -2471,6 +2471,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("copyToArray.kt")
|
||||
public void testCopyToArray() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/copyToArray.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultJavaClass.kt")
|
||||
public void testDefaultJavaClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/defaultJavaClass.kt");
|
||||
@@ -2542,6 +2548,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("spreads.kt")
|
||||
public void testSpreads() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/spreads.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargs.kt")
|
||||
public void testVarargs() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/varargs.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/storeStackBeforeInline")
|
||||
|
||||
Reference in New Issue
Block a user