[FIR JS] Prepare the infrastructure for FIR JS tests
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.fir.session
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||
|
||||
class KlibBasedAnnotationDeserializer(
|
||||
session: FirSession
|
||||
) : AbstractAnnotationDeserializer(session) {
|
||||
override val protocol: SerializerExtensionProtocol
|
||||
get() = KlibMetadataSerializerProtocol
|
||||
|
||||
override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotation> {
|
||||
val annotations = typeProto.getExtension(KlibMetadataProtoBuf.typeAnnotation).orEmpty()
|
||||
return annotations.map { deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.fir.session
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.deserialization.*
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataClassDataFinder
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import java.nio.file.Paths
|
||||
|
||||
class KlibBasedSymbolProvider(
|
||||
session: FirSession,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
private val resolvedLibrary: KotlinResolvedLibrary,
|
||||
defaultDeserializationOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library
|
||||
) : AbstractFirDeserializedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, defaultDeserializationOrigin) {
|
||||
private val moduleHeader by lazy {
|
||||
resolvedLibrary.loadModuleHeader(resolvedLibrary.library)
|
||||
}
|
||||
|
||||
private val fragmentNameList by lazy {
|
||||
moduleHeader.packageFragmentNameList.toSet()
|
||||
}
|
||||
|
||||
private val annotationDeserializer = KlibBasedAnnotationDeserializer(session)
|
||||
private val constDeserializer = FirConstDeserializer(session)
|
||||
private val deserializationConfiguration = CompilerDeserializationConfiguration(session.languageVersionSettings)
|
||||
private val cachedFragments = mutableMapOf<Pair<String, String>, ProtoBuf.PackageFragment>()
|
||||
|
||||
private fun getPackageFragment(packageStringName: String, packageMetadataPart: String): ProtoBuf.PackageFragment {
|
||||
return cachedFragments.getOrPut(packageStringName to packageMetadataPart) {
|
||||
resolvedLibrary.loadPackageFragment(resolvedLibrary.library, packageStringName, packageMetadataPart)
|
||||
}
|
||||
}
|
||||
|
||||
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
|
||||
val packageStringName = packageFqName.asString()
|
||||
|
||||
if (packageStringName !in fragmentNameList) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return resolvedLibrary.library.packageMetadataParts(packageStringName).mapNotNull {
|
||||
val fragment = getPackageFragment(packageStringName, it)
|
||||
|
||||
val libraryPath = Paths.get(resolvedLibrary.library.libraryName)
|
||||
val moduleData = moduleDataProvider.getModuleData(libraryPath) ?: return@mapNotNull null
|
||||
val packageProto = fragment.`package`
|
||||
|
||||
val nameResolver = NameResolverImpl(
|
||||
fragment.strings,
|
||||
fragment.qualifiedNames,
|
||||
)
|
||||
|
||||
PackagePartsCacheData(
|
||||
packageProto,
|
||||
FirDeserializationContext.createForPackage(
|
||||
packageFqName, packageProto, nameResolver, moduleData,
|
||||
annotationDeserializer,
|
||||
constDeserializer,
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
|
||||
val packageStringName = classId.packageFqName.asString()
|
||||
|
||||
if (packageStringName !in fragmentNameList) {
|
||||
return null
|
||||
}
|
||||
|
||||
resolvedLibrary.library.packageMetadataParts(packageStringName).forEach {
|
||||
val libraryPath = Paths.get(resolvedLibrary.library.libraryName)
|
||||
val fragment = getPackageFragment(packageStringName, it)
|
||||
|
||||
val nameResolver = NameResolverImpl(
|
||||
fragment.strings,
|
||||
fragment.qualifiedNames,
|
||||
)
|
||||
|
||||
val finder = KlibMetadataClassDataFinder(fragment, nameResolver)
|
||||
val classProto = finder.findClassData(classId)?.classProto ?: return@forEach
|
||||
|
||||
val source = object : DeserializedContainerSource {
|
||||
override val incompatibility: IncompatibleVersionErrorData<*>? = null
|
||||
override val isPreReleaseInvisible =
|
||||
deserializationConfiguration.reportErrorsOnPreReleaseDependencies && (moduleHeader.flags and 1) != 0
|
||||
override val abiStability = DeserializedContainerAbiStability.STABLE
|
||||
override val presentableString = "Package '${classId.packageFqName}'"
|
||||
|
||||
override fun getContainingFile() = SourceFile.NO_SOURCE_FILE
|
||||
}
|
||||
|
||||
return ClassMetadataFindResult.Metadata(
|
||||
nameResolver,
|
||||
classProto,
|
||||
annotationDeserializer,
|
||||
moduleDataProvider.getModuleData(libraryPath),
|
||||
source,
|
||||
classPostProcessor = {}
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isNewPlaceForBodyGeneration(classProto: ProtoBuf.Class) = false
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? {
|
||||
return if (fqName.toString() in fragmentNameList) {
|
||||
fqName
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||
@@ -44,7 +45,8 @@ import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
abstract class AbstractAnnotationDeserializer(
|
||||
private val session: FirSession
|
||||
) {
|
||||
protected val protocol = BuiltInSerializerProtocol
|
||||
protected open val protocol: SerializerExtensionProtocol
|
||||
get() = BuiltInSerializerProtocol
|
||||
|
||||
open fun inheritAnnotationInfo(parent: AbstractAnnotationDeserializer) {
|
||||
}
|
||||
|
||||
+269
-34
@@ -5,9 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.frontend.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
@@ -17,13 +19,22 @@ import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
@@ -36,10 +47,14 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.DependencyRelation
|
||||
import org.jetbrains.kotlin.test.model.FrontendFacade
|
||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
class FirFrontendFacade(
|
||||
testServices: TestServices,
|
||||
@@ -72,48 +87,51 @@ class FirFrontendFacade(
|
||||
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
|
||||
}
|
||||
|
||||
val moduleName = Name.identifier(module.name)
|
||||
val languageVersionSettings = module.languageVersionSettings
|
||||
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
||||
|
||||
val analyzerServices = module.targetPlatform.getAnalyzerServices()
|
||||
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||
val extensionRegistrars = FirExtensionRegistrar.getInstances(project)
|
||||
|
||||
val librariesScope = ProjectScope.getLibrariesScope(project)
|
||||
val sourcesScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
|
||||
|
||||
val session = FirSessionFactory.createSessionWithDependencies(
|
||||
Name.identifier(module.name),
|
||||
module.targetPlatform,
|
||||
module.targetPlatform.getAnalyzerServices(),
|
||||
moduleInfoProvider.firSessionProvider,
|
||||
VfsBasedProjectEnvironment(
|
||||
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
|
||||
{ packagePartProviderFactory.invoke(it) }
|
||||
),
|
||||
languageVersionSettings,
|
||||
PsiBasedProjectFileSearchScope(sourcesScope),
|
||||
PsiBasedProjectFileSearchScope(librariesScope),
|
||||
lookupTracker = null,
|
||||
enumWhenTracker = null,
|
||||
incrementalCompilationContext = null,
|
||||
extensionRegistrars = FirExtensionRegistrar.getInstances(project),
|
||||
needRegisterJavaElementFinder = true,
|
||||
dependenciesConfigurator = {
|
||||
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
||||
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
||||
|
||||
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||
|
||||
sourceDependencies(moduleInfoProvider.getRegularDependentSourceModules(module))
|
||||
sourceFriendsDependencies(moduleInfoProvider.getDependentFriendSourceModules(module))
|
||||
sourceDependsOnDependencies(moduleInfoProvider.getDependentDependsOnSourceModules(module))
|
||||
}
|
||||
) {
|
||||
val sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {
|
||||
if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
|
||||
registerExtendedCommonCheckers()
|
||||
}
|
||||
additionalSessionConfiguration?.invoke(this)
|
||||
}
|
||||
|
||||
val session = when {
|
||||
module.targetPlatform.isJvm() || module.targetPlatform.isCommon() -> {
|
||||
configureSessionsForJvmOrCommon(
|
||||
module,
|
||||
moduleName,
|
||||
project,
|
||||
ktFiles,
|
||||
compilerConfigurationProvider,
|
||||
moduleInfoProvider,
|
||||
analyzerServices,
|
||||
configuration,
|
||||
sessionConfigurator,
|
||||
extensionRegistrars,
|
||||
languageVersionSettings,
|
||||
)
|
||||
}
|
||||
module.targetPlatform.isJs() -> {
|
||||
configureSessionsForJs(
|
||||
module,
|
||||
moduleName,
|
||||
moduleInfoProvider,
|
||||
analyzerServices,
|
||||
configuration,
|
||||
testServices,
|
||||
sessionConfigurator,
|
||||
extensionRegistrars,
|
||||
languageVersionSettings,
|
||||
)
|
||||
}
|
||||
else -> error("Unsupported")
|
||||
}
|
||||
|
||||
moduleInfoProvider.registerModuleData(module, session.moduleData)
|
||||
|
||||
val enablePluginPhases = FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES in module.directives
|
||||
@@ -136,6 +154,223 @@ class FirFrontendFacade(
|
||||
}
|
||||
}
|
||||
|
||||
private fun DependencyListForCliModule.Builder.configureJvmDependencies(
|
||||
configuration: CompilerConfiguration,
|
||||
) {
|
||||
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
||||
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
||||
|
||||
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||
}
|
||||
|
||||
private fun DependencyListForCliModule.Builder.configureJsDependencies(
|
||||
module: TestModule,
|
||||
testServices: TestServices,
|
||||
) {
|
||||
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
||||
|
||||
dependencies(runtimeKlibsPaths.map { Paths.get(it).toAbsolutePath() })
|
||||
dependencies(transitiveLibraries.map { it.toPath().toAbsolutePath() })
|
||||
|
||||
friendDependencies(friendLibraries.map { it.toPath().toAbsolutePath() })
|
||||
}
|
||||
|
||||
private fun getJsDependencies(module: TestModule, testServices: TestServices): Triple<List<String>, List<File>, List<File>> {
|
||||
val runtimeKlibsPaths = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
|
||||
val transitiveLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.RegularDependency)
|
||||
val friendLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.FriendDependency)
|
||||
return Triple(runtimeKlibsPaths, transitiveLibraries, friendLibraries)
|
||||
}
|
||||
|
||||
private fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
|
||||
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
||||
return runtimeKlibsPaths + transitiveLibraries.map { it.path } + friendLibraries.map { it.path }
|
||||
}
|
||||
|
||||
fun resolveJsLibraries(
|
||||
module: TestModule,
|
||||
testServices: TestServices,
|
||||
configuration: CompilerConfiguration
|
||||
): List<KotlinResolvedLibrary> {
|
||||
val paths = getAllJsDependenciesPaths(module, testServices)
|
||||
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
|
||||
val logger = configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList()
|
||||
}
|
||||
|
||||
private fun buildDependencyList(
|
||||
module: TestModule,
|
||||
moduleName: Name,
|
||||
moduleInfoProvider: FirModuleInfoProvider,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
configureDependencies: DependencyListForCliModule.Builder.() -> Unit,
|
||||
) = DependencyListForCliModule.build(moduleName, module.targetPlatform, analyzerServices) {
|
||||
configureDependencies()
|
||||
sourceDependencies(moduleInfoProvider.getRegularDependentSourceModules(module))
|
||||
sourceFriendsDependencies(moduleInfoProvider.getDependentFriendSourceModules(module))
|
||||
sourceDependsOnDependencies(moduleInfoProvider.getDependentDependsOnSourceModules(module))
|
||||
}
|
||||
|
||||
private fun configureSessionsForJvmOrCommon(
|
||||
module: TestModule,
|
||||
moduleName: Name,
|
||||
project: Project,
|
||||
ktFiles: Collection<KtFile>,
|
||||
compilerConfigurationProvider: CompilerConfigurationProvider,
|
||||
moduleInfoProvider: FirModuleInfoProvider,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
configuration: CompilerConfiguration,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||
extensionRegistrars: List<FirExtensionRegistrar>,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
val librariesScope = ProjectScope.getLibrariesScope(project)
|
||||
val sourcesScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
|
||||
|
||||
val dependencyList = buildDependencyList(module, moduleName, moduleInfoProvider, analyzerServices) {
|
||||
configureJvmDependencies(configuration)
|
||||
}
|
||||
|
||||
configureLibrarySessionForJvmOrCommon(
|
||||
module,
|
||||
moduleName,
|
||||
moduleInfoProvider.firSessionProvider,
|
||||
dependencyList,
|
||||
librariesScope,
|
||||
project,
|
||||
compilerConfigurationProvider,
|
||||
languageVersionSettings,
|
||||
)
|
||||
|
||||
val mainModuleData = FirModuleDataImpl(
|
||||
moduleName,
|
||||
dependencyList.regularDependencies,
|
||||
dependencyList.dependsOnDependencies,
|
||||
dependencyList.friendsDependencies,
|
||||
dependencyList.platform,
|
||||
dependencyList.analyzerServices
|
||||
)
|
||||
|
||||
return configureMainSessionForJvmOrCommon(
|
||||
module,
|
||||
project,
|
||||
compilerConfigurationProvider,
|
||||
sessionConfigurator,
|
||||
extensionRegistrars,
|
||||
sourcesScope,
|
||||
mainModuleData,
|
||||
moduleInfoProvider.firSessionProvider,
|
||||
languageVersionSettings,
|
||||
)
|
||||
}
|
||||
|
||||
private fun configureLibrarySessionForJvmOrCommon(
|
||||
module: TestModule,
|
||||
moduleName: Name,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
dependencyList: DependencyListForCliModule,
|
||||
librariesScope: GlobalSearchScope,
|
||||
project: Project,
|
||||
compilerConfigurationProvider: CompilerConfigurationProvider,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
||||
|
||||
val projectEnvironment = VfsBasedProjectEnvironment(
|
||||
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
|
||||
) { packagePartProviderFactory.invoke(it) }
|
||||
|
||||
val projectFileSearchScope = PsiBasedProjectFileSearchScope(librariesScope)
|
||||
|
||||
return FirSessionFactory.createLibrarySession(
|
||||
moduleName,
|
||||
sessionProvider,
|
||||
dependencyList.moduleDataProvider,
|
||||
projectFileSearchScope,
|
||||
projectEnvironment,
|
||||
projectEnvironment.getPackagePartProvider(projectFileSearchScope),
|
||||
languageVersionSettings,
|
||||
)
|
||||
}
|
||||
|
||||
private fun configureMainSessionForJvmOrCommon(
|
||||
module: TestModule,
|
||||
project: Project,
|
||||
compilerConfigurationProvider: CompilerConfigurationProvider,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||
extensionRegistrars: List<FirExtensionRegistrar>,
|
||||
sourcesScope: GlobalSearchScope,
|
||||
mainModuleData: FirModuleData,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
||||
|
||||
val projectEnvironment = VfsBasedProjectEnvironment(
|
||||
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
|
||||
) { packagePartProviderFactory.invoke(it) }
|
||||
|
||||
val projectFileSearchScope = PsiBasedProjectFileSearchScope(sourcesScope)
|
||||
|
||||
return FirSessionFactory.createJavaModuleBasedSession(
|
||||
mainModuleData,
|
||||
sessionProvider,
|
||||
projectFileSearchScope,
|
||||
projectEnvironment,
|
||||
incrementalCompilationContext = null,
|
||||
extensionRegistrars,
|
||||
languageVersionSettings,
|
||||
lookupTracker = null,
|
||||
enumWhenTracker = null,
|
||||
needRegisterJavaElementFinder = true,
|
||||
sessionConfigurator,
|
||||
)
|
||||
}
|
||||
|
||||
private fun configureSessionsForJs(
|
||||
module: TestModule,
|
||||
moduleName: Name,
|
||||
moduleInfoProvider: FirModuleInfoProvider,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
configuration: CompilerConfiguration,
|
||||
testServices: TestServices,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||
extensionRegistrars: List<FirExtensionRegistrar>,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
val dependencyList = buildDependencyList(module, moduleName, moduleInfoProvider, analyzerServices) {
|
||||
configureJsDependencies(module, testServices)
|
||||
}
|
||||
|
||||
FirJsSessionFactory.createJsLibrarySession(
|
||||
moduleName,
|
||||
module,
|
||||
testServices,
|
||||
configuration,
|
||||
moduleInfoProvider.firSessionProvider,
|
||||
dependencyList.moduleDataProvider,
|
||||
languageVersionSettings,
|
||||
)
|
||||
|
||||
val mainModuleData = FirModuleDataImpl(
|
||||
moduleName,
|
||||
dependencyList.regularDependencies,
|
||||
dependencyList.dependsOnDependencies,
|
||||
dependencyList.friendsDependencies,
|
||||
dependencyList.platform,
|
||||
dependencyList.analyzerServices
|
||||
)
|
||||
|
||||
return FirJsSessionFactory.createJsModuleBasedSession(
|
||||
mainModuleData,
|
||||
moduleInfoProvider.firSessionProvider,
|
||||
extensionRegistrars,
|
||||
languageVersionSettings,
|
||||
null,
|
||||
sessionConfigurator,
|
||||
)
|
||||
}
|
||||
|
||||
fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
|
||||
return when {
|
||||
isJvm() -> JvmPlatformAnalyzerServices
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.test.frontend.fir
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
||||
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
import org.jetbrains.kotlin.fir.extensions.FirSwitchableExtensionDeclarationsSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.FirCliSession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.*
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
|
||||
import org.jetbrains.kotlin.fir.session.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object FirJsSessionFactory {
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
fun createJsLibrarySession(
|
||||
mainModuleName: Name,
|
||||
module: TestModule,
|
||||
testServices: TestServices,
|
||||
configuration: CompilerConfiguration,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
return FirCliSession(sessionProvider, FirSession.Kind.Library).apply session@{
|
||||
moduleDataProvider.allModuleData.forEach {
|
||||
sessionProvider.registerSession(it, this)
|
||||
it.bindSession(this)
|
||||
}
|
||||
|
||||
registerCliCompilerOnlyComponents()
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
|
||||
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||
|
||||
val builtinsModuleData = FirSessionFactory.createModuleDataForBuiltins(
|
||||
mainModuleName,
|
||||
moduleDataProvider.platform,
|
||||
moduleDataProvider.analyzerServices
|
||||
).also { it.bindSession(this@session) }
|
||||
|
||||
val klibProviders = resolveJsLibraries(module, testServices, configuration).map {
|
||||
KlibBasedSymbolProvider(this@session, moduleDataProvider, kotlinScopeProvider, it)
|
||||
}
|
||||
|
||||
val otherProviders = listOf(
|
||||
FirBuiltinSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
FirCloneableSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
FirDependenciesSymbolProviderImpl(this)
|
||||
)
|
||||
|
||||
val symbolProvider = FirCompositeSymbolProvider(this, otherProviders + klibProviders)
|
||||
|
||||
register(FirSymbolProvider::class, symbolProvider)
|
||||
register(FirProvider::class, FirLibrarySessionProvider(symbolProvider))
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirSession.registerJsSpecificResolveComponents() {
|
||||
register(FirVisibilityChecker::class, FirVisibilityChecker.Default)
|
||||
register(ConeCallConflictResolverFactory::class, JsCallConflictResolverFactory)
|
||||
register(FirPlatformClassMapper::class, FirPlatformClassMapper.Default)
|
||||
register(FirSyntheticNamesProvider::class, FirJsSyntheticNamesProvider)
|
||||
register(FirOverridesBackwardCompatibilityHelper::class, FirOverridesBackwardCompatibilityHelper.Default())
|
||||
}
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
fun createJsModuleBasedSession(
|
||||
moduleData: FirModuleData,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
extensionRegistrars: List<FirExtensionRegistrar>,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
lookupTracker: LookupTracker? = null,
|
||||
init: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||
): FirSession {
|
||||
return FirCliSession(sessionProvider, FirSession.Kind.Source).apply session@{
|
||||
moduleData.bindSession(this@session)
|
||||
sessionProvider.registerSession(moduleData, this@session)
|
||||
registerModuleData(moduleData)
|
||||
registerCliCompilerOnlyComponents()
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
registerResolveComponents(lookupTracker)
|
||||
registerJsSpecificResolveComponents()
|
||||
|
||||
val kotlinScopeProvider = FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope }
|
||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||
|
||||
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
|
||||
register(FirProvider::class, firProvider)
|
||||
|
||||
FirSessionFactory.FirSessionConfigurator(this).apply {
|
||||
registerCommonCheckers()
|
||||
for (extensionRegistrar in extensionRegistrars) {
|
||||
registerExtensions(extensionRegistrar.configure())
|
||||
}
|
||||
init()
|
||||
}.configure()
|
||||
|
||||
val dependenciesSymbolProvider = FirDependenciesSymbolProviderImpl(this)
|
||||
val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this)
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
FirCompositeSymbolProvider(
|
||||
this,
|
||||
listOfNotNull(
|
||||
firProvider.symbolProvider,
|
||||
generatedSymbolsProvider,
|
||||
dependenciesSymbolProvider,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
generatedSymbolsProvider?.let { register(FirSwitchableExtensionDeclarationsSymbolProvider::class, it) }
|
||||
|
||||
register(
|
||||
FirDependenciesSymbolProvider::class,
|
||||
dependenciesSymbolProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.fir.NoMutableState
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider
|
||||
import org.jetbrains.kotlin.load.java.setMethodName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@NoMutableState
|
||||
object FirJsSyntheticNamesProvider : FirSyntheticNamesProvider() {
|
||||
override fun possibleGetterNamesByPropertyName(name: Name): List<Name> = emptyList()
|
||||
override fun setterNameByGetterName(name: Name): Name = setMethodName(getMethodName = name)
|
||||
override fun possiblePropertyNamesByAccessorName(name: Name): List<Name> = emptyList()
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.fir.NoMutableState
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCompositeConflictResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeIntegerOperatorConflictResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeOverloadConflictResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.jvm.ConeEquivalentCallConflictResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.types.typeContext
|
||||
import org.jetbrains.kotlin.js.resolve.JsTypeSpecificityComparatorWithoutDelegate
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
|
||||
@NoMutableState
|
||||
object JsCallConflictResolverFactory : ConeCallConflictResolverFactory() {
|
||||
override fun create(
|
||||
typeSpecificityComparator: TypeSpecificityComparator,
|
||||
components: InferenceComponents,
|
||||
transformerComponents: BodyResolveComponents
|
||||
): ConeCompositeConflictResolver {
|
||||
val specificityComparator = JsTypeSpecificityComparatorWithoutDelegate(components.session.typeContext)
|
||||
return ConeCompositeConflictResolver(
|
||||
ConeOverloadConflictResolver(specificityComparator, components, transformerComponents),
|
||||
ConeEquivalentCallConflictResolver(specificityComparator, components, transformerComponents),
|
||||
ConeIntegerOperatorConflictResolver(specificityComparator, components, transformerComponents)
|
||||
)
|
||||
}
|
||||
}
|
||||
+7
-4
@@ -153,13 +153,13 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
||||
ConfigurationDirectives.WITH_STDLIB in module.directives
|
||||
|
||||
val names = if (needsFullIrRuntime) listOf("full.stdlib", "kotlin.test") else listOf("reduced.stdlib")
|
||||
names.mapTo(result) { System.getProperty("kotlin.js.$it.path") }
|
||||
names.mapNotNullTo(result) { System.getProperty("kotlin.js.$it.path") }
|
||||
val runtimeClasspaths = testServices.runtimeClasspathProviders.flatMap { it.runtimeClassPaths(module) }
|
||||
runtimeClasspaths.mapTo(result) { it.absolutePath }
|
||||
return result
|
||||
}
|
||||
|
||||
fun getDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List<ModuleDescriptorImpl> {
|
||||
fun getKlibDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List<File> {
|
||||
val visited = mutableSetOf<TestModule>()
|
||||
fun getRecursive(module: TestModule, kind: DependencyRelation) {
|
||||
val dependencies = if (kind == DependencyRelation.FriendDependency) module.friendDependencies else module.regularDependencies
|
||||
@@ -171,8 +171,11 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
||||
}
|
||||
}
|
||||
getRecursive(module, kind)
|
||||
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> {
|
||||
return getKlibDependencies(module, testServices, kind)
|
||||
.map { testServices.jsLibraryProvider.getDescriptorByPath(it.absolutePath) }
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
package org.jetbrains.kotlin.js.analyze
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||
|
||||
@@ -24,8 +24,13 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContextDelegate
|
||||
|
||||
class JsTypeSpecificityComparator(val context: TypeSystemInferenceExtensionContextDelegate) : TypeSpecificityComparator {
|
||||
// Replacing the TypeSystemInferenceExtensionContextDelegate with
|
||||
// TypeSystemInferenceExtensionContext here leads to clashed registrations
|
||||
// (for example, when trying to run IrJsTextTestCaseGenerated).
|
||||
class JsTypeSpecificityComparator(context: TypeSystemInferenceExtensionContextDelegate) :
|
||||
TypeSpecificityComparator by JsTypeSpecificityComparatorWithoutDelegate(context)
|
||||
|
||||
class JsTypeSpecificityComparatorWithoutDelegate(val context: TypeSystemInferenceExtensionContext) : TypeSpecificityComparator {
|
||||
private fun TypeSystemInferenceExtensionContext.checkOnlyDynamicFlexibleType(type: KotlinTypeMarker) {
|
||||
if (type.asFlexibleType() != null) {
|
||||
assert(type.isDynamic()) {
|
||||
|
||||
Reference in New Issue
Block a user