JS IR: moved klib creation to the serialization_test module
This commit is contained in:
@@ -4,21 +4,40 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:backend-common"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compile(project(":compiler:ir.psi2ir"))
|
||||
compile(project(":compiler:ir.backend.common"))
|
||||
compile(project(":compiler:ir.serialization.common"))
|
||||
compile(project(":js:js.ast"))
|
||||
compile(project(":js:js.frontend"))
|
||||
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompileOnly(project(":compiler:frontend"))
|
||||
testCompileOnly(project(":compiler:cli"))
|
||||
testCompileOnly(project(":compiler:util"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
val generateIrRuntimeKlib by smartJavaExec {
|
||||
val inDirs = arrayOf(fileFrom(rootDir, "core", "builtins", "src"),
|
||||
fileFrom(rootDir, "core", "builtins", "native"),
|
||||
fileFrom(rootDir, "libraries", "stdlib", "common", "src"),
|
||||
fileFrom(rootDir, "libraries", "stdlib", "src", "kotlin"),
|
||||
fileFrom(rootDir, "libraries", "stdlib", "js", "src", "generated"),
|
||||
fileFrom(rootDir, "libraries", "stdlib", "js", "irRuntime"),
|
||||
fileFrom(rootDir, "libraries", "stdlib", "unsigned"),
|
||||
fileFrom(rootDir, "js", "js.translator", "testData", "_commonFiles"))
|
||||
inDirs.forEach { inputs.dir(it) }
|
||||
|
||||
val outDir = "$rootDir/js/js.translator/testData/out/klibs/"
|
||||
outputs.dir(outDir)
|
||||
|
||||
classpath = sourceSets.test.get().runtimeClasspath
|
||||
main = "org.jetbrains.kotlin.ir.backend.js.GenerateIrRuntimeKt"
|
||||
workingDir = rootDir
|
||||
}
|
||||
|
||||
testsJar {}
|
||||
@@ -35,7 +35,10 @@ import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
@@ -53,10 +56,8 @@ data class KlibModuleRef(
|
||||
internal val JS_KLIBRARY_CAPABILITY = ModuleDescriptor.Capability<File>("JS KLIBRARY")
|
||||
internal val moduleHeaderFileName = "module.kji"
|
||||
internal val declarationsDirName = "ir/"
|
||||
private val logggg = object : LoggingContext {
|
||||
override var inVerbosePhase: Boolean
|
||||
get() = TODO("not implemented")
|
||||
set(_) {}
|
||||
private val emptyLoggingContext = object : LoggingContext {
|
||||
override var inVerbosePhase = false
|
||||
|
||||
override fun log(message: () -> String) {}
|
||||
}
|
||||
@@ -76,12 +77,9 @@ fun generateKLib(
|
||||
): KlibModuleRef {
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
|
||||
|
||||
val analysisResult = depsDescriptors.runAnalysis()
|
||||
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
|
||||
|
||||
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
|
||||
|
||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files)
|
||||
val moduleFragment = psi2IrContext.generateModuleFragment(files)
|
||||
|
||||
val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!!
|
||||
serializeModuleIntoKlib(
|
||||
@@ -114,28 +112,40 @@ fun loadIr(
|
||||
): IrModuleInfo {
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
|
||||
|
||||
val analysisResult = depsDescriptors.runAnalysis()
|
||||
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
|
||||
|
||||
val moduleDescriptor = analysisResult.moduleDescriptor
|
||||
|
||||
val symbolTable = SymbolTable()
|
||||
|
||||
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
||||
val irBuiltIns = psi2IrContext.irBuiltIns
|
||||
val symbolTable = psi2IrContext.symbolTable
|
||||
val moduleDescriptor = psi2IrContext.moduleDescriptor
|
||||
|
||||
val deserializer = JsIrLinker(moduleDescriptor, logggg, irBuiltIns, symbolTable)
|
||||
val deserializer = JsIrLinker(moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable)
|
||||
|
||||
val deserializedModuleFragments = depsDescriptors.sortedImmediateDependencies.map {
|
||||
val moduleFile = File(it.klibPath, moduleHeaderFileName)
|
||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
||||
}
|
||||
|
||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files, deserializer)
|
||||
val moduleFragment = psi2IrContext.generateModuleFragment(files, deserializer)
|
||||
|
||||
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
|
||||
}
|
||||
|
||||
private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): GeneratorContext {
|
||||
val analysisResult = depsDescriptors.runAnalysis()
|
||||
|
||||
return GeneratorContext(
|
||||
Psi2IrConfiguration(),
|
||||
analysisResult.moduleDescriptor,
|
||||
analysisResult.bindingContext,
|
||||
depsDescriptors.compilerConfiguration.languageVersionSettings,
|
||||
SymbolTable(),
|
||||
GeneratorExtensions()
|
||||
)
|
||||
}
|
||||
|
||||
private fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: JsIrLinker? = null) =
|
||||
Psi2IrTranslator(languageVersionSettings, configuration).generateModuleFragment(this, files, deserializer)
|
||||
|
||||
|
||||
private fun loadKlibMetadataParts(
|
||||
moduleId: KlibModuleRef
|
||||
): JsKlibMetadataParts {
|
||||
@@ -157,8 +167,12 @@ private fun loadKlibMetadata(
|
||||
): ModuleDescriptorImpl {
|
||||
assert(isBuiltIn == (builtinsModule === null))
|
||||
val builtIns = builtinsModule?.builtIns ?: object : KotlinBuiltIns(storageManager) {}
|
||||
val md = ModuleDescriptorImpl(Name.special("<${moduleId.moduleName}>"), storageManager, builtIns,
|
||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to File(moduleId.klibPath)))
|
||||
val md = ModuleDescriptorImpl(
|
||||
Name.special("<${moduleId.moduleName}>"),
|
||||
storageManager,
|
||||
builtIns,
|
||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to File(moduleId.klibPath))
|
||||
)
|
||||
if (isBuiltIn) builtIns.builtInsModule = md
|
||||
val currentModuleFragmentProvider = createJsKlibMetadataPackageFragmentProvider(
|
||||
storageManager, md, parts.header, parts.body, metadataVersion,
|
||||
@@ -178,10 +192,10 @@ private fun loadKlibMetadata(
|
||||
}
|
||||
|
||||
|
||||
class ModulesStructure(
|
||||
private class ModulesStructure(
|
||||
private val project: Project,
|
||||
private val files: List<KtFile>,
|
||||
private val compilerConfiguration: CompilerConfiguration,
|
||||
val compilerConfiguration: CompilerConfiguration,
|
||||
immediateDependencies: List<KlibModuleRef>,
|
||||
private val allDependencies: List<KlibModuleRef>
|
||||
) {
|
||||
@@ -265,7 +279,7 @@ fun serializeModuleIntoKlib(
|
||||
) {
|
||||
val declarationTable = JsDeclarationTable(moduleFragment.irBuiltins, DescriptorTable())
|
||||
|
||||
val serializedIr = JsIrModuleSerializer(logggg, declarationTable).serializedIrModule(moduleFragment)
|
||||
val serializedIr = JsIrModuleSerializer(emptyLoggingContext, declarationTable).serializedIrModule(moduleFragment)
|
||||
val serializer = JsKlibMetadataSerializationUtil
|
||||
|
||||
val moduleDescription =
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.ir.backend.js
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
|
||||
fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguration {
|
||||
val runtimeConfiguration = environment.configuration.copy()
|
||||
runtimeConfiguration.put(CommonConfigurationKeys.MODULE_NAME, "JS_IR_RUNTIME")
|
||||
runtimeConfiguration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||
|
||||
runtimeConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE,
|
||||
specificFeatures = mapOf(
|
||||
LanguageFeature.AllowContractsForCustomFunctions to LanguageFeature.State.ENABLED,
|
||||
LanguageFeature.MultiPlatformProjects to LanguageFeature.State.ENABLED
|
||||
),
|
||||
analysisFlags = mapOf(
|
||||
AnalysisFlags.useExperimental to listOf("kotlin.contracts.ExperimentalContracts", "kotlin.Experimental"),
|
||||
AnalysisFlags.allowResultReturnType to true
|
||||
)
|
||||
)
|
||||
|
||||
return runtimeConfiguration
|
||||
}
|
||||
|
||||
private val fullRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeFull/"
|
||||
private val defaultRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeDefault/"
|
||||
|
||||
fun main() {
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForTests(Disposable { }, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
|
||||
|
||||
fun createPsiFile(fileName: String): KtFile {
|
||||
val psiManager = PsiManager.getInstance(environment.project)
|
||||
val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||
|
||||
val file = fileSystem.findFileByPath(fileName) ?: error("File not found: $fileName")
|
||||
|
||||
return psiManager.findFile(file) as KtFile
|
||||
}
|
||||
|
||||
|
||||
fun buildKlib(sources: List<String>, outputPath: String) {
|
||||
generateKLib(
|
||||
project = environment.project,
|
||||
files = sources.map(::createPsiFile),
|
||||
configuration = buildConfiguration(environment),
|
||||
immediateDependencies = emptyList(),
|
||||
allDependencies = emptyList(),
|
||||
outputKlibPath = outputPath
|
||||
)
|
||||
}
|
||||
|
||||
buildKlib(JsIrTestRuntime.FULL.sources, fullRuntimeKlibPath)
|
||||
buildKlib(JsIrTestRuntime.DEFAULT.sources, defaultRuntimeKlibPath)
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
private const val runtimeDir = "js/js.translator/testData/out/irBox"
|
||||
|
||||
enum class JsIrTestRuntime(
|
||||
val sources: List<String>,
|
||||
val path: String
|
||||
) {
|
||||
// Includes all built-ins and reduced subset of stdlib
|
||||
DEFAULT(
|
||||
sources = reducedRuntimeSources,
|
||||
path = "$runtimeDir/testRuntime.js"
|
||||
),
|
||||
|
||||
// Includes almost full stdlib
|
||||
FULL(
|
||||
sources = fullRuntimeSources,
|
||||
path = "$runtimeDir/testRuntimeFull.js"
|
||||
)
|
||||
}
|
||||
|
||||
// Required to compile native builtins with the rest of runtime
|
||||
private const val builtInsHeader = """@file:Suppress(
|
||||
"NON_ABSTRACT_FUNCTION_WITH_NO_BODY",
|
||||
"MUST_BE_INITIALIZED_OR_BE_ABSTRACT",
|
||||
"EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE",
|
||||
"PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED",
|
||||
"WRONG_MODIFIER_TARGET"
|
||||
)
|
||||
"""
|
||||
|
||||
// Native builtins that were not implemented in JS IR runtime
|
||||
private val unimplementedNativeBuiltInsDir = KotlinTestUtils.tmpDir("unimplementedBuiltins").also { tmpDir ->
|
||||
val allBuiltins = listOfKtFilesFrom("core/builtins/native/kotlin").map { File(it).name }
|
||||
val implementedBuiltIns = listOfKtFilesFrom("libraries/stdlib/js/irRuntime/builtins/").map { File(it).name }
|
||||
val unimplementedBuiltIns = allBuiltins - implementedBuiltIns
|
||||
for (filename in unimplementedBuiltIns) {
|
||||
val originalFile = File("core/builtins/native/kotlin", filename)
|
||||
val newFile = File(tmpDir, filename)
|
||||
val sourceCode = builtInsHeader + originalFile.readText()
|
||||
newFile.writeText(sourceCode)
|
||||
}
|
||||
}
|
||||
|
||||
private val fullRuntimeSources = listOfKtFilesFrom(
|
||||
"core/builtins/src/kotlin",
|
||||
"libraries/stdlib/common/src",
|
||||
"libraries/stdlib/src/kotlin/",
|
||||
"libraries/stdlib/js/src/kotlin",
|
||||
"libraries/stdlib/js/src/generated",
|
||||
"libraries/stdlib/js/irRuntime",
|
||||
"libraries/stdlib/js/runtime",
|
||||
"libraries/stdlib/unsigned",
|
||||
|
||||
"core/builtins/src/kotlin/Unit.kt",
|
||||
unimplementedNativeBuiltInsDir.path,
|
||||
"js/js.translator/testData/_commonFiles"
|
||||
) - listOfKtFilesFrom(
|
||||
"libraries/stdlib/common/src/kotlin/JvmAnnotationsH.kt",
|
||||
"libraries/stdlib/src/kotlin/annotations/Multiplatform.kt",
|
||||
"libraries/stdlib/common/src/kotlin/NativeAnnotationsH.kt",
|
||||
|
||||
// TODO: Support Int.pow
|
||||
"libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt",
|
||||
|
||||
// Fails with: EXPERIMENTAL_IS_NOT_ENABLED
|
||||
"libraries/stdlib/common/src/kotlin/annotations/Annotations.kt",
|
||||
|
||||
// Conflicts with libraries/stdlib/js/src/kotlin/annotations.kt
|
||||
"libraries/stdlib/js/runtime/hacks.kt",
|
||||
|
||||
// TODO: Reuse in IR BE
|
||||
"libraries/stdlib/js/runtime/Enum.kt",
|
||||
|
||||
// JS-specific optimized version of emptyArray() already defined
|
||||
"core/builtins/src/kotlin/ArrayIntrinsics.kt",
|
||||
|
||||
// Unnecessary for now
|
||||
"libraries/stdlib/js/src/kotlin/dom",
|
||||
"libraries/stdlib/js/src/kotlin/browser",
|
||||
|
||||
// TODO: fix compilation issues in arrayPlusCollection
|
||||
// Replaced with irRuntime/kotlinHacks.kt
|
||||
"libraries/stdlib/js/src/kotlin/kotlin.kt",
|
||||
|
||||
"libraries/stdlib/js/src/kotlin/currentBeMisc.kt",
|
||||
|
||||
// IR BE has its own generated sources
|
||||
"libraries/stdlib/js/src/generated",
|
||||
"libraries/stdlib/js/src/kotlin/collectionsExternal.kt",
|
||||
|
||||
// Full version is defined in stdlib
|
||||
// This file is useful for smaller subset of runtime sources
|
||||
"libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt",
|
||||
|
||||
// Mostly array-specific stuff
|
||||
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
||||
|
||||
// coroutines
|
||||
// TODO: merge coroutines_13 with JS BE coroutines
|
||||
"libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt",
|
||||
"libraries/stdlib/js/src/kotlin/coroutines/CoroutineImpl.kt",
|
||||
|
||||
// Inlining of js fun doesn't update the variables inside
|
||||
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
||||
"libraries/stdlib/js/src/kotlin/collections/utils.kt",
|
||||
|
||||
// TODO: Remove stub
|
||||
"libraries/stdlib/js/src/kotlin/builtins.kt"
|
||||
)
|
||||
|
||||
private val reducedRuntimeSources = fullRuntimeSources - listOfKtFilesFrom(
|
||||
"libraries/stdlib/unsigned",
|
||||
"libraries/stdlib/common/src/generated/_Arrays.kt",
|
||||
"libraries/stdlib/common/src/generated/_Collections.kt",
|
||||
"libraries/stdlib/common/src/generated/_Comparisons.kt",
|
||||
"libraries/stdlib/common/src/generated/_Maps.kt",
|
||||
"libraries/stdlib/common/src/generated/_Sequences.kt",
|
||||
"libraries/stdlib/common/src/generated/_Sets.kt",
|
||||
"libraries/stdlib/common/src/generated/_Strings.kt",
|
||||
"libraries/stdlib/common/src/generated/_UArrays.kt",
|
||||
"libraries/stdlib/common/src/generated/_URanges.kt",
|
||||
"libraries/stdlib/common/src/generated/_UCollections.kt",
|
||||
"libraries/stdlib/common/src/generated/_UComparisons.kt",
|
||||
"libraries/stdlib/common/src/generated/_USequences.kt",
|
||||
"libraries/stdlib/common/src/kotlin/SequencesH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/TextH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/UMath.kt",
|
||||
"libraries/stdlib/common/src/kotlin/collections/",
|
||||
"libraries/stdlib/common/src/kotlin/ioH.kt",
|
||||
"libraries/stdlib/js/irRuntime/collectionsHacks.kt",
|
||||
"libraries/stdlib/js/irRuntime/generated/",
|
||||
"libraries/stdlib/js/src/kotlin/char.kt",
|
||||
"libraries/stdlib/js/src/kotlin/collections.kt",
|
||||
"libraries/stdlib/js/src/kotlin/collections/",
|
||||
"libraries/stdlib/js/src/kotlin/console.kt",
|
||||
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
||||
"libraries/stdlib/js/src/kotlin/date.kt",
|
||||
"libraries/stdlib/js/src/kotlin/debug.kt",
|
||||
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
||||
"libraries/stdlib/js/src/kotlin/json.kt",
|
||||
"libraries/stdlib/js/src/kotlin/numberConversions.kt",
|
||||
"libraries/stdlib/js/src/kotlin/promise.kt",
|
||||
"libraries/stdlib/js/src/kotlin/regex.kt",
|
||||
"libraries/stdlib/js/src/kotlin/regexp.kt",
|
||||
"libraries/stdlib/js/src/kotlin/sequence.kt",
|
||||
"libraries/stdlib/js/src/kotlin/string.kt",
|
||||
"libraries/stdlib/js/src/kotlin/stringsCode.kt",
|
||||
"libraries/stdlib/js/src/kotlin/text.kt",
|
||||
"libraries/stdlib/src/kotlin/collections/",
|
||||
"libraries/stdlib/src/kotlin/experimental/bitwiseOperations.kt",
|
||||
"libraries/stdlib/src/kotlin/properties/Delegates.kt",
|
||||
"libraries/stdlib/src/kotlin/random/URandom.kt",
|
||||
"libraries/stdlib/src/kotlin/text/",
|
||||
"libraries/stdlib/src/kotlin/util/KotlinVersion.kt",
|
||||
"libraries/stdlib/src/kotlin/util/Tuples.kt"
|
||||
) + listOfKtFilesFrom(
|
||||
"libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt"
|
||||
)
|
||||
|
||||
private fun listOfKtFilesFrom(vararg paths: String): List<String> {
|
||||
val currentDir = File("")
|
||||
return paths.flatMap { path ->
|
||||
File(path)
|
||||
.walkTopDown()
|
||||
.filter { it.extension == "kt" }
|
||||
.map { it.relativeToOrSelf(currentDir).path }
|
||||
.asIterable()
|
||||
}.distinct()
|
||||
}
|
||||
Reference in New Issue
Block a user