From 7b9aed25da2004a63fb6e1855fd7e5f3a656ef00 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Wed, 19 Oct 2022 12:52:23 +0000 Subject: [PATCH] [K/JS] Add the ability to turn off polyfills generating --- .../cli/common/arguments/K2JSCompilerArguments.kt | 6 ++++++ .../src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 1 + .../org/jetbrains/kotlin/ir/backend/js/compiler.kt | 11 +++++++++-- .../jetbrains/kotlin/ir/backend/js/compilerWithIC.kt | 7 ++++++- .../backend/js/lower/CollectNativeImplementations.kt | 5 ----- .../js/transformers/irToJs/IrModuleToJsTransformer.kt | 10 +++++++--- .../transformers/irToJs/IrModuleToJsTransformerTmp.kt | 7 ++++--- .../ir/backend/js/transformers/irToJs/Merger.kt | 10 ++++++++-- compiler/testData/cli/js/jsExtraHelp.out | 1 + .../configuration/JsEnvironmentConfigurator.kt | 1 + .../kotlin/js/config/JSConfigurationKeys.java | 3 +++ .../scripting/repl/js/test/AbstractJsReplTest.kt | 2 ++ 12 files changed, 48 insertions(+), 16 deletions(-) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index 319dade07bf..df12c87636f 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -267,6 +267,12 @@ class K2JSCompilerArguments : CommonCompilerArguments() { ) var generateDts: Boolean by FreezableVar(false) + @Argument( + value = "-Xgenerate-polyfills", + description = "Generate polyfills for features from the ES6+ standards." + ) + var generatePolyfills: Boolean by FreezableVar(true) + @Argument( value = "-Xstrict-implicit-export-types", description = "Generate strict types for implicitly exported entities inside d.ts files. Available in IR backend only." diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 9136aebe7e0..079956ce795 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -228,6 +228,7 @@ class K2JsIrCompiler : CLICompiler() { configurationJs.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage) configurationJs.put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.renderInternalDiagnosticNames) configurationJs.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, arguments.irPropertyLazyInitialization) + configurationJs.put(JSConfigurationKeys.GENERATE_POLYFILLS, arguments.generatePolyfills) configurationJs.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, arguments.irGenerateInlineAnonymousFunctions) if (!checkKotlinPackageUsage(environmentForJS.configuration, sourcesFiles)) return COMPILATION_ERROR 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 e3dd9531fe4..c4bc7704a91 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 @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.js.backend.ast.JsProgram +import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.name.FqName import java.io.File @@ -110,6 +111,7 @@ fun compileIr( ): LoweredIr { val moduleDescriptor = moduleFragment.descriptor val irFactory = symbolTable.irFactory + val shouldGeneratePolyfills = configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS) val allModules = when (mainModule) { is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment) @@ -141,7 +143,10 @@ fun compileIr( irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process") allModules.forEach { module -> - collectNativeImplementations(context, module) + if (shouldGeneratePolyfills) { + collectNativeImplementations(context, module) + } + moveBodilessDeclarationsToSeparatePlace(context, module) } @@ -160,7 +165,9 @@ fun generateJsCode( moduleFragment: IrModuleFragment, nameTables: NameTables ): String { - collectNativeImplementations(context, moduleFragment) + if (context.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)) { + collectNativeImplementations(context, moduleFragment) + } moveBodilessDeclarationsToSeparatePlace(context, moduleFragment) jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment)) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt index 5c62bd2b3d7..859a74f9b5a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSepara import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors @@ -53,8 +54,12 @@ class JsIrCompilerWithIC( dirtyFiles: Collection, mainArguments: List? ): List { + val shouldGeneratePolyfills = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS) + allModules.forEach { - collectNativeImplementations(context, it) + if (shouldGeneratePolyfills) { + collectNativeImplementations(context, it) + } moveBodilessDeclarationsToSeparatePlace(context, it) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CollectNativeImplementations.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CollectNativeImplementations.kt index cb1ede0f6b2..d8bdb50a3ad 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CollectNativeImplementations.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CollectNativeImplementations.kt @@ -5,22 +5,17 @@ package org.jetbrains.kotlin.ir.backend.js.lower -import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase -import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid fun collectNativeImplementations(context: JsIrBackendContext, moduleFragment: IrModuleFragment) = CollectNativeImplementationsVisitor(context).let { collector -> moduleFragment.files.forEach { it.accept(collector, null) } } - class CollectNativeImplementationsVisitor(private val context: JsIrBackendContext) : IrElementVisitorVoid { override fun visitElement(element: IrElement) {} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt index 52095ddca29..c64c8b82b94 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformer.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer import org.jetbrains.kotlin.js.util.TextOutputImpl import org.jetbrains.kotlin.utils.DFS +import org.jetbrains.kotlin.utils.addToStdlib.runIf import java.io.File import java.util.* @@ -45,6 +46,7 @@ class IrModuleToJsTransformer( private val moduleToName: Map = emptyMap(), private val removeUnusedAssociatedObjects: Boolean = true ) { + private val shouldGeneratePolyfills = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS) private val generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS) fun generateModule(modules: Iterable): CompilerResult { @@ -148,7 +150,8 @@ class IrModuleToJsTransformer( globalNameScope = namer.globalNames ) - val polyfillStatements = generatePolyfillStatements(modules) + val polyfillStatements = runIf(shouldGeneratePolyfills) { generatePolyfillStatements(modules) } + val (importStatements, importedJsModules) = generateImportStatements( getNameForExternalDeclaration = { staticContext.getNameForStaticDeclaration(it) }, @@ -168,7 +171,7 @@ class IrModuleToJsTransformer( if (generateScriptModule) { with(program.globalBlock) { - statements.addWithComment("block: polyfills", polyfillStatements) + polyfillStatements?.let { statements.addWithComment("block: polyfills", it) } statements.addWithComment("block: imports", importStatements + crossModuleImports) statements += moduleBody statements.addWithComment("block: exports", exportStatements + crossModuleExports) @@ -189,7 +192,8 @@ class IrModuleToJsTransformer( } } - program.globalBlock.statements.addWithComment("block: polyfills", polyfillStatements) + polyfillStatements?.let { program.globalBlock.statements.addWithComment("block: polyfills", it) } + program.globalBlock.statements += ModuleWrapperTranslation.wrap( exportedModule.name, rootFunction, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt index 6b9a0fa02c9..d77af8fae2a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt @@ -13,8 +13,6 @@ import org.jetbrains.kotlin.ir.backend.js.lower.StaticMembersLowering import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstSerializer import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor @@ -90,6 +88,7 @@ class IrModuleToJsTransformerTmp( private val moduleToName: Map = emptyMap(), private val removeUnusedAssociatedObjects: Boolean = true, ) { + private val shouldGeneratePolyfills = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS) private val generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS) private val mainModuleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!! @@ -233,7 +232,9 @@ class IrModuleToJsTransformerTmp( ) val result = JsIrProgramFragment(file.fqName.asString()).apply { - polyfills.statements += backendContext.polyfills.getAllPolyfillsFor(file) + if (shouldGeneratePolyfills) { + polyfills.statements += backendContext.polyfills.getAllPolyfillsFor(file) + } } val internalModuleName = ReservedJsNames.makeInternalModuleName().takeIf { !isEsModules } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt index 844982cd92c..8c2625f74b4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt @@ -241,7 +241,10 @@ class Merger( if (generateScriptModule) { with(program.globalBlock) { - statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements) + polyfillDeclarationBlock.statements + .takeIf { it.isNotEmpty() } + ?.let { statements.addWithComment("block: polyfills", it) } + statements.addWithComment("block: imports", importStatements) statements += moduleBody statements.addWithComment("block: exports", exportStatements) @@ -265,7 +268,10 @@ class Merger( } } - program.globalBlock.statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements) + polyfillDeclarationBlock.statements + .takeIf { it.isNotEmpty() } + ?.let { program.globalBlock.statements.addWithComment("block: polyfills", it) } + program.globalBlock.statements += ModuleWrapperTranslation.wrap( moduleName, rootFunction, diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 78d6fbff033..0ad356a3016 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -9,6 +9,7 @@ where advanced options include: -Xfriend-modules= Paths to friend modules -Xfriend-modules-disabled Disable internal declaration export -Xgenerate-dts Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only. + -Xgenerate-polyfills Generate polyfills for features from the ES6+ standards. -Xinclude= A path to an intermediate library that should be processed in the same manner as source files. -Xir-base-class-in-metadata Write base class into metadata -Xir-build-cache Use compiler to build cache diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt index 3fdadf261ba..ae78d944c53 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt @@ -291,6 +291,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, TYPED_ARRAYS in registeredDirectives) + configuration.put(JSConfigurationKeys.GENERATE_POLYFILLS, true) configuration.put(JSConfigurationKeys.GENERATE_REGION_COMMENTS, true) configuration.put( diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java index 8434f47e2b5..25f085de4b3 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java @@ -77,6 +77,9 @@ public class JSConfigurationKeys { public static final CompilerConfigurationKey GENERATE_COMMENTS_WITH_FILE_PATH = CompilerConfigurationKey.create("generate comments with file path at the start of each file block"); + public static final CompilerConfigurationKey GENERATE_POLYFILLS = + CompilerConfigurationKey.create("generate polyfills for newest properties, methods and classes from ES6+"); + public static final CompilerConfigurationKey GENERATE_REGION_COMMENTS = CompilerConfigurationKey.create("generate special comments at the start and the end of each file block, " + "it allows to fold them and navigate to them in the IDEA"); diff --git a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt index a9d7668b856..73129140e5a 100644 --- a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt +++ b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition @@ -68,6 +69,7 @@ abstract class AbstractJsReplTest : Closeable { configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar()) configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, collector) configuration.put(CommonConfigurationKeys.MODULE_NAME, "repl.kts") + configuration.put(JSConfigurationKeys.GENERATE_POLYFILLS, true) val stdlibPath = System.getProperty("kotlin.js.full.stdlib.path") val scriptConfiguration = ScriptCompilationConfiguration { baseClass("kotlin.Any")