FIR JS: enable full JS box tests with FIR
This commit is contained in:
+1
-1
@@ -50,7 +50,7 @@ class KlibBasedSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
|
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
|
||||||
val packageStringName = packageFqName.asString()
|
val packageStringName = if (packageFqName.isRoot) "" else packageFqName.asString()
|
||||||
|
|
||||||
if (packageStringName !in fragmentNameList) {
|
if (packageStringName !in fragmentNameList) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
|
|||||||
+2
-2
@@ -28,8 +28,8 @@ abstract class FirSerializerExtension {
|
|||||||
open fun shouldSerializeTypeAlias(typeAlias: FirTypeAlias): Boolean = true
|
open fun shouldSerializeTypeAlias(typeAlias: FirTypeAlias): Boolean = true
|
||||||
open fun shouldUseTypeTable(): Boolean = false
|
open fun shouldUseTypeTable(): Boolean = false
|
||||||
open fun shouldUseNormalizedVisibility(): Boolean = false
|
open fun shouldUseNormalizedVisibility(): Boolean = false
|
||||||
open fun shouldSerializeFunction(function: FirFunction): Boolean = false
|
abstract fun shouldSerializeFunction(function: FirFunction): Boolean
|
||||||
open fun shouldSerializeProperty(property: FirProperty): Boolean = false
|
abstract fun shouldSerializeProperty(property: FirProperty): Boolean
|
||||||
|
|
||||||
open fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
open fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-17
@@ -6,8 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.buildKlibPackageFragment
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.buildKlibPackageFragment
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
@@ -19,14 +18,11 @@ import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension
|
|||||||
import org.jetbrains.kotlin.fir.serialization.TypeApproximatorForMetadataSerializer
|
import org.jetbrains.kotlin.fir.serialization.TypeApproximatorForMetadataSerializer
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.serialization.SerializableStringTable
|
import org.jetbrains.kotlin.serialization.SerializableStringTable
|
||||||
|
|
||||||
fun serializeSingleFirFile(file: FirFile, session: FirSession, scopeSession: ScopeSession, configuration: CompilerConfiguration): ProtoBuf.PackageFragment {
|
fun serializeSingleFirFile(file: FirFile, session: FirSession, scopeSession: ScopeSession, metadataVersion: BinaryVersion): ProtoBuf.PackageFragment {
|
||||||
val serializerExtension = FirKLibSerializerExtension(
|
val serializerExtension = FirKLibSerializerExtension(session, metadataVersion, FirElementAwareSerializableStringTable())
|
||||||
session,
|
|
||||||
configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!,
|
|
||||||
FirElementAwareSerializableStringTable()
|
|
||||||
)
|
|
||||||
val approximator = TypeApproximatorForMetadataSerializer(session)
|
val approximator = TypeApproximatorForMetadataSerializer(session)
|
||||||
val packageSerializer = FirElementSerializer.createTopLevel(session, scopeSession, serializerExtension, approximator)
|
val packageSerializer = FirElementSerializer.createTopLevel(session, scopeSession, serializerExtension, approximator)
|
||||||
|
|
||||||
@@ -36,14 +32,15 @@ fun serializeSingleFirFile(file: FirFile, session: FirSession, scopeSession: Sco
|
|||||||
|
|
||||||
val packageProto = packageSerializer.packagePartProto(file.packageFqName, file).build()
|
val packageProto = packageSerializer.packagePartProto(file.packageFqName, file).build()
|
||||||
|
|
||||||
// TODO: filter out expects
|
fun List<FirDeclaration>.makeClassesProtoWithNested(): List<Pair<ProtoBuf.Class, Int>> =
|
||||||
val classifiers = file.declarations.filterIsInstance<FirClass>().sortedBy { it.classId.asFqNameString() }
|
// TODO: filter out expects
|
||||||
|
filterIsInstance<FirClass>().sortedBy { it.classId.asFqNameString() }.flatMap {
|
||||||
|
val classSerializer = FirElementSerializer.create(session, scopeSession, it, serializerExtension, null, approximator)
|
||||||
|
val index = classSerializer.stringTable.getFqNameIndex(it)
|
||||||
|
listOf(classSerializer.classProto(it).build() to index) + it.declarations.makeClassesProtoWithNested()
|
||||||
|
}
|
||||||
|
|
||||||
val classesProto = classifiers.map {
|
val classesProto = file.declarations.makeClassesProtoWithNested()
|
||||||
val classSerializer = FirElementSerializer.create(session, scopeSession, it, serializerExtension, null, approximator)
|
|
||||||
val index = classSerializer.stringTable.getFqNameIndex(it)
|
|
||||||
classSerializer.classProto(it).build() to index
|
|
||||||
}
|
|
||||||
|
|
||||||
val hasTopLevelDeclarations = file.declarations.any {
|
val hasTopLevelDeclarations = file.declarations.any {
|
||||||
it is FirProperty || it is FirSimpleFunction || it is FirTypeAlias
|
it is FirProperty || it is FirSimpleFunction || it is FirTypeAlias
|
||||||
@@ -62,6 +59,12 @@ class FirKLibSerializerExtension(
|
|||||||
override val session: FirSession,
|
override val session: FirSession,
|
||||||
override val metadataVersion: BinaryVersion,
|
override val metadataVersion: BinaryVersion,
|
||||||
override val stringTable: FirElementAwareSerializableStringTable
|
override val stringTable: FirElementAwareSerializableStringTable
|
||||||
) : FirSerializerExtension()
|
) : FirSerializerExtension() {
|
||||||
|
override fun shouldSerializeFunction(function: FirFunction): Boolean = true
|
||||||
|
|
||||||
class FirElementAwareSerializableStringTable() : FirElementAwareStringTable, SerializableStringTable()
|
override fun shouldSerializeProperty(property: FirProperty): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirElementAwareSerializableStringTable() : FirElementAwareStringTable, SerializableStringTable() {
|
||||||
|
override fun getLocalClassIdReplacement(firClass: FirClass): ClassId? = ClassId.topLevel(StandardNames.FqNames.any.toSafe())
|
||||||
|
}
|
||||||
|
|||||||
+4
-5
@@ -6,20 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.test.services
|
package org.jetbrains.kotlin.test.services
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
|
||||||
class JsLibraryProvider(private val testServices: TestServices) : TestService {
|
class JsLibraryProvider(private val testServices: TestServices) : TestService {
|
||||||
private val descriptorToLibrary = mutableMapOf<ModuleDescriptor, KotlinLibrary>()
|
private val descriptorToLibrary = mutableMapOf<ModuleDescriptor, KotlinLibrary>()
|
||||||
private val stdlibPathToDescriptor = mutableMapOf<String, ModuleDescriptorImpl>()
|
private val stdlibPathToDescriptor = mutableMapOf<String, ModuleDescriptor>()
|
||||||
|
|
||||||
fun getDescriptorByPath(path: String): ModuleDescriptorImpl {
|
fun getDescriptorByPath(path: String): ModuleDescriptor {
|
||||||
return stdlibPathToDescriptor[path] ?: testServices.assertions.fail {
|
return stdlibPathToDescriptor[path] ?: testServices.assertions.fail {
|
||||||
"There is no library with path $path"
|
"There is no library with path $path"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDescriptorAndLibraryByName(name: String, descriptor: ModuleDescriptorImpl, library: KotlinLibrary) {
|
fun setDescriptorAndLibraryByName(name: String, descriptor: ModuleDescriptor, library: KotlinLibrary) {
|
||||||
stdlibPathToDescriptor[name] = descriptor
|
stdlibPathToDescriptor[name] = descriptor
|
||||||
descriptorToLibrary[descriptor] = library
|
descriptorToLibrary[descriptor] = library
|
||||||
}
|
}
|
||||||
@@ -40,7 +39,7 @@ class JsLibraryProvider(private val testServices: TestServices) : TestService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOrCreateStdlibByPath(path: String, create: (String) -> Pair<ModuleDescriptorImpl, KotlinLibrary>): ModuleDescriptorImpl {
|
fun getOrCreateStdlibByPath(path: String, create: (String) -> Pair<ModuleDescriptor, KotlinLibrary>): ModuleDescriptor {
|
||||||
return stdlibPathToDescriptor.getOrPut(path) {
|
return stdlibPathToDescriptor.getOrPut(path) {
|
||||||
create(path).let {
|
create(path).let {
|
||||||
descriptorToLibrary += it
|
descriptorToLibrary += it
|
||||||
|
|||||||
+3
-3
@@ -15,9 +15,9 @@ import org.jetbrains.kotlin.test.services.getOrCreateTempDirectory
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IrInterpreterDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
|
class IrInterpreterDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
|
||||||
private fun getDump(): Pair<File, File>? {
|
private fun getDump(module: TestModule): Pair<File, File>? {
|
||||||
val dumpDirectory = testServices.getOrCreateTempDirectory(PhasedIrDumpHandler.DUMPED_IR_FOLDER_NAME)
|
val dumpDirectory = testServices.getOrCreateTempDirectory(PhasedIrDumpHandler.DUMPED_IR_FOLDER_NAME)
|
||||||
val dumpFiles = dumpDirectory.resolve(FirModuleDescriptor.FIR_MODULE_NAME.asString()).listFiles()
|
val dumpFiles = dumpDirectory.resolve(module.name).listFiles()
|
||||||
val before = dumpFiles?.single { it.name.contains(PhasedIrDumpHandler.BEFORE_PREFIX) } ?: return null
|
val before = dumpFiles?.single { it.name.contains(PhasedIrDumpHandler.BEFORE_PREFIX) } ?: return null
|
||||||
val after = dumpFiles.single { it.name.contains(PhasedIrDumpHandler.AFTER_PREFIX) } ?: return null
|
val after = dumpFiles.single { it.name.contains(PhasedIrDumpHandler.AFTER_PREFIX) } ?: return null
|
||||||
return Pair(before, after)
|
return Pair(before, after)
|
||||||
@@ -41,7 +41,7 @@ class IrInterpreterDumpHandler(testServices: TestServices) : JvmBinaryArtifactHa
|
|||||||
|
|
||||||
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
|
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
|
||||||
if (CodegenTestDirectives.DUMP_IR_FOR_GIVEN_PHASES !in module.directives) return
|
if (CodegenTestDirectives.DUMP_IR_FOR_GIVEN_PHASES !in module.directives) return
|
||||||
val (before, after) = getDump() ?: testServices.assertions.fail { "Cannot find BEFORE and AFTER lowering files" }
|
val (before, after) = getDump(module) ?: testServices.assertions.fail { "Cannot find BEFORE and AFTER lowering files" }
|
||||||
|
|
||||||
val beforeText = before.readText()
|
val beforeText = before.readText()
|
||||||
val afterText = after.readText()
|
val afterText = after.readText()
|
||||||
|
|||||||
+10
-8
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.container.get
|
|||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.context.withModule
|
import org.jetbrains.kotlin.context.withModule
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
@@ -93,6 +94,7 @@ class ClassicFrontendFacade(
|
|||||||
val ktFiles = ktFilesMap.values.toList()
|
val ktFiles = ktFilesMap.values.toList()
|
||||||
|
|
||||||
setupJavacIfNeeded(module, ktFiles, configuration)
|
setupJavacIfNeeded(module, ktFiles, configuration)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
val analysisResult = performResolve(
|
val analysisResult = performResolve(
|
||||||
module,
|
module,
|
||||||
project,
|
project,
|
||||||
@@ -100,9 +102,9 @@ class ClassicFrontendFacade(
|
|||||||
packagePartProviderFactory,
|
packagePartProviderFactory,
|
||||||
ktFiles,
|
ktFiles,
|
||||||
compilerEnvironment = multiplatformAnalysisConfiguration.getCompilerEnvironment(module),
|
compilerEnvironment = multiplatformAnalysisConfiguration.getCompilerEnvironment(module),
|
||||||
dependencyDescriptors = multiplatformAnalysisConfiguration.getDependencyDescriptors(module),
|
dependencyDescriptors = multiplatformAnalysisConfiguration.getDependencyDescriptors(module) as List<ModuleDescriptorImpl>,
|
||||||
friendsDescriptors = multiplatformAnalysisConfiguration.getFriendDescriptors(module),
|
friendsDescriptors = multiplatformAnalysisConfiguration.getFriendDescriptors(module) as List<ModuleDescriptorImpl>,
|
||||||
dependsOnDescriptors = multiplatformAnalysisConfiguration.getDependsOnDescriptors(module)
|
dependsOnDescriptors = multiplatformAnalysisConfiguration.getDependsOnDescriptors(module) as List<ModuleDescriptorImpl>
|
||||||
)
|
)
|
||||||
moduleDescriptorProvider.replaceModuleDescriptorForModule(module, analysisResult.moduleDescriptor)
|
moduleDescriptorProvider.replaceModuleDescriptorForModule(module, analysisResult.moduleDescriptor)
|
||||||
return ClassicFrontendOutputArtifact(
|
return ClassicFrontendOutputArtifact(
|
||||||
@@ -251,7 +253,7 @@ class ClassicFrontendFacade(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptorImpl> {
|
private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptor> {
|
||||||
val resolvedLibraries = jsResolveLibraries(
|
val resolvedLibraries = jsResolveLibraries(
|
||||||
names,
|
names,
|
||||||
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||||
@@ -261,8 +263,8 @@ class ClassicFrontendFacade(
|
|||||||
var builtInsModule: KotlinBuiltIns? = null
|
var builtInsModule: KotlinBuiltIns? = null
|
||||||
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
return resolvedLibraries.zip(names).map { (resolvedLibrary, klibPath) ->
|
return resolvedLibraries.map { resolvedLibrary ->
|
||||||
testServices.jsLibraryProvider.getOrCreateStdlibByPath(klibPath) {
|
testServices.jsLibraryProvider.getOrCreateStdlibByPath(resolvedLibrary.library.libraryName) {
|
||||||
val storageManager = LockBasedStorageManager("ModulesStructure")
|
val storageManager = LockBasedStorageManager("ModulesStructure")
|
||||||
val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty()
|
val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty()
|
||||||
|
|
||||||
@@ -290,8 +292,8 @@ class ClassicFrontendFacade(
|
|||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
compilerEnvironment: TargetEnvironment,
|
compilerEnvironment: TargetEnvironment,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
dependencyDescriptors: List<ModuleDescriptorImpl>,
|
dependencyDescriptors: List<ModuleDescriptor>,
|
||||||
friendsDescriptors: List<ModuleDescriptorImpl>,
|
friendsDescriptors: List<ModuleDescriptor>,
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
val runtimeKlibsNames = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
|
val runtimeKlibsNames = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
|
||||||
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration)
|
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration)
|
||||||
|
|||||||
+2
-3
@@ -15,16 +15,15 @@ import org.jetbrains.kotlin.test.model.TestModule
|
|||||||
class ModuleDescriptorProvider(
|
class ModuleDescriptorProvider(
|
||||||
private val testServices: TestServices
|
private val testServices: TestServices
|
||||||
) : TestService {
|
) : TestService {
|
||||||
private val moduleDescriptorByModule = mutableMapOf<TestModule, ModuleDescriptorImpl>()
|
private val moduleDescriptorByModule = mutableMapOf<TestModule, ModuleDescriptor>()
|
||||||
|
|
||||||
fun getModuleDescriptor(testModule: TestModule): ModuleDescriptorImpl {
|
fun getModuleDescriptor(testModule: TestModule): ModuleDescriptor {
|
||||||
return moduleDescriptorByModule[testModule] ?: testServices.assertions.fail {
|
return moduleDescriptorByModule[testModule] ?: testServices.assertions.fail {
|
||||||
"Module descriptor for module ${testModule.name} not found"
|
"Module descriptor for module ${testModule.name} not found"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun replaceModuleDescriptorForModule(testModule: TestModule, moduleDescriptor: ModuleDescriptor) {
|
fun replaceModuleDescriptorForModule(testModule: TestModule, moduleDescriptor: ModuleDescriptor) {
|
||||||
require(moduleDescriptor is ModuleDescriptorImpl)
|
|
||||||
moduleDescriptorByModule[testModule] = moduleDescriptor
|
moduleDescriptorByModule[testModule] = moduleDescriptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -42,9 +42,9 @@ internal fun MultiplatformAnalysisConfiguration(testServices: TestServices): Mul
|
|||||||
internal interface MultiplatformAnalysisConfiguration {
|
internal interface MultiplatformAnalysisConfiguration {
|
||||||
fun getCompilerEnvironment(module: TestModule): TargetEnvironment
|
fun getCompilerEnvironment(module: TestModule): TargetEnvironment
|
||||||
fun getKtFilesForForSourceFiles(project: Project, module: TestModule): Map<TestFile, KtFile>
|
fun getKtFilesForForSourceFiles(project: Project, module: TestModule): Map<TestFile, KtFile>
|
||||||
fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptorImpl>
|
fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptor>
|
||||||
fun getFriendDescriptors(module: TestModule): List<ModuleDescriptorImpl>
|
fun getFriendDescriptors(module: TestModule): List<ModuleDescriptor>
|
||||||
fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptorImpl>
|
fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptor>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,18 +63,18 @@ internal class MultiplatformSeparateAnalysisConfiguration(
|
|||||||
return CompilerEnvironment
|
return CompilerEnvironment
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
return getDescriptors(
|
return getDescriptors(
|
||||||
module.allDependencies - module.dependsOnDependencies.toSet(),
|
module.allDependencies - module.dependsOnDependencies.toSet(),
|
||||||
dependencyProvider, moduleDescriptorProvider
|
dependencyProvider, moduleDescriptorProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFriendDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getFriendDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
return getDescriptors(
|
return getDescriptors(
|
||||||
module.friendDependencies, dependencyProvider, moduleDescriptorProvider
|
module.friendDependencies, dependencyProvider, moduleDescriptorProvider
|
||||||
)
|
)
|
||||||
@@ -121,7 +121,7 @@ internal class MultiplatformCompositeAnalysisConfiguration(
|
|||||||
return sourceFileProvider.getKtFilesForSourceFiles(module.files, project)
|
return sourceFileProvider.getKtFilesForSourceFiles(module.files, project)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getDependencyDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
// Transitive dependsOn descriptors should also be returned as dependencies
|
// Transitive dependsOn descriptors should also be returned as dependencies
|
||||||
val allDependsOnDependencies = module.dependsOnDependencies.closure(preserveOrder = true) { dependsOnDependency ->
|
val allDependsOnDependencies = module.dependsOnDependencies.closure(preserveOrder = true) { dependsOnDependency ->
|
||||||
dependencyProvider.getTestModule(dependsOnDependency.moduleName).dependsOnDependencies
|
dependencyProvider.getTestModule(dependsOnDependency.moduleName).dependsOnDependencies
|
||||||
@@ -130,11 +130,11 @@ internal class MultiplatformCompositeAnalysisConfiguration(
|
|||||||
return getDescriptors(allDependencies, dependencyProvider, moduleDescriptorProvider)
|
return getDescriptors(allDependencies, dependencyProvider, moduleDescriptorProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getDependsOnDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
return getDescriptors(module.dependsOnDependencies, dependencyProvider, moduleDescriptorProvider)
|
return getDescriptors(module.dependsOnDependencies, dependencyProvider, moduleDescriptorProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFriendDescriptors(module: TestModule): List<ModuleDescriptorImpl> {
|
override fun getFriendDescriptors(module: TestModule): List<ModuleDescriptor> {
|
||||||
return getDescriptors(module.friendDependencies, dependencyProvider, moduleDescriptorProvider)
|
return getDescriptors(module.friendDependencies, dependencyProvider, moduleDescriptorProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ private fun getDescriptors(
|
|||||||
dependencies: Iterable<DependencyDescription>,
|
dependencies: Iterable<DependencyDescription>,
|
||||||
dependencyProvider: DependencyProvider,
|
dependencyProvider: DependencyProvider,
|
||||||
moduleDescriptorProvider: ModuleDescriptorProvider
|
moduleDescriptorProvider: ModuleDescriptorProvider
|
||||||
): List<ModuleDescriptorImpl> {
|
): List<ModuleDescriptor> {
|
||||||
return dependencies.filter { it.kind == DependencyKind.Source }
|
return dependencies.filter { it.kind == DependencyKind.Source }
|
||||||
.map { dependencyDescription -> dependencyProvider.getTestModule(dependencyDescription.moduleName) }
|
.map { dependencyDescription -> dependencyProvider.getTestModule(dependencyDescription.moduleName) }
|
||||||
.map { dependencyModule -> moduleDescriptorProvider.getModuleDescriptor(dependencyModule) }
|
.map { dependencyModule -> moduleDescriptorProvider.getModuleDescriptor(dependencyModule) }
|
||||||
|
|||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test.frontend.fir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter
|
||||||
|
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsFactories
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.getSerializedData
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.serializeSingleFirFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
|
import org.jetbrains.kotlin.test.model.BackendKinds
|
||||||
|
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
|
||||||
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||||
|
import org.jetbrains.kotlin.test.services.jsLibraryProvider
|
||||||
|
|
||||||
|
class Fir2IrJsResultsConverter(
|
||||||
|
testServices: TestServices
|
||||||
|
) : Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>(
|
||||||
|
testServices,
|
||||||
|
FrontendKinds.FIR,
|
||||||
|
BackendKinds.IrBackend
|
||||||
|
) {
|
||||||
|
override fun transform(
|
||||||
|
module: TestModule,
|
||||||
|
inputArtifact: FirOutputArtifact
|
||||||
|
): IrBackendInput {
|
||||||
|
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||||
|
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
|
||||||
|
val fir2IrExtensions = Fir2IrExtensions.Default
|
||||||
|
val firFiles = inputArtifact.allFirFiles.values
|
||||||
|
val (irModuleFragment, components) =
|
||||||
|
inputArtifact.firAnalyzerFacade.convertToJsIr(firFiles, fir2IrExtensions, module, configuration, testServices)
|
||||||
|
|
||||||
|
val sourceFiles = firFiles.mapNotNull { it.sourceFile }
|
||||||
|
val firFilesBySourceFile = firFiles.associateBy { it.sourceFile }
|
||||||
|
|
||||||
|
val icData = configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList()
|
||||||
|
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||||
|
val metadataVersion =
|
||||||
|
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
|
||||||
|
?: GenerationState.LANGUAGE_TO_METADATA_VERSION.getValue(module.languageVersionSettings.languageVersion)
|
||||||
|
|
||||||
|
return IrBackendInput.JsIrBackendInput(
|
||||||
|
irModuleFragment,
|
||||||
|
sourceFiles,
|
||||||
|
icData,
|
||||||
|
expectDescriptorToSymbol,
|
||||||
|
hasErrors = false // TODO: implement error check
|
||||||
|
) { file ->
|
||||||
|
val firFile = firFilesBySourceFile[file] ?: error("cannot find FIR file by source file ${file.name} (${file.path})")
|
||||||
|
serializeSingleFirFile(firFile, components.session, components.scopeSession, metadataVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AbstractFirAnalyzerFacade.convertToJsIr(
|
||||||
|
firFiles: Collection<FirFile>,
|
||||||
|
fir2IrExtensions: Fir2IrExtensions,
|
||||||
|
module: TestModule,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
testServices: TestServices
|
||||||
|
): Fir2IrResult {
|
||||||
|
this as FirAnalyzerFacade
|
||||||
|
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
||||||
|
val commonFirFiles = session.moduleData.dependsOnDependencies
|
||||||
|
.map { it.session }
|
||||||
|
.filter { it.kind == FirSession.Kind.Source }
|
||||||
|
.flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() }
|
||||||
|
|
||||||
|
// TODO: consider avoiding repeated libraries resolution
|
||||||
|
val libraries = resolveJsLibraries(module, testServices, configuration)
|
||||||
|
val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
|
||||||
|
|
||||||
|
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
|
||||||
|
session, scopeSession, firFiles + commonFirFiles,
|
||||||
|
languageVersionSettings, signaturer,
|
||||||
|
fir2IrExtensions,
|
||||||
|
FirJvmKotlinMangler(session), // TODO: replace with potentially simpler JS version
|
||||||
|
JsManglerIr, IrFactoryImpl,
|
||||||
|
Fir2IrVisibilityConverter.Default,
|
||||||
|
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO: replace with appropriate (probably empty) implementation
|
||||||
|
irGeneratorExtensions,
|
||||||
|
generateSignatures = false,
|
||||||
|
kotlinBuiltIns = builtIns ?: DefaultBuiltIns.Instance // TODO: consider passing externally
|
||||||
|
).also {
|
||||||
|
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadResolvedLibraries(
|
||||||
|
resolvedLibraries: List<KotlinResolvedLibrary>,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
testServices: TestServices
|
||||||
|
): Pair<List<ModuleDescriptor>, KotlinBuiltIns?> {
|
||||||
|
var builtInsModule: KotlinBuiltIns? = null
|
||||||
|
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
|
return resolvedLibraries.map { resolvedLibrary ->
|
||||||
|
// resolvedLibrary.library.libraryName in fact resolves to (modified) file path, which is confising and maybe should be refactored
|
||||||
|
testServices.jsLibraryProvider.getOrCreateStdlibByPath(resolvedLibrary.library.libraryName) {
|
||||||
|
// TODO: check safety of the approach of creating a separate storage manager per library
|
||||||
|
val storageManager = LockBasedStorageManager("ModulesStructure")
|
||||||
|
|
||||||
|
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
|
resolvedLibrary.library,
|
||||||
|
languageVersionSettings,
|
||||||
|
storageManager,
|
||||||
|
builtInsModule,
|
||||||
|
packageAccessHandler = null,
|
||||||
|
lookupTracker = LookupTracker.DO_NOTHING
|
||||||
|
)
|
||||||
|
dependencies += moduleDescriptor
|
||||||
|
moduleDescriptor.setDependencies(ArrayList(dependencies))
|
||||||
|
|
||||||
|
Pair(moduleDescriptor, resolvedLibrary.library)
|
||||||
|
}.also {
|
||||||
|
val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty()
|
||||||
|
if (isBuiltIns) builtInsModule = it.builtIns
|
||||||
|
}
|
||||||
|
} to builtInsModule
|
||||||
|
}
|
||||||
+4
-2
@@ -83,7 +83,9 @@ class FirFrontendFacade(
|
|||||||
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
|
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleName = Name.identifier(module.name)
|
// the special name is required for `KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns`
|
||||||
|
// it doesn't seem convincingly legitimate, probably should be refactored
|
||||||
|
val moduleName = Name.special("<${module.name}>")
|
||||||
val languageVersionSettings = module.languageVersionSettings
|
val languageVersionSettings = module.languageVersionSettings
|
||||||
val analyzerServices = module.targetPlatform.getAnalyzerServices()
|
val analyzerServices = module.targetPlatform.getAnalyzerServices()
|
||||||
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
@@ -249,7 +251,7 @@ private fun getJsDependencies(module: TestModule, testServices: TestServices): T
|
|||||||
return Triple(runtimeKlibsPaths, transitiveLibraries, friendLibraries)
|
return Triple(runtimeKlibsPaths, transitiveLibraries, friendLibraries)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
|
fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
|
||||||
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
||||||
return runtimeKlibsPaths + transitiveLibraries.map { it.path } + friendLibraries.map { it.path }
|
return runtimeKlibsPaths + transitiveLibraries.map { it.path } + friendLibraries.map { it.path }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
|
|||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.LanguageVersion
|
import org.jetbrains.kotlin.config.LanguageVersion
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||||
import org.jetbrains.kotlin.js.config.*
|
import org.jetbrains.kotlin.js.config.*
|
||||||
@@ -155,7 +156,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
ConfigurationDirectives.WITH_STDLIB in module.directives
|
ConfigurationDirectives.WITH_STDLIB in module.directives
|
||||||
|
|
||||||
val names = if (needsFullIrRuntime) listOf("full.stdlib", "kotlin.test") else listOf("reduced.stdlib")
|
val names = if (needsFullIrRuntime) listOf("full.stdlib", "kotlin.test") else listOf("reduced.stdlib")
|
||||||
names.mapNotNullTo(result) { System.getProperty("kotlin.js.$it.path") }
|
names.mapNotNullTo(result) { System.getProperty("kotlin.js.$it.path")?.let { File(it).absolutePath } }
|
||||||
val runtimeClasspaths = testServices.runtimeClasspathProviders.flatMap { it.runtimeClassPaths(module) }
|
val runtimeClasspaths = testServices.runtimeClasspathProviders.flatMap { it.runtimeClassPaths(module) }
|
||||||
runtimeClasspaths.mapTo(result) { it.absolutePath }
|
runtimeClasspaths.mapTo(result) { it.absolutePath }
|
||||||
return result
|
return result
|
||||||
@@ -176,7 +177,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
return visited.map { testServices.dependencyProvider.getArtifact(it, ArtifactKinds.KLib).outputFile }
|
return visited.map { testServices.dependencyProvider.getArtifact(it, ArtifactKinds.KLib).outputFile }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List<ModuleDescriptorImpl> {
|
fun getDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List<ModuleDescriptor> {
|
||||||
return getKlibDependencies(module, testServices, kind)
|
return getKlibDependencies(module, testServices, kind)
|
||||||
.map { testServices.jsLibraryProvider.getDescriptorByPath(it.absolutePath) }
|
.map { testServices.jsLibraryProvider.getDescriptorByPath(it.absolutePath) }
|
||||||
}
|
}
|
||||||
@@ -190,7 +191,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
|
|
||||||
fun getAllRecursiveDependenciesFor(module: TestModule, testServices: TestServices): Set<ModuleDescriptorImpl> {
|
fun getAllRecursiveDependenciesFor(module: TestModule, testServices: TestServices): Set<ModuleDescriptorImpl> {
|
||||||
val visited = mutableSetOf<ModuleDescriptorImpl>()
|
val visited = mutableSetOf<ModuleDescriptorImpl>()
|
||||||
fun getRecursive(descriptor: ModuleDescriptorImpl) {
|
fun getRecursive(descriptor: ModuleDescriptor) {
|
||||||
descriptor.allDependencyModules.forEach {
|
descriptor.allDependencyModules.forEach {
|
||||||
if (it is ModuleDescriptorImpl && it !in visited) {
|
if (it is ModuleDescriptorImpl && it !in visited) {
|
||||||
visited += it
|
visited += it
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ object ReflectionBasedTargetBackendComputer : TargetBackendComputer {
|
|||||||
}
|
}
|
||||||
require(testKClass.isOpen) {
|
require(testKClass.isOpen) {
|
||||||
"""
|
"""
|
||||||
Test runner which inherits from ${runnerMarkerKClass.simpleName} and used as base class
|
Test runner ${testKClass.simpleName} which inherits from ${runnerMarkerKClass.simpleName} and used as base class
|
||||||
for real test should have `open` modality
|
for real test should have `open` modality
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.container.get
|
|||||||
import org.jetbrains.kotlin.context.ContextForNewModule
|
import org.jetbrains.kotlin.context.ContextForNewModule
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.frontend.js.di.createContainerForJS
|
import org.jetbrains.kotlin.frontend.js.di.createContainerForJS
|
||||||
@@ -44,6 +45,7 @@ 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.serialization.js.PackagesWithHeaderMetadata
|
import org.jetbrains.kotlin.serialization.js.PackagesWithHeaderMetadata
|
||||||
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
abstract class AbstractTopDownAnalyzerFacadeForJS {
|
abstract class AbstractTopDownAnalyzerFacadeForJS {
|
||||||
|
|
||||||
@@ -51,11 +53,11 @@ abstract class AbstractTopDownAnalyzerFacadeForJS {
|
|||||||
files: Collection<KtFile>,
|
files: Collection<KtFile>,
|
||||||
project: Project,
|
project: Project,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
moduleDescriptors: List<ModuleDescriptorImpl>,
|
moduleDescriptors: List<ModuleDescriptor>,
|
||||||
friendModuleDescriptors: List<ModuleDescriptorImpl>,
|
friendModuleDescriptors: List<ModuleDescriptor>,
|
||||||
targetEnvironment: TargetEnvironment,
|
targetEnvironment: TargetEnvironment,
|
||||||
thisIsBuiltInsModule: Boolean = false,
|
thisIsBuiltInsModule: Boolean = false,
|
||||||
customBuiltInsModule: ModuleDescriptorImpl? = null
|
customBuiltInsModule: ModuleDescriptor? = null
|
||||||
): JsAnalysisResult {
|
): JsAnalysisResult {
|
||||||
require(!thisIsBuiltInsModule || customBuiltInsModule == null) {
|
require(!thisIsBuiltInsModule || customBuiltInsModule == null) {
|
||||||
"Can't simultaneously use custom built-ins module and set current module as built-ins"
|
"Can't simultaneously use custom built-ins module and set current module as built-ins"
|
||||||
@@ -83,7 +85,8 @@ abstract class AbstractTopDownAnalyzerFacadeForJS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val dependencies = mutableSetOf(context.module) + moduleDescriptors + builtIns.builtInsModule
|
val dependencies = mutableSetOf(context.module) + moduleDescriptors + builtIns.builtInsModule
|
||||||
context.module.setDependencies(dependencies.toList(), friendModuleDescriptors.toSet())
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
context.module.setDependencies(dependencies.toList() as List<ModuleDescriptorImpl>, friendModuleDescriptors.toSet() as Set<ModuleDescriptorImpl>)
|
||||||
|
|
||||||
val moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
val moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,12 @@ import org.jetbrains.kotlin.platform.js.JsPlatforms
|
|||||||
import org.jetbrains.kotlin.test.Constructor
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.*
|
||||||
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
|
|
||||||
import org.jetbrains.kotlin.test.builders.irHandlersStep
|
|
||||||
import org.jetbrains.kotlin.test.builders.jsArtifactsHandlersStep
|
|
||||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
|
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
|
||||||
import org.jetbrains.kotlin.test.model.*
|
import org.jetbrains.kotlin.test.model.*
|
||||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.commonClassicFrontendHandlersForCodegenTest
|
import org.jetbrains.kotlin.test.runners.codegen.commonClassicFrontendHandlersForCodegenTest
|
||||||
@@ -105,6 +103,10 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
|
|||||||
useHandlers(::ClassicDiagnosticsHandler)
|
useHandlers(::ClassicDiagnosticsHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firHandlersStep {
|
||||||
|
useHandlers(::FirDiagnosticsHandler)
|
||||||
|
}
|
||||||
|
|
||||||
facadeStep(frontendToBackendConverter)
|
facadeStep(frontendToBackendConverter)
|
||||||
irHandlersStep()
|
irHandlersStep()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.js.test.converters
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||||
|
import org.jetbrains.kotlin.js.test.utils.JsIrIncrementalDataProvider
|
||||||
|
import org.jetbrains.kotlin.js.test.utils.jsIrIncrementalDataProvider
|
||||||
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendFacade
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ModuleDescriptorProvider
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.getAllJsDependenciesPaths
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.resolveJsLibraries
|
||||||
|
import org.jetbrains.kotlin.test.model.ArtifactKinds
|
||||||
|
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
import org.jetbrains.kotlin.test.services.*
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class FirJsKlibBackendFacade(
|
||||||
|
testServices: TestServices,
|
||||||
|
private val firstTimeCompilation: Boolean
|
||||||
|
) : IrBackendFacade<BinaryArtifacts.KLib>(testServices, ArtifactKinds.KLib) {
|
||||||
|
|
||||||
|
override val additionalServices: List<ServiceRegistrationData>
|
||||||
|
get() = listOf(service(::JsIrIncrementalDataProvider), service(::ModuleDescriptorProvider))
|
||||||
|
|
||||||
|
constructor(testServices: TestServices): this(testServices, firstTimeCompilation = true)
|
||||||
|
|
||||||
|
override fun shouldRunAnalysis(module: TestModule): Boolean {
|
||||||
|
return module.backendKind == inputKind
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transform(module: TestModule, inputArtifact: IrBackendInput): BinaryArtifacts.KLib {
|
||||||
|
require(inputArtifact is IrBackendInput.JsIrBackendInput) {
|
||||||
|
"JsKlibBackendFacade expects IrBackendInput.JsIrBackendInput as input"
|
||||||
|
}
|
||||||
|
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val outputFile = JsEnvironmentConfigurator.getJsKlibArtifactPath(testServices, module.name)
|
||||||
|
|
||||||
|
// TODO: consider avoiding repeated libraries resolution
|
||||||
|
val libraries = resolveJsLibraries(module, testServices, configuration)
|
||||||
|
|
||||||
|
if (firstTimeCompilation) {
|
||||||
|
serializeModuleIntoKlib(
|
||||||
|
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
||||||
|
configuration,
|
||||||
|
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
|
||||||
|
inputArtifact.sourceFiles,
|
||||||
|
klibPath = outputFile,
|
||||||
|
libraries.map { it.library },
|
||||||
|
inputArtifact.irModuleFragment,
|
||||||
|
inputArtifact.expectDescriptorToSymbol,
|
||||||
|
cleanFiles = inputArtifact.icData,
|
||||||
|
nopack = true,
|
||||||
|
perFile = false,
|
||||||
|
containsErrorCode = inputArtifact.hasErrors,
|
||||||
|
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
|
||||||
|
jsOutputName = null,
|
||||||
|
inputArtifact.serializeSingleFile
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: consider avoiding repeated libraries resolution
|
||||||
|
val lib = jsResolveLibraries(
|
||||||
|
getAllJsDependenciesPaths(module, testServices) + listOf(outputFile),
|
||||||
|
emptyList(),
|
||||||
|
configuration.resolverLogger
|
||||||
|
).getFullResolvedList().last().library
|
||||||
|
|
||||||
|
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
|
lib,
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
LockBasedStorageManager("ModulesStructure"),
|
||||||
|
inputArtifact.irModuleFragment.descriptor.builtIns,
|
||||||
|
packageAccessHandler = null,
|
||||||
|
lookupTracker = LookupTracker.DO_NOTHING
|
||||||
|
)
|
||||||
|
// TODO: find out why it must be so weird
|
||||||
|
moduleDescriptor.safeAs<ModuleDescriptorImpl>()?.let {
|
||||||
|
it.setDependencies(inputArtifact.irModuleFragment.descriptor.allDependencyModules.filterIsInstance<ModuleDescriptorImpl>() + it)
|
||||||
|
}
|
||||||
|
|
||||||
|
testServices.moduleDescriptorProvider.replaceModuleDescriptorForModule(module, moduleDescriptor)
|
||||||
|
if (JsEnvironmentConfigurator.incrementalEnabled(testServices)) {
|
||||||
|
testServices.jsIrIncrementalDataProvider.recordIncrementalData(module, lib)
|
||||||
|
}
|
||||||
|
testServices.jsLibraryProvider.setDescriptorAndLibraryByName(outputFile, moduleDescriptor, lib)
|
||||||
|
|
||||||
|
return BinaryArtifacts.KLib(File(outputFile))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.js.test.ir
|
package org.jetbrains.kotlin.js.test.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.test.AbstractJsBlackBoxCodegenTestBase
|
import org.jetbrains.kotlin.js.test.AbstractJsBlackBoxCodegenTestBase
|
||||||
|
import org.jetbrains.kotlin.js.test.converters.FirJsKlibBackendFacade
|
||||||
import org.jetbrains.kotlin.js.test.JsSteppingTestAdditionalSourceProvider
|
import org.jetbrains.kotlin.js.test.JsSteppingTestAdditionalSourceProvider
|
||||||
import org.jetbrains.kotlin.js.test.converters.JsIrBackendFacade
|
import org.jetbrains.kotlin.js.test.converters.JsIrBackendFacade
|
||||||
import org.jetbrains.kotlin.js.test.converters.JsKlibBackendFacade
|
import org.jetbrains.kotlin.js.test.converters.JsKlibBackendFacade
|
||||||
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.test.directives.*
|
|||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrJsResultsConverter
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
|
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
||||||
@@ -186,7 +188,7 @@ private class SkipMultiModuleTestsMetaConfigurator(testServices: TestServices) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractFirJsTest(
|
open class AbstractFirJsTest(
|
||||||
pathToTestDir: String = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/box/",
|
pathToTestDir: String = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/box/",
|
||||||
testGroupOutputDirPrefix: String = "box/",
|
testGroupOutputDirPrefix: String = "box/",
|
||||||
) : AbstractJsBlackBoxCodegenTestBase<FirOutputArtifact, IrBackendInput, BinaryArtifacts.KLib>(
|
) : AbstractJsBlackBoxCodegenTestBase<FirOutputArtifact, IrBackendInput, BinaryArtifacts.KLib>(
|
||||||
@@ -196,10 +198,10 @@ abstract class AbstractFirJsTest(
|
|||||||
get() = ::FirFrontendFacade
|
get() = ::FirFrontendFacade
|
||||||
|
|
||||||
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
|
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
|
||||||
get() = ::Fir2IrResultsConverter
|
get() = ::Fir2IrJsResultsConverter
|
||||||
|
|
||||||
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.KLib>>
|
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.KLib>>
|
||||||
get() = ::JsKlibBackendFacade
|
get() = ::FirJsKlibBackendFacade
|
||||||
|
|
||||||
override val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.KLib, BinaryArtifacts.Js>>?
|
override val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.KLib, BinaryArtifacts.Js>>?
|
||||||
get() = ::JsIrBackendFacade
|
get() = ::JsIrBackendFacade
|
||||||
@@ -213,8 +215,6 @@ abstract class AbstractFirJsTest(
|
|||||||
super.configure(builder)
|
super.configure(builder)
|
||||||
with (builder) {
|
with (builder) {
|
||||||
defaultDirectives {
|
defaultDirectives {
|
||||||
+ConfigurationDirectives.WITH_STDLIB
|
|
||||||
+LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE
|
|
||||||
val runIc = getBoolean("kotlin.js.ir.icMode")
|
val runIc = getBoolean("kotlin.js.ir.icMode")
|
||||||
if (runIc) +JsEnvironmentConfigurationDirectives.RUN_IC
|
if (runIc) +JsEnvironmentConfigurationDirectives.RUN_IC
|
||||||
if (getBoolean("kotlin.js.ir.klibMainModule")) +JsEnvironmentConfigurationDirectives.KLIB_MAIN_MODULE
|
if (getBoolean("kotlin.js.ir.klibMainModule")) +JsEnvironmentConfigurationDirectives.KLIB_MAIN_MODULE
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// IGNORE_FIR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1253
|
// EXPECTED_REACHABLE_NODES: 1253
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
|
// NO_COMMON_FILES
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
interface II {
|
interface II {
|
||||||
companion object : DDD by error("OK")
|
companion object : DDD by error("OK")
|
||||||
@@ -11,6 +11,7 @@ interface DDD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MODULE: main(lib)
|
// MODULE: main(lib)
|
||||||
|
// NO_COMMON_FILES
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun box() : String {
|
fun box() : String {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user