Report correct source to output mapping for kjsm files
Now IC can correctly remove kjsm files when source files are changed
This commit is contained in:
@@ -27,8 +27,6 @@ import com.intellij.util.SmartList;
|
|||||||
import com.intellij.util.containers.HashMap;
|
import com.intellij.util.containers.HashMap;
|
||||||
import kotlin.collections.ArraysKt;
|
import kotlin.collections.ArraysKt;
|
||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import kotlin.io.FilesKt;
|
|
||||||
import kotlin.sequences.SequencesKt;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||||
@@ -66,7 +64,6 @@ import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
|
|||||||
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver;
|
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver;
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
|
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
||||||
import org.jetbrains.kotlin.utils.*;
|
import org.jetbrains.kotlin.utils.*;
|
||||||
|
|
||||||
@@ -297,23 +294,12 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||||
|
|
||||||
if (config.getConfiguration().getBoolean(JSConfigurationKeys.META_INFO)) {
|
|
||||||
removeKjsmFilesFromOutput(outputDir);
|
|
||||||
}
|
|
||||||
OutputUtilsKt.writeAll(outputFiles, outputDir, messageCollector,
|
OutputUtilsKt.writeAll(outputFiles, outputDir, messageCollector,
|
||||||
configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES));
|
configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeKjsmFilesFromOutput(File outputDir) {
|
|
||||||
for (File file : SequencesKt.toList(FilesKt.walkTopDown(outputDir))) {
|
|
||||||
if (file.isFile() && file.getPath().endsWith(KotlinJavascriptSerializationUtil.INSTANCE.getCLASS_METADATA_FILE_EXTENSION())) {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkDuplicateSourceFileNames(
|
private static void checkDuplicateSourceFileNames(
|
||||||
@NotNull MessageCollector log,
|
@NotNull MessageCollector log,
|
||||||
@NotNull List<KtFile> sourceFiles,
|
@NotNull List<KtFile> sourceFiles,
|
||||||
|
|||||||
@@ -94,16 +94,6 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
private val PATH_TO_KOTLIN_JS_LIBRARY = AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/KotlinJavaScriptProjectWithDirectoryAsLibrary/" + KOTLIN_JS_LIBRARY
|
private val PATH_TO_KOTLIN_JS_LIBRARY = AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/KotlinJavaScriptProjectWithDirectoryAsLibrary/" + KOTLIN_JS_LIBRARY
|
||||||
private val KOTLIN_JS_LIBRARY_JAR = "$KOTLIN_JS_LIBRARY.jar"
|
private val KOTLIN_JS_LIBRARY_JAR = "$KOTLIN_JS_LIBRARY.jar"
|
||||||
|
|
||||||
private fun k2jsOutput(vararg moduleNames: String): Array<String> {
|
|
||||||
val list = arrayListOf<String>()
|
|
||||||
for (moduleName in moduleNames) {
|
|
||||||
val outputDir = File("out/production/$moduleName")
|
|
||||||
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputFile(outputDir, moduleName, false).path))
|
|
||||||
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputMetaFile(outputDir, moduleName, false).path))
|
|
||||||
}
|
|
||||||
return list.toTypedArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMethodsOfClass(classFile: File): Set<String> {
|
private fun getMethodsOfClass(classFile: File): Set<String> {
|
||||||
val result = TreeSet<String>()
|
val result = TreeSet<String>()
|
||||||
ClassReader(FileUtil.loadFileBytes(classFile)).accept(object : ClassVisitor(Opcodes.ASM5) {
|
ClassReader(FileUtil.loadFileBytes(classFile)).accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||||
@@ -257,6 +247,21 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME))
|
checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun k2jsOutput(vararg moduleNames: String): Array<String> {
|
||||||
|
val list = arrayListOf<String>()
|
||||||
|
for (moduleName in moduleNames) {
|
||||||
|
val outputDir = File("out/production/$moduleName")
|
||||||
|
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputFile(outputDir, moduleName, false).path))
|
||||||
|
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputMetaFile(outputDir, moduleName, false).path))
|
||||||
|
|
||||||
|
val kjsmFiles = File(workDir, outputDir.path).walk()
|
||||||
|
.filter { it.isFile && it.extension.equals("kjsm", ignoreCase = true) }
|
||||||
|
list.addAll(kjsmFiles.map { toSystemIndependentName(it.relativeTo(workDir).path) })
|
||||||
|
|
||||||
|
}
|
||||||
|
return list.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
fun testKotlinJavaScriptProjectWithSourceMap() {
|
fun testKotlinJavaScriptProjectWithSourceMap() {
|
||||||
initProject(JS_STDLIB)
|
initProject(JS_STDLIB)
|
||||||
buildAllModules().assertSuccessful()
|
buildAllModules().assertSuccessful()
|
||||||
|
|||||||
+6
-4
@@ -115,8 +115,10 @@ object KotlinJavascriptSerializationUtil {
|
|||||||
private val jsDescriptor: JsModuleDescriptor<ModuleDescriptor>,
|
private val jsDescriptor: JsModuleDescriptor<ModuleDescriptor>,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
fun asContentMap(): Map<String, ByteArray> {
|
class SerializedPackage(val fqName: FqName, val bytes: ByteArray)
|
||||||
val contentMap = mutableMapOf<String, ByteArray>()
|
|
||||||
|
fun serializedPackages(): List<SerializedPackage> {
|
||||||
|
val packages = arrayListOf<SerializedPackage>()
|
||||||
|
|
||||||
for ((fqName, part) in serializedFragments) {
|
for ((fqName, part) in serializedFragments) {
|
||||||
val stream = ByteArrayOutputStream()
|
val stream = ByteArrayOutputStream()
|
||||||
@@ -129,10 +131,10 @@ object KotlinJavascriptSerializationUtil {
|
|||||||
serializeHeader(jsDescriptor.data, fqName, languageVersionSettings).writeDelimitedTo(stream)
|
serializeHeader(jsDescriptor.data, fqName, languageVersionSettings).writeDelimitedTo(stream)
|
||||||
part.writeTo(stream)
|
part.writeTo(stream)
|
||||||
|
|
||||||
contentMap[JsSerializerProtocol.getKjsmFilePath(fqName)] = stream.toByteArray()
|
packages.add(SerializedPackage(fqName, stream.toByteArray()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentMap
|
return packages
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asString(): String =
|
fun asString(): String =
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
|
|||||||
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
||||||
import org.jetbrains.kotlin.js.util.TextOutput
|
import org.jetbrains.kotlin.js.util.TextOutput
|
||||||
import org.jetbrains.kotlin.js.util.TextOutputImpl
|
import org.jetbrains.kotlin.js.util.TextOutputImpl
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
|
import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
|
||||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
||||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -114,9 +116,9 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost
|
|||||||
val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent)
|
val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent)
|
||||||
outputFiles.add(jsMetaFile)
|
outputFiles.add(jsMetaFile)
|
||||||
|
|
||||||
serializedMetadata.asContentMap().forEach {
|
for (serializedPackage in serializedMetadata.serializedPackages()) {
|
||||||
// TODO Add correct source files
|
val outputBinaryFile = kjsmFileForPackage(serializedPackage.fqName, serializedPackage.bytes)
|
||||||
outputFiles.add(SimpleOutputBinaryFile(emptyList(), config.moduleId + VfsUtilCore.VFS_SEPARATOR_CHAR + it.key, it.value))
|
outputFiles.add(outputBinaryFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +132,15 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost
|
|||||||
return SimpleOutputFileCollection(outputFiles)
|
return SimpleOutputFileCollection(outputFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun kjsmFileForPackage(packageFqName: FqName, bytes: ByteArray): SimpleOutputBinaryFile {
|
||||||
|
val ktFiles = (bindingContext.get(BindingContext.PACKAGE_TO_FILES, packageFqName) ?: emptyList())
|
||||||
|
val sourceFiles = ktFiles.map { VfsUtilCore.virtualToIoFile(it.virtualFile) }
|
||||||
|
val relativePath = config.moduleId +
|
||||||
|
VfsUtilCore.VFS_SEPARATOR_CHAR +
|
||||||
|
JsSerializerProtocol.getKjsmFilePath(packageFqName)
|
||||||
|
return SimpleOutputBinaryFile(sourceFiles, relativePath, bytes)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getCode(output: TextOutput, sourceLocationConsumer: SourceLocationConsumer?) {
|
private fun getCode(output: TextOutput, sourceLocationConsumer: SourceLocationConsumer?) {
|
||||||
program.accept(JsToStringGenerationVisitor(output, sourceLocationConsumer ?: NoOpSourceLocationConsumer))
|
program.accept(JsToStringGenerationVisitor(output, sourceLocationConsumer ?: NoOpSourceLocationConsumer))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user