diff --git a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index e439c0faa10..b2e8a528895 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -62,6 +62,9 @@ object CommonConfigurationKeys { @JvmField val PROFILE_PHASES = CompilerConfigurationKey.create("profile backend phase execution") + + @JvmField + val EXCLUDED_ELEMENTS_FROM_DUMPING = CompilerConfigurationKey.create>("lowering elements which shouldn't be dumped at all") } var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings 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 79436f05738..63286e1026f 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.CommonBackendContext +import org.jetbrains.kotlin.backend.common.CompilerPhases import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor import org.jetbrains.kotlin.backend.common.ir.Ir @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.getPropertyDeclaration import org.jetbrains.kotlin.ir.util.kotlinPackageFqn +import org.jetbrains.kotlin.js.backend.ast.JsNode import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -47,11 +49,14 @@ class JsIrBackendContext( override val irBuiltIns: IrBuiltIns, val symbolTable: SymbolTable, irModuleFragment: IrModuleFragment, - val configuration: CompilerConfiguration + val configuration: CompilerConfiguration, + val dependencies: List ) : CommonBackendContext { override val builtIns = module.builtIns + val phases = CompilerPhases(jsPhases, configuration) + val internalPackageFragmentDescriptor = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal")) val implicitDeclarationFile by lazy { IrFileImpl(object : SourceManager.FileEntry { @@ -165,6 +170,9 @@ class JsIrBackendContext( val originalModuleIndex = ModuleIndex(irModuleFragment) + lateinit var moduleFragmentCopy: IrModuleFragment + lateinit var jsProgram: JsNode + fun getOperatorByName(name: Name, type: KotlinType) = operatorMap[name]?.get(type) override val ir = object : Ir(this, irModuleFragment) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt new file mode 100644 index 00000000000..1650c2524c1 --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -0,0 +1,384 @@ +/* + * 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 + +import org.jetbrains.kotlin.backend.common.* +import org.jetbrains.kotlin.backend.common.lower.* +import org.jetbrains.kotlin.ir.backend.js.lower.* +import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering +import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering +import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering +import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining +import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering +import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering +import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols +import org.jetbrains.kotlin.ir.util.patchDeclarationParents +import org.jetbrains.kotlin.ir.visitors.acceptVoid + +private fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) } + +private fun DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable) = files.forEach { runOnFilePostfix(it) } + +private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { runOnFilePostfix(it) } + + +object IrModuleStartPhase : CompilerPhase { + override val name = "IrModuleFragment" + override val description = "State at start of IrModuleFragment lowering" + override val prerequisite = emptySet() + override fun invoke(context: BackendContext, input: IrModuleFragment) = input +} + +private fun makeJsPhase( + lowering: (JsIrBackendContext, IrModuleFragment) -> Unit, + description: String, + name: String, + prerequisite: Set> = emptySet() +) = makePhase(lowering, description, name, prerequisite) + +private val MoveExternalDeclarationsToSeparatePlacePhase = makeJsPhase( + { _, module -> MoveExternalDeclarationsToSeparatePlace().lower(module) }, + name = "MoveExternalDeclarationsToSeparatePlace", + description = "Move `external` declarations into separate place to make the following lowerings do not care about them" +) + +private val ExpectDeclarationsRemovingPhase = makeJsPhase( + { context, module -> ExpectDeclarationsRemoving(context).lower(module) }, + name = "ExpectDeclarationsRemoving", + description = "Remove expect declaration from module fragment" +) + +private val CoroutineIntrinsicLoweringPhase = makeJsPhase( + { context, module -> CoroutineIntrinsicLowering(context).lower(module) }, + name = "CoroutineIntrinsicLowering", + description = "Replace common coroutine intrinsics with platform specific ones" +) + +private val ArrayInlineConstructorLoweringPhase = makeJsPhase( + { context, module -> ArrayInlineConstructorLowering(context).lower(module) }, + name = "ArrayInlineConstructorLowering", + description = "Replace array constructor with platform specific factory functions" +) + +private val LateinitLoweringPhase = makeJsPhase( + { context, module -> LateinitLowering(context, true).lower(module) }, + name = "LateinitLowering", + description = "Insert checks for lateinit field references" +) + +private val ModuleCopyingPhase = makeJsPhase( + { context, module -> context.moduleFragmentCopy = module.deepCopyWithSymbols() }, + name = "ModuleCopying", + description = " Copy current module to make it accessible from different one", + prerequisite = setOf(LateinitLoweringPhase) +) + +private val FunctionInliningPhase = makeJsPhase( + { context, module -> + FunctionInlining(context).inline(module) + module.replaceUnboundSymbols(context) + module.patchDeclarationParents() + }, + name = "FunctionInliningPhase", + description = "Perform function inlining", + prerequisite = setOf(ModuleCopyingPhase, LateinitLoweringPhase, ArrayInlineConstructorLoweringPhase, CoroutineIntrinsicLoweringPhase) +) + +private val RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsPhase( + { _, module -> RemoveInlineFunctionsWithReifiedTypeParametersLowering().lower(module) }, + name = "RemoveInlineFunctionsWithReifiedTypeParametersLowering", + description = "Remove Inline functions with reified parameters from context", + prerequisite = setOf(FunctionInliningPhase) +) + +private val ThrowableSuccessorsLoweringPhase = makeJsPhase( + { context, module -> ThrowableSuccessorsLowering(context).lower(module) }, + name = "ThrowableSuccessorsLowering", + description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions" +) + +private val TailrecLoweringPhase = makeJsPhase( + { context, module -> TailrecLowering(context).lower(module) }, + name = "TailrecLowering", + description = "Replace `tailrec` callsites with equivalent loop" +) + +private val UnitMaterializationLoweringPhase = makeJsPhase( + { context, module -> UnitMaterializationLowering(context).lower(module) }, + name = "UnitMaterializationLowering", + description = "Insert Unit object where it is supposed to be", + prerequisite = setOf(TailrecLoweringPhase) +) + +private val EnumClassLoweringPhase = makeJsPhase( + { context, module -> EnumClassLowering(context).lower(module) }, + name = "EnumClassLowering", + description = "Transform Enum Class into regular Class" +) + +private val EnumUsageLoweringPhase = makeJsPhase( + { context, module -> EnumUsageLowering(context).lower(module) }, + name = "EnumUsageLowering", + description = "Replace enum access with invocation of corresponding function" +) + +private val SharedVariablesLoweringPhase = makeJsPhase( + { context, module -> SharedVariablesLowering(context).lower(module) }, + name = "SharedVariablesLowering", + description = "Box captured mutable variables" +) + +private val ReturnableBlockLoweringPhase = makeJsPhase( + { context, module -> ReturnableBlockLowering(context).lower(module) }, + name = "ReturnableBlockLowering", + description = "Replace returnable block with do-while loop", + prerequisite = setOf(FunctionInliningPhase) +) + +private val LocalDelegatedPropertiesLoweringPhase = makeJsPhase( + { _, module -> LocalDelegatedPropertiesLowering().lower(module) }, + name = "LocalDelegatedPropertiesLowering", + description = "Transform Local Delegated properties" +) + +private val LocalDeclarationsLoweringPhase = makeJsPhase( + { context, module -> LocalDeclarationsLowering(context).lower(module) }, + name = "LocalDeclarationsLowering", + description = "Move local declarations into nearest declaration container", + prerequisite = setOf(SharedVariablesLoweringPhase) +) + +private val InnerClassesLoweringPhase = makeJsPhase( + { context, module -> InnerClassesLowering(context).lower(module) }, + name = "InnerClassesLowering", + description = "Capture outer this reference to inner class" +) + +private val InnerClassConstructorCallsLoweringPhase = makeJsPhase( + { context, module -> InnerClassConstructorCallsLowering(context).lower(module) }, + name = "InnerClassConstructorCallsLowering", + description = "Replace inner class constructor invocation" +) + +private val SuspendFunctionsLoweringPhase = makeJsPhase( + { context, module -> SuspendFunctionsLowering(context).lower(module) }, + name = "SuspendFunctionsLowering", + description = "Transform suspend functions into CoroutineImpl instance and build state machine", + prerequisite = setOf(UnitMaterializationLoweringPhase, CoroutineIntrinsicLoweringPhase) +) + +private val CallableReferenceLoweringPhase = makeJsPhase( + { context, module -> CallableReferenceLowering(context).lower(module) }, + name = "CallableReferenceLowering", + description = "Handle callable references", + prerequisite = setOf(SuspendFunctionsLoweringPhase, LocalDeclarationsLoweringPhase, LocalDelegatedPropertiesLoweringPhase) +) + +private val DefaultArgumentStubGeneratorPhase = makeJsPhase( + { context, module -> DefaultArgumentStubGenerator(context).lower(module) }, + name = "DefaultArgumentStubGenerator", + description = "Generate synthetic stubs for functions with default parameter values" +) + +private val DefaultParameterInjectorPhase = makeJsPhase( + { context, module -> DefaultParameterInjector(context).lower(module) }, + name = "DefaultParameterInjector", + description = "Replace callsite with default parameters with corresponding stub function", + prerequisite = setOf(CallableReferenceLoweringPhase, InnerClassesLoweringPhase) +) + +private val DefaultParameterCleanerPhase = makeJsPhase( + { context, module -> DefaultParameterCleaner(context).lower(module) }, + name = "DefaultParameterCleaner", + description = "Clean default parameters up" +) + +private val VarargLoweringPhase = makeJsPhase( + { context, module -> VarargLowering(context).lower(module) }, + name = "VarargLowering", + description = "Lower vararg arguments", + prerequisite = setOf(CallableReferenceLoweringPhase) +) + +private val PropertiesLoweringPhase = makeJsPhase( + { _, module -> PropertiesLowering().lower(module) }, + name = "PropertiesLowering", + description = "Move fields and accessors out from its property" +) + +private val InitializersLoweringPhase = makeJsPhase( + { context, module -> InitializersLowering(context, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).lower(module) }, + name = "InitializersLowering", + description = "Merge init block and field initializers into [primary] constructor", + prerequisite = setOf(EnumClassLoweringPhase) +) + +private val MultipleCatchesLoweringPhase = makeJsPhase( + { context, module -> MultipleCatchesLowering(context).lower(module) }, + name = "MultipleCatchesLowering", + description = "Replace multiple catches with single one" +) + +private val BridgesConstructionPhase = makeJsPhase( + { context, module -> BridgesConstruction(context).lower(module) }, + name = "BridgesConstruction", + description = "Generate bridges", + prerequisite = setOf(SuspendFunctionsLoweringPhase) +) + +private val TypeOperatorLoweringPhase = makeJsPhase( + { context, module -> TypeOperatorLowering(context).lower(module) }, + name = "TypeOperatorLowering", + description = "Lower IrTypeOperator with corresponding logic", + prerequisite = setOf(BridgesConstructionPhase, RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase) +) + +private val SecondaryCtorLoweringPhase = makeJsPhase( + { context, module -> + SecondaryCtorLowering(context).run { + constructorProcessorLowering.runOnFilesPostfix(module.files + context.dependencies.flatMap { it.files }) + constructorRedirectorLowering.lower(module) + } + }, + name = "SecondaryCtorLoweringPhase", + description = "Generate static functions for each secondary constructor and replace usages", + prerequisite = setOf(InnerClassesLoweringPhase) +) + +private val InlineClassLoweringPhase = makeJsPhase( + { context, module -> + InlineClassLowering(context).run { + inlineClassDeclarationLowering.runOnFilesPostfix(module) + inlineClassUsageLowering.lower(module) + } + }, + name = "InlineClassLowering", + description = "Handle inline classes" +) + +private val AutoboxingTransformerPhase = makeJsPhase( + { context, module -> AutoboxingTransformer(context).lower(module) }, + name = "AutoboxingTransformer", + description = "Insert box/unbox intrinsics" +) + +private val BlockDecomposerLoweringPhase = makeJsPhase( + { context, module -> + BlockDecomposerLowering(context).lower(module) + module.patchDeclarationParents() + }, + name = "BlockDecomposerLowering", + description = "Transform statement-like-expression nodes into pure-statement to make it easily transform into JS", + prerequisite = setOf(TypeOperatorLoweringPhase, SuspendFunctionsLoweringPhase) +) + +private val ClassReferenceLoweringPhase = makeJsPhase( + { context, module -> ClassReferenceLowering(context).lower(module) }, + name = "ClassReferenceLowering", + description = "Handle class references" +) + +private val PrimitiveCompanionLoweringPhase = makeJsPhase( + { context, module -> PrimitiveCompanionLowering(context).lower(module) }, + name = "PrimitiveCompanionLowering", + description = "Replace common companion object access with platform one" +) + +private val ConstLoweringPhase = makeJsPhase( + { context, module -> ConstLowering(context).lower(module) }, + name = "ConstLowering", + description = "Wrap Long and Char constants into constructor invocation" +) + +private val CallsLoweringPhase = makeJsPhase( + { context, module -> CallsLowering(context).lower(module) }, + name = "CallsLowering", + description = "Handle intrinsics" +) + +object IrValidationPhase : CompilerPhase { + + private val validatorConfig = IrValidatorConfig( + abortOnError = true, + ensureAllNodesAreDifferent = true, + checkTypes = false, + checkDescriptors = false + ) + + override val name = "IrValidator" + override val description = "Make sure that various Ir Invariants are met" + override val prerequisite = emptySet() + override fun invoke(context: CommonBackendContext, input: IrModuleFragment): IrModuleFragment { + IrValidator(context, validatorConfig).let { input.acceptVoid(it) } + input.checkDeclarationParents() + return input + } +} + +object IrModuleEndPhase : CompilerPhase { + override val name = "IrModuleFragment" + override val description = "State at end of IrModuleFragment lowering" + override val prerequisite = emptySet() + override fun invoke(context: BackendContext, input: IrModuleFragment) = input +} + +private val IrToJsPhase = makeJsPhase( + { context, module -> context.jsProgram = IrModuleToJsTransformer(context).let { module.accept(it, null) } }, + name = "IrModuleToJsTransformer", + description = "Generate JsAst from IrTree" +) + +val jsPhases = listOf( + IrModuleStartPhase, + MoveExternalDeclarationsToSeparatePlacePhase, + ExpectDeclarationsRemovingPhase, + CoroutineIntrinsicLoweringPhase, + ArrayInlineConstructorLoweringPhase, + LateinitLoweringPhase, + ModuleCopyingPhase, + FunctionInliningPhase, + RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase, + IrValidationPhase, + ThrowableSuccessorsLoweringPhase, + TailrecLoweringPhase, + UnitMaterializationLoweringPhase, + EnumClassLoweringPhase, + EnumUsageLoweringPhase, + SharedVariablesLoweringPhase, + ReturnableBlockLoweringPhase, + LocalDelegatedPropertiesLoweringPhase, + LocalDeclarationsLoweringPhase, + InnerClassesLoweringPhase, + InnerClassConstructorCallsLoweringPhase, + IrValidationPhase, + SuspendFunctionsLoweringPhase, + CallableReferenceLoweringPhase, + DefaultArgumentStubGeneratorPhase, + DefaultParameterInjectorPhase, + DefaultParameterCleanerPhase, + VarargLoweringPhase, + PropertiesLoweringPhase, + InitializersLoweringPhase, + MultipleCatchesLoweringPhase, + BridgesConstructionPhase, + TypeOperatorLoweringPhase, + SecondaryCtorLoweringPhase, + InlineClassLoweringPhase, + IrValidationPhase, + AutoboxingTransformerPhase, + BlockDecomposerLoweringPhase, + ClassReferenceLoweringPhase, + PrimitiveCompanionLoweringPhase, + ConstLoweringPhase, + IrValidationPhase, + CallsLoweringPhase, + IrModuleEndPhase, + IrToJsPhase +) \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsPhaseRunner.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsPhaseRunner.kt new file mode 100644 index 00000000000..cf80f44752c --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsPhaseRunner.kt @@ -0,0 +1,32 @@ +/* + * 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 + +import org.jetbrains.kotlin.backend.common.CheckDeclarationParentsVisitor +import org.jetbrains.kotlin.backend.common.DefaultIrPhaseRunner +import org.jetbrains.kotlin.backend.common.IrValidator +import org.jetbrains.kotlin.backend.common.IrValidatorConfig +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment + +private fun validationCallback(module: IrModuleFragment, context: JsIrBackendContext) { + val validatorConfig = IrValidatorConfig( + abortOnError = true, + ensureAllNodesAreDifferent = true, + checkTypes = false, + checkDescriptors = false + ) + module.accept(IrValidator(context, validatorConfig), null) + module.accept(CheckDeclarationParentsVisitor, null) +} + +object JsPhaseRunner : DefaultIrPhaseRunner(::validationCallback) { + override val startPhaseMarker = IrModuleStartPhase + override val endPhaseMarker = IrModuleEndPhase + + override fun phases(context: JsIrBackendContext) = context.phases + override fun elementName(input: IrModuleFragment) = input.name.asString() + override fun configuration(context: JsIrBackendContext) = context.configuration +} \ No newline at end of file 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 9f012cabe25..098795be062 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 @@ -6,29 +6,12 @@ package org.jetbrains.kotlin.ir.backend.js import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.backend.common.* -import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension -import org.jetbrains.kotlin.backend.common.lower.* -import org.jetbrains.kotlin.backend.common.lower.InlineClassLowering +import org.jetbrains.kotlin.backend.common.CompilerPhaseManager import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.ir.backend.js.lower.* -import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering -import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering -import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering -import org.jetbrains.kotlin.ir.backend.js.lower.inline.FunctionInlining -import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWithReifiedTypeParametersLowering -import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering -import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols -import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer -import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols -import org.jetbrains.kotlin.ir.util.patchDeclarationParents -import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus @@ -64,116 +47,13 @@ fun compile( psi2IrContext.irBuiltIns, psi2IrContext.symbolTable, moduleFragment, - configuration + configuration, + irDependencyModules ) - ExternalDependenciesGenerator(psi2IrContext.moduleDescriptor, psi2IrContext.symbolTable, psi2IrContext.irBuiltIns) - .generateUnboundSymbolsAsDependencies(moduleFragment) - - val extensions = IrGenerationExtension.getInstances(project) - extensions.forEach { extension -> - moduleFragment.files.forEach { irFile -> extension.generate(irFile, context, psi2IrContext.bindingContext) } + CompilerPhaseManager(context, context.phases, moduleFragment, JsPhaseRunner).run { + jsPhases.fold(data) { m, p -> phase(p, context, m) } } - MoveExternalDeclarationsToSeparatePlace().lower(moduleFragment) - ExpectDeclarationsRemoving(context).lower(moduleFragment) - CoroutineIntrinsicLowering(context).lower(moduleFragment) - ArrayInlineConstructorLowering(context).lower(moduleFragment) - LateinitLowering(context, true).lower(moduleFragment) - - val moduleFragmentCopy = moduleFragment.deepCopyWithSymbols() - - context.performInlining(moduleFragment) - - context.lower(moduleFragment, irDependencyModules) - - val program = moduleFragment.accept(IrModuleToJsTransformer(context), null) - - return Result(analysisResult.moduleDescriptor, program.toString(), moduleFragmentCopy) -} - -private fun JsIrBackendContext.performInlining(moduleFragment: IrModuleFragment) { - FunctionInlining(this).inline(moduleFragment) - - moduleFragment.replaceUnboundSymbols(this) - moduleFragment.patchDeclarationParents() - - RemoveInlineFunctionsWithReifiedTypeParametersLowering.runOnFilesPostfix(moduleFragment) -} - -private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment, dependencies: List) { - val validateIr = { - val visitor = IrValidator(this, validatorConfig) - moduleFragment.acceptVoid(visitor) - moduleFragment.checkDeclarationParents() - } - validateIr() - ThrowableSuccessorsLowering(this).lower(moduleFragment) - TailrecLowering(this).runOnFilesPostfix(moduleFragment) - UnitMaterializationLowering(this).lower(moduleFragment) - EnumClassLowering(this).runOnFilesPostfix(moduleFragment) - EnumUsageLowering(this).lower(moduleFragment) - LateinitLowering(this, true).lower(moduleFragment) - SharedVariablesLowering(this).runOnFilesPostfix(moduleFragment) - ReturnableBlockLowering(this).lower(moduleFragment) - LocalDelegatedPropertiesLowering().lower(moduleFragment) - LocalDeclarationsLowering(this).runOnFilesPostfix(moduleFragment) - InnerClassesLowering(this).runOnFilesPostfix(moduleFragment) - InnerClassConstructorCallsLowering(this).runOnFilesPostfix(moduleFragment) - validateIr() - SuspendFunctionsLowering(this).lower(moduleFragment) - CallableReferenceLowering(this).lower(moduleFragment) - DefaultArgumentStubGenerator(this).runOnFilesPostfix(moduleFragment) - DefaultParameterInjector(this).runOnFilesPostfix(moduleFragment) - DefaultParameterCleaner(this).runOnFilesPostfix(moduleFragment) - VarargLowering(this).lower(moduleFragment) - PropertiesLowering().lower(moduleFragment) - InitializersLowering(this, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).runOnFilesPostfix(moduleFragment) - MultipleCatchesLowering(this).lower(moduleFragment) - BridgesConstruction(this).runOnFilesPostfix(moduleFragment) - TypeOperatorLowering(this).lower(moduleFragment) - - SecondaryCtorLowering(this).apply { - constructorProcessorLowering.runOnFilesPostfix(moduleFragment.files + dependencies.flatMap { it.files }) - constructorRedirectorLowering.runOnFilesPostfix(moduleFragment) - } - - InlineClassLowering(this).apply { - inlineClassDeclarationLowering.runOnFilesPostfix(moduleFragment) - inlineClassUsageLowering.lower(moduleFragment) - } - validateIr() - AutoboxingTransformer(this).lower(moduleFragment) - BlockDecomposerLowering(this).runOnFilesPostfix(moduleFragment) - // TODO: Fix BlockDecomposerLowering parents - moduleFragment.patchDeclarationParents() - ClassReferenceLowering(this).lower(moduleFragment) - PrimitiveCompanionLowering(this).lower(moduleFragment) - ConstLowering(this).lower(moduleFragment) - validateIr() - CallsLowering(this).lower(moduleFragment) -} - -val validatorConfig = IrValidatorConfig( - abortOnError = true, - ensureAllNodesAreDifferent = true, - checkTypes = false, - checkDescriptors = false -) - -private fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) } - -private fun DeclarationContainerLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = - moduleFragment.files.forEach { runOnFilePostfix(it) } - -private fun DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable) = - files.forEach { runOnFilePostfix(it) } - -private fun BodyLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = - moduleFragment.files.forEach { runOnFilePostfix(it) } - -private fun FunctionLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = - moduleFragment.files.forEach { runOnFilePostfix(it) } - -private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = - moduleFragment.files.forEach { runOnFilePostfix(it) } + return Result(analysisResult.moduleDescriptor, context.jsProgram.toString(), context.moduleFragmentCopy) +} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/RemoveInlineFunctionsWithReifiedTypeParametersLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/RemoveInlineFunctionsWithReifiedTypeParametersLowering.kt index 01218098fb9..1e2fe8b16da 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/RemoveInlineFunctionsWithReifiedTypeParametersLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/RemoveInlineFunctionsWithReifiedTypeParametersLowering.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat -object RemoveInlineFunctionsWithReifiedTypeParametersLowering: DeclarationContainerLoweringPass { +class RemoveInlineFunctionsWithReifiedTypeParametersLowering: DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.transformDeclarationsFlat { if (it is IrFunction && it.isInline && it.typeParameters.any { it.isReified }) listOf() else null diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index 6e364f9e8b6..c7aff732741 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -135,6 +135,8 @@ abstract class BasicIrBoxTest( // TODO: split input files to some parts (global common, local common, test) .filterNot { it.virtualFilePath.contains(BasicBoxTest.COMMON_FILES_DIR_PATH) } +// config.configuration.put(CommonConfigurationKeys.EXCLUDED_ELEMENTS_FROM_DUMPING, setOf("")) + val runtimeConfiguration = config.configuration.copy() // TODO: is it right in general? Maybe sometimes we need to compile with newer versions or with additional language features. @@ -151,6 +153,7 @@ abstract class BasicIrBoxTest( ) if (runtimeResult == null) { + runtimeConfiguration.put(CommonConfigurationKeys.MODULE_NAME, "JS_IR_RUNTIME") runtimeResult = compile(config.project, runtimeSources.map(::createPsiFile), runtimeConfiguration) runtimeFile.write(runtimeResult!!.generatedCode) } @@ -159,6 +162,10 @@ abstract class BasicIrBoxTest( val dependencies = listOf(runtimeResult!!.moduleDescriptor) + dependencyNames.mapNotNull { compilationCache[it]?.moduleDescriptor } val irDependencies = listOf(runtimeResult!!.moduleFragment) + compilationCache.values.map { it.moduleFragment } +// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE, setOf("UnitMaterializationLowering")) +// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_BEFORE, setOf("ReturnableBlockLowering")) +// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_AFTER, setOf("MultipleCatchesLowering")) + val result = compile( config.project, filesToCompile,