Generate synthetic functions for local functions with default values, by

re-ordering the lowering phases.

The changes in InterfaceLowering are necessary so that IrElements that
target the removed functions are re-targeted to the new functions in
DefaultImpls. This affects local functions in interface functions since
now LocalDeclarationsLowering comes before InterfaceLowering.
This commit is contained in:
Mark Punzalan
2019-06-26 21:01:06 -07:00
committed by max-kammerer
parent d2f1852c5e
commit 1abdf0561a
26 changed files with 239 additions and 89 deletions
@@ -190,7 +190,7 @@ class InlineClassLowering(val context: BackendContext) {
return expression
}
return irCall(expression, getOrCreateStaticMethod(function), dispatchReceiverAsFirstArgument = false)
return irCall(expression, getOrCreateStaticMethod(function), dispatchReceiverAsArgument = false)
}
override fun visitCall(expression: IrCall): IrExpression {
@@ -208,7 +208,7 @@ class InlineClassLowering(val context: BackendContext) {
return irCall(
expression,
getOrCreateStaticMethod(function),
dispatchReceiverAsFirstArgument = (function is IrSimpleFunction)
dispatchReceiverAsArgument = (function is IrSimpleFunction)
)
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.backend.js.lower.calls
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
@@ -48,7 +47,7 @@ internal fun <K> MutableMap<K, (IrFunctionAccessExpression) -> IrExpression>.add
internal typealias MemberToTransformer = HashMap<SimpleMemberKey, (IrFunctionAccessExpression) -> IrExpression>
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunctionSymbol) {
add(type, name) { irCall(it, v, dispatchReceiverAsFirstArgument = true) }
add(type, name) { irCall(it, v, dispatchReceiverAsArgument = true) }
}
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunction) {
@@ -53,7 +53,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
comparator.owner.returnType,
comparator
).apply {
putValueArgument(0, irCall(call, intrinsics.longCompareToLong, firstArgumentAsDispatchReceiver = true))
putValueArgument(0, irCall(call, intrinsics.longCompareToLong, argumentAsDispatchReceiver = true))
putValueArgument(1, JsIrBuilder.buildInt(irBuiltIns.intType, 0))
}
}
@@ -95,7 +95,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
chooseEqualityOperatorForPrimitiveTypes(call)
!isLhsPrimitive && !lhs.type.isNullable() && equalsMethod != null ->
irCall(call, equalsMethod.symbol, firstArgumentAsDispatchReceiver = true)
irCall(call, equalsMethod.symbol, argumentAsDispatchReceiver = true)
else ->
irCall(call, intrinsics.jsEquals)
@@ -127,7 +127,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
// Use runtime function call in case when receiverType is a primitive JS type that doesn't have `compareTo` method,
// or has a potential to be primitive type (being fake overridden from `Comparable`)
function.isMethodOfPrimitiveJSType() || function.isFakeOverriddenFromComparable() ->
irCall(call, intrinsics.jsCompareTo, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsCompareTo, dispatchReceiverAsArgument = true)
// Valid `compareTo` method must be present at this point
else ->
@@ -144,12 +144,12 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
// `Any.equals` works as identity operator
call.isSuperToAny() ->
irCall(call, intrinsics.jsEqeqeq, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsEqeqeq, dispatchReceiverAsArgument = true)
// Use runtime function call in case when receiverType is a primitive JS type that doesn't have `equals` method,
// or has a potential to be primitive type (being fake overridden from `Any`)
function.isMethodOfPotentiallyPrimitiveJSType() ->
irCall(call, intrinsics.jsEquals, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsEquals, dispatchReceiverAsArgument = true)
// Valid `equals` method must be present at this point
else -> call
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.types.isString
import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
import org.jetbrains.kotlin.ir.util.isNullable
import org.jetbrains.kotlin.ir.util.isSuperToAny
import org.jetbrains.kotlin.name.Name
@@ -30,9 +29,9 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform
put(Name.identifier("toString")) { call ->
if (shouldReplaceToStringWithRuntimeCall(call)) {
if ((call as IrCall).isSuperToAny()) {
irCall(call, intrinsics.jsAnyToString, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsAnyToString, dispatchReceiverAsArgument = true)
} else {
irCall(call, intrinsics.jsToString, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsToString, dispatchReceiverAsArgument = true)
}
} else {
call
@@ -42,9 +41,9 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform
put(Name.identifier("hashCode")) { call ->
if (call.symbol.owner.isFakeOverriddenFromAny()) {
if ((call as IrCall).isSuperToAny()) {
irCall(call, intrinsics.jsGetObjectHashCode, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsGetObjectHashCode, dispatchReceiverAsArgument = true)
} else {
irCall(call, intrinsics.jsHashCode, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsHashCode, dispatchReceiverAsArgument = true)
}
} else {
call
@@ -46,9 +46,9 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
irBuiltIns.booleanType.let {
// These operators are not short-circuit -- using bitwise operators '&', '|', '^' followed by coercion to boolean
add(it, OperatorNames.AND) { call -> toBoolean(irCall(call, intrinsics.jsBitAnd, dispatchReceiverAsFirstArgument = true)) }
add(it, OperatorNames.OR) { call -> toBoolean(irCall(call, intrinsics.jsBitOr, dispatchReceiverAsFirstArgument = true)) }
add(it, OperatorNames.XOR) { call -> toBoolean(irCall(call, intrinsics.jsBitXor, dispatchReceiverAsFirstArgument = true)) }
add(it, OperatorNames.AND) { call -> toBoolean(irCall(call, intrinsics.jsBitAnd, dispatchReceiverAsArgument = true)) }
add(it, OperatorNames.OR) { call -> toBoolean(irCall(call, intrinsics.jsBitOr, dispatchReceiverAsArgument = true)) }
add(it, OperatorNames.XOR) { call -> toBoolean(irCall(call, intrinsics.jsBitXor, dispatchReceiverAsArgument = true)) }
add(it, OperatorNames.NOT, intrinsics.jsNot)
}
@@ -88,9 +88,9 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
return with(call.symbol.owner.valueParameters[0].type) {
when {
isByte() || isShort() || isInt() ->
irCall(call, intrinsics.jsNumberRangeToNumber, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsNumberRangeToNumber, dispatchReceiverAsArgument = true)
isLong() ->
irCall(call, intrinsics.jsNumberRangeToLong, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsNumberRangeToLong, dispatchReceiverAsArgument = true)
else -> call
}
}
@@ -101,7 +101,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
intrinsic: IrFunctionSymbol,
toInt32: Boolean = false
): IrExpression {
val newCall = irCall(call, intrinsic, dispatchReceiverAsFirstArgument = true)
val newCall = irCall(call, intrinsic, dispatchReceiverAsArgument = true)
if (toInt32)
return toInt32(newCall)
return newCall
@@ -152,7 +152,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
transformCrement(call, intrinsics.jsMinus)
private fun transformCrement(call: IrFunctionAccessExpression, correspondingBinaryOp: IrFunctionSymbol): IrExpression {
val operation = irCall(call, correspondingBinaryOp, dispatchReceiverAsFirstArgument = true).apply {
val operation = irCall(call, correspondingBinaryOp, dispatchReceiverAsArgument = true).apply {
putValueArgument(1, buildInt(1))
}
@@ -161,7 +161,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
private fun transformUnaryMinus(call: IrFunctionAccessExpression) =
convertResultToPrimitiveType(
irCall(call, intrinsics.jsUnaryMinus, dispatchReceiverAsFirstArgument = true),
irCall(call, intrinsics.jsUnaryMinus, dispatchReceiverAsArgument = true),
call.type
)
@@ -20,7 +20,12 @@ import org.jetbrains.kotlin.name.NameUtils
private fun makePatchParentsPhase(number: Int) = namedIrFilePhase(
lower = object : SameTypeCompilerPhase<CommonBackendContext, IrFile> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrFile>, context: CommonBackendContext, input: IrFile): IrFile {
override fun invoke(
phaseConfig: PhaseConfig,
phaserState: PhaserState<IrFile>,
context: CommonBackendContext,
input: IrFile
): IrFile {
input.acceptVoid(PatchDeclarationParentsVisitor())
return input
}
@@ -59,12 +64,6 @@ private val propertiesPhase = makeIrFilePhase<CommonBackendContext>(
stickyPostconditions = setOf((PropertiesLowering)::checkNoProperties)
)
private val defaultArgumentStubPhase = makeIrFilePhase<CommonBackendContext>(
{ context -> DefaultArgumentStubGenerator(context, false) },
name = "DefaultArgumentsStubGenerator",
description = "Generate synthetic stubs for functions with default parameter values"
)
private val localDeclarationsPhase = makeIrFilePhase<CommonBackendContext>(
{ context ->
LocalDeclarationsLowering(context, object : LocalNameProvider {
@@ -77,6 +76,13 @@ private val localDeclarationsPhase = makeIrFilePhase<CommonBackendContext>(
prerequisite = setOf(sharedVariablesPhase)
)
private val defaultArgumentStubPhase = makeIrFilePhase<CommonBackendContext>(
{ context -> DefaultArgumentStubGenerator(context, false) },
name = "DefaultArgumentsStubGenerator",
description = "Generate synthetic stubs for functions with default parameter values",
prerequisite = setOf(localDeclarationsPhase)
)
private val innerClassesPhase = makeIrFilePhase(
::InnerClassesLowering,
name = "InnerClasses",
@@ -105,11 +111,7 @@ val jvmPhases = namedIrFilePhase<JvmBackendContext>(
tailrecPhase then
jvmInlineClassPhase then
defaultArgumentStubPhase then
interfacePhase then
interfaceDelegationPhase then
interfaceSuperCallsPhase then
sharedVariablesPhase then
makePatchParentsPhase(1) then
@@ -117,6 +119,12 @@ val jvmPhases = namedIrFilePhase<JvmBackendContext>(
enumWhenPhase then
singletonReferencesPhase then
localDeclarationsPhase then
defaultArgumentStubPhase then
interfacePhase then
interfaceDelegationPhase then
interfaceSuperCallsPhase then
singleAbstractMethodPhase then
addContinuationPhase then
callableReferencePhase then
@@ -205,7 +205,7 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl
if (superCallee.isDefinitelyNotDefaultImplsMethod()) return super.visitCall(expression)
val redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee)
val newCall = irCall(expression, redirectTarget, dispatchReceiverAsFirstArgument = true)
val newCall = irCall(expression, redirectTarget, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true)
return super.visitCall(newCall)
}
@@ -22,11 +22,15 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom
import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -42,6 +46,7 @@ internal val interfacePhase = makeIrFilePhase(
private class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
val state = context.state
val removedFunctions = hashMapOf<IrFunctionSymbol, IrFunctionSymbol>()
override fun lower(irClass: IrClass) {
if (!irClass.isInterface) return
@@ -54,7 +59,10 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
if (function !is IrSimpleFunction) continue
if (function.modality != Modality.ABSTRACT && function.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
val element = context.declarationFactory.getDefaultImplsFunction(function)
val element = context.declarationFactory.getDefaultImplsFunction(function).also {
if (shouldRemoveFunction(function))
removedFunctions[function.symbol] = it.symbol
}
members.add(element)
element.body = function.body?.patchDeclarationParents(element)
if (function.hasJvmDefault() &&
@@ -69,10 +77,11 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
}
}
// Update IrElements (e.g., IrCalls) to point to the new functions.
irClass.transformChildrenVoid(this)
irClass.declarations.removeAll {
it is IrFunction && shouldRemoveFunction(it)
it is IrFunction && removedFunctions.containsKey(it.symbol)
}
}
@@ -85,7 +94,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
val startOffset = interfaceMethod.startOffset
val endOffset = interfaceMethod.endOffset
return IrCallImpl(interfaceMethod.startOffset, interfaceMethod.endOffset, interfaceMethod.returnType, defaultImpls.symbol).apply {
return IrCallImpl(startOffset, endOffset, interfaceMethod.returnType, defaultImpls.symbol).apply {
passTypeArgumentsFrom(interfaceMethod)
var offset = 0
@@ -100,6 +109,53 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
}
}
}
override fun visitReturn(expression: IrReturn): IrExpression {
val newFunction = removedFunctions[expression.returnTargetSymbol]?.owner
return super.visitReturn(
if (newFunction != null) {
with(expression) {
IrReturnImpl(startOffset, endOffset, type, newFunction.symbol, value)
}
} else {
expression
}
)
}
override fun visitCall(expression: IrCall): IrExpression {
val newFunction = removedFunctions[expression.symbol]?.owner
return super.visitCall(
if (newFunction != null) {
irCall(expression, newFunction, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true)
} else {
expression
}
)
}
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
val newFunction = removedFunctions[expression.symbol]?.owner
return super.visitFunctionReference(
if (newFunction != null) {
with(expression) {
IrFunctionReferenceImpl(
startOffset,
endOffset,
type,
newFunction.symbol,
newFunction.descriptor,
typeArgumentsCount,
origin
).apply {
copyTypeAndValueArgumentsFrom(expression, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true)
}
}
} else {
expression
}
)
}
}
@@ -349,6 +349,7 @@ fun IrDeclaration.isEffectivelyExternal(): Boolean {
is IrSimpleFunction -> correspondingProperty ?: parent as? IrDeclaration
else -> parent as? IrDeclaration
}
val parent = parent
return when (this) {
is IrFunction -> isExternal || (effectiveParentDeclaration()?.isEffectivelyExternal() ?: false)
@@ -418,7 +419,7 @@ fun ReferenceSymbolTable.referenceFunction(callable: CallableDescriptor): IrFunc
*/
fun irConstructorCall(
call: IrMemberAccessExpression,
call: IrFunctionAccessExpression,
newFunction: IrConstructor,
dispatchReceiverAsFirstArgument: Boolean = false,
firstArgumentAsDispatchReceiver: Boolean = false
@@ -426,7 +427,7 @@ fun irConstructorCall(
irConstructorCall(call, newFunction.symbol, dispatchReceiverAsFirstArgument, firstArgumentAsDispatchReceiver)
fun irConstructorCall(
call: IrMemberAccessExpression,
call: IrFunctionAccessExpression,
newSymbol: IrConstructorSymbol,
dispatchReceiverAsFirstArgument: Boolean = false,
firstArgumentAsDispatchReceiver: Boolean = false
@@ -452,18 +453,29 @@ fun irConstructorCall(
}
fun irCall(
call: IrMemberAccessExpression,
call: IrFunctionAccessExpression,
newFunction: IrFunction,
dispatchReceiverAsFirstArgument: Boolean = false,
firstArgumentAsDispatchReceiver: Boolean = false
dispatchReceiverAsArgument: Boolean = false,
argumentAsDispatchReceiver: Boolean = false,
extensionReceiverAsArgument: Boolean = false,
argumentAsExtensionReceiver: Boolean = false
): IrCall =
irCall(call, newFunction.symbol, dispatchReceiverAsFirstArgument, firstArgumentAsDispatchReceiver)
irCall(
call,
newFunction.symbol,
dispatchReceiverAsArgument,
argumentAsDispatchReceiver,
extensionReceiverAsArgument,
argumentAsExtensionReceiver
)
fun irCall(
call: IrMemberAccessExpression,
call: IrFunctionAccessExpression,
newSymbol: IrFunctionSymbol,
dispatchReceiverAsFirstArgument: Boolean = false,
firstArgumentAsDispatchReceiver: Boolean = false
dispatchReceiverAsArgument: Boolean = false,
argumentAsDispatchReceiver: Boolean = false,
extensionReceiverAsArgument: Boolean = false,
argumentAsExtensionReceiver: Boolean = false
): IrCall =
call.run {
IrCallImpl(
@@ -477,46 +489,95 @@ fun irCall(
).apply {
copyTypeAndValueArgumentsFrom(
call,
dispatchReceiverAsFirstArgument,
firstArgumentAsDispatchReceiver
dispatchReceiverAsArgument,
argumentAsDispatchReceiver,
extensionReceiverAsArgument,
argumentAsExtensionReceiver
)
}
}
private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom(
call: IrMemberAccessExpression,
dispatchReceiverAsFirstArgument: Boolean = false,
firstArgumentAsDispatchReceiver: Boolean = false
) {
copyTypeArgumentsFrom(call)
fun IrFunctionAccessExpression.copyTypeAndValueArgumentsFrom(
src: IrFunctionAccessExpression,
dispatchReceiverAsArgument: Boolean = false,
argumentAsDispatchReceiver: Boolean = false,
extensionReceiverAsArgument: Boolean = false,
argumentAsExtensionReceiver: Boolean = false
) = copyTypeAndValueArgumentsFrom(
src,
src.symbol.owner,
symbol.owner,
dispatchReceiverAsArgument,
argumentAsDispatchReceiver,
extensionReceiverAsArgument,
argumentAsExtensionReceiver
)
var toValueArgumentIndex = 0
var fromValueArgumentIndex = 0
fun IrFunctionReference.copyTypeAndValueArgumentsFrom(
src: IrFunctionReference,
dispatchReceiverAsArgument: Boolean = false,
argumentAsDispatchReceiver: Boolean = false,
extensionReceiverAsArgument: Boolean = false,
argumentAsExtensionReceiver: Boolean = false
) = copyTypeAndValueArgumentsFrom(
src,
src.symbol.owner,
symbol.owner,
dispatchReceiverAsArgument,
argumentAsDispatchReceiver,
extensionReceiverAsArgument,
argumentAsExtensionReceiver
)
private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom(
src: IrMemberAccessExpression,
srcFunction: IrFunction,
destFunction: IrFunction,
dispatchReceiverAsArgument: Boolean = false,
argumentAsDispatchReceiver: Boolean = false,
extensionReceiverAsArgument: Boolean = false,
argumentAsExtensionReceiver: Boolean = false
) {
copyTypeArgumentsFrom(src)
var destValueArgumentIndex = 0
var srcValueArgumentIndex = 0
when {
dispatchReceiverAsFirstArgument -> {
putValueArgument(toValueArgumentIndex++, call.dispatchReceiver)
dispatchReceiverAsArgument && srcFunction.dispatchReceiverParameter != null -> {
putValueArgument(destValueArgumentIndex++, src.dispatchReceiver)
}
firstArgumentAsDispatchReceiver -> {
dispatchReceiver = call.getValueArgument(fromValueArgumentIndex++)
argumentAsDispatchReceiver && destFunction.dispatchReceiverParameter != null -> {
dispatchReceiver = src.getValueArgument(srcValueArgumentIndex++)
}
else -> {
dispatchReceiver = call.dispatchReceiver
dispatchReceiver = src.dispatchReceiver
}
}
extensionReceiver = call.extensionReceiver
when {
extensionReceiverAsArgument && srcFunction.extensionReceiverParameter != null -> {
putValueArgument(destValueArgumentIndex++, src.extensionReceiver)
}
argumentAsExtensionReceiver && destFunction.extensionReceiverParameter != null -> {
extensionReceiver = src.getValueArgument(srcValueArgumentIndex++)
}
else -> {
extensionReceiver = src.extensionReceiver
}
}
while (fromValueArgumentIndex < call.valueArgumentsCount) {
putValueArgument(toValueArgumentIndex++, call.getValueArgument(fromValueArgumentIndex++))
while (srcValueArgumentIndex < src.valueArgumentsCount) {
putValueArgument(destValueArgumentIndex++, src.getValueArgument(srcValueArgumentIndex++))
}
}
val IrDeclaration.file: IrFile get() = parent.let {
when (it) {
is IrFile -> it
is IrPackageFragment -> TODO("Unknown file")
is IrDeclaration -> it.file
else -> TODO("Unexpected declaration parent")
val IrDeclaration.file: IrFile
get() = parent.let {
when (it) {
is IrFile -> it
is IrPackageFragment -> TODO("Unknown file")
is IrDeclaration -> it.file
else -> TODO("Unexpected declaration parent")
}
}
}
@@ -1,5 +1,5 @@
// !LANGUAGE: +NewInference
// IGNORE_BACKEND: JVM_IR, JS
// IGNORE_BACKEND: JS
fun call0(f: (String) -> String, x: String): String = f(x)
fun call1(f: (String, String) -> String, x: String, y: String): String = f(x, y)
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun box(): String {
val x = "OK"
fun bar(y: String = x): String = y
@@ -1,11 +1,10 @@
// IGNORE_BACKEND: JVM_IR
fun box() : String {
fun local(i: Int = 1) : Int {
return i
}
return if (local() != 1) "fail" else "OK"
}
if (local() != 1) return "Fail 1"
if (local(2) != 2) return "Fail 2"
return "OK"
}
@@ -0,0 +1,12 @@
class C() {
fun box(): Int {
fun local(i: Int = 1): Int {
return i
}
return local()
}
}
fun box(): String {
return if (C().box() != 1) "fail" else "OK"
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun foo(): String {
fun bar(x: String, y: String = x): String {
return y
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
-1
View File
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun box(): String {
val s = "captured";
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt
package test
@@ -11504,6 +11504,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978.kt");
}
@TestMetadata("kt3978_2.kt")
public void testKt3978_2() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978_2.kt");
}
@TestMetadata("kt4119.kt")
public void testKt4119() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt4119.kt");
@@ -11504,6 +11504,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978.kt");
}
@TestMetadata("kt3978_2.kt")
public void testKt3978_2() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978_2.kt");
}
@TestMetadata("kt4119.kt")
public void testKt4119() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt4119.kt");
@@ -10394,6 +10394,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978.kt");
}
@TestMetadata("kt3978_2.kt")
public void testKt3978_2() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978_2.kt");
}
@TestMetadata("kt4119.kt")
public void testKt4119() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt4119.kt");
@@ -9019,6 +9019,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978.kt");
}
@TestMetadata("kt3978_2.kt")
public void testKt3978_2() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978_2.kt");
}
@TestMetadata("kt4119.kt")
public void testKt4119() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt4119.kt");
@@ -10104,6 +10104,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978.kt");
}
@TestMetadata("kt3978_2.kt")
public void testKt3978_2() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt3978_2.kt");
}
@TestMetadata("kt4119.kt")
public void testKt4119() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/kt4119.kt");