JS IR: moved klib creation to the serialization_test module

This commit is contained in:
Anton Bannykh
2019-03-21 20:12:46 +03:00
parent 0f183ed662
commit ad4c2144a7
11 changed files with 87 additions and 55 deletions
+26 -7
View File
@@ -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()
}