From 9bc057afb2f1872084c47c00221fb4e93f626d01 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Mon, 18 Jul 2022 20:54:32 +0200 Subject: [PATCH] [JS IR] Generate the correct relative paths in source maps --- .../jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 7 +-- .../kotlin/gradle/Kotlin2JsGradlePluginIT.kt | 43 +++++++++++++------ .../internal/RewriteSourceMapFilterReader.kt | 16 +++++-- .../gradle/targets/js/ir/KotlinJsIrTarget.kt | 14 ++++++ .../js/ir/KotlinJsIrTargetConfigurator.kt | 11 ----- 5 files changed, 59 insertions(+), 32 deletions(-) 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 07f0821d547..9784526ff86 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 @@ -190,12 +190,9 @@ class K2JsIrCompiler : CLICompiler() { val moduleName = arguments.irModuleName ?: FileUtil.getNameWithoutExtension(outputFile) configurationJs.put(CommonConfigurationKeys.MODULE_NAME, moduleName) - // TODO: in this method at least 3 different compiler configurations are used (original, env.configuration, jsConfig.configuration) - // Such situation seems a bit buggy... - val config = JsConfig(projectJs, configurationJs, CompilerEnvironment) val outputDir: File = outputFile.parentFile ?: outputFile.absoluteFile.parentFile!! try { - config.configuration.put(JSConfigurationKeys.OUTPUT_DIR, outputDir.canonicalFile) + configurationJs.put(JSConfigurationKeys.OUTPUT_DIR, outputDir.canonicalFile) } catch (e: IOException) { messageCollector.report(ERROR, "Could not resolve output directory", null) return ExitCode.COMPILATION_ERROR @@ -262,7 +259,7 @@ class K2JsIrCompiler : CLICompiler() { configurationJs, libraries, friendLibraries, - AnalyzerWithCompilerReport(config.configuration) + AnalyzerWithCompilerReport(configurationJs) ) val result = sourceModule.jsFrontEndResult.jsAnalysisResult if (result is JsAnalysisResult.RetryWithAdditionalRoots) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index e0a80b4cc37..032b94c478a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -620,10 +620,30 @@ abstract class AbstractKotlin2JsGradlePluginIT(protected val irBackend: Boolean) fun testKotlinJsSourceMap(gradleVersion: GradleVersion) { project("kotlin2JsProjectWithSourceMap", gradleVersion) { build(if (irBackend) "compileDevelopmentExecutableKotlinJs" else "compileKotlinJs") { - val mapFilePath = projectPath - .resolve("build/js/packages/$projectName-app/kotlin/$projectName-app.js.map") + if (irBackend) { + assertFileContains( + subProject("app").projectPath + .resolve("build/compileSync/main/developmentExecutable/kotlin/$projectName-app.js.map"), + "\"../../../../../src/main/kotlin/main.kt\"", + "\"../../../../../../lib/src/main/kotlin/foo.kt\"", + "\"sourcesContent\":[null", + ) + assertFileContains( + subProject("app").projectPath + .resolve("build/compileSync/main/developmentExecutable/kotlin/$projectName-lib.js.map"), + "\"../../../../../../lib/src/main/kotlin/foo.kt\"", + "\"sourcesContent\":[null", + ) + assertFileContains( + projectPath + .resolve("build/js/packages/$projectName-app/kotlin/$projectName-lib.js.map"), + "\"../../../../../lib/src/main/kotlin/foo.kt\"", + "\"sourcesContent\":[null", + ) + } assertFileContains( - mapFilePath, + projectPath + .resolve("build/js/packages/$projectName-app/kotlin/$projectName-app.js.map"), "\"../../../../../app/src/main/kotlin/main.kt\"", "\"../../../../../lib/src/main/kotlin/foo.kt\"", "\"sourcesContent\":[null", @@ -669,10 +689,6 @@ abstract class AbstractKotlin2JsGradlePluginIT(protected val irBackend: Boolean) } @DisplayName("path in source maps are remapped for custom outputFile") - @DisabledIf( - "org.jetbrains.kotlin.gradle.AbstractKotlin2JsGradlePluginIT#getIrBackend", - disabledReason = "Source maps are not supported in IR backend" - ) @GradleTest fun testKotlinJsSourceMapCustomOutputFile(gradleVersion: GradleVersion) { project("kotlin2JsProjectWithSourceMap", gradleVersion) { @@ -693,11 +709,14 @@ abstract class AbstractKotlin2JsGradlePluginIT(protected val irBackend: Boolean) build(if (irBackend) "compileDevelopmentExecutableKotlinJs" else "compileKotlinJs") { val mapFilePath = subProject("app").projectPath .resolve("build/kotlin2js/app.js.map") - assertFileContains( - mapFilePath, - "\"../../src/main/kotlin/main.kt\"", - "\"../../../../../lib/src/main/kotlin/foo.kt\"", - ) + assertFileContains(mapFilePath,"\"../../src/main/kotlin/main.kt\"") + if (irBackend) { + // The IR BE generates correct paths for dependencies + assertFileContains(mapFilePath, "\"../../../lib/src/main/kotlin/foo.kt\"") + } else { + // The legacy BE doesn't. + assertFileContains(mapFilePath, "\"../../../../../lib/src/main/kotlin/foo.kt\"") + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/RewriteSourceMapFilterReader.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/RewriteSourceMapFilterReader.kt index 728ef0f3c31..72e02d9eac9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/RewriteSourceMapFilterReader.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/RewriteSourceMapFilterReader.kt @@ -141,12 +141,20 @@ open class RewriteSourceMapFilterReader( log.warn("Cannot rewrite paths in JavaScript source maps: $reason") } - protected open fun transformString(value: String): String = - File(srcSourceRoot) + protected open fun transformString(value: String): String { + val sourceFileResolved = File(srcSourceRoot) .resolve(value) .canonicalFile - .relativeToOrSelf(File(targetSourceRoot)) - .path + + val transformedPath = sourceFileResolved.relativeToOrNull(File(targetSourceRoot))?.path ?: return sourceFileResolved.path + + return if (File.separatorChar == '\\') { + transformedPath.replace('\\', '/') + } else { + transformedPath + } + } + override fun read(): Int { maybeReadFirst() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt index 7d3d79971d7..aed43193822 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec import org.jetbrains.kotlin.gradle.targets.js.dsl.* +import org.jetbrains.kotlin.gradle.targets.js.internal.RewriteSourceMapFilterReader import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.registerTask @@ -145,6 +146,19 @@ constructor( task.from(project.tasks.named(compilation.processResourcesTaskName)) + // Rewrite relative paths in sourcemaps in the target directory + task.eachFile { + if (it.name.endsWith(".js.map")) { + it.filter( + mapOf( + "srcSourceRoot" to it.file.parentFile, + "targetSourceRoot" to npmProject.dist + ), + RewriteSourceMapFilterReader::class.java + ) + } + } + task.into(npmProject.dist) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt index 4e0671d413d..b5000ca089e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt @@ -128,17 +128,6 @@ open class KotlinJsIrTargetConfigurator() : .all { binary -> binary.linkTask.configure { linkTask -> linkTask.kotlinOptions.configureOptions() - - val rootDir = binary.project.rootDir - linkTask.kotlinOptions.freeCompilerArgs += listOf( - "-source-map-base-dirs", - rootDir.absolutePath - ) - - linkTask.kotlinOptions.freeCompilerArgs += listOf( - "-source-map-prefix", - rootDir.toRelativeString(binary.compilation.npmProject.dist) + File.separator - ) } } }