diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cbe4979bc2f..54da476c864 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -207,28 +207,24 @@ public class ExpressionCodegen extends JetVisitor implem ); literalCodegen.generate(); - if (containsReifiedParametersInSupertypes(classDescriptor)) { - literalCodegen.setWereReifierMarkers(true); - } + addReifiedParametersFromSignature(literalCodegen, classDescriptor); + propagateChildReifiedTypeParametersUsages(literalCodegen.getReifiedTypeParametersUsages()); - if (literalCodegen.wereReifierMarkers()) { - getParentCodegen().setWereReifierMarkers(true); - } - - return new ObjectLiteralResult(literalCodegen.wereReifierMarkers(), classDescriptor); + return new ObjectLiteralResult( + literalCodegen.getReifiedTypeParametersUsages().wereUsedReifiedParameters(), + classDescriptor + ); } - private static boolean containsReifiedParametersInSupertypes(@NotNull ClassDescriptor descriptor) { + private static void addReifiedParametersFromSignature(@NotNull MemberCodegen member, @NotNull ClassDescriptor descriptor) { for (JetType type : descriptor.getTypeConstructor().getSupertypes()) { for (TypeProjection supertypeArgument : type.getArguments()) { TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(supertypeArgument.getType()); if (parameterDescriptor != null && parameterDescriptor.isReified()) { - return true; + member.getReifiedTypeParametersUsages().addUsedReifiedParameter(parameterDescriptor.getName().asString()); } } } - - return false; } private static class ObjectLiteralResult { @@ -1404,8 +1400,9 @@ public class ExpressionCodegen extends JetVisitor implem closureCodegen.generate(); - if (closureCodegen.wereReifierMarkers()) { + if (closureCodegen.getReifiedTypeParametersUsages().wereUsedReifiedParameters()) { ReifiedTypeInliner.putNeedClassReificationMarker(v); + propagateChildReifiedTypeParametersUsages(closureCodegen.getReifiedTypeParametersUsages()); } return closureCodegen.putInstanceOnStack(this); @@ -2304,7 +2301,7 @@ public class ExpressionCodegen extends JetVisitor implem @NotNull private CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall resolvedCall) { Map typeArguments = resolvedCall.getTypeArguments(); - ReifiedTypeParameterMappings mappings = new ReifiedTypeParameterMappings(typeArguments.size()); + ReifiedTypeParameterMappings mappings = new ReifiedTypeParameterMappings(); for (Map.Entry entry : typeArguments.entrySet()) { TypeParameterDescriptor key = entry.getKey(); if (!key.isReified()) continue; @@ -2314,16 +2311,13 @@ public class ExpressionCodegen extends JetVisitor implem // type is not generic // boxType call needed because inlined method is compiled for T as java/lang/Object mappings.addParameterMappingToType( - key.getIndex(), key.getName().getIdentifier(), boxType(asmType(entry.getValue())) ); } else { mappings.addParameterMappingToNewParameter( - key.getIndex(), key.getName().getIdentifier(), - parameterDescriptor.getIndex(), parameterDescriptor.getName().getIdentifier() ); } @@ -3901,15 +3895,23 @@ The "returned" value of try expression with no finally is either the last expres public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull JetType type, @NotNull String markerMethodName) { TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type); if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) { - parentCodegen.setWereReifierMarkers(true); - v.iconst(typeParameterDescriptor.getIndex()); + if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) { + parentCodegen.getReifiedTypeParametersUsages(). + addUsedReifiedParameter(typeParameterDescriptor.getName().asString()); + } + + v.visitLdcInsn(typeParameterDescriptor.getName().asString()); v.invokestatic( IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName, - Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE), false + Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false ); } } + public void propagateChildReifiedTypeParametersUsages(@NotNull ReifiedTypeParametersUsages usages) { + parentCodegen.getReifiedTypeParametersUsages().propagateChildUsagesWithinContext(usages, context); + } + @Override public StackValue visitWhenExpression(@NotNull JetWhenExpression expression, StackValue receiver) { return generateWhenExpression(expression, false); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index a646a80b185..ec2f5119842 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.inline.InlineCodegenUtil; import org.jetbrains.jet.codegen.inline.NameGenerator; +import org.jetbrains.jet.codegen.inline.ReifiedTypeParametersUsages; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; @@ -46,9 +47,7 @@ import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; @@ -69,7 +68,7 @@ public abstract class MemberCodegen classesToRemove = new HashSet(); - private boolean needFurtherReification = false; + private final ReifiedTypeParametersUsages reifiedTypeParametersUsages = new ReifiedTypeParametersUsages(); private InlineResult() { @@ -50,11 +50,8 @@ public class InlineResult { return classesToRemove; } - public boolean needFurtherReification() { - return needFurtherReification; - } - - public void markAsNeededFurtherReificationIf(boolean condtition) { - this.needFurtherReification |= condtition; + @NotNull + public ReifiedTypeParametersUsages getReifiedTypeParametersUsages() { + return reifiedTypeParametersUsages; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java index 99511c688e4..ed0628e9e28 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java @@ -172,9 +172,9 @@ public class MethodInliner { result.addClassToRemove(anonymousObjectGen.getOwnerInternalName()); } - if (transformResult.needFurtherReification()) { + if (transformResult.getReifiedTypeParametersUsages().wereUsedReifiedParameters()) { ReifiedTypeInliner.putNeedClassReificationMarker(mv); - result.markAsNeededFurtherReificationIf(true); + result.getReifiedTypeParametersUsages().mergeAll(transformResult.getReifiedTypeParametersUsages()); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt index 846b711bea6..80556472b24 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt @@ -34,6 +34,8 @@ import org.jetbrains.org.objectweb.asm.signature.SignatureReader import org.jetbrains.org.objectweb.asm.signature.SignatureWriter import org.jetbrains.org.objectweb.asm.MethodVisitor import com.google.common.collect.ImmutableSet +import org.jetbrains.jet.codegen.context.MethodContext +import org.jetbrains.jet.lang.resolve.DescriptorUtils public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) { @@ -70,34 +72,35 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame } /** - * @return true if there is something need to be reified further + * @return set of type parameters' identifiers contained in markers that should be reified further * e.g. when we're generating inline function containing reified T * and another function containing reifiable parts is inlined into that function */ - public fun reifyInstructions(instructions: InsnList): Boolean { - if (parametersMapping == null) return false - var needFurtherReification = false + public fun reifyInstructions(instructions: InsnList): ReifiedTypeParametersUsages { + if (parametersMapping == null) return ReifiedTypeParametersUsages() + var result = ReifiedTypeParametersUsages() for (insn in instructions.toArray()) { if (isParametrisedReifiedMarker(insn)) { - if (processReifyMarker(insn as MethodInsnNode, instructions)) { - needFurtherReification = true + val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions) + if (newName != null) { + result.addUsedReifiedParameter(newName) } } } - return needFurtherReification + return result } public fun reifySignature(oldSignature: String): SignatureReificationResult { - if (parametersMapping == null) return SignatureReificationResult(oldSignature, false) + if (parametersMapping == null) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages()) val signatureRemapper = object : SignatureWriter() { - var needFurtherReification = false + var typeParamsToReify = ReifiedTypeParametersUsages() override fun visitTypeVariable(name: String?) { val mapping = getMappingByName(name) ?: - return super.visitTypeArgument() + return super.visitTypeVariable(name) if (mapping.newName != null) { - needFurtherReification = true + typeParamsToReify.addUsedReifiedParameter(mapping.newName) return super.visitTypeVariable(mapping.newName) } @@ -110,7 +113,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame val mapping = getMappingByName(name) ?: return super.visitFormalTypeParameter(name) if (mapping.newName != null) { - needFurtherReification = true + typeParamsToReify.addUsedReifiedParameter(mapping.newName) super.visitFormalTypeParameter(mapping.newName) } } @@ -120,35 +123,38 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame SignatureReader(oldSignature).accept(signatureRemapper) - return SignatureReificationResult(signatureRemapper.toString(), signatureRemapper.needFurtherReification) + return SignatureReificationResult(signatureRemapper.toString(), signatureRemapper.typeParamsToReify) } - data class SignatureReificationResult(val newSignature: String, val needFurtherReification: Boolean) + data class SignatureReificationResult(val newSignature: String, val typeParametersUsages: ReifiedTypeParametersUsages) /** - * @return true if this marker should be reified further + * @return new type parameter identifier if this marker should be reified further + * or null if it shouldn't */ - private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): Boolean { - val mapping = getTypeParameterMapping(insn) ?: return false + private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? { + val mapping = getTypeParameterMapping(insn) ?: return null val asmType = mapping.asmType if (asmType != null) { - if (!when (insn.name) { + // process* methods return false if marker should be reified further + // or it's invalid (may be emitted explicitly in code) + // they return true if instruction is reified and marker can be deleted + if (when (insn.name) { 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 false + instructions.remove(insn.getPrevious()!!) + instructions.remove(insn) } - instructions.remove(insn.getPrevious()!!) - instructions.remove(insn) - return false + return null } else { - instructions.set(insn.getPrevious()!!, iconstInsn(mapping.newIndex!!)) - return true + instructions.set(insn.getPrevious()!!, LdcInsnNode(mapping.newName)) + return mapping.newName } } @@ -174,51 +180,61 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame return true } - private fun getParameterIndex(insn: MethodInsnNode): Int? { + private fun getParameterName(insn: MethodInsnNode): String? { val prev = insn.getPrevious()!! return when (prev.getOpcode()) { - Opcodes.ICONST_0 -> 0 - Opcodes.ICONST_1 -> 1 - Opcodes.ICONST_2 -> 2 - Opcodes.ICONST_3 -> 3 - Opcodes.ICONST_4 -> 4 - Opcodes.ICONST_5 -> 5 - Opcodes.BIPUSH, Opcodes.SIPUSH -> (prev as IntInsnNode).operand - Opcodes.LDC -> (prev as LdcInsnNode).cst as Int - else -> throw AssertionError("Unexpected opcode ${prev.getOpcode()}") + Opcodes.LDC -> (prev as LdcInsnNode).cst as String + else -> null } } private fun getTypeParameterMapping(insn: MethodInsnNode): ReifiedTypeParameterMapping? { - return parametersMapping?.get(getParameterIndex(insn) ?: return null) + return parametersMapping?.get(getParameterName(insn) ?: return null) } } -public class ReifiedTypeParameterMappings(private val size: Int) { - private val mappingsByIndex = arrayOfNulls(size) - private val indexByParameterName = hashMapOf() +public class ReifiedTypeParameterMappings() { + private val mappingsByName = hashMapOf() - public fun addParameterMappingToType(index: Int, name: String, asmType: Type) { - mappingsByIndex[index] = ReifiedTypeParameterMapping(name, asmType, null, null) - indexByParameterName[name] = index + public fun addParameterMappingToType(name: String, asmType: Type) { + mappingsByName[name] = ReifiedTypeParameterMapping(name, asmType, null) } - public fun addParameterMappingToNewParameter(index: Int, name: String, newIndex: Int, newName: String) { - mappingsByIndex[index] = ReifiedTypeParameterMapping(name, null, newIndex, newName) - indexByParameterName[name] = index + public fun addParameterMappingToNewParameter(name: String, newName: String) { + mappingsByName[name] = ReifiedTypeParameterMapping(name, null, newName) } - fun get(index: Int) = mappingsByIndex[index] fun get(name: String): ReifiedTypeParameterMapping? { - return this[indexByParameterName[name] ?: return null] + return mappingsByName[name] } } -public class ReifiedTypeParameterMapping(val name: String, val asmType: Type?, val newIndex: Int?, val newName: String?) +public class ReifiedTypeParameterMapping(val name: String, val asmType: Type?, val newName: String?) -private fun iconstInsn(n: Int): AbstractInsnNode { - val node = MethodNode() - InstructionAdapter(node).iconst(n) - return node.instructions.getFirst()!! +public class ReifiedTypeParametersUsages { + val usedTypeParameters: MutableSet = hashSetOf() + + public fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty() + + public fun addUsedReifiedParameter(name: String) { + usedTypeParameters.add(name) + } + + public fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) { + if (!child.wereUsedReifiedParameters()) return + // used for propagating reified TP usages from children member codegen to parent's + // mark enclosing object-literal/lambda as needed reification iff + // 1. at least one of it's method contains operations to reify + // 2. reified type parameter of these operations is not from current method signature + // i.e. from outer scope + child.usedTypeParameters.filterNot { + DescriptorUtils.containsReifiedTypeParameterWithName(context.getContextDescriptor(), it) + }.forEach { usedTypeParameters.add(it) } + } + + public fun mergeAll(other: ReifiedTypeParametersUsages) { + if (!other.wereUsedReifiedParameters()) return + usedTypeParameters.addAll(other.usedTypeParameters) + } } diff --git a/compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectNoPropagate.kt b/compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectNoPropagate.kt new file mode 100644 index 00000000000..b405666b768 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectNoPropagate.kt @@ -0,0 +1,36 @@ +import kotlin.test.assertEquals + +trait A { + fun f1(): String + fun f2(): String + fun f3(): String +} + +fun doWork(block: () -> String) = block() +inline fun doWorkInline(block: () -> String) = block() + +fun box(): String { + val x = object { + inline fun bar1(): A = object : A { + override fun f1(): String = javaClass().getName() + override fun f2(): String = doWork { javaClass().getName() } + override fun f3(): String = doWorkInline { javaClass().getName() } + } + + inline fun bar2() = javaClass().getName() + inline fun bar3() = doWork { javaClass().getName() } + inline fun bar4() = doWorkInline { javaClass().getName() } + } + + val y: A = x.bar1() + assertEquals("java.lang.String", y.f1()) + assertEquals("java.lang.String", y.f2()) + assertEquals("java.lang.String", y.f3()) + + + assertEquals("java.lang.Integer", x.bar2()) + assertEquals("java.lang.Double", x.bar3()) + assertEquals("java.lang.Long", x.bar4()) + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/nestedReified.kt b/compiler/testData/codegen/boxWithStdlib/reified/nestedReified.kt new file mode 100644 index 00000000000..4d5b463c553 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/nestedReified.kt @@ -0,0 +1,42 @@ +import kotlin.test.assertEquals + +inline fun foo(): Array { + val x = object { + inline fun bar(): Array = array( + javaClass().getName(), javaClass().getName(), javaClass().getName() + ) + fun f1() = bar() + fun f2() = bar() + fun f3() = bar() + fun f4() = bar() + } + + val x1 = x.f1() + val x2 = x.f2() + val x3 = x.f3() + val x4 = x.f4() + + return array( + x1[0], x1[1], x1[2], + x2[0], x2[1], x2[2], + x3[0], x3[1], x3[2], + x4[0], x4[1], x4[2] + ) +} + +fun box(): String { + val result = foo() + + val expected = array( + "java.lang.Double", "java.lang.Integer", "java.lang.Integer", + "java.lang.Integer", "java.lang.Double", "java.lang.Integer", + "java.lang.Boolean", "java.lang.Double", "java.lang.Integer", + "java.lang.Double", "java.lang.Boolean", "java.lang.Integer" + ) + + for (i in expected.indices) { + assertEquals(expected[i], result[i], "$i-th element") + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/nestedReifiedSignature.kt b/compiler/testData/codegen/boxWithStdlib/reified/nestedReifiedSignature.kt new file mode 100644 index 00000000000..9967b2e9d3a --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/nestedReifiedSignature.kt @@ -0,0 +1,32 @@ +import kotlin.test.assertEquals + +open class A + +inline fun foo(): Array> { + val x = object { + inline fun bar(): A<*,*,*> = object : A() {} + fun f1() = bar() + fun f2() = bar() + fun f3() = bar() + fun f4() = bar() + } + + return array(x.f1(), x.f2(), x.f3(), x.f4()) +} + +fun box(): String { + val result = foo() + + val expected = array( + Triple("java.lang.Double", "java.lang.Integer", "java.lang.Integer"), + Triple("java.lang.Integer", "java.lang.Double", "java.lang.Integer"), + Triple("java.lang.Boolean", "java.lang.Double", "java.lang.Integer"), + Triple("java.lang.Double", "java.lang.Boolean", "java.lang.Integer") + ).map { "A<${it.first}, ${it.second}, ${it.third}>" } + + for (i in expected.indices) { + assertEquals(expected[i], result[i].javaClass.getGenericSuperclass()?.toString(), "$i-th element") + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObject.kt b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObject.kt new file mode 100644 index 00000000000..339a09dd4a4 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObject.kt @@ -0,0 +1,21 @@ +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +trait A { + fun f(): String + fun g(): String +} + +fun box(): String { + val x: A = object : A { + private inline fun localClassName(): String = javaClass().getName() + override fun f(): String = foo { localClassName() } + override fun g(): String = foo { localClassName() } + } + + assertEquals("java.lang.String", x.f()) + assertEquals("java.lang.Integer", x.g()) + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObjectWithinReified.kt b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObjectWithinReified.kt new file mode 100644 index 00000000000..94335af2b62 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObjectWithinReified.kt @@ -0,0 +1,28 @@ +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +inline fun className(): String = javaClass().getName() + +inline fun lambdaShouldBeReified(): String = foo { className() } + +trait A { + fun f(): String + fun g(): String +} +inline fun AFactory(): A = object : A { + override fun f(): String = className() + override fun g(): String = foo { className() } +} + +fun box(): String { + assertEquals("java.lang.String", lambdaShouldBeReified()) + assertEquals("java.lang.Integer", lambdaShouldBeReified()) + + val x: A = AFactory() + + assertEquals("java.lang.String", x.f()) + assertEquals("java.lang.Integer", x.g()) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 58d5972e836..7bb0504cf0c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2640,6 +2640,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("anonymousObjectNoPropagate.kt") + public void testAnonymousObjectNoPropagate() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectNoPropagate.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("anonymousObjectReifiedSupertype.kt") public void testAnonymousObjectReifiedSupertype() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectReifiedSupertype.kt"); @@ -2688,6 +2694,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("nestedReified.kt") + public void testNestedReified() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/nestedReified.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("nestedReifiedSignature.kt") + public void testNestedReifiedSignature() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/nestedReifiedSignature.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("newArrayInt.kt") public void testNewArrayInt() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt"); @@ -2718,6 +2736,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("reifiedInlineFunOfObject.kt") + public void testReifiedInlineFunOfObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObject.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("reifiedInlineFunOfObjectWithinReified.kt") + public void testReifiedInlineFunOfObjectWithinReified() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineFunOfObjectWithinReified.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("reifiedInlineIntoNonInlineableLambda.kt") public void testReifiedInlineIntoNonInlineableLambda() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 87d107d0e0a..5e276544ae6 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -442,4 +442,12 @@ public class DescriptorUtils { } return result; } + + public static boolean containsReifiedTypeParameterWithName(@NotNull CallableDescriptor descriptor, @NotNull String name) { + for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { + if (typeParameterDescriptor.isReified() && typeParameterDescriptor.getName().asString().equals(name)) return true; + } + + return false; + } } diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java index bce20822b32..dd21e83d4a3 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java @@ -109,19 +109,19 @@ public class Intrinsics { throw new UnsupportedOperationException("You should not use functions with reified parameter without inline"); } - public static void reifyNewArray(int parameterTypeIndex) { + public static void reifyNewArray(String typeParameterIdentifier) { throwUndefinedForReified(); } - public static void reifyCheckcast(int parameterTypeIndex) { + public static void reifyCheckcast(String typeParameterIdentifier) { throwUndefinedForReified(); } - public static void reifyInstanceof(int parameterTypeIndex) { + public static void reifyInstanceof(String typeParameterIdentifier) { throwUndefinedForReified(); } - public static void reifyJavaClass(int parameterTypeIndex) { + public static void reifyJavaClass(String typeParameterIdentifier) { throwUndefinedForReified(); }