diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/KnownDescriptors.kt similarity index 99% rename from compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt rename to compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/KnownDescriptors.kt index 0b2ab2044e6..dc1a6802481 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/KnownDescriptors.kt @@ -3,7 +3,7 @@ * that can be found in the license/LICENSE.txt file. */ -package org.jetbrains.kotlin.backend.jvm.descriptors +package org.jetbrains.kotlin.backend.common.descriptors import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index 930d7951600..2a96bb13655 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -73,6 +73,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid is IrProperty -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations() is IrField -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations() is IrAnonymousInitializer -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations() + // TODO: visit children as well else -> null } } @@ -178,8 +179,6 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid private fun collectRewrittenDeclarations(): ArrayList = ArrayList(localFunctions.size + localClasses.size + 1).apply { - add(memberDeclaration) - localFunctions.values.mapTo(this) { val original = it.declaration it.transformedDeclaration.apply { @@ -195,6 +194,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid localClasses.values.mapTo(this) { it.declaration } + + add(memberDeclaration) } private inner class FunctionBodiesRewriter(val localContext: LocalContext?) : IrElementTransformerVoid() { @@ -490,7 +491,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid newValueParameters, oldDescriptor.returnType, Modality.FINAL, - Visibilities.PRIVATE + Visibilities.LOCAL ) oldDescriptor.extensionReceiverParameter?.let { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt index de52ab160dc..e85fffd82c1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt @@ -7,9 +7,12 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl +import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl object JsLoweredDeclarationOrigin : IrDeclarationOrigin { object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER") object SECONDARY_CTOR_RECEIVER : IrDeclarationOriginImpl("SECONDARY_CTOR_RECEIVER") object JS_INTRINSICS_STUB : IrDeclarationOriginImpl("JS_INTRINSICS_STUB") + object JS_CLOSURE_BOX_CLASS : IrStatementOriginImpl("JS_CLOSURE_BOX_CLASS") + object JS_LAMBDA_CREATION : IrDeclarationOriginImpl("JS_LAMBDA_CREATION") } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index ee7758919f0..6ccf6073ab0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -7,24 +7,31 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.ReflectionTypes +import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.KotlinTypeFactory +import org.jetbrains.kotlin.types.Variance class JsIrBackendContext( val module: ModuleDescriptor, @@ -36,7 +43,8 @@ class JsIrBackendContext( val intrinsics = JsIntrinsics(module, irBuiltIns, symbolTable) override val builtIns = module.builtIns - override val sharedVariablesManager = JsSharedVariablesManager(builtIns) + override val sharedVariablesManager = + JsSharedVariablesManager(builtIns, KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))) override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { // TODO diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt index ae25ff20488..13caa798ac7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt @@ -5,29 +5,204 @@ package org.jetbrains.kotlin.ir.backend.js +import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrGetValue -import org.jetbrains.kotlin.ir.expressions.IrSetVariable +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrValueSymbol +import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.* -class JsSharedVariablesManager(builtIns: KotlinBuiltIns): SharedVariablesManager { - override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor { - TODO("not implemented") - } +class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPackage: PackageFragmentDescriptor) : SharedVariablesManager { + + override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor = + LocalVariableDescriptor( + variableDescriptor.containingDeclaration, Annotations.EMPTY, variableDescriptor.name, + getSharedVariableType(variableDescriptor.type), + false, false, variableDescriptor.isLateInit, variableDescriptor.source + ) override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement { - TODO("not implemented") + val valueType = originalDeclaration.descriptor.type + val boxConstructor = closureBoxConstructorTypeDescriptor + val boxConstructorSymbol = closureBoxConstrctorTypeSymbol + val constructorTypeParam = closureBoxConstructorTypeDescriptor.typeParameters[0] + val boxConstructorTypeArgument = mapOf(constructorTypeParam to valueType) + val initializer = originalDeclaration.initializer ?: IrConstImpl.constNull( + originalDeclaration.startOffset, + originalDeclaration.endOffset, + valueType + ) + val constructorCall = IrCallImpl( + originalDeclaration.startOffset, + originalDeclaration.endOffset, + boxConstructorSymbol, + boxConstructor, + boxConstructorTypeArgument, + JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS + ).apply { putValueArgument(0, initializer) } + + + return IrVariableImpl( + originalDeclaration.startOffset, + originalDeclaration.endOffset, + originalDeclaration.origin, + sharedVariableDescriptor, + constructorCall + ) } - override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression { - TODO("not implemented") + override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression = + IrGetFieldImpl( + originalGet.startOffset, originalGet.endOffset, + closureBoxFieldSymbol, + IrGetValueImpl( + originalGet.startOffset, + originalGet.endOffset, + symbolForDescriptor(sharedVariableDescriptor) + ), + originalGet.origin + ) + + override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression = + IrSetFieldImpl( + originalSet.startOffset, originalSet.endOffset, + closureBoxFieldSymbol, + IrGetValueImpl( + originalSet.startOffset, + originalSet.endOffset, + symbolForDescriptor(sharedVariableDescriptor) + ), + originalSet.value, + originalSet.origin + ) + + private val boxTypeName = "\$closureBox\$" + + private val closureBoxTypeDescriptor = createClosureBoxClass() + private val closureBoxConstructorTypeDescriptor = createClosureBoxClassConstructor() + private val closureBoxFieldDescriptor = createClosureBoxField() + + private val closureBoxTypeSymbol = IrClassSymbolImpl(closureBoxTypeDescriptor) + val closureBoxConstrctorTypeSymbol = createFunctionSymbol(closureBoxConstructorTypeDescriptor) + private val closureBoxFieldSymbol = IrFieldSymbolImpl(closureBoxFieldDescriptor) + + + private fun createClosureBoxClass(): ClassDescriptor = + KnownClassDescriptor.createClassWithTypeParameters( + Name.identifier(boxTypeName), jsInterinalPackage, listOf(builtIns.anyType), listOf( + Name.identifier("T") + ) + ) + + private fun createClosureBoxClassConstructor(): ClassConstructorDescriptor = + ClassConstructorDescriptorImpl.create( + closureBoxTypeDescriptor, + Annotations.EMPTY, + true, + SourceElement.NO_SOURCE + ).apply { + + /// constructor(v: T) : T + + val typeParameter = constructedClass.declaredTypeParameters[0] + + +// val typeParameter = typeParameters[0] + val typeParameterType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( + Annotations.EMPTY, + typeParameter.typeConstructor, + listOf(), + false, + MemberScope.Empty + ) + + val parameterType = KotlinTypeFactory.simpleType( + Annotations.EMPTY, + typeParameter.typeConstructor, + listOf(), true + ) + + val paramDesc = ValueParameterDescriptorImpl( + this, + null, + 0, + Annotations.EMPTY, + Name.identifier("v"), + parameterType, + false, + false, + false, + null, + SourceElement.NO_SOURCE + ) + + initialize(listOf(paramDesc), Visibilities.PUBLIC) + returnType = KotlinTypeFactory.simpleNotNullType( + Annotations.EMPTY, + closureBoxTypeDescriptor, + listOf(TypeProjectionImpl(Variance.INVARIANT, typeParameterType)) + ) + } + + private fun createClosureBoxField(): PropertyDescriptor { + val desc = PropertyDescriptorImpl.create( + closureBoxTypeDescriptor, + Annotations.EMPTY, + Modality.FINAL, + Visibilities.PUBLIC, + true, + Name.identifier("v"), + CallableMemberDescriptor.Kind.DECLARATION, + SourceElement.NO_SOURCE, + false, + false, + false, + false, + false, + false + ) + + + desc.setType(builtIns.anyType, emptyList(), closureBoxTypeDescriptor.thisAsReceiverParameter, null as ReceiverParameterDescriptor?) + desc.initialize(null, null) + + return desc } - override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression { - TODO("not implemented") - } + private fun getSubstitutedRefConstructor(valueType: KotlinType): ClassConstructorDescriptor = + closureBoxConstructorTypeDescriptor.substitute( + TypeSubstitutor.create( + closureBoxConstructorTypeDescriptor.typeParameters.associate { + it.typeConstructor to TypeProjectionImpl( + Variance.INVARIANT, + valueType + ) + } + ) + )!! + + private fun getRefType(valueType: KotlinType) = + KotlinTypeFactory.simpleNotNullType( + Annotations.EMPTY, + closureBoxTypeDescriptor, + listOf(TypeProjectionImpl(Variance.INVARIANT, valueType)) + ) + + private fun getSharedVariableType(type: KotlinType) = getRefType(type) + + private val variableSymbols = mutableMapOf() + + private fun symbolForDescriptor(sharedVariableDescriptor: VariableDescriptor): IrValueSymbol = + variableSymbols.getOrPut(sharedVariableDescriptor, { IrVariableSymbolImpl(sharedVariableDescriptor) }) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 80c32d2ce95..eb8d56c8d02 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -9,8 +9,7 @@ import com.intellij.openapi.project.Project import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.ir.backend.js.lower.IntrinsicifyCallsLowering -import org.jetbrains.kotlin.ir.backend.js.lower.SecondaryCtorLowering +import org.jetbrains.kotlin.ir.backend.js.lower.* import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator @@ -56,11 +55,13 @@ fun compile( fun JsIrBackendContext.lower(file: IrFile) { LateinitLowering(this, true).lower(file) - LocalFunctionsLowering(this).lower(file) DefaultArgumentStubGenerator(this).runOnFilePostfix(file) + SharedVariablesLowering(this).runOnFilePostfix(file) + LocalDeclarationsLowering(this).runOnFilePostfix(file) PropertiesLowering().lower(file) InitializersLowering(this, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).runOnFilePostfix(file) SecondaryCtorLowering(this).lower(file) - IntrinsicifyCallsLowering(this).lower(file) + FunctionReferenceLowering(this).lower(file) + } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/FunctionReferenceLowering.kt new file mode 100644 index 00000000000..b4733f83968 --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/FunctionReferenceLowering.kt @@ -0,0 +1,178 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.backend.js.lower + +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrFunctionReference +import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl +import org.jetbrains.kotlin.ir.visitors.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.KotlinType + +class FunctionReferenceLowering(val context: JsIrBackendContext) : FileLoweringPass { + override fun lower(irFile: IrFile) { + irFile.acceptVoid(FunctionReferenceCollector()) + irFile.transformChildrenVoid(LambdaFunctionVisitor()) + irFile.transformChildrenVoid(FunctionReferenceVisitor()) + lambdaImpls.forEach { it.transformChildrenVoid(FunctionReferenceVisitor()) } + } + + val lambdas = mutableMapOf() + val oldToNewDeclMap = mutableMapOf() + val lambdaImpls = mutableListOf() + + inner class FunctionReferenceCollector : IrElementVisitorVoid { + override fun visitFunctionReference(expression: IrFunctionReference) { + lambdas[expression.symbol.owner as IrFunction] = expression.type + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + } + + inner class FunctionReferenceVisitor : IrElementTransformerVoid() { + override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { + val newTarget = oldToNewDeclMap[expression.symbol.owner] + + return if (newTarget != null) IrCallImpl(expression.startOffset, expression.endOffset, newTarget.symbol).apply { + copyTypeArgumentsFrom(expression) + var index = 0 + for (i in 0 until expression.valueArgumentsCount) { + val arg = expression.getValueArgument(i) + if (arg != null) { + putValueArgument(index++, arg) + } + } + } else expression + } + + } + + inner class LambdaFunctionVisitor : IrElementTransformerVoid() { + override fun visitFunction(declaration: IrFunction): IrStatement { + if (declaration !in lambdas.keys) return declaration + + // transform + // foo$lambda(a: A, b: B, c: closure$C, d: closure$D) { /*body*/ } ===> + // foo$lambda(c: closure$C, d: closure$D) { + // var $funcRef = function(a: A, b: B) { /*body*/ } + // return $funcRef + // } + + val functionType = lambdas[declaration]!! + + // FunctionN, arguments.size = N + 1 + + val lambdaParamCount = + if (declaration.extensionReceiverParameter == null) functionType.arguments.size - 1 else functionType.arguments.size - 2 + + assert(lambdaParamCount >= 0) + + val descriptor = SimpleFunctionDescriptorImpl.create( + declaration.descriptor.containingDeclaration, + Annotations.EMPTY, + Name.identifier("${declaration.descriptor.name}_impl"), + declaration.descriptor.kind, + declaration.descriptor.source + ) + descriptor.initialize( + null, + declaration.descriptor.dispatchReceiverParameter, +// declaration.descriptor.typeParameters, + emptyList(), + declaration.descriptor.valueParameters.drop(declaration.valueParameters.size - lambdaParamCount).mapIndexed { index, valueParameterDescriptor -> + valueParameterDescriptor.copy(descriptor, valueParameterDescriptor.name, index) + }, + declaration.descriptor.returnType, + declaration.descriptor.modality, + declaration.descriptor.visibility + ) + + val symbol = IrSimpleFunctionSymbolImpl(descriptor) + val func = IrFunctionImpl(declaration.startOffset, declaration.endOffset, declaration.origin, symbol).apply { + dispatchReceiverParameter = declaration.dispatchReceiverParameter + extensionReceiverParameter = declaration.extensionReceiverParameter + declaration.valueParameters.drop(declaration.valueParameters.size - lambdaParamCount).forEachIndexed { index, param -> + valueParameters += IrValueParameterImpl( + param.startOffset, + param.endOffset, + param.origin, + descriptor.valueParameters[index] + ) + } + } + + val newDeclDescriptor = SimpleFunctionDescriptorImpl.create( + declaration.descriptor.containingDeclaration, + declaration.descriptor.annotations, + declaration.descriptor.name, + declaration.descriptor.kind, + declaration.descriptor.source + ).initialize( + null, + declaration.descriptor.dispatchReceiverParameter, +// declaration.descriptor.typeParameters, + emptyList(), + declaration.descriptor.valueParameters.dropLast(lambdaParamCount), + functionType, + declaration.descriptor.modality, + declaration.descriptor.visibility + ) + val newDeclSymbol = IrSimpleFunctionSymbolImpl(newDeclDescriptor) + + val funcReference = IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, functionType, symbol, descriptor, null, null) + val varDescriptor = IrTemporaryVariableDescriptorImpl(newDeclDescriptor, Name.identifier("\$funRef"), functionType) + val closureStmt = IrVariableImpl( + declaration.startOffset, + declaration.endOffset, + JsLoweredDeclarationOrigin.JS_LAMBDA_CREATION, + varDescriptor, + funcReference + ) + val returnStmt = IrReturnImpl( + declaration.startOffset, + declaration.endOffset, + symbol, + IrGetValueImpl(declaration.startOffset, declaration.endOffset, IrVariableSymbolImpl(varDescriptor)) + ) + + val oldBody = declaration.body + + val newBody = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(closureStmt, returnStmt)) + func.body = oldBody + + lambdaImpls += func + + val newDeclaration = IrFunctionImpl(declaration.startOffset, declaration.endOffset, declaration.origin, newDeclSymbol).apply { + body = newBody + valueParameters += declaration.valueParameters.dropLast(lambdaParamCount) + } + + oldToNewDeclMap[declaration] = newDeclaration + + return newDeclaration + } + } +} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt index 434ce4de6dd..43063159742 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt @@ -114,16 +114,19 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL return irCall(call, it.symbol) } - (symbol.owner as? IrFunction)?.dispatchReceiverParameter?.let { - val key = SimpleMemberKey(it.type, symbol.name) + if (symbol.isBound) { - memberToIrFunction[key]?.let { - // TODO: don't apply intrinsics when type of receiver or argument is Long - return irCall(call, it.symbol, dispatchReceiverAsFirstArgument = true) - } + (symbol.owner as? IrFunction)?.dispatchReceiverParameter?.let { + val key = SimpleMemberKey(it.type, symbol.name) - memberToTransformer[key]?.let { - return it(call) + memberToIrFunction[key]?.let { + // TODO: don't apply intrinsics when type of receiver or argument is Long + return irCall(call, it.symbol, dispatchReceiverAsFirstArgument = true) + } + + memberToTransformer[key]?.let { + return it(call) + } } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt index bf3eafb0c0d..2132a217136 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt @@ -268,11 +268,18 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement = super.visitFunction(declaration, declaration) override fun visitCall(expression: IrCall, ownerFunc: IrFunction?): IrElement { - val target = expression.symbol.owner as IrFunction + if (expression.symbol.isBound) { - if (target is IrConstructor) { - if (!target.descriptor.isPrimary) { - return redirectCall(expression, context.secondaryConstructorsMap[target.symbol]!!.stub) + val target = expression.symbol.owner as IrFunction + + if (target is IrConstructor) { + if (!target.descriptor.isPrimary) { + val ctor = context.secondaryConstructorsMap[target.symbol] + if (ctor != null) { + + return redirectCall(expression, ctor.stub) + } + } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrDeclarationToJsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrDeclarationToJsTransformer.kt index d0f24f176a7..553d2c23665 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrDeclarationToJsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrDeclarationToJsTransformer.kt @@ -11,9 +11,6 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.js.backend.ast.* class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer { - override fun visitProperty(declaration: IrProperty, context: JsGenerationContext): JsStatement { - return jsVar(declaration.name, declaration.backingField?.initializer?.expression, context) - } override fun visitSimpleFunction(declaration: IrSimpleFunction, context: JsGenerationContext): JsStatement { return declaration.accept(IrFunctionToJsTransformer(), context).makeStmt() @@ -28,7 +25,7 @@ class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer { - // TODO: should we prohibit using blocks as expression in the future? - override fun visitBlock(expression: IrBlock, context: JsGenerationContext): JsExpression { - if (expression.statements.isEmpty()) { - // TODO: what should we do here? Crash? Generate throw? Should it be treated as unreachable code? - return super.visitBlock(expression, context) + private val neutralExpression: JsExpression = JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(1)) + + override fun visitContainerExpression(expression: IrContainerExpression, context: JsGenerationContext): JsExpression = + expression.statements.map { it.accept(this, context) }.fold(neutralExpression) { left, right -> + if (left != neutralExpression) JsBinaryOperation(JsBinaryOperator.COMMA, left, right) else right } - return expression.statements - .map { it.accept(this, context) } - .reduce { left, right -> JsBinaryOperation(JsBinaryOperator.COMMA, left, right) } - } + override fun visitBlock(expression: IrBlock, data: JsGenerationContext): JsExpression = visitContainerExpression(expression, data) - override fun visitExpressionBody(body: IrExpressionBody, context: JsGenerationContext): JsExpression { - return body.expression.accept(this, context) + override fun visitComposite(expression: IrComposite, data: JsGenerationContext): JsExpression = + visitContainerExpression(expression, data) + + override fun visitExpressionBody(body: IrExpressionBody, context: JsGenerationContext): JsExpression = + body.expression.accept(this, context) + + override fun visitFunctionReference(expression: IrFunctionReference, context: JsGenerationContext): JsExpression { + val irFunction = expression.symbol.owner as IrFunction + return irFunction.accept(IrFunctionToJsTransformer(), context) } override fun visitConst(expression: IrConst, context: JsGenerationContext): JsExpression { @@ -61,36 +66,36 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer JsExpression -class JsIntrinsicTransformers(intrinsics: JsIntrinsics) { +class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { private val transformers: Map init { + val intrinsics = backendContext.intrinsics + transformers = mutableMapOf() transformers.apply { @@ -63,7 +65,14 @@ class JsIntrinsicTransformers(intrinsics: JsIntrinsics) { val classToCreate = call.getTypeArgument(0)!! val prototype = prototypeOf(classToCreate.constructor.declarationDescriptor!!.name.toJsName().makeRef()) JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype) + } + add(backendContext.sharedVariablesManager.closureBoxConstructorTypeSymbol) { call, context -> + val args = translateCallArguments(call, context) + val initializer = args[0] + val propertyInit = JsPropertyInitializer(JsNameRef("v"), initializer) + val objectLiteral = JsObjectLiteral() + objectLiteral.apply { propertyInitializers += propertyInit } } addIfNotNull(intrinsics.jsCode) { call, context -> @@ -71,7 +80,7 @@ class JsIntrinsicTransformers(intrinsics: JsIntrinsics) { when (jsCode) { is JsExpression -> jsCode - // TODO don't generate function for this case + // TODO don't generate function for this case else -> JsInvocation(JsFunction(context.currentScope, jsCode as? JsBlock ?: JsBlock(jsCode as JsStatement), "")) } } @@ -81,6 +90,10 @@ class JsIntrinsicTransformers(intrinsics: JsIntrinsics) { operator fun get(symbol: IrSymbol): IrCallTransformer? = transformers[symbol] } +private fun MutableMap.add(functionSymbol: IrSymbol, t: IrCallTransformer) { + put(functionSymbol, t) +} + private fun MutableMap.add(function: IrFunction, t: IrCallTransformer) { put(function.symbol, t) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt index 71fdcf59a20..bc9b9899bd2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt @@ -12,15 +12,23 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.name.Name -@Deprecated("Use context.getNameForSymbol(symbol) instead") -fun Name.toJsName() = JsDynamicScope.declareName(asString()) +// TODO don't use JsDynamicScope +val dummyScope = JsDynamicScope -fun jsVar(name: Name, initializer: IrExpression?, context: JsGenerationContext): JsVars { +fun Name.toJsName() = +// TODO sanitize + dummyScope.declareName(asString()) + +fun jsVar(name: JsName, initializer: IrExpression?, context: JsGenerationContext): JsVars { val jsInitializer = initializer?.accept(IrElementToJsExpressionTransformer(), context) - return JsVars(JsVars.JsVar(name.toJsName(), jsInitializer)) + return JsVars(JsVars.JsVar(name, jsInitializer)) } -fun IrWhen.toJsNode(tr: BaseIrElementToJsNodeTransformer, data: D, node: (JsExpression, T, T?) -> T): T? = +fun IrWhen.toJsNode( + tr: BaseIrElementToJsNodeTransformer, + data: D, + node: (JsExpression, T, T?) -> T +): T? = branches.foldRight(null) { br, n -> val body = br.result.accept(tr, data) if (br is IrElseBranch) body @@ -47,14 +55,8 @@ fun translateFunction(declaration: IrFunction, name: JsName?, context: JsGenerat parameters.add(JsParameter(parameter)) } - declaration.extensionReceiverParameter?.let { function.addParameter("\$receiver") } - declaration.valueParameters.forEach { - if (it.name.isSpecial) { - function.addParameter(context.staticContext.getSpecialNameString(it.name.asString())) - } else { - function.addParameter(it.name.asString()) - } - } + declaration.extensionReceiverParameter?.let { function.addParameter(context.getNameForSymbol(it.symbol).ident) } + declaration.valueParameters.forEach { function.addParameter(context.getNameForSymbol(it.symbol).ident) } return function } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt index 5c99f93eae7..49e14092f90 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt @@ -5,16 +5,10 @@ package org.jetbrains.kotlin.ir.backend.js.utils -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrElementToJsExpressionTransformer -import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrElementToJsStatementTransformer -import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.toJsName import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.js.backend.ast.* -import org.jetbrains.kotlin.name.Name class JsGenerationContext { fun newDeclaration(scope: JsScope, func: IrFunction? = null): JsGenerationContext { @@ -48,5 +42,4 @@ class JsGenerationContext { } fun getNameForSymbol(symbol: IrSymbol): JsName = staticContext.getNameForSymbol(symbol) - fun getSpecialRefForName(name: Name): JsExpression = staticContext.getSpecialRefForName(name) } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt index 5706f1d8b39..12572630681 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt @@ -18,11 +18,9 @@ class JsStaticContext( private val rootScope: JsRootScope, private val globalBlock: JsGlobalBlock, private val nameGenerator: NameGenerator, - val backendContext: JsIrBackendContext + backendContext: JsIrBackendContext ) { - val intrinsics = JsIntrinsicTransformers(backendContext.intrinsics) + val intrinsics = JsIntrinsicTransformers(backendContext) fun getNameForSymbol(irSymbol: IrSymbol) = nameGenerator.getNameForSymbol(irSymbol, rootScope) - fun getSpecialRefForName(name: Name): JsExpression = nameGenerator.getSpecialRefForName(name) - fun getSpecialNameString(specNameString: String): String = nameGenerator.getSpecialNameString(specNameString) } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameGenerator.kt index 0ce97aac742..382f49042e5 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameGenerator.kt @@ -5,16 +5,10 @@ package org.jetbrains.kotlin.ir.backend.js.utils -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.js.backend.ast.JsExpression import org.jetbrains.kotlin.js.backend.ast.JsName import org.jetbrains.kotlin.js.backend.ast.JsScope -import org.jetbrains.kotlin.name.Name interface NameGenerator { fun getNameForSymbol(symbol: IrSymbol, scope: JsScope): JsName - - fun getSpecialRefForName(name: Name): JsExpression - fun getSpecialNameString(specNameString: String): String } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/Namer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/Namer.kt index 4c59bcb055a..6be3999683b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/Namer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/Namer.kt @@ -40,7 +40,8 @@ object Namer { val ROOT_PACKAGE = "_" - val RECEIVER_PARAMETER_NAME = "\$receiver" + val EXTENSION_RECEIVER_NAME = "\$receiver" + val IMPLICIT_RECEIVER_NAME = "this" val ANOTHER_THIS_PARAMETER_NAME = "$this" val THROW_CLASS_CAST_EXCEPTION_FUN_NAME = "throwCCE" diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt index 8bcf248cd65..e5647df92e7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt @@ -6,11 +6,14 @@ package org.jetbrains.kotlin.ir.backend.js.utils import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.js.backend.ast.* +import org.jetbrains.kotlin.js.backend.ast.JsName +import org.jetbrains.kotlin.js.backend.ast.JsScope import org.jetbrains.kotlin.js.naming.isES5IdentifierPart import org.jetbrains.kotlin.js.naming.isES5IdentifierStart -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver class SimpleNameGenerator : NameGenerator { @@ -18,24 +21,34 @@ class SimpleNameGenerator : NameGenerator { override fun getNameForSymbol(symbol: IrSymbol, scope: JsScope): JsName = getNameForDescriptor(symbol.descriptor, scope) - override fun getSpecialRefForName(name: Name): JsExpression { - assert(name.isSpecial) - - val nameString = name.asString() - return when (nameString) { - Namer.THIS_SPECIAL_NAME -> JsThisRef() - else -> JsNameRef(getSpecialNameString(nameString)) - } - } - - override fun getSpecialNameString(specNameString: String): String = when (specNameString) { - Namer.SET_SPECIAL_NAME -> Namer.SETTER_ARGUMENT - else -> TODO("for Name ${specNameString}") - } - private fun getNameForDescriptor(descriptor: DeclarationDescriptor, scope: JsScope): JsName = nameCache.getOrPut(descriptor, { val nameBuilder = StringBuilder() when (descriptor) { + is ReceiverParameterDescriptor -> { + when (descriptor.value) { + is ExtensionReceiver -> nameBuilder.append(Namer.EXTENSION_RECEIVER_NAME) + is ImplicitClassReceiver -> nameBuilder.append(Namer.IMPLICIT_RECEIVER_NAME) + else -> TODO("name for $descriptor") + } + } + is ValueParameterDescriptor -> { + if (descriptor.name.isSpecial) { + // TODO: consider this case more carefully + nameBuilder.append(Namer.IMPLICIT_RECEIVER_NAME) + nameBuilder.append('_') + nameBuilder.append(descriptor.index) + } else { + val declaredName = descriptor.name.identifier + nameBuilder.append(declaredName) + if (declaredName.startsWith("\$")) { + nameBuilder.append('_') + nameBuilder.append(descriptor.index) + } + } + } + is PropertyDescriptor -> { + nameBuilder.append(descriptor.name.identifier) + } is PropertyAccessorDescriptor -> { when (descriptor) { is PropertyGetterDescriptor -> nameBuilder.append(Namer.GETTER_PREFIX) @@ -43,6 +56,21 @@ class SimpleNameGenerator : NameGenerator { } nameBuilder.append(descriptor.correspondingProperty.name.asString()) } + is ClassDescriptor -> { + if (descriptor.name.isSpecial) { + nameBuilder.append(descriptor.name.asString().let { + it.substring(1, it.length - 1) + "${descriptor.hashCode()}" + }) + } else { + nameBuilder.append(descriptor.name.identifier) + } + } + is ConstructorDescriptor -> { + nameBuilder.append(getNameForDescriptor(descriptor.constructedClass, scope)) + } + is LocalVariableDescriptor -> { + nameBuilder.append(descriptor.name.identifier) + } is CallableDescriptor -> { nameBuilder.append(descriptor.name.asString()) descriptor.typeParameters.forEach { nameBuilder.append("_${it.name.asString()}") } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/DefaultImplsClassDescriptor.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/DefaultImplsClassDescriptor.kt index 33af0f4817a..40d9cdae1c7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/DefaultImplsClassDescriptor.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/DefaultImplsClassDescriptor.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.descriptors +import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptorImpl.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptorImpl.kt index 7f013aefdc0..2b5f6213d44 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptorImpl.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptorImpl.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.descriptors +import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor import org.jetbrains.kotlin.codegen.descriptors.FileClassDescriptor import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt index 2411e6e6c65..f4ddab287c2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt @@ -16,7 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.descriptors -import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager +import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.* diff --git a/compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt b/compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt index a59a7507800..9af27d0f74f 100644 --- a/compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt +++ b/compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt @@ -2,14 +2,42 @@ import kotlin.test.assertEquals -inline fun foo(x: String, block: (String) -> String) = block(x) + +fun run(r: () -> Any) = r() + + +fun test(i: Int, j: Int, k: Int): String { + + + var i = 0 + var j = 2 + val k = 4 + + fun f(): String = "OK" + + val funVal = { + println(k) + } + run(funVal) + + val funLit = { i += 1 + j += k + f() } + val ret = run(funLit) as String + if (i != 1 || j != 6 || k != 4) return "fail" + return ret +} fun box(): String { - fun bar(y: String) = y + "cde" - - val res = foo("abc") { bar(it) } - - assertEquals("abccde", res) - - return "OK" + return test(1, 2, 3) } + +//fun box(): String { +//// fun bar(y: String) = y + "cde" +// +//// val res = foo("abc") { bar(it) } +// +//// assertEquals("abccde", res) +// +// return "OK" +//} diff --git a/js/js.translator/testData/box/closure/closureLocalFunction.kt b/js/js.translator/testData/box/closure/closureLocalFunction.kt index c96cefee30f..f574790a3cf 100644 --- a/js/js.translator/testData/box/closure/closureLocalFunction.kt +++ b/js/js.translator/testData/box/closure/closureLocalFunction.kt @@ -2,13 +2,54 @@ // EXPECTED_REACHABLE_NODES: 1113 package foo -fun test(): String { - fun f(): String = "OK" - val funLit = { f() } - return funLit() +class closureBox(var v: T) + + + +//fun run(r: () -> Any) = r() + +fun wrapper(t1:T1, t2:T2, i1:Int, block: (t1:T1, t2:T2, i1:Int) -> T3): T3 { + val f = { tt1:T1, tt2:T2, ii:Int -> block(tt1, tt2, ii) } + return f(t1, t2, i1) } +fun test(ii: Int, jj: Int, kk: Int): String { + + var i = ii + var j = jj + val k = kk + var ggg: Int + + fun f(): String = "OK" + +// fun f() {} + val funVal = { + k + } + +// run(funVal) + + val funLit = { x:Int, l:Int, a:Int, b:Int, c:Int, d:Int, g:Int -> i += 1 + j += k + ggg = 333 + x + f() } + val ret = funLit(50, 77, 1, 2, 3, 4, 5) +// funLit(50, 77L) + if (i != 1 || j != 6 || k != 4) return "fail" + return ret +// return "OK" +} + +//fun test(aa:Int, bb:Int, cc:Int) : Int { +// val c = cc +// var d = 0 +// val f = { a:Int,b:Int -> d = a*b+c} +// f(aa, bb) +// return d +//} + fun box(): String { - return test() +// val i_box = closureBox(99) + return test(1, 2, 3).toString() } \ No newline at end of file