javaClass<T> is supported for reified T

This commit is contained in:
Denis Zharkov
2014-10-06 15:29:26 +04:00
committed by Andrey Breslav
parent f3c49c605f
commit fc1d8dd9ce
7 changed files with 62 additions and 2 deletions
@@ -3810,7 +3810,7 @@ The "returned" value of try expression with no finally is either the last expres
return StackValue.onStack(type);
}
private void putReifierMarkerIfTypeIsReifiedParameter(@NotNull JetType type, @NotNull String markerMethodName) {
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull JetType type, @NotNull String markerMethodName) {
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
v.iconst(typeParameterDescriptor.getIndex());
@@ -37,6 +37,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
}
public fun reifyInstructions(instructions: InsnList) {
@@ -62,6 +63,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, asmType)
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, asmType)
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
else -> false
}) {
return
@@ -88,6 +90,13 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
return true
}
private fun processJavaClass(insn: MethodInsnNode, parameter: Type): Boolean {
val next = insn.getNext()
if (next !is LdcInsnNode) return false
next.cst = parameter
return true
}
private fun getParameterIndex(insn: MethodInsnNode): Int? {
val prev = insn.getPrevious()!!
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.codegen.inline.ReifiedTypeInliner;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
@@ -49,7 +50,12 @@ public class JavaClassFunction extends IntrinsicMethod {
(JetElement) element, codegen.getBindingContext());
JetType returnType = resolvedCall.getResultingDescriptor().getReturnType();
assert returnType != null;
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(returnType.getArguments().get(0).getType()));
JetType type = returnType.getArguments().get(0).getType();
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(type));
return getType(Class.class);
}
@@ -0,0 +1,17 @@
import kotlin.test.assertEquals
inline fun <reified T> foo(x: Class<T> = javaClass<T>()): String = x.getName()
inline fun <reified R> bar(x: R): String = foo<R>()
fun box(): String {
assertEquals("java.lang.String", foo<String>())
assertEquals("java.lang.Integer", foo<Int>())
assertEquals("java.lang.Object", foo<Any>())
assertEquals("java.lang.String", bar("abc"))
assertEquals("java.lang.Integer", bar(1))
assertEquals("java.lang.Object", bar(Any()))
return "OK"
}
@@ -0,0 +1,12 @@
import kotlin.test.assertEquals
inline fun<reified T> javaClassName(): String {
return javaClass<T>().getName()
}
fun box(): String {
assertEquals("java.lang.String", javaClassName<String>())
assertEquals("java.lang.Integer", javaClassName<Int>())
assertEquals("java.lang.Object", javaClassName<Any>())
return "OK"
}
@@ -2426,6 +2426,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("defaultJavaClass.kt")
public void testDefaultJavaClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/defaultJavaClass.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("filterIsInstance.kt")
public void testFilterIsInstance() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/filterIsInstance.kt");
@@ -2438,6 +2444,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("javaClass.kt")
public void testJavaClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/javaClass.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("newArrayInt.kt")
public void testNewArrayInt() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt");
@@ -118,6 +118,10 @@ public class Intrinsics {
throwUndefinedForReified();
}
public static void reifyJavaClass(int parameterTypeIndex) {
throwUndefinedForReified();
}
public static <T extends Throwable> T sanitizeStackTrace(T throwable) {
StackTraceElement[] stackTrace = throwable.getStackTrace();
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>(stackTrace.length);