Special enum function support; Fix for KT-10569: Cannot iterate over values of an enum class when it is used as a generic parameter
#KT-10569 Fixed
This commit is contained in:
@@ -4445,6 +4445,12 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||
) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, operationKind, v);
|
||||
}
|
||||
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v
|
||||
) {
|
||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.expressions.LabelResolver;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
@@ -171,7 +172,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
SMAPAndMethodNode nodeAndSmap = null;
|
||||
try {
|
||||
nodeAndSmap = createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault);
|
||||
nodeAndSmap = createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, resolvedCall);
|
||||
endCall(inlineCall(nodeAndSmap));
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
@@ -227,8 +228,24 @@ public class InlineCodegen extends CallGenerator {
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull CodegenContext context,
|
||||
boolean callDefault
|
||||
boolean callDefault,
|
||||
@Nullable ResolvedCall<?> resolvedCall
|
||||
) {
|
||||
if (InlineCodegenUtil.isSpecialEnumMethod(functionDescriptor)) {
|
||||
assert resolvedCall != null : "Resolved call for " + functionDescriptor + " should be not null";
|
||||
Map<TypeParameterDescriptor, KotlinType> arguments = resolvedCall.getTypeArguments();
|
||||
assert arguments.size() == 1 : "Resolved call for " + functionDescriptor + " should have 1 type argument";
|
||||
KotlinType type = arguments.values().iterator().next();
|
||||
MethodNode node =
|
||||
InlineCodegenUtil.createSpecialEnumMethodBody(
|
||||
codegen,
|
||||
functionDescriptor.getName().asString(),
|
||||
type,
|
||||
codegen.getState().getTypeMapper()
|
||||
);
|
||||
return new SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1));
|
||||
}
|
||||
|
||||
final GenerationState state = codegen.getState();
|
||||
final Method asmMethod =
|
||||
callDefault
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class InlineCodegenForDefaultBody(
|
||||
}
|
||||
|
||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault)
|
||||
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, null)
|
||||
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
|
||||
|
||||
val node = nodeAndSmap.node
|
||||
|
||||
@@ -22,6 +22,8 @@ import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.kotlin.codegen.MemberCodegen;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
@@ -44,6 +46,7 @@ import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -54,6 +57,7 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public class InlineCodegenUtil {
|
||||
@@ -509,4 +513,47 @@ public class InlineCodegenUtil {
|
||||
public static boolean isThis0(@NotNull String name) {
|
||||
return THIS$0.equals(name);
|
||||
}
|
||||
|
||||
public static boolean isSpecialEnumMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
if (!containingDeclaration.getName().equals(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) {
|
||||
return false;
|
||||
}
|
||||
if (functionDescriptor.getTypeParameters().size() != 1) {
|
||||
return false;
|
||||
}
|
||||
String name = functionDescriptor.getName().asString();
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
return "enumValues".equals(name) && parameters.size() == 0 ||
|
||||
"enumValueOf".equals(name) && parameters.size() == 1 && KotlinBuiltIns.isString(parameters.get(0).getType());
|
||||
}
|
||||
|
||||
public static MethodNode createSpecialEnumMethodBody(
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull String name,
|
||||
@NotNull KotlinType type,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
) {
|
||||
boolean isEnumValues = "enumValues".equals(name);
|
||||
Type invokeType = typeMapper.mapType(type);
|
||||
String desc = getSpecialEnumFunDescriptor(invokeType, isEnumValues);
|
||||
|
||||
MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null);
|
||||
if (!isEnumValues) {
|
||||
node.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
}
|
||||
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node));
|
||||
node.visitMethodInsn(Opcodes.INVOKESTATIC, invokeType.getInternalName(), isEnumValues ? "values" : "valueOf", desc, false);
|
||||
node.visitInsn(Opcodes.ARETURN);
|
||||
node.visitMaxs(isEnumValues ? 2 : 3, isEnumValues ? 0 : 1);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static String getSpecialEnumFunDescriptor(@NotNull Type type, boolean isEnumValues) {
|
||||
return (isEnumValues ? "()[" : "(Ljava/lang/String;)") + "L" + type.getInternalName() + ";";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class ReificationArgument(
|
||||
|
||||
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) {
|
||||
enum class OperationKind {
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED;
|
||||
|
||||
val id: Int get() = ordinal
|
||||
}
|
||||
@@ -139,6 +139,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
OperationKind.SAFE_AS -> processAs(insn, instructions, kotlinType, asmType, safe = true)
|
||||
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
||||
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, asmType)
|
||||
}) {
|
||||
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||
instructions.remove(insn.previous!!) // PUSH type parameter
|
||||
@@ -219,6 +220,14 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
next.cst = parameter
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processSpecialEnumFunction(insn: MethodInsnNode, parameter: Type): Boolean {
|
||||
val next = insn.next
|
||||
if (next !is MethodInsnNode) return false
|
||||
next.owner = parameter.internalName
|
||||
next.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, "values" == next.name)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private val MethodInsnNode.reificationArgument: ReificationArgument?
|
||||
|
||||
@@ -7,6 +7,8 @@ public fun byteArrayOf(/*0*/ vararg elements: kotlin.Byte /*kotlin.ByteArray*/):
|
||||
public fun charArrayOf(/*0*/ vararg elements: kotlin.Char /*kotlin.CharArray*/): kotlin.CharArray
|
||||
public fun doubleArrayOf(/*0*/ vararg elements: kotlin.Double /*kotlin.DoubleArray*/): kotlin.DoubleArray
|
||||
public inline fun </*0*/ reified @kotlin.internal.PureReifiable T> emptyArray(): kotlin.Array<T>
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValueOf(/*0*/ name: kotlin.String): T
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValues(): kotlin.Array<T>
|
||||
public fun floatArrayOf(/*0*/ vararg elements: kotlin.Float /*kotlin.FloatArray*/): kotlin.FloatArray
|
||||
public fun intArrayOf(/*0*/ vararg elements: kotlin.Int /*kotlin.IntArray*/): kotlin.IntArray
|
||||
public fun longArrayOf(/*0*/ vararg elements: kotlin.Long /*kotlin.LongArray*/): kotlin.LongArray
|
||||
|
||||
@@ -7,6 +7,8 @@ public fun byteArrayOf(/*0*/ vararg elements: kotlin.Byte /*kotlin.ByteArray*/):
|
||||
public fun charArrayOf(/*0*/ vararg elements: kotlin.Char /*kotlin.CharArray*/): kotlin.CharArray
|
||||
public fun doubleArrayOf(/*0*/ vararg elements: kotlin.Double /*kotlin.DoubleArray*/): kotlin.DoubleArray
|
||||
public inline fun </*0*/ reified @kotlin.internal.PureReifiable T> emptyArray(): kotlin.Array<T>
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValueOf(/*0*/ name: kotlin.String): T
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValues(): kotlin.Array<T>
|
||||
public fun floatArrayOf(/*0*/ vararg elements: kotlin.Float /*kotlin.FloatArray*/): kotlin.FloatArray
|
||||
public fun intArrayOf(/*0*/ vararg elements: kotlin.Int /*kotlin.IntArray*/): kotlin.IntArray
|
||||
public fun longArrayOf(/*0*/ vararg elements: kotlin.Long /*kotlin.LongArray*/): kotlin.LongArray
|
||||
|
||||
@@ -7,6 +7,8 @@ public fun byteArrayOf(/*0*/ vararg elements: kotlin.Byte /*kotlin.ByteArray*/):
|
||||
public fun charArrayOf(/*0*/ vararg elements: kotlin.Char /*kotlin.CharArray*/): kotlin.CharArray
|
||||
public fun doubleArrayOf(/*0*/ vararg elements: kotlin.Double /*kotlin.DoubleArray*/): kotlin.DoubleArray
|
||||
public inline fun </*0*/ reified @kotlin.internal.PureReifiable T> emptyArray(): kotlin.Array<T>
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValueOf(/*0*/ name: kotlin.String): T
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValues(): kotlin.Array<T>
|
||||
public fun floatArrayOf(/*0*/ vararg elements: kotlin.Float /*kotlin.FloatArray*/): kotlin.FloatArray
|
||||
public fun intArrayOf(/*0*/ vararg elements: kotlin.Int /*kotlin.IntArray*/): kotlin.IntArray
|
||||
public fun longArrayOf(/*0*/ vararg elements: kotlin.Long /*kotlin.LongArray*/): kotlin.LongArray
|
||||
|
||||
@@ -7,6 +7,8 @@ public fun byteArrayOf(/*0*/ vararg elements: kotlin.Byte /*kotlin.ByteArray*/):
|
||||
public fun charArrayOf(/*0*/ vararg elements: kotlin.Char /*kotlin.CharArray*/): kotlin.CharArray
|
||||
public fun doubleArrayOf(/*0*/ vararg elements: kotlin.Double /*kotlin.DoubleArray*/): kotlin.DoubleArray
|
||||
public inline fun </*0*/ reified @kotlin.internal.PureReifiable T> emptyArray(): kotlin.Array<T>
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValueOf(/*0*/ name: kotlin.String): T
|
||||
public inline fun </*0*/ reified T : kotlin.Enum<T>> enumValues(): kotlin.Array<T>
|
||||
public fun floatArrayOf(/*0*/ vararg elements: kotlin.Float /*kotlin.FloatArray*/): kotlin.FloatArray
|
||||
public fun intArrayOf(/*0*/ vararg elements: kotlin.Int /*kotlin.IntArray*/): kotlin.IntArray
|
||||
public fun longArrayOf(/*0*/ vararg elements: kotlin.Long /*kotlin.LongArray*/): kotlin.LongArray
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
var result = ""
|
||||
|
||||
inline fun <reified T : Enum<T>> renderOptions(render: (T) -> String) {
|
||||
val values = enumValues<T>()
|
||||
for (v in values) {
|
||||
result += render(v)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K;
|
||||
|
||||
val myParam = name
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
renderOptions<Z> {
|
||||
it.myParam
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValueOf(): String {
|
||||
return enumValueOf<T>("OK").name
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValueOf<Z>()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValueOf(): String {
|
||||
return { enumValueOf<T>("OK") }().name
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValueOf<Z>()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValueOf(): String {
|
||||
return myValueOf2<T>()
|
||||
}
|
||||
|
||||
inline fun <reified Y : Enum<Y>> myValueOf2(): String {
|
||||
return enumValueOf<Y>("OK").name
|
||||
}
|
||||
|
||||
|
||||
enum class Z {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValueOf<Z>()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValueOf(): String {
|
||||
return myValueOf2<T>()
|
||||
}
|
||||
|
||||
inline fun <reified Y : Enum<Y>> myValueOf2(): String {
|
||||
return { enumValueOf<Y>("OK").name }()
|
||||
}
|
||||
|
||||
|
||||
enum class Z {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValueOf<Z>()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun myValueOf(): String {
|
||||
return enumValueOf<Z>("OK").name
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValueOf()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValues(): String {
|
||||
val values = enumValues<T>()
|
||||
return values.joinToString("")
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValues<Z>()
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValues(): Array<T> {
|
||||
return enumValues<T>()
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K;
|
||||
|
||||
val myParam = name
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return test(myValues<Z>())
|
||||
}
|
||||
|
||||
fun test(myValues: Array<Z>): String {
|
||||
return myValues.map { it.myParam }.joinToString ("");
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified T : Enum<T>> myValues(): String {
|
||||
val values = { enumValues<T>() }()
|
||||
return values.joinToString("")
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValues<Z>()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified Y : Enum<Y>> myValues2(): String {
|
||||
val values = enumValues<Y>()
|
||||
return values.joinToString("")
|
||||
}
|
||||
|
||||
inline fun <reified T : Enum<T>> myValues(): String {
|
||||
return myValues2<T>()
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValues<Z>()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun <reified Y : Enum<Y>> myValues2(): String {
|
||||
val values = { enumValues<Y>() }()
|
||||
return values.joinToString("")
|
||||
}
|
||||
|
||||
inline fun <reified T : Enum<T>> myValues(): String {
|
||||
return myValues2<T>()
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValues<Z>()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
// WITH_RUNTIME
|
||||
package test
|
||||
|
||||
inline fun myValues(): String {
|
||||
val values = enumValues<Z>()
|
||||
return values.joinToString("")
|
||||
}
|
||||
|
||||
enum class Z {
|
||||
O, K
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
return myValues()
|
||||
}
|
||||
@@ -941,6 +941,87 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/enum")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Enum extends AbstractBlackBoxInlineCodegenTest {
|
||||
public void testAllFilesPresentInEnum() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/enum"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt10569.kt")
|
||||
public void testKt10569() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/kt10569.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOf.kt")
|
||||
public void testValueOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOf.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfCapturedType.kt")
|
||||
public void testValueOfCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfChain.kt")
|
||||
public void testValueOfChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfChain.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfChainCapturedType.kt")
|
||||
public void testValueOfChainCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfChainCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfNonReified.kt")
|
||||
public void testValueOfNonReified() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfNonReified.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("values.kt")
|
||||
public void testValues() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/values.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesAsArray.kt")
|
||||
public void testValuesAsArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesAsArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesCapturedType.kt")
|
||||
public void testValuesCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesChain.kt")
|
||||
public void testValuesChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesChain.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesChainCapturedType.kt")
|
||||
public void testValuesChainCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesChainCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesNonReified.kt")
|
||||
public void testValuesNonReified() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesNonReified.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/functionExpression")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+81
@@ -941,6 +941,87 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/enum")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Enum extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
||||
public void testAllFilesPresentInEnum() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/enum"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt10569.kt")
|
||||
public void testKt10569() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/kt10569.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOf.kt")
|
||||
public void testValueOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOf.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfCapturedType.kt")
|
||||
public void testValueOfCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfChain.kt")
|
||||
public void testValueOfChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfChain.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfChainCapturedType.kt")
|
||||
public void testValueOfChainCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfChainCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueOfNonReified.kt")
|
||||
public void testValueOfNonReified() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valueOfNonReified.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("values.kt")
|
||||
public void testValues() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/values.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesAsArray.kt")
|
||||
public void testValuesAsArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesAsArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesCapturedType.kt")
|
||||
public void testValuesCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesChain.kt")
|
||||
public void testValuesChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesChain.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesChainCapturedType.kt")
|
||||
public void testValuesChainCapturedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesChainCapturedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valuesNonReified.kt")
|
||||
public void testValuesNonReified() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enum/valuesNonReified.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/functionExpression")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -79,3 +79,13 @@ public fun byteArrayOf(vararg elements: Byte): ByteArray
|
||||
* Returns an array containing the specified boolean values.
|
||||
*/
|
||||
public fun booleanArrayOf(vararg elements: Boolean): BooleanArray
|
||||
|
||||
/**
|
||||
* Returns an array containing enum T entries.
|
||||
*/
|
||||
public inline fun <reified T : Enum<T>> enumValues(): Array<T>
|
||||
|
||||
/**
|
||||
* Returns an enum entry with specified name.
|
||||
*/
|
||||
public inline fun <reified T : Enum<T>> enumValueOf(name: String): T
|
||||
@@ -14,4 +14,5 @@ fun bar() {
|
||||
// EXIST: { itemText: "object: C1<...>(){...}" }
|
||||
// EXIST: { itemText: "object: C2(){...}" }
|
||||
// EXIST: { itemText: "object: C3(){...}" }
|
||||
// EXIST: { itemText: "enumValueOf" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -15,4 +15,5 @@ fun bar() {
|
||||
// EXIST: { itemText: "object: C1<...>(){...}" }
|
||||
// EXIST: { itemText: "object: C2(){...}" }
|
||||
// EXIST: { itemText: "object: C4<String>(){...}" }
|
||||
// EXIST: { itemText: "enumValueOf" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -10,4 +10,5 @@ fun bar() {
|
||||
|
||||
// EXIST: { itemText: "object: I<...>{...}" }
|
||||
// EXIST: { itemText: "object: C<...>(){...}" }
|
||||
// EXIST: { itemText: "enumValueOf" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -17,4 +17,5 @@ fun bar() {
|
||||
// EXIST: { itemText: "object: I<...>{...}" }
|
||||
// EXIST: { itemText: "object: C1<X>(){...}" }
|
||||
// EXIST: { itemText: "object: C2(){...}" }
|
||||
// EXIST: { itemText: "enumValueOf" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
Reference in New Issue
Block a user