[JS] Factor out source map path rewriting

This commit is contained in:
Sergej Jaskiewicz
2022-05-25 23:36:17 +03:00
committed by Space
parent 0320d49ddc
commit 53233c487e
2 changed files with 56 additions and 26 deletions
@@ -124,37 +124,29 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
}
private fun mapSourcePaths(inputFile: File, targetFile: File): Boolean {
val json = try {
parseJson(inputFile)
} catch (e: JsonSyntaxException) {
return false
}
val sourcesArray = (json as? JsonObject)?.properties?.get("sources") as? JsonArray ?: return false
val sources = sourcesArray.elements.map {
(it as? JsonString)?.value ?: return false
}
val jsonOut = StringWriter()
val pathCalculator = RelativePathCalculator(targetFile.parentFile)
val mappedSources = sources.map {
val result = pathCalculator.calculateRelativePathTo(File(inputFile.parentFile, it))
if (result != null) {
if (File(targetFile.parentFile, result).exists()) {
result
val sourceMapChanged = try {
SourceMap.mapSources(inputFile.readText(), jsonOut) {
val result = pathCalculator.calculateRelativePathTo(File(inputFile.parentFile, it))
if (result != null) {
if (File(targetFile.parentFile, result).exists()) {
result
} else {
it
}
} else {
it
}
} else {
it
}
} catch (e: SourceMapSourceReplacementException) {
false
}
if (mappedSources == sources) return false
json.properties["sources"] = JsonArray(*mappedSources.map { JsonString(it) }.toTypedArray())
if (!sourceMapChanged) return false
targetFile.parentFile.mkdirs()
OutputStreamWriter(FileOutputStream(targetFile), "UTF-8").use { it.write(json.toString()) }
OutputStreamWriter(FileOutputStream(targetFile), "UTF-8").use { it.write(jsonOut.toString()) }
return true
}
@@ -16,9 +16,7 @@
package org.jetbrains.kotlin.js.parser.sourcemaps
import java.io.File
import java.io.PrintStream
import java.io.Reader
import java.io.*
class SourceMap(val sourceContentResolver: (String) -> Reader?) {
val groups = mutableListOf<SourceMapGroup>()
@@ -49,8 +47,48 @@ class SourceMap(val sourceContentResolver: (String) -> Reader?) {
writer.println()
}
}
companion object {
@Throws(IOException::class, SourceMapSourceReplacementException::class)
fun replaceSources(sourceMapFile: File, mapping: (String) -> String): Boolean {
val content = sourceMapFile.readText()
return sourceMapFile.writer().buffered().use {
mapSources(content, it, mapping)
}
}
@Throws(IOException::class, SourceMapSourceReplacementException::class)
fun mapSources(content: String, output: Writer, mapping: (String) -> String): Boolean {
val json = try {
parseJson(content)
} catch (e: JsonSyntaxException) {
throw SourceMapSourceReplacementException(cause = e)
}
val jsonObject = json as? JsonObject ?: throw SourceMapSourceReplacementException("Top-level object expected")
val sources = jsonObject.properties["sources"]
if (sources != null) {
val sourcesArray =
sources as? JsonArray ?: throw SourceMapSourceReplacementException("'sources' property is not of array type")
var changed = false
val fixedSources = sourcesArray.elements.mapTo(mutableListOf<JsonNode>()) {
val sourcePath = it as? JsonString ?: throw SourceMapSourceReplacementException("'sources' array must contain strings")
val replacedPath = mapping(sourcePath.value)
if (!changed && replacedPath != sourcePath.value) {
changed = true
}
JsonString(replacedPath)
}
if (!changed) return false
jsonObject.properties["sources"] = JsonArray(fixedSources)
}
jsonObject.write(output)
return true
}
}
}
class SourceMapSourceReplacementException(message: String? = null, cause: Throwable? = null) : Exception(message, cause)
data class SourceMapSegment(
val generatedColumnNumber: Int,
val sourceFileName: String?,
@@ -66,4 +104,4 @@ sealed class SourceMapParseResult
class SourceMapSuccess(val value: SourceMap) : SourceMapParseResult()
class SourceMapError(val message: String) : SourceMapParseResult()
class SourceMapError(val message: String) : SourceMapParseResult()