[K/JS] Add the ability to turn off polyfills generating

This commit is contained in:
Artem Kobzar
2022-10-19 12:52:23 +00:00
committed by Space Team
parent dbf0ba442a
commit 7b9aed25da
12 changed files with 48 additions and 16 deletions
@@ -267,6 +267,12 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
) )
var generateDts: Boolean by FreezableVar(false) 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( @Argument(
value = "-Xstrict-implicit-export-types", value = "-Xstrict-implicit-export-types",
description = "Generate strict types for implicitly exported entities inside d.ts files. Available in IR backend only." description = "Generate strict types for implicitly exported entities inside d.ts files. Available in IR backend only."
@@ -228,6 +228,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
configurationJs.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage) configurationJs.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
configurationJs.put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.renderInternalDiagnosticNames) configurationJs.put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.renderInternalDiagnosticNames)
configurationJs.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, arguments.irPropertyLazyInitialization) configurationJs.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, arguments.irPropertyLazyInitialization)
configurationJs.put(JSConfigurationKeys.GENERATE_POLYFILLS, arguments.generatePolyfills)
configurationJs.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, arguments.irGenerateInlineAnonymousFunctions) configurationJs.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, arguments.irGenerateInlineAnonymousFunctions)
if (!checkKotlinPackageUsage(environmentForJS.configuration, sourcesFiles)) return COMPILATION_ERROR if (!checkKotlinPackageUsage(environmentForJS.configuration, sourcesFiles)) return COMPILATION_ERROR
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.js.backend.ast.JsProgram 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.js.config.RuntimeDiagnostic
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import java.io.File import java.io.File
@@ -110,6 +111,7 @@ fun compileIr(
): LoweredIr { ): LoweredIr {
val moduleDescriptor = moduleFragment.descriptor val moduleDescriptor = moduleFragment.descriptor
val irFactory = symbolTable.irFactory val irFactory = symbolTable.irFactory
val shouldGeneratePolyfills = configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)
val allModules = when (mainModule) { val allModules = when (mainModule) {
is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment) is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment)
@@ -141,7 +143,10 @@ fun compileIr(
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process") irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
allModules.forEach { module -> allModules.forEach { module ->
collectNativeImplementations(context, module) if (shouldGeneratePolyfills) {
collectNativeImplementations(context, module)
}
moveBodilessDeclarationsToSeparatePlace(context, module) moveBodilessDeclarationsToSeparatePlace(context, module)
} }
@@ -160,7 +165,9 @@ fun generateJsCode(
moduleFragment: IrModuleFragment, moduleFragment: IrModuleFragment,
nameTables: NameTables nameTables: NameTables
): String { ): String {
collectNativeImplementations(context, moduleFragment) if (context.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)) {
collectNativeImplementations(context, moduleFragment)
}
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment) moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment)) jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment))
@@ -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.backend.js.transformers.irToJs.*
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -53,8 +54,12 @@ class JsIrCompilerWithIC(
dirtyFiles: Collection<IrFile>, dirtyFiles: Collection<IrFile>,
mainArguments: List<String>? mainArguments: List<String>?
): List<JsIrFragmentAndBinaryAst> { ): List<JsIrFragmentAndBinaryAst> {
val shouldGeneratePolyfills = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)
allModules.forEach { allModules.forEach {
collectNativeImplementations(context, it) if (shouldGeneratePolyfills) {
collectNativeImplementations(context, it)
}
moveBodilessDeclarationsToSeparatePlace(context, it) moveBodilessDeclarationsToSeparatePlace(context, it)
} }
@@ -5,22 +5,17 @@
package org.jetbrains.kotlin.ir.backend.js.lower 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.IrElement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext 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.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
fun collectNativeImplementations(context: JsIrBackendContext, moduleFragment: IrModuleFragment) = fun collectNativeImplementations(context: JsIrBackendContext, moduleFragment: IrModuleFragment) =
CollectNativeImplementationsVisitor(context).let { collector -> CollectNativeImplementationsVisitor(context).let { collector ->
moduleFragment.files.forEach { it.accept(collector, null) } moduleFragment.files.forEach { it.accept(collector, null) }
} }
class CollectNativeImplementationsVisitor(private val context: JsIrBackendContext) : IrElementVisitorVoid { class CollectNativeImplementationsVisitor(private val context: JsIrBackendContext) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {} override fun visitElement(element: IrElement) {}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer
import org.jetbrains.kotlin.js.util.TextOutputImpl import org.jetbrains.kotlin.js.util.TextOutputImpl
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.io.File import java.io.File
import java.util.* import java.util.*
@@ -45,6 +46,7 @@ class IrModuleToJsTransformer(
private val moduleToName: Map<IrModuleFragment, String> = emptyMap(), private val moduleToName: Map<IrModuleFragment, String> = emptyMap(),
private val removeUnusedAssociatedObjects: Boolean = true 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 generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS)
fun generateModule(modules: Iterable<IrModuleFragment>): CompilerResult { fun generateModule(modules: Iterable<IrModuleFragment>): CompilerResult {
@@ -148,7 +150,8 @@ class IrModuleToJsTransformer(
globalNameScope = namer.globalNames globalNameScope = namer.globalNames
) )
val polyfillStatements = generatePolyfillStatements(modules) val polyfillStatements = runIf(shouldGeneratePolyfills) { generatePolyfillStatements(modules) }
val (importStatements, importedJsModules) = val (importStatements, importedJsModules) =
generateImportStatements( generateImportStatements(
getNameForExternalDeclaration = { staticContext.getNameForStaticDeclaration(it) }, getNameForExternalDeclaration = { staticContext.getNameForStaticDeclaration(it) },
@@ -168,7 +171,7 @@ class IrModuleToJsTransformer(
if (generateScriptModule) { if (generateScriptModule) {
with(program.globalBlock) { with(program.globalBlock) {
statements.addWithComment("block: polyfills", polyfillStatements) polyfillStatements?.let { statements.addWithComment("block: polyfills", it) }
statements.addWithComment("block: imports", importStatements + crossModuleImports) statements.addWithComment("block: imports", importStatements + crossModuleImports)
statements += moduleBody statements += moduleBody
statements.addWithComment("block: exports", exportStatements + crossModuleExports) 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( program.globalBlock.statements += ModuleWrapperTranslation.wrap(
exportedModule.name, exportedModule.name,
rootFunction, rootFunction,
@@ -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.*
import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstSerializer import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstSerializer
import org.jetbrains.kotlin.ir.declarations.* 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.isInterface
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
@@ -90,6 +88,7 @@ class IrModuleToJsTransformerTmp(
private val moduleToName: Map<IrModuleFragment, String> = emptyMap(), private val moduleToName: Map<IrModuleFragment, String> = emptyMap(),
private val removeUnusedAssociatedObjects: Boolean = true, 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 generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS)
private val mainModuleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!! private val mainModuleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!!
@@ -233,7 +232,9 @@ class IrModuleToJsTransformerTmp(
) )
val result = JsIrProgramFragment(file.fqName.asString()).apply { 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 } val internalModuleName = ReservedJsNames.makeInternalModuleName().takeIf { !isEsModules }
@@ -241,7 +241,10 @@ class Merger(
if (generateScriptModule) { if (generateScriptModule) {
with(program.globalBlock) { 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.addWithComment("block: imports", importStatements)
statements += moduleBody statements += moduleBody
statements.addWithComment("block: exports", exportStatements) 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( program.globalBlock.statements += ModuleWrapperTranslation.wrap(
moduleName, moduleName,
rootFunction, rootFunction,
+1
View File
@@ -9,6 +9,7 @@ where advanced options include:
-Xfriend-modules=<path> Paths to friend modules -Xfriend-modules=<path> Paths to friend modules
-Xfriend-modules-disabled Disable internal declaration export -Xfriend-modules-disabled Disable internal declaration export
-Xgenerate-dts Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only. -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=<path> A path to an intermediate library that should be processed in the same manner as source files. -Xinclude=<path> 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-base-class-in-metadata Write base class into metadata
-Xir-build-cache Use compiler to build cache -Xir-build-cache Use compiler to build cache
@@ -291,6 +291,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, TYPED_ARRAYS in registeredDirectives) 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(JSConfigurationKeys.GENERATE_REGION_COMMENTS, true)
configuration.put( configuration.put(
@@ -77,6 +77,9 @@ public class JSConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> GENERATE_COMMENTS_WITH_FILE_PATH = public static final CompilerConfigurationKey<Boolean> GENERATE_COMMENTS_WITH_FILE_PATH =
CompilerConfigurationKey.create("generate comments with file path at the start of each file block"); CompilerConfigurationKey.create("generate comments with file path at the start of each file block");
public static final CompilerConfigurationKey<Boolean> GENERATE_POLYFILLS =
CompilerConfigurationKey.create("generate polyfills for newest properties, methods and classes from ES6+");
public static final CompilerConfigurationKey<Boolean> GENERATE_REGION_COMMENTS = public static final CompilerConfigurationKey<Boolean> GENERATE_REGION_COMMENTS =
CompilerConfigurationKey.create("generate special comments at the start and the end of each file block, " + 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"); "it allows to fold them and navigate to them in the IDEA");
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration 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.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
@@ -68,6 +69,7 @@ abstract class AbstractJsReplTest : Closeable {
configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar()) configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar())
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, collector) configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, collector)
configuration.put(CommonConfigurationKeys.MODULE_NAME, "repl.kts") configuration.put(CommonConfigurationKeys.MODULE_NAME, "repl.kts")
configuration.put(JSConfigurationKeys.GENERATE_POLYFILLS, true)
val stdlibPath = System.getProperty("kotlin.js.full.stdlib.path") val stdlibPath = System.getProperty("kotlin.js.full.stdlib.path")
val scriptConfiguration = ScriptCompilationConfiguration { val scriptConfiguration = ScriptCompilationConfiguration {
baseClass("kotlin.Any") baseClass("kotlin.Any")