Use source map remapper in JS inliner
This commit is contained in:
@@ -22,6 +22,7 @@ import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
object JsLibraryUtils {
|
||||
@@ -43,49 +44,53 @@ object JsLibraryUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic fun traverseJsLibraries(libs: List<File>, action: (content: String, path: String) -> Unit) {
|
||||
@JvmStatic fun traverseJsLibraries(libs: List<File>, action: (JsLibrary) -> Unit) {
|
||||
libs.forEach { traverseJsLibrary(it, action) }
|
||||
}
|
||||
|
||||
@JvmStatic fun traverseJsLibrary(lib: File, action: (content: String, path: String) -> Unit) {
|
||||
@JvmStatic fun traverseJsLibrary(lib: File, action: (JsLibrary) -> Unit) {
|
||||
when {
|
||||
lib.isDirectory -> traverseDirectory(lib, action)
|
||||
FileUtil.isJarOrZip(lib) -> traverseArchive(lib, action)
|
||||
lib.name.endsWith(KotlinJavascriptMetadataUtils.JS_EXT) -> {
|
||||
lib.runIfFileExists(action)
|
||||
lib.runIfFileExists(lib.path, action)
|
||||
val jsFile = lib.withReplacedExtensionOrNull(
|
||||
KotlinJavascriptMetadataUtils.META_JS_SUFFIX, KotlinJavascriptMetadataUtils.JS_EXT
|
||||
)
|
||||
jsFile?.runIfFileExists(action)
|
||||
jsFile?.runIfFileExists(jsFile.path, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun File.runIfFileExists(action: (content: String, path: String) -> Unit) {
|
||||
private fun File.runIfFileExists(relativePath: String, action: (JsLibrary) -> Unit) {
|
||||
if (isFile) {
|
||||
action(FileUtil.loadFile(this), "")
|
||||
action(JsLibrary(readText(), relativePath, correspondingSourceMapFile().contentIfExists()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyJsFilesFromDirectory(dir: File, outputLibraryJsPath: String) {
|
||||
traverseDirectory(dir) { content, relativePath ->
|
||||
FileUtil.writeToFile(File(outputLibraryJsPath, relativePath), content)
|
||||
traverseDirectory(dir) { (content, path) ->
|
||||
FileUtil.writeToFile(File(outputLibraryJsPath, path), content)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processDirectory(dir: File, action: (content: String, relativePath: String) -> Unit) {
|
||||
private fun File.contentIfExists(): String? = if (exists()) readText() else null
|
||||
|
||||
private fun File.correspondingSourceMapFile(): File = File(parentFile, name + ".map")
|
||||
|
||||
private fun processDirectory(dir: File, action: (JsLibrary) -> Unit) {
|
||||
FileUtil.processFilesRecursively(dir, Processor<File> { file ->
|
||||
val relativePath = FileUtil.getRelativePath(dir, file)
|
||||
?: throw IllegalArgumentException("relativePath should not be null $dir $file")
|
||||
if (file.isFile && relativePath.endsWith(KotlinJavascriptMetadataUtils.JS_EXT)) {
|
||||
if (relativePath.endsWith(KotlinJavascriptMetadataUtils.JS_EXT)) {
|
||||
val suggestedRelativePath = getSuggestedPath(relativePath) ?: return@Processor true
|
||||
action(FileUtil.loadFile(file), suggestedRelativePath)
|
||||
file.runIfFileExists(suggestedRelativePath, action)
|
||||
}
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
private fun traverseDirectory(dir: File, action: (content: String, relativePath: String) -> Unit) {
|
||||
private fun traverseDirectory(dir: File, action: (JsLibrary) -> Unit) {
|
||||
try {
|
||||
processDirectory(dir, action)
|
||||
}
|
||||
@@ -95,26 +100,48 @@ object JsLibraryUtils {
|
||||
}
|
||||
|
||||
private fun copyJsFilesFromZip(file: File, outputLibraryJsPath: String) {
|
||||
traverseArchive(file) { content, relativePath ->
|
||||
FileUtil.writeToFile(File(outputLibraryJsPath, relativePath), content)
|
||||
traverseArchive(file) { library ->
|
||||
FileUtil.writeToFile(File(outputLibraryJsPath, library.path), library.content)
|
||||
}
|
||||
}
|
||||
|
||||
private fun traverseArchive(file: File, action: (content: String, relativePath: String) -> Unit) {
|
||||
private fun traverseArchive(file: File, action: (JsLibrary) -> Unit) {
|
||||
val zipFile = ZipFile(file.path)
|
||||
try {
|
||||
val zipEntries = zipFile.entries()
|
||||
val librariesWithoutSourceMaps = mutableListOf<JsLibrary>()
|
||||
val possibleMapFiles = mutableMapOf<String, ZipEntry>()
|
||||
|
||||
while (zipEntries.hasMoreElements()) {
|
||||
val entry = zipEntries.nextElement()
|
||||
val entryName = entry.name
|
||||
if (!entry.isDirectory && entryName.endsWith(KotlinJavascriptMetadataUtils.JS_EXT)) {
|
||||
val relativePath = getSuggestedPath(entryName) ?: continue
|
||||
if (!entry.isDirectory) {
|
||||
if (entryName.endsWith(KotlinJavascriptMetadataUtils.JS_EXT)) {
|
||||
val relativePath = getSuggestedPath(entryName) ?: continue
|
||||
|
||||
val stream = zipFile.getInputStream(entry)
|
||||
val content = FileUtil.loadTextAndClose(stream)
|
||||
action(content, relativePath)
|
||||
val stream = zipFile.getInputStream(entry)
|
||||
val content = FileUtil.loadTextAndClose(stream)
|
||||
librariesWithoutSourceMaps += JsLibrary(content, relativePath, null)
|
||||
}
|
||||
else if (entryName.endsWith(KotlinJavascriptMetadataUtils.JS_MAP_EXT)) {
|
||||
possibleMapFiles[entryName.removeSuffix(KotlinJavascriptMetadataUtils.JS_MAP_EXT)] = entry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
librariesWithoutSourceMaps
|
||||
.map {
|
||||
val zipEntry = possibleMapFiles[it.path]
|
||||
if (zipEntry != null) {
|
||||
val stream = zipFile.getInputStream(zipEntry)
|
||||
val content = FileUtil.loadTextAndClose(stream)
|
||||
it.copy(sourceMapContent = content)
|
||||
}
|
||||
else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.forEach(action)
|
||||
}
|
||||
catch (ex: IOException) {
|
||||
LOG.error("Could not extract files from archive ${file.name}: ${ex.message}")
|
||||
@@ -136,3 +163,5 @@ object JsLibraryUtils {
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
||||
data class JsLibrary(val content: String, val path: String, val sourceMapContent: String?)
|
||||
|
||||
@@ -57,6 +57,7 @@ class JsMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
|
||||
object KotlinJavascriptMetadataUtils {
|
||||
const val JS_EXT: String = ".js"
|
||||
const val META_JS_SUFFIX: String = ".meta.js"
|
||||
const val JS_MAP_EXT: String = ".js.map"
|
||||
private val KOTLIN_JAVASCRIPT_METHOD_NAME = "kotlin_module_metadata"
|
||||
private val KOTLIN_JAVASCRIPT_METHOD_NAME_PATTERN = "\\.kotlin_module_metadata\\(".toPattern()
|
||||
|
||||
@@ -78,8 +79,8 @@ object KotlinJavascriptMetadataUtils {
|
||||
fun loadMetadata(file: File): List<KotlinJavascriptMetadata> {
|
||||
assert(file.exists()) { "Library $file not found" }
|
||||
val metadataList = arrayListOf<KotlinJavascriptMetadata>()
|
||||
JsLibraryUtils.traverseJsLibrary(file) { content, _ ->
|
||||
parseMetadata(content, metadataList)
|
||||
JsLibraryUtils.traverseJsLibrary(file) { library ->
|
||||
parseMetadata(library.content, metadataList)
|
||||
}
|
||||
|
||||
return metadataList
|
||||
|
||||
Reference in New Issue
Block a user