JVM_IR KT-45967 generate accessor for argument of indy intrinsic
TODO handle inaccessible constructors gracefully
This commit is contained in:
committed by
TeamCityServer
parent
5f9fe8e5de
commit
f59b49db68
+46
@@ -20821,6 +20821,52 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testVoidReturnTypeAsObject() throws Exception {
|
public void testVoidReturnTypeAsObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class WithAccessor {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateBoundOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateBoundOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateBoundOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateCompanionObjectMember.kt")
|
||||||
|
public void testPrivateCompanionObjectMember() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateCompanionObjectMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassConstructor.kt")
|
||||||
|
public void testPrivateOuterClassConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelExtFun.kt")
|
||||||
|
public void testPrivateTopLevelExtFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelExtFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelFun.kt")
|
||||||
|
public void testPrivateTopLevelFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+140
-82
@@ -83,74 +83,135 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
val withSuper = (expression as? IrCall)?.superQualifierSymbol != null
|
val withSuper = (expression as? IrCall)?.superQualifierSymbol != null
|
||||||
val thisSymbol = (expression as? IrCall)?.dispatchReceiver?.type?.classifierOrNull as? IrClassSymbol
|
val thisSymbol = (expression as? IrCall)?.dispatchReceiver?.type?.classifierOrNull as? IrClassSymbol
|
||||||
|
|
||||||
|
if (expression is IrCall && callee.symbol == context.ir.symbols.indyLambdaMetafactoryIntrinsic) {
|
||||||
|
return super.visitExpression(handleLambdaMetafactoryIntrinsic(expression, thisSymbol))
|
||||||
|
}
|
||||||
|
|
||||||
val accessor = when {
|
val accessor = when {
|
||||||
callee is IrConstructor && callee.isOrShouldBeHidden ->
|
callee is IrConstructor && callee.isOrShouldBeHidden ->
|
||||||
handleHiddenConstructor(callee).symbol
|
handleHiddenConstructor(callee).symbol
|
||||||
|
!expression.symbol.isAccessible(withSuper, thisSymbol) ->
|
||||||
!expression.symbol.isAccessible(withSuper, thisSymbol) -> {
|
createAccessor(expression)
|
||||||
// Find the right container to insert the accessor. Simply put, when we call a function on a class A,
|
else ->
|
||||||
// we also need to put its accessor into A. However, due to the way that calls are implemented in the
|
return super.visitFunctionAccess(expression)
|
||||||
// IR we generally need to look at the type of the dispatchReceiver *argument* in order to find the
|
|
||||||
// correct class. Consider the following code:
|
|
||||||
//
|
|
||||||
// fun run(f : () -> Int): Int = f()
|
|
||||||
//
|
|
||||||
// open class A {
|
|
||||||
// private fun f() = 0
|
|
||||||
// fun g() = run { this.f() }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// class B : A {
|
|
||||||
// override fun g() = 1
|
|
||||||
// fun h() = run { super.g() }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// We have calls to the private methods A.f from a generated Lambda subclass for the argument to `run`
|
|
||||||
// in class A and a super call to A.g from a generated Lambda subclass in class B.
|
|
||||||
//
|
|
||||||
// In the first case, we need to produce an accessor in class A to access the private member of A.
|
|
||||||
// Both the parent of the function f and the type of the dispatch receiver point to the correct class.
|
|
||||||
// In the second case we need to call A.g from within class B, since this is the only way to invoke
|
|
||||||
// a method of a superclass on the JVM. However, the IR for the call to super.g points directly to the
|
|
||||||
// function g in class A. Confusingly, the `superQualifier` on this call also points to class A.
|
|
||||||
// The only way to compute the actual enclosing class for the call is by looking at the type of the
|
|
||||||
// dispatch receiver argument, which points to B.
|
|
||||||
//
|
|
||||||
// Beyond this, there can be accessors that are needed because other lowerings produce code calling
|
|
||||||
// private methods (e.g., local functions for lambdas are private and called from generated
|
|
||||||
// SAM wrapper classes). In this case we rely on the parent field of the called function.
|
|
||||||
//
|
|
||||||
// Finally, we need to produce accessors for calls to protected static methods coming from Java,
|
|
||||||
// which we put in the closest enclosing class which has access to the method in question.
|
|
||||||
val symbol = expression.symbol
|
|
||||||
val dispatchReceiverType = expression.dispatchReceiver?.type
|
|
||||||
val parent = symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent)
|
|
||||||
|
|
||||||
// The key in the cache/map needs to be BOTH the symbol of the function being accessed AND the parent
|
|
||||||
// of the accessor. Going from the above example, if we have another class C similar to B:
|
|
||||||
//
|
|
||||||
// class C : A {
|
|
||||||
// override fun g() = 2
|
|
||||||
// fun i() = run { super.g() }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// For the call to super.g in function i, the accessor to A.g must be produced in C. Therefore, we
|
|
||||||
// cannot use the function symbol (A.g in the example) by itself as the key since there should be
|
|
||||||
// one accessor per dispatch receiver (i.e., parent of the accessor).
|
|
||||||
functionMap.getOrPut(symbol to parent) {
|
|
||||||
when (symbol) {
|
|
||||||
is IrConstructorSymbol -> symbol.owner.makeConstructorAccessor().also(pendingAccessorsToAdd::add).symbol
|
|
||||||
is IrSimpleFunctionSymbol -> symbol.owner.makeSimpleFunctionAccessor(expression as IrCall, parent).symbol
|
|
||||||
else -> error("Unknown subclass of IrFunctionSymbol")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> return super.visitFunctionAccess(expression)
|
|
||||||
}
|
}
|
||||||
return super.visitExpression(modifyFunctionAccessExpression(expression, accessor))
|
return super.visitExpression(modifyFunctionAccessExpression(expression, accessor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createAccessor(expression: IrFunctionAccessExpression): IrFunctionSymbol =
|
||||||
|
if (expression is IrCall)
|
||||||
|
createAccessor(expression.symbol, expression.dispatchReceiver?.type, expression.superQualifierSymbol)
|
||||||
|
else
|
||||||
|
createAccessor(expression.symbol, null, null)
|
||||||
|
|
||||||
|
private fun createAccessor(
|
||||||
|
symbol: IrFunctionSymbol,
|
||||||
|
dispatchReceiverType: IrType?,
|
||||||
|
superQualifierSymbol: IrClassSymbol?
|
||||||
|
): IrFunctionSymbol {
|
||||||
|
// Find the right container to insert the accessor. Simply put, when we call a function on a class A,
|
||||||
|
// we also need to put its accessor into A. However, due to the way that calls are implemented in the
|
||||||
|
// IR we generally need to look at the type of the dispatchReceiver *argument* in order to find the
|
||||||
|
// correct class. Consider the following code:
|
||||||
|
//
|
||||||
|
// fun run(f : () -> Int): Int = f()
|
||||||
|
//
|
||||||
|
// open class A {
|
||||||
|
// private fun f() = 0
|
||||||
|
// fun g() = run { this.f() }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// class B : A {
|
||||||
|
// override fun g() = 1
|
||||||
|
// fun h() = run { super.g() }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// We have calls to the private methods A.f from a generated Lambda subclass for the argument to `run`
|
||||||
|
// in class A and a super call to A.g from a generated Lambda subclass in class B.
|
||||||
|
//
|
||||||
|
// In the first case, we need to produce an accessor in class A to access the private member of A.
|
||||||
|
// Both the parent of the function f and the type of the dispatch receiver point to the correct class.
|
||||||
|
// In the second case we need to call A.g from within class B, since this is the only way to invoke
|
||||||
|
// a method of a superclass on the JVM. However, the IR for the call to super.g points directly to the
|
||||||
|
// function g in class A. Confusingly, the `superQualifier` on this call also points to class A.
|
||||||
|
// The only way to compute the actual enclosing class for the call is by looking at the type of the
|
||||||
|
// dispatch receiver argument, which points to B.
|
||||||
|
//
|
||||||
|
// Beyond this, there can be accessors that are needed because other lowerings produce code calling
|
||||||
|
// private methods (e.g., local functions for lambdas are private and called from generated
|
||||||
|
// SAM wrapper classes). In this case we rely on the parent field of the called function.
|
||||||
|
//
|
||||||
|
// Finally, we need to produce accessors for calls to protected static methods coming from Java,
|
||||||
|
// which we put in the closest enclosing class which has access to the method in question.
|
||||||
|
|
||||||
|
val parent = symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent)
|
||||||
|
|
||||||
|
// The key in the cache/map needs to be BOTH the symbol of the function being accessed AND the parent
|
||||||
|
// of the accessor. Going from the above example, if we have another class C similar to B:
|
||||||
|
//
|
||||||
|
// class C : A {
|
||||||
|
// override fun g() = 2
|
||||||
|
// fun i() = run { super.g() }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// For the call to super.g in function i, the accessor to A.g must be produced in C. Therefore, we
|
||||||
|
// cannot use the function symbol (A.g in the example) by itself as the key since there should be
|
||||||
|
// one accessor per dispatch receiver (i.e., parent of the accessor).
|
||||||
|
return functionMap.getOrPut(symbol to parent) {
|
||||||
|
when (symbol) {
|
||||||
|
is IrConstructorSymbol ->
|
||||||
|
symbol.owner.makeConstructorAccessor()
|
||||||
|
.also(pendingAccessorsToAdd::add)
|
||||||
|
.symbol
|
||||||
|
is IrSimpleFunctionSymbol -> {
|
||||||
|
symbol.owner.makeSimpleFunctionAccessor(superQualifierSymbol, dispatchReceiverType, parent)
|
||||||
|
.also(pendingAccessorsToAdd::add)
|
||||||
|
.symbol
|
||||||
|
}
|
||||||
|
else -> error("Unknown subclass of IrFunctionSymbol")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleLambdaMetafactoryIntrinsic(call: IrCall, thisSymbol: IrClassSymbol?): IrExpression {
|
||||||
|
val implFunRef = call.getValueArgument(1) as? IrFunctionReference
|
||||||
|
?: throw AssertionError("'implMethodReference' is expected to be 'IrFunctionReference': ${call.dump()}")
|
||||||
|
val implFunSymbol = implFunRef.symbol
|
||||||
|
|
||||||
|
if (implFunSymbol.isAccessible(false, thisSymbol)) return call
|
||||||
|
|
||||||
|
val accessorSymbol = createAccessor(implFunSymbol, implFunRef.dispatchReceiver?.type, null)
|
||||||
|
val accessorFun = accessorSymbol.owner
|
||||||
|
val accessorRef =
|
||||||
|
IrFunctionReferenceImpl(
|
||||||
|
implFunRef.startOffset, implFunRef.endOffset, implFunRef.type,
|
||||||
|
accessorSymbol,
|
||||||
|
accessorFun.typeParameters.size,
|
||||||
|
accessorFun.valueParameters.size,
|
||||||
|
implFunRef.reflectionTarget, implFunRef.origin
|
||||||
|
)
|
||||||
|
|
||||||
|
accessorRef.copyTypeArgumentsFrom(implFunRef)
|
||||||
|
|
||||||
|
val implFun = implFunSymbol.owner
|
||||||
|
var accessorArgIndex = 0
|
||||||
|
if (implFun.dispatchReceiverParameter != null) {
|
||||||
|
accessorRef.putValueArgument(accessorArgIndex++, implFunRef.dispatchReceiver)
|
||||||
|
}
|
||||||
|
if (implFun.extensionReceiverParameter != null) {
|
||||||
|
accessorRef.putValueArgument(accessorArgIndex++, implFunRef.extensionReceiver)
|
||||||
|
}
|
||||||
|
for (implArgIndex in 0 until implFunRef.valueArgumentsCount) {
|
||||||
|
accessorRef.putValueArgument(accessorArgIndex++, implFunRef.getValueArgument(implArgIndex))
|
||||||
|
}
|
||||||
|
if (accessorFun is IrConstructor) {
|
||||||
|
accessorRef.putValueArgument(accessorArgIndex, createAccessorMarkerArgument())
|
||||||
|
}
|
||||||
|
|
||||||
|
call.putValueArgument(1, accessorRef)
|
||||||
|
return call
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||||
val dispatchReceiverType = expression.receiver?.type
|
val dispatchReceiverType = expression.receiver?.type
|
||||||
return super.visitExpression(
|
return super.visitExpression(
|
||||||
@@ -318,28 +379,31 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
copyAllParamsToArgs(it, accessor)
|
copyAllParamsToArgs(it, accessor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.makeSimpleFunctionAccessor(expression: IrCall, parent: IrDeclarationParent): IrSimpleFunction {
|
private fun IrSimpleFunction.makeSimpleFunctionAccessor(
|
||||||
|
superQualifierSymbol: IrClassSymbol?,
|
||||||
|
dispatchReceiverType: IrType?,
|
||||||
|
parent: IrDeclarationParent
|
||||||
|
): IrSimpleFunction {
|
||||||
val source = this
|
val source = this
|
||||||
|
|
||||||
return factory.buildFun {
|
return factory.buildFun {
|
||||||
startOffset = parent.startOffset
|
startOffset = parent.startOffset
|
||||||
endOffset = parent.startOffset
|
endOffset = parent.startOffset
|
||||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||||
name = source.accessorName(expression.superQualifierSymbol)
|
name = source.accessorName(superQualifierSymbol)
|
||||||
visibility = DescriptorVisibilities.PUBLIC
|
visibility = DescriptorVisibilities.PUBLIC
|
||||||
modality = if (parent is IrClass && parent.isJvmInterface) Modality.OPEN else Modality.FINAL
|
modality = if (parent is IrClass && parent.isJvmInterface) Modality.OPEN else Modality.FINAL
|
||||||
isSuspend = source.isSuspend // synthetic accessors of suspend functions are handled in codegen
|
isSuspend = source.isSuspend // synthetic accessors of suspend functions are handled in codegen
|
||||||
}.also { accessor ->
|
}.also { accessor ->
|
||||||
accessor.parent = parent
|
accessor.parent = parent
|
||||||
pendingAccessorsToAdd.add(accessor)
|
|
||||||
|
|
||||||
accessor.copyTypeParametersFrom(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
|
accessor.copyTypeParametersFrom(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
|
||||||
accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, expression.dispatchReceiver?.type)
|
accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, dispatchReceiverType)
|
||||||
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
||||||
|
|
||||||
accessor.body = IrExpressionBodyImpl(
|
accessor.body = IrExpressionBodyImpl(
|
||||||
accessor.startOffset, accessor.startOffset,
|
accessor.startOffset, accessor.startOffset,
|
||||||
createSimpleFunctionCall(accessor, source.symbol, expression.superQualifierSymbol)
|
createSimpleFunctionCall(accessor, source.symbol, superQualifierSymbol)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -487,18 +551,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
newExpression.putValueArgument(i, irExpression)
|
newExpression.putValueArgument(i, irExpression)
|
||||||
}
|
}
|
||||||
if (accessorSymbol is IrConstructorSymbol) {
|
if (accessorSymbol is IrConstructorSymbol) {
|
||||||
newExpression.putValueArgument(
|
newExpression.putValueArgument(receiverAndArgs.size, createAccessorMarkerArgument())
|
||||||
receiverAndArgs.size,
|
|
||||||
IrConstImpl.constNull(
|
|
||||||
UNDEFINED_OFFSET,
|
|
||||||
UNDEFINED_OFFSET,
|
|
||||||
context.ir.symbols.defaultConstructorMarker.defaultType.makeNullable()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return newExpression
|
return newExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createAccessorMarkerArgument() =
|
||||||
|
IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.ir.symbols.defaultConstructorMarker.defaultType.makeNullable())
|
||||||
|
|
||||||
private fun modifyGetterExpression(
|
private fun modifyGetterExpression(
|
||||||
oldExpression: IrGetField,
|
oldExpression: IrGetField,
|
||||||
accessorSymbol: IrSimpleFunctionSymbol
|
accessorSymbol: IrSimpleFunctionSymbol
|
||||||
@@ -618,14 +678,6 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
return "p" + if (isStatic && visibility.isProtected) "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() else ""
|
return "p" + if (isStatic && visibility.isProtected) "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
private val DescriptorVisibility.isPrivate
|
|
||||||
get() = DescriptorVisibilities.isPrivate(this)
|
|
||||||
|
|
||||||
private val DescriptorVisibility.isProtected
|
|
||||||
get() = this == DescriptorVisibilities.PROTECTED ||
|
|
||||||
this == JavaDescriptorVisibilities.PROTECTED_AND_PACKAGE ||
|
|
||||||
this == JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY
|
|
||||||
|
|
||||||
private fun IrSymbol.isAccessible(withSuper: Boolean, thisObjReference: IrClassSymbol?): Boolean {
|
private fun IrSymbol.isAccessible(withSuper: Boolean, thisObjReference: IrClassSymbol?): Boolean {
|
||||||
/// We assume that IR code that reaches us has been checked for correctness at the frontend.
|
/// 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.
|
/// This function needs to single out those cases where Java accessibility rules differ from Kotlin's.
|
||||||
@@ -705,4 +757,10 @@ private fun IrClass.syntheticAccessorToSuperSuffix(): String =
|
|||||||
// TODO: change this to `fqNameUnsafe.asString().replace(".", "_")` as soon as we're ready to break compatibility with pre-KT-21178 code
|
// TODO: change this to `fqNameUnsafe.asString().replace(".", "_")` as soon as we're ready to break compatibility with pre-KT-21178 code
|
||||||
name.asString().hashCode().toString()
|
name.asString().hashCode().toString()
|
||||||
|
|
||||||
|
val DescriptorVisibility.isPrivate
|
||||||
|
get() = DescriptorVisibilities.isPrivate(this)
|
||||||
|
|
||||||
|
val DescriptorVisibility.isProtected
|
||||||
|
get() = this == DescriptorVisibilities.PROTECTED ||
|
||||||
|
this == JavaDescriptorVisibilities.PROTECTED_AND_PACKAGE ||
|
||||||
|
this == JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY
|
||||||
|
|||||||
+9
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod
|
|||||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.findInterfaceImplementation
|
import org.jetbrains.kotlin.backend.jvm.lower.findInterfaceImplementation
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.isPrivate
|
||||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||||
@@ -71,6 +72,13 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
|||||||
|
|
||||||
val implFun = reference.symbol.owner
|
val implFun = reference.symbol.owner
|
||||||
|
|
||||||
|
if (implFun is IrConstructor && implFun.visibility.isPrivate) {
|
||||||
|
// Kotlin generates constructor accessors differently from Java.
|
||||||
|
// TODO more precise accessibility check (see SyntheticAccessorLowering::isAccessible)
|
||||||
|
// TODO wrap inaccessible constructor with a local function
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// Can't use JDK LambdaMetafactory for annotated lambdas.
|
// Can't use JDK LambdaMetafactory for annotated lambdas.
|
||||||
// JDK LambdaMetafactory doesn't copy annotations from implementation method to an instance method in a
|
// JDK LambdaMetafactory doesn't copy annotations from implementation method to an instance method in a
|
||||||
// corresponding synthetic class, which doesn't look like a binary compatible change.
|
// corresponding synthetic class, which doesn't look like a binary compatible change.
|
||||||
@@ -323,6 +331,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun IrValueParameter.copy(parent: IrSimpleFunction, newIndex: Int, newName: Name = this.name): IrValueParameter =
|
private fun IrValueParameter.copy(parent: IrSimpleFunction, newIndex: Int, newName: Name = this.name): IrValueParameter =
|
||||||
buildValueParameter(parent) {
|
buildValueParameter(parent) {
|
||||||
updateFrom(this@copy)
|
updateFrom(this@copy)
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateBoundOuterClassMemberFun.kt
|
||||||
|
interface GetStep {
|
||||||
|
fun get(): Step
|
||||||
|
}
|
||||||
|
|
||||||
|
class Outer(val k: String) {
|
||||||
|
fun gs(x: Outer) =
|
||||||
|
object : GetStep {
|
||||||
|
override fun get(): Step = Step(x::test)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun test(s: String) = s + k
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
Outer("!").gs(Outer("K")).get().step("O")
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
String step(String string);
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateCompanionObjectMember.kt
|
||||||
|
class StepProcessor {
|
||||||
|
fun build() = Step(::test)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun test(string: String): String = string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
StepProcessor().build().step("OK")
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
String step(String string);
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateOuterClassConstructor.kt
|
||||||
|
interface GetStep {
|
||||||
|
fun get(): Step
|
||||||
|
}
|
||||||
|
|
||||||
|
class Outer {
|
||||||
|
private val ok: String
|
||||||
|
|
||||||
|
private constructor(ok: String) {
|
||||||
|
this.ok = ok
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.ok = "xxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
val obj = object : GetStep {
|
||||||
|
override fun get(): Step = Step(::Outer)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString() = ok
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() =
|
||||||
|
Outer().obj.get().step("OK").toString()
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
Object step(String string);
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateOuterClassMemberFun.kt
|
||||||
|
interface GetStep {
|
||||||
|
fun get(): Step
|
||||||
|
}
|
||||||
|
|
||||||
|
class Outer(val k: String) {
|
||||||
|
val obj = object : GetStep {
|
||||||
|
override fun get(): Step = Step(::test)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun test(s: String) = s + k
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
Outer("K").obj.get().step("O")
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
String step(String string);
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateTopLevelExtFun.kt
|
||||||
|
class StepProcessor {
|
||||||
|
fun build() = Step("O"::test)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.test(string: String): String =
|
||||||
|
this + string
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
StepProcessor().build().step("K")
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
String step(String string);
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// SAM_CONVERSIONS: INDY
|
||||||
|
|
||||||
|
// FILE: privateTopLevelFun.kt
|
||||||
|
class StepProcessor {
|
||||||
|
fun build() = Step(::test)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun test(string: String): String = string
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
StepProcessor().build().step("OK")
|
||||||
|
|
||||||
|
// FILE: Step.java
|
||||||
|
public interface Step {
|
||||||
|
String step(String string);
|
||||||
|
}
|
||||||
+46
@@ -20803,6 +20803,52 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
public void testVoidReturnTypeAsObject() throws Exception {
|
public void testVoidReturnTypeAsObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class WithAccessor {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateBoundOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateBoundOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateBoundOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateCompanionObjectMember.kt")
|
||||||
|
public void testPrivateCompanionObjectMember() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateCompanionObjectMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassConstructor.kt")
|
||||||
|
public void testPrivateOuterClassConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelExtFun.kt")
|
||||||
|
public void testPrivateTopLevelExtFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelExtFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelFun.kt")
|
||||||
|
public void testPrivateTopLevelFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+46
@@ -20821,6 +20821,52 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testVoidReturnTypeAsObject() throws Exception {
|
public void testVoidReturnTypeAsObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class WithAccessor {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateBoundOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateBoundOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateBoundOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateCompanionObjectMember.kt")
|
||||||
|
public void testPrivateCompanionObjectMember() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateCompanionObjectMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassConstructor.kt")
|
||||||
|
public void testPrivateOuterClassConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelExtFun.kt")
|
||||||
|
public void testPrivateTopLevelExtFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelExtFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTopLevelFun.kt")
|
||||||
|
public void testPrivateTopLevelFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+43
@@ -17396,6 +17396,49 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testVoidReturnTypeAsObject() throws Exception {
|
public void testVoidReturnTypeAsObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/voidReturnTypeAsObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class WithAccessor extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateBoundOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateBoundOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateBoundOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateCompanionObjectMember.kt")
|
||||||
|
public void testPrivateCompanionObjectMember() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateCompanionObjectMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateOuterClassConstructor.kt")
|
||||||
|
public void testPrivateOuterClassConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateOuterClassMemberFun.kt")
|
||||||
|
public void testPrivateOuterClassMemberFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateOuterClassMemberFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateTopLevelExtFun.kt")
|
||||||
|
public void testPrivateTopLevelExtFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelExtFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateTopLevelFun.kt")
|
||||||
|
public void testPrivateTopLevelFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor/privateTopLevelFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+13
@@ -14990,6 +14990,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class WithAccessor extends AbstractIrJsCodegenBoxES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
|||||||
Generated
+13
@@ -14411,6 +14411,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class WithAccessor extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
|||||||
Generated
+13
@@ -14476,6 +14476,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class WithAccessor extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+13
@@ -8422,6 +8422,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
public void testAllFilesPresentInFunctionRefToJavaInterface() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class WithAccessor extends AbstractIrCodegenBoxWasmTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInWithAccessor() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/withAccessor"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
@TestMetadata("compiler/testData/codegen/box/invokedynamic/sam/inlineClassInSignature")
|
||||||
|
|||||||
Reference in New Issue
Block a user