[JS IR] Add to IR keep possibility similar to legacy-dce one

It helps to:

- keep declarations even if they are not reachable and not exported
- not minify names of not exported declarations

Compiler argument: -Xir-keep=A,B

Can be used for top-level declarations or for member

^KT-54118 fixed
This commit is contained in:
Ilya Goncharov
2022-09-20 16:06:17 +00:00
committed by Space
parent 4863e5d47b
commit d203dc35bf
28 changed files with 460 additions and 13 deletions
@@ -593,7 +593,15 @@ class GenerateIrRuntime {
private fun doBackEnd(
module: IrModuleFragment, symbolTable: SymbolTable, irBuiltIns: IrBuiltIns, jsLinker: JsIrLinker
): CompilerResult {
val context = JsIrBackendContext(module.descriptor, irBuiltIns, symbolTable, module, emptySet(), configuration)
val context = JsIrBackendContext(
module.descriptor,
irBuiltIns,
symbolTable,
module,
additionalExportedDeclarationNames = emptySet(),
keep = emptySet(),
configuration
)
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker)).generateUnboundSymbolsAsDependencies()
@@ -81,6 +81,7 @@ class JsIrBackendFacade(
val splitPerFile = JsEnvironmentConfigurationDirectives.SPLIT_PER_FILE in module.directives
val perModule = JsEnvironmentConfigurationDirectives.PER_MODULE in module.directives
val runNewIr2Js = JsEnvironmentConfigurationDirectives.RUN_NEW_IR_2_JS in module.directives
val keep = module.directives[JsEnvironmentConfigurationDirectives.KEEP].toSet()
val granularity = when {
!firstTimeCompilation -> JsGenerationGranularity.WHOLE_PROGRAM
@@ -145,6 +146,7 @@ class JsIrBackendFacade(
deserializer,
phaseConfig,
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, TEST_FUNCTION))),
keep = keep,
dceRuntimeDiagnostic = null,
es6mode = false,
baseClassIntoMetadata = false,
@@ -166,6 +168,7 @@ class JsIrBackendFacade(
val mainArguments = JsEnvironmentConfigurator.getMainCallParametersForModule(module)
.run { if (shouldBeGenerated()) arguments() else null }
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in module.directives
val onlyIrDce = JsEnvironmentConfigurationDirectives.ONLY_IR_DCE in module.directives
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in module.directives
val runNewIr2Js = JsEnvironmentConfigurationDirectives.RUN_NEW_IR_2_JS in module.directives
val perModuleOnly = JsEnvironmentConfigurationDirectives.SPLIT_PER_MODULE in module.directives
@@ -180,7 +183,7 @@ class JsIrBackendFacade(
// If perModuleOnly then skip whole program
// (it.dce => runIrDce) && (perModuleOnly => it.perModule)
val translationModes = TranslationMode.values()
.filter { (!it.dce || runIrDce) && (!perModuleOnly || it.perModule) }
.filter { (it.dce || !onlyIrDce) && (!it.dce || runIrDce) && (!perModuleOnly || it.perModule) }
.filter { it.dce == it.minimizedMemberNames }
.toSet()
val compilationOut = transformer.generateModule(loweredIr.allModules, translationModes, false)
@@ -33,8 +33,9 @@ class JsMinifierRunner(testServices: TestServices) : AbstractJsArtifactsCollecto
val dontRunGeneratedCode = globalDirectives[JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE]
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in globalDirectives
val onlyIrDce = JsEnvironmentConfigurationDirectives.ONLY_IR_DCE in globalDirectives
if (dontRunGeneratedCode || esModules) return
if (dontRunGeneratedCode || esModules || onlyIrDce) return
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
@@ -22,7 +22,6 @@ import java.io.File
class NodeJsGeneratorHandler(testServices: TestServices) : AbstractJsArtifactsCollector(testServices) {
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
if (someAssertionWasFailed) return
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
val globalDirectives = testServices.moduleStructure.allDirectives
@@ -31,8 +30,11 @@ class NodeJsGeneratorHandler(testServices: TestServices) : AbstractJsArtifactsCo
val generateNodeJsRunner = JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER in globalDirectives
val skipNodeJs = JsEnvironmentConfigurationDirectives.SKIP_NODE_JS in globalDirectives
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in globalDirectives
val onlyIrDce = JsEnvironmentConfigurationDirectives.ONLY_IR_DCE in globalDirectives
if (dontRunGeneratedCode || !generateNodeJsRunner || skipNodeJs || esModules) return
if (dontRunGeneratedCode || !generateNodeJsRunner || skipNodeJs || esModules || onlyIrDce) return
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
val mainModuleName = getMainModuleName(testServices)
val outputDir = File(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices).absolutePath)
@@ -136,10 +136,14 @@ fun getAllFilesForRunner(
val artifactsPaths = modulesToArtifact.values.map { it.outputFile.absolutePath }.filter { !File(it).isDirectory }
val allJsFiles = additionalFiles + inputJsFilesBefore +artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
val result = mutableMapOf(TranslationMode.FULL to allJsFiles)
val result = mutableMapOf<TranslationMode, List<String>>()
val globalDirectives = testServices.moduleStructure.allDirectives
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in globalDirectives
val onlyIrDce = JsEnvironmentConfigurationDirectives.ONLY_IR_DCE in globalDirectives
if (!onlyIrDce) {
result[TranslationMode.FULL] = allJsFiles
}
if (runIrDce) {
val dceJsFiles = artifactsPaths.map { it.replace(outputDir.absolutePath, dceOutputDir.absolutePath) }
val dceAllJsFiles = additionalFiles + inputJsFilesBefore + dceJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter