[JS] J2K for SourceMapBuilderConsumer
This commit is contained in:
+72
-104
@@ -2,124 +2,92 @@
|
|||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
package org.jetbrains.kotlin.js.sourceMap
|
||||||
|
|
||||||
package org.jetbrains.kotlin.js.sourceMap;
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.js.backend.SourceLocationConsumer
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.JsLocationWithSource
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.JsNode
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.isFakePsiElement
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.popLast
|
||||||
|
import java.io.*
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
class SourceMapBuilderConsumer(
|
||||||
import com.intellij.psi.PsiFile;
|
private val sourceBaseDir: File,
|
||||||
import org.jetbrains.annotations.NotNull;
|
private val mappingConsumer: SourceMapMappingConsumer,
|
||||||
import org.jetbrains.annotations.Nullable;
|
private val pathResolver: SourceFilePathResolver,
|
||||||
import org.jetbrains.kotlin.js.backend.SourceLocationConsumer;
|
private val provideCurrentModuleContent: Boolean,
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsLocation;
|
private val provideExternalModuleContent: Boolean
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsLocationWithSource;
|
) : SourceLocationConsumer {
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
|
||||||
|
|
||||||
import java.io.*;
|
private val sourceStack = mutableListOf<Any?>()
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class SourceMapBuilderConsumer implements SourceLocationConsumer {
|
override fun newLine() {
|
||||||
@NotNull
|
mappingConsumer.newLine()
|
||||||
private final File sourceBaseDir;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final SourceMapMappingConsumer mappingConsumer;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final SourceFilePathResolver pathResolver;
|
|
||||||
|
|
||||||
private final boolean provideCurrentModuleContent;
|
|
||||||
|
|
||||||
private final boolean provideExternalModuleContent;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final List<Object> sourceStack = new ArrayList<>();
|
|
||||||
|
|
||||||
public SourceMapBuilderConsumer(
|
|
||||||
@NotNull File sourceBaseDir,
|
|
||||||
@NotNull SourceMapMappingConsumer mappingConsumer,
|
|
||||||
@NotNull SourceFilePathResolver pathResolver,
|
|
||||||
boolean provideCurrentModuleContent, boolean provideExternalModuleContent
|
|
||||||
) {
|
|
||||||
this.sourceBaseDir = sourceBaseDir;
|
|
||||||
this.mappingConsumer = mappingConsumer;
|
|
||||||
this.pathResolver = pathResolver;
|
|
||||||
this.provideCurrentModuleContent = provideCurrentModuleContent;
|
|
||||||
this.provideExternalModuleContent = provideExternalModuleContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun pushSourceInfo(info: Any?) {
|
||||||
public void newLine() {
|
sourceStack.add(info)
|
||||||
mappingConsumer.newLine();
|
addMapping(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun popSourceInfo() {
|
||||||
public void pushSourceInfo(@Nullable Object info) {
|
sourceStack.popLast()
|
||||||
sourceStack.add(info);
|
addMapping(sourceStack.lastOrNull())
|
||||||
addMapping(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private fun addMapping(sourceInfo: Any?) {
|
||||||
public void popSourceInfo() {
|
when (sourceInfo) {
|
||||||
sourceStack.remove(sourceStack.size() - 1);
|
null -> mappingConsumer.addEmptyMapping()
|
||||||
Object sourceInfo = !sourceStack.isEmpty() ? sourceStack.get(sourceStack.size() - 1) : null;
|
is PsiElement -> {
|
||||||
addMapping(sourceInfo);
|
// This branch is only taken on the legacy backend
|
||||||
}
|
if (sourceInfo.isFakePsiElement) return
|
||||||
|
|
||||||
private void addMapping(@Nullable Object sourceInfo) {
|
|
||||||
if (sourceInfo == null) {
|
|
||||||
mappingConsumer.addEmptyMapping();
|
|
||||||
}
|
|
||||||
if (sourceInfo instanceof PsiElement) {
|
|
||||||
PsiElement element = (PsiElement) sourceInfo;
|
|
||||||
if (CallUtilKt.isFakePsiElement(element)) return;
|
|
||||||
try {
|
|
||||||
JsLocation location = PsiUtils.extractLocationFromPsi(element, pathResolver);
|
|
||||||
PsiFile psiFile = element.getContainingFile();
|
|
||||||
File file = new File(psiFile.getViewProvider().getVirtualFile().getPath());
|
|
||||||
Supplier<Reader> contentSupplier;
|
|
||||||
if (provideCurrentModuleContent) {
|
|
||||||
contentSupplier = () -> {
|
|
||||||
try {
|
|
||||||
return new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
contentSupplier = () -> null;
|
|
||||||
}
|
|
||||||
mappingConsumer.addMapping(location.getFile(), null, contentSupplier, location.getStartLine(), location.getStartChar());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new RuntimeException("IO error occurred generating source maps", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sourceInfo instanceof JsLocationWithSource) {
|
|
||||||
JsLocationWithSource location = (JsLocationWithSource) sourceInfo;
|
|
||||||
Supplier<Reader> contentSupplier = provideExternalModuleContent ? location.getSourceProvider()::invoke : () -> null;
|
|
||||||
String path;
|
|
||||||
|
|
||||||
File absFile = new File(location.getFile()).isAbsolute() ?
|
|
||||||
new File(location.getFile()) :
|
|
||||||
new File(sourceBaseDir, location.getFile());
|
|
||||||
if (absFile.isAbsolute()) {
|
|
||||||
try {
|
try {
|
||||||
path = pathResolver.getPathRelativeToSourceRoots(absFile);
|
val (sourceFilePath, startLine, startChar) = PsiUtils.extractLocationFromPsi(sourceInfo, pathResolver)
|
||||||
}
|
val psiFile = sourceInfo.containingFile
|
||||||
catch (IOException e) {
|
val file = File(psiFile.viewProvider.virtualFile.path)
|
||||||
path = location.getFile();
|
val contentSupplier = if (provideCurrentModuleContent) {
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
InputStreamReader(FileInputStream(file), StandardCharsets.UTF_8)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
{ null }
|
||||||
|
}
|
||||||
|
mappingConsumer.addMapping(sourceFilePath, null, contentSupplier, startLine, startChar)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw RuntimeException("IO error occurred generating source maps", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
is JsLocationWithSource -> {
|
||||||
path = location.getFile();
|
val contentSupplier = if (provideExternalModuleContent) sourceInfo.sourceProvider else {
|
||||||
|
{ null }
|
||||||
|
}
|
||||||
|
val sourceFile = File(sourceInfo.file)
|
||||||
|
val absFile = if (sourceFile.isAbsolute) sourceFile else File(sourceBaseDir, sourceInfo.file)
|
||||||
|
val path = if (absFile.isAbsolute) {
|
||||||
|
try {
|
||||||
|
pathResolver.getPathRelativeToSourceRoots(absFile)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
sourceInfo.file
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sourceInfo.file
|
||||||
|
}
|
||||||
|
mappingConsumer.addMapping(
|
||||||
|
path,
|
||||||
|
sourceInfo.identityObject,
|
||||||
|
contentSupplier,
|
||||||
|
sourceInfo.startLine,
|
||||||
|
sourceInfo.startChar
|
||||||
|
)
|
||||||
}
|
}
|
||||||
mappingConsumer.addMapping(path, location.getIdentityObject(), contentSupplier,
|
is JsNode -> { /* Can occur on legacy BE, not sure if it's a bug or not. */ }
|
||||||
location.getStartLine(), location.getStartChar());
|
else -> error("Unexpected sourceInfo: $sourceInfo")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user