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
|
@NotNull
|
||||||
public Type expressionType(JetExpression expression) {
|
public Type expressionType(JetExpression expression) {
|
||||||
JetType type = bindingContext.get(EXPRESSION_TYPE, expression);
|
JetType type = expressionJetType(expression);
|
||||||
return type == null ? Type.VOID_TYPE : asmType(type);
|
return type == null ? Type.VOID_TYPE : asmType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetType expressionJetType(JetExpression expression) {
|
||||||
|
return bindingContext.get(EXPRESSION_TYPE, expression);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, StackValue receiver) {
|
public StackValue visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, StackValue receiver) {
|
||||||
return genQualified(receiver, expression.getExpression());
|
return genQualified(receiver, expression.getExpression());
|
||||||
@@ -2525,14 +2530,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
v.dup();
|
v.dup();
|
||||||
v.invokevirtual(owner, "size", "()I", false);
|
v.invokevirtual(owner, "size", "()I", false);
|
||||||
v.newarray(elementType);
|
newArrayInstruction(outType);
|
||||||
v.invokevirtual(owner, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
|
v.invokevirtual(owner, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
|
||||||
v.checkcast(type);
|
v.checkcast(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.iconst(arguments.size());
|
v.iconst(arguments.size());
|
||||||
v.newarray(elementType);
|
newArrayInstruction(outType);
|
||||||
for (int i = 0; i != size; ++i) {
|
for (int i = 0; i != size; ++i) {
|
||||||
v.dup();
|
v.dup();
|
||||||
v.iconst(i);
|
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);
|
throw new CompilationException("primitive array constructor requires one argument", null, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArray) {
|
gen(args.get(0), Type.INT_TYPE);
|
||||||
gen(args.get(0), Type.INT_TYPE);
|
newArrayInstruction(arrayType);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.size() == 2) {
|
if (args.size() == 2) {
|
||||||
int sizeIndex = myFrameMap.enterTemp(Type.INT_TYPE);
|
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
|
@Override
|
||||||
public StackValue visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression, StackValue receiver) {
|
public StackValue visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression, StackValue receiver) {
|
||||||
JetExpression array = expression.getArrayExpression();
|
JetExpression array = expression.getArrayExpression();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen.intrinsics;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.Type;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
@@ -45,7 +46,11 @@ public class CopyToArray extends IntrinsicMethod {
|
|||||||
v.dup();
|
v.dup();
|
||||||
v.invokeinterface("java/util/Collection", "size", "()I");
|
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;");
|
v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;");
|
||||||
|
|
||||||
return getType(Object[].class);
|
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);
|
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")
|
@TestMetadata("defaultJavaClass.kt")
|
||||||
public void testDefaultJavaClass() throws Exception {
|
public void testDefaultJavaClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/defaultJavaClass.kt");
|
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");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt");
|
||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/storeStackBeforeInline")
|
||||||
|
|||||||
Reference in New Issue
Block a user