[JS IR] support source maps in new Ir2Js

This commit is contained in:
Anton Bannykh
2021-10-29 11:18:01 +03:00
committed by TeamCityServer
parent a7d8c34927
commit 3c859138d1
2 changed files with 66 additions and 4 deletions
@@ -119,6 +119,8 @@ fun generateJsFromAst(
"main", "main",
ModuleKind.PLAIN, ModuleKind.PLAIN,
fragments.modules.flatMap { it.fragments }, fragments.modules.flatMap { it.fragments },
sourceMapsInfo = null,
generateScriptModule = false,
generateCallToMain = true, generateCallToMain = true,
), null ), null
) )
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.backend.js.CompilationOutputs import org.jetbrains.kotlin.ir.backend.js.CompilationOutputs
import org.jetbrains.kotlin.ir.backend.js.CompilerResult import org.jetbrains.kotlin.ir.backend.js.CompilerResult
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -19,11 +20,17 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
import org.jetbrains.kotlin.js.backend.NoOpSourceLocationConsumer import org.jetbrains.kotlin.js.backend.NoOpSourceLocationConsumer
import org.jetbrains.kotlin.js.backend.SourceLocationConsumer
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
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.js.util.TextOutputImpl
import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.ModuleKind
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File
class IrModuleToJsTransformerTmp( class IrModuleToJsTransformerTmp(
private val backendContext: JsIrBackendContext, private val backendContext: JsIrBackendContext,
@@ -62,6 +69,7 @@ class IrModuleToJsTransformerTmp(
mainModuleName, mainModuleName,
moduleKind, moduleKind,
generateProgramFragments(modules, exportData), generateProgramFragments(modules, exportData),
SourceMapsInfo.from(backendContext.configuration),
relativeRequirePath, relativeRequirePath,
generateScriptModule, generateScriptModule,
) else null ) else null
@@ -74,6 +82,7 @@ class IrModuleToJsTransformerTmp(
mainModuleName, mainModuleName,
moduleKind, moduleKind,
generateProgramFragments(modules, exportData), generateProgramFragments(modules, exportData),
SourceMapsInfo.from(backendContext.configuration),
relativeRequirePath, relativeRequirePath,
generateScriptModule, generateScriptModule,
) )
@@ -262,8 +271,9 @@ private fun generateWrappedModuleBody(
mainModuleName: String, mainModuleName: String,
moduleKind: ModuleKind, moduleKind: ModuleKind,
program: JsIrProgram, program: JsIrProgram,
sourceMapsInfo: SourceMapsInfo?,
relativeRequirePath: Boolean, relativeRequirePath: Boolean,
generateScriptModule: Boolean, generateScriptModule: Boolean
): CompilationOutputs { ): CompilationOutputs {
if (multiModule) { if (multiModule) {
@@ -276,6 +286,7 @@ private fun generateWrappedModuleBody(
mainModuleName, mainModuleName,
moduleKind, moduleKind,
main.fragments, main.fragments,
sourceMapsInfo,
generateScriptModule, generateScriptModule,
generateCallToMain = true, generateCallToMain = true,
moduleToRef[main]!!, moduleToRef[main]!!,
@@ -288,6 +299,7 @@ private fun generateWrappedModuleBody(
moduleName, moduleName,
moduleKind, moduleKind,
module.fragments, module.fragments,
sourceMapsInfo,
generateScriptModule, generateScriptModule,
generateCallToMain = false, generateCallToMain = false,
moduleToRef[module]!!, moduleToRef[module]!!,
@@ -300,6 +312,7 @@ private fun generateWrappedModuleBody(
mainModuleName, mainModuleName,
moduleKind, moduleKind,
program.modules.flatMap { it.fragments }, program.modules.flatMap { it.fragments },
sourceMapsInfo,
generateScriptModule, generateScriptModule,
generateCallToMain = true, generateCallToMain = true,
) )
@@ -310,9 +323,10 @@ fun generateSingleWrappedModuleBody(
moduleName: String, moduleName: String,
moduleKind: ModuleKind, moduleKind: ModuleKind,
fragments: List<JsIrProgramFragment>, fragments: List<JsIrProgramFragment>,
sourceMapsInfo: SourceMapsInfo?,
generateScriptModule: Boolean, generateScriptModule: Boolean,
generateCallToMain: Boolean, generateCallToMain: Boolean,
crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty, crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty
): CompilationOutputs { ): CompilationOutputs {
val program = Merger( val program = Merger(
moduleName, moduleName,
@@ -328,10 +342,56 @@ fun generateSingleWrappedModuleBody(
val jsCode = TextOutputImpl() val jsCode = TextOutputImpl()
program.accept(JsToStringGenerationVisitor(jsCode, NoOpSourceLocationConsumer)) val sourceMapBuilder: SourceMap3Builder?
val sourceMapBuilderConsumer: SourceLocationConsumer
if (sourceMapsInfo != null) {
val sourceMapPrefix = sourceMapsInfo.sourceMapPrefix
sourceMapBuilder = SourceMap3Builder(null, jsCode, sourceMapPrefix)
val sourceRoots = sourceMapsInfo.sourceRoots.map(::File)
val generateRelativePathsInSourceMap = sourceMapPrefix.isEmpty() && sourceRoots.isEmpty()
val outputDir = if (generateRelativePathsInSourceMap) sourceMapsInfo.outputDir else null
val pathResolver = SourceFilePathResolver(sourceRoots, outputDir)
val sourceMapContentEmbedding =
sourceMapsInfo.sourceMapContentEmbedding
sourceMapBuilderConsumer = SourceMapBuilderConsumer(
File("."),
sourceMapBuilder,
pathResolver,
sourceMapContentEmbedding == SourceMapSourceEmbedding.ALWAYS,
sourceMapContentEmbedding != SourceMapSourceEmbedding.NEVER
)
} else {
sourceMapBuilder = null
sourceMapBuilderConsumer = NoOpSourceLocationConsumer
}
program.accept(JsToStringGenerationVisitor(jsCode, sourceMapBuilderConsumer))
return CompilationOutputs( return CompilationOutputs(
jsCode.toString(), jsCode.toString(),
null program,
sourceMapBuilder?.build()
) )
}
class SourceMapsInfo(
val sourceMapPrefix: String,
val sourceRoots: List<String>,
val outputDir: File?,
val sourceMapContentEmbedding: SourceMapSourceEmbedding,
) {
companion object {
fun from(configuration: CompilerConfiguration) : SourceMapsInfo {
return SourceMapsInfo(
configuration.get(JSConfigurationKeys.SOURCE_MAP_PREFIX, ""),
configuration.get(JSConfigurationKeys.SOURCE_MAP_SOURCE_ROOTS, emptyList<String>()),
configuration.get(JSConfigurationKeys.OUTPUT_DIR),
configuration.get(JSConfigurationKeys.SOURCE_MAP_EMBED_SOURCES, SourceMapSourceEmbedding.INLINING),
)
}
}
} }