JVM_IR. Proper lower toArray functions
This commit is contained in:
+10
-1
@@ -484,7 +484,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
/// We assume that IR code that reaches us has been checked for correctness at the frontend.
|
||||
/// This function needs to single out those cases where Java accessibility rules differ from Kotlin's.
|
||||
|
||||
val declarationRaw = owner as IrDeclarationWithVisibility
|
||||
val symbolOwner = owner
|
||||
val declarationRaw = symbolOwner as IrDeclarationWithVisibility
|
||||
val declaration =
|
||||
(declarationRaw as? IrSimpleFunction)?.resolveFakeOverride()
|
||||
?: (declarationRaw as? IrField)?.resolveFakeOverride() ?: declarationRaw
|
||||
@@ -495,6 +496,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
// `internal` maps to public and requires no accessor.
|
||||
if (!withSuper && !declaration.visibility.isPrivate && !declaration.visibility.isProtected) return true
|
||||
|
||||
//`toArray` is always accessible cause mapped to public functions
|
||||
if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray() || symbolOwner.isGenericToArray(context))) {
|
||||
val parent = symbolOwner.parent
|
||||
if (parent is IrClass && parent.isCollectionSubClass()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// If local variables are accessible by Kotlin rules, they also are by Java rules.
|
||||
val symbolDeclarationContainer = (declaration.parent as? IrDeclarationContainer) as? IrElement ?: return true
|
||||
val contextDeclarationContainer = (currentScope!!.irElement as IrDeclaration).getAccessContext(withSuper) ?: return false
|
||||
|
||||
+147
-136
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -18,7 +19,6 @@ import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
@@ -35,7 +35,9 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isClass
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
|
||||
internal val toArrayPhase = makeIrFilePhase(
|
||||
@@ -46,173 +48,162 @@ internal val toArrayPhase = makeIrFilePhase(
|
||||
|
||||
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (irClass.isJvmInterface || !irClass.isDirectCollectionSubClass()) return
|
||||
if (irClass.isJvmInterface || !irClass.isCollectionSubClass()) return
|
||||
|
||||
val irBuiltIns = context.irBuiltIns
|
||||
val symbols = context.ir.symbols
|
||||
|
||||
val toArrayName = Name.identifier("toArray")
|
||||
val genericToArray = irClass.declarations.find { it.isGenericToArray() }
|
||||
val nonGenericToArray = irClass.declarations.find { it.isNonGenericToArray() }
|
||||
|
||||
val genericToArray = irClass.declarations.filterIsInstance<IrSimpleFunction>().find { it.isGenericToArray(context) }
|
||||
val nonGenericToArray = irClass.declarations.filterIsInstance<IrSimpleFunction>().find { it.isNonGenericToArray() }
|
||||
val isDirectCollectionSubClass = irClass.isDirectCollectionSubClass()
|
||||
if (genericToArray == null) {
|
||||
val typeParameterDescriptor = WrappedTypeParameterDescriptor()
|
||||
val typeParameter = IrTypeParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrTypeParameterSymbolImpl(typeParameterDescriptor),
|
||||
Name.identifier("T"),
|
||||
index = 0,
|
||||
variance = Variance.INVARIANT,
|
||||
isReified = false
|
||||
).apply {
|
||||
typeParameterDescriptor.bind(this)
|
||||
superTypes.add(irBuiltIns.anyNType)
|
||||
}
|
||||
|
||||
val substitutedArrayType = irBuiltIns.arrayClass.typeWith(typeParameter.defaultType)
|
||||
val functionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
val irFunction = IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrSimpleFunctionSymbolImpl(functionDescriptor),
|
||||
toArrayName,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
returnType = substitutedArrayType,
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = false,
|
||||
isExpect = false,
|
||||
isFakeOverride = false
|
||||
)
|
||||
functionDescriptor.bind(irFunction)
|
||||
irFunction.parent = irClass
|
||||
|
||||
typeParameter.parent = irFunction
|
||||
irFunction.typeParameters.add(typeParameter)
|
||||
|
||||
val dispatchReceiverParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(dispatchReceiverParameterDescriptor),
|
||||
Name.special("<this>"),
|
||||
index = -1,
|
||||
type = irClass.defaultType,
|
||||
varargElementType = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
parent = irFunction
|
||||
}
|
||||
val valueParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.valueParameters.add(
|
||||
IrValueParameterImpl(
|
||||
if (isDirectCollectionSubClass) {
|
||||
val typeParameterDescriptor = WrappedTypeParameterDescriptor()
|
||||
val typeParameter = IrTypeParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(valueParameterDescriptor),
|
||||
Name.identifier("array"),
|
||||
IrTypeParameterSymbolImpl(typeParameterDescriptor),
|
||||
Name.identifier("T"),
|
||||
index = 0,
|
||||
variance = Variance.INVARIANT,
|
||||
isReified = false
|
||||
).apply {
|
||||
typeParameterDescriptor.bind(this)
|
||||
superTypes.add(irBuiltIns.anyNType)
|
||||
}
|
||||
|
||||
val substitutedArrayType = irBuiltIns.arrayClass.typeWith(typeParameter.defaultType)
|
||||
val functionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
val irFunction = IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrSimpleFunctionSymbolImpl(functionDescriptor),
|
||||
toArrayName,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
returnType = substitutedArrayType,
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = false,
|
||||
isExpect = false,
|
||||
isFakeOverride = false
|
||||
)
|
||||
functionDescriptor.bind(irFunction)
|
||||
irFunction.parent = irClass
|
||||
|
||||
typeParameter.parent = irFunction
|
||||
irFunction.typeParameters.add(typeParameter)
|
||||
|
||||
val dispatchReceiverParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(dispatchReceiverParameterDescriptor),
|
||||
Name.special("<this>"),
|
||||
index = -1,
|
||||
type = irClass.defaultType,
|
||||
varargElementType = null,
|
||||
type = substitutedArrayType,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
valueParameterDescriptor.bind(this)
|
||||
parent = irFunction
|
||||
}
|
||||
)
|
||||
val valueParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.valueParameters.add(
|
||||
IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(valueParameterDescriptor),
|
||||
Name.identifier("array"),
|
||||
index = 0,
|
||||
varargElementType = null,
|
||||
type = substitutedArrayType,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
valueParameterDescriptor.bind(this)
|
||||
parent = irFunction
|
||||
}
|
||||
)
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(symbols.genericToArray, symbols.genericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
)
|
||||
putValueArgument(1, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.valueParameters[0].symbol))
|
||||
})
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(symbols.genericToArray, symbols.genericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
)
|
||||
putValueArgument(1, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.valueParameters[0].symbol))
|
||||
})
|
||||
}
|
||||
|
||||
irClass.declarations.add(irFunction)
|
||||
}
|
||||
|
||||
irClass.declarations.add(irFunction)
|
||||
} else {
|
||||
//TODO patch visibility
|
||||
(genericToArray as IrFunctionImpl).visibility = Visibilities.PUBLIC
|
||||
}
|
||||
|
||||
if (nonGenericToArray == null) {
|
||||
val functionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
val irFunction = IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrSimpleFunctionSymbolImpl(functionDescriptor),
|
||||
toArrayName,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
returnType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType),
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = false,
|
||||
isExpect = false,
|
||||
isFakeOverride = false
|
||||
)
|
||||
functionDescriptor.bind(irFunction)
|
||||
irFunction.parent = irClass
|
||||
if (isDirectCollectionSubClass) {
|
||||
val functionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
val irFunction = IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrSimpleFunctionSymbolImpl(functionDescriptor),
|
||||
toArrayName,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
returnType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType),
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = false,
|
||||
isExpect = false,
|
||||
isFakeOverride = false
|
||||
)
|
||||
functionDescriptor.bind(irFunction)
|
||||
irFunction.parent = irClass
|
||||
|
||||
val dispatchReceiverParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(dispatchReceiverParameterDescriptor),
|
||||
Name.special("<this>"),
|
||||
index = -1,
|
||||
type = irClass.defaultType,
|
||||
varargElementType = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
parent = irFunction
|
||||
val dispatchReceiverParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
irFunction.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
IrValueParameterSymbolImpl(dispatchReceiverParameterDescriptor),
|
||||
Name.special("<this>"),
|
||||
index = -1,
|
||||
type = irClass.defaultType,
|
||||
varargElementType = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
parent = irFunction
|
||||
}
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(symbols.nonGenericToArray, symbols.nonGenericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
irClass.declarations.add(irFunction)
|
||||
}
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(symbols.nonGenericToArray, symbols.nonGenericToArray.owner.returnType).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
irClass.declarations.add(irFunction)
|
||||
} else {
|
||||
//TODO patch visibility
|
||||
(nonGenericToArray as IrFunctionImpl).visibility = Visibilities.PUBLIC
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrDeclaration.isGenericToArray(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
val signature = context.methodSignatureMapper.mapAsmMethod(this)
|
||||
return signature.toString() == "toArray([Ljava/lang/Object;)[Ljava/lang/Object;"
|
||||
}
|
||||
|
||||
private fun IrDeclaration.isNonGenericToArray(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (this.name.asString() != "toArray") return false
|
||||
if (typeParameters.isNotEmpty() || valueParameters.isNotEmpty()) return false
|
||||
if (!returnType.isArray()) return false
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private val IrClass.superClasses
|
||||
get() = superTypes.mapNotNull { it.getClass() }
|
||||
|
||||
// Have to check by name, since irBuiltins is unreliable.
|
||||
private fun IrClass.isCollectionSubClass() =
|
||||
internal fun IrClass.isCollectionSubClass() =
|
||||
DFS.ifAny(listOf(this), IrClass::superClasses) { it.defaultType.isCollection() }
|
||||
|
||||
// If this class inherits from another Kotlin class that implements Collection, it already has toArray.
|
||||
@@ -220,3 +211,23 @@ private fun IrClass.isDirectCollectionSubClass() =
|
||||
isCollectionSubClass() && !superClasses.any {
|
||||
it.isClass && it.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && it.isCollectionSubClass()
|
||||
}
|
||||
|
||||
|
||||
internal fun IrSimpleFunction.isGenericToArray(context: JvmBackendContext): Boolean {
|
||||
if (name.asString() != "toArray") return false
|
||||
if (typeParameters.size != 1 || valueParameters.size != 1 || extensionReceiverParameter != null) return false
|
||||
|
||||
val paramType = valueParameters[0].type
|
||||
|
||||
if (!returnType.isArray() || !paramType.isArray()) return false
|
||||
|
||||
val elementType = typeParameters[0].defaultType
|
||||
val expectedType = context.ir.symbols.array.typeWith(elementType)
|
||||
return expectedType == paramType && expectedType == returnType
|
||||
}
|
||||
|
||||
internal fun IrSimpleFunction.isNonGenericToArray(): Boolean {
|
||||
if (name.asString() != "toArray") return false
|
||||
if (typeParameters.isNotEmpty() || valueParameters.isNotEmpty() || extensionReceiverParameter != null) return false
|
||||
return returnType.isArray()
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: SingletonCollection.kt
|
||||
package test
|
||||
|
||||
open class SingletonCollection<T>(val value: T) : AbstractCollection<T>() {
|
||||
override val size = 1
|
||||
override fun iterator(): Iterator<T> = listOf(value).iterator()
|
||||
|
||||
protected override final fun toArray(): Array<Any?> =
|
||||
arrayOf<Any?>(value)
|
||||
|
||||
protected override final fun <E> toArray(a: Array<E>): Array<E> {
|
||||
a[0] = value as E
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
open class SingletonCollection2<T>(val value: T) : AbstractCollection<T>() {
|
||||
override val size = 1
|
||||
override fun iterator(): Iterator<T> = listOf(value).iterator()
|
||||
}
|
||||
|
||||
// FILE: DerivedSingletonCollection.kt
|
||||
package test2
|
||||
|
||||
import test.*
|
||||
|
||||
class DerivedSingletonCollection<T>(value: T) : SingletonCollection<T>(value) {
|
||||
fun test() = object {
|
||||
fun test() = toArray()
|
||||
}.test()
|
||||
|
||||
fun <E> test(a: Array<E>) = object {
|
||||
fun test() = toArray(a)
|
||||
}.test()
|
||||
}
|
||||
|
||||
class DerivedSingletonCollection2<T>(value: T) : SingletonCollection2<T>(value) {
|
||||
fun test() = object {
|
||||
fun test() = toArray()
|
||||
}.test()
|
||||
|
||||
fun <E> test(a: Array<E>) = object {
|
||||
fun test() = toArray(a)
|
||||
}.test()
|
||||
|
||||
}
|
||||
|
||||
// @test/SingletonCollection.class:
|
||||
// 0 access\$
|
||||
// 2 public final toArray
|
||||
// 0 \.toArray
|
||||
|
||||
// @test/SingletonCollection2.class:
|
||||
// 0 access\$
|
||||
// 0 toArray
|
||||
|
||||
// @test2/DerivedSingletonCollection.class:
|
||||
// 0 access\$
|
||||
// 0 toArray
|
||||
|
||||
// @test2/DerivedSingletonCollection2.class:
|
||||
// 0 access\$
|
||||
// 0 toArray
|
||||
@@ -4061,6 +4061,24 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/toArray")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ToArray extends AbstractBytecodeTextTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInToArray() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/toArray"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("noAccessorForToArray.kt")
|
||||
public void testNoAccessorForToArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/toArray/noAccessorForToArray.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/unsignedTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -3979,6 +3979,24 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/toArray")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ToArray extends AbstractIrBytecodeTextTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInToArray() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/toArray"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("noAccessorForToArray.kt")
|
||||
public void testNoAccessorForToArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/toArray/noAccessorForToArray.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/unsignedTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user