Add JvmBuiltIns.Kind instead of boolean flags in constructor

This commit is contained in:
Alexander Udalov
2019-03-21 16:57:45 +01:00
parent c32d7ef116
commit 87c6b723f0
7 changed files with 60 additions and 20 deletions
@@ -142,7 +142,7 @@ object TopDownAnalyzerFacadeForJVM {
val jvmTarget = configuration.get(JVMConfigurationKeys.JVM_TARGET, JvmTarget.DEFAULT)
val languageVersionSettings = configuration.languageVersionSettings
val fallbackBuiltIns = JvmBuiltIns(storageManager, loadBuiltInsFromCurrentClassLoader = true, isFallback = true).apply {
val fallbackBuiltIns = JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FALLBACK).apply {
initialize(builtInsModule, languageVersionSettings)
}.builtInsModule
@@ -269,7 +269,7 @@ object TopDownAnalyzerFacadeForJVM {
private fun createModuleContext(project: Project, configuration: CompilerConfiguration): MutableModuleContext {
val projectContext = ProjectContext(project)
val builtIns = JvmBuiltIns(projectContext.storageManager, false)
val builtIns = JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
return ContextForNewModule(
projectContext, Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"), builtIns, null
).apply {
@@ -32,7 +32,7 @@ object JvmPlatform : TargetPlatform("JVM") {
}
}
for (builtInPackage in JvmBuiltIns(storageManager).builtInPackagesImportedByDefault) {
for (builtInPackage in JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER).builtInPackagesImportedByDefault) {
addAllClassifiersFromScope(builtInPackage.memberScope)
}
}
@@ -587,7 +587,8 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
val platform =
if (nameSuffix.isEmpty()) null
else if (nameSuffix == "common") MultiTargetPlatform.Common else MultiTargetPlatform.Specific(nameSuffix.toUpperCase())
return ModuleDescriptorImpl(Name.special("<$moduleName>"), storageManager, JvmBuiltIns(storageManager), platform)
val builtIns = JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
return ModuleDescriptorImpl(Name.special("<$moduleName>"), storageManager, builtIns, platform)
}
protected open fun createSealedModule(storageManager: StorageManager): ModuleDescriptorImpl =
@@ -63,7 +63,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
val environment = createEnvironment(moduleDirs)
val modules = setupModules(environment, moduleDirs)
val projectContext = ProjectContext(environment.project)
val builtIns = JvmBuiltIns(projectContext.storageManager)
val builtIns = JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
val resolverForProject = ResolverForProjectImpl(
"test",
projectContext, modules,
@@ -13,12 +13,46 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.sure
class JvmBuiltIns @JvmOverloads constructor(
storageManager: StorageManager,
loadBuiltInsFromCurrentClassLoader: Boolean = true,
// TODO: change this value to loadBuiltInsFromCurrentClassLoader as soon as built-ins are loaded from module dependencies everywhere
isFallback: Boolean = false
) : KotlinBuiltIns(storageManager) {
class JvmBuiltIns(storageManager: StorageManager, kind: Kind) : KotlinBuiltIns(storageManager) {
/**
* Where built-ins should be loaded from.
*/
enum class Kind {
/**
* Load built-ins from dependencies of the module that's being compiled. In this case, any request to a built-in class such as
* `kotlin.String` would end up querying contents of the module and all its dependencies in order until the first one returns
* anything, similarly to how it's done for normal (.class file-based) dependencies. If there's a class with FQ name `kotlin.String`
* in module sources, it'll be returned in [KotlinBuiltIns.getString], otherwise it'll be loaded from the first dependency that
* has the `kotlin/kotlin.kotlin_builtins` file where metadata of `kotlin.String` is located.
*
* If this mode is selected, the module should be injected after an instance of [JvmBuiltIns] is created via setting
* [KotlinBuiltIns.builtInsModule] to point to the module that's being compiled.
*
* This mode is preferred and should be used in new code when possible.
*/
FROM_DEPENDENCIES,
/**
* Load built-ins by looking up `.kotlin_builtins` resources in the class loader of the current compiler or IDE plugin.
*
* This mode is discouraged and should be avoided when possible. The reason is that in case versions of the compiler and the
* standard library in compilation dependencies do not match, there can be tricky errors or even differences in behavior if
* built-ins API has changed.
*/
FROM_CLASS_LOADER,
/**
* Similarly to [FROM_CLASS_LOADER], load built-ins from the compiler class loader, but also mark the loaded package
* fragments as "fallback" (`BuiltInsPackageFragment.isFallback`) to make the compiler report errors on any usages of elements
* from these built-ins.
*
* This mode is useful as a "secondary" built-ins source to ensure there are at least some built-ins for the compiler frontend to
* work correctly. Such fallback built-ins are usually placed at the end of the dependencies list, so that built-ins from the
* standard library (which are present in >99% cases) would win in the resolution.
*/
FALLBACK,
}
// Module containing JDK classes or having them among dependencies
private var ownerModuleDescriptor: ModuleDescriptor? = null
private var isAdditionalBuiltInsFeatureSupported: Boolean = true
@@ -41,8 +75,11 @@ class JvmBuiltIns @JvmOverloads constructor(
}
init {
if (loadBuiltInsFromCurrentClassLoader) {
createBuiltInsModule(isFallback)
when (kind) {
Kind.FROM_DEPENDENCIES -> {
}
Kind.FROM_CLASS_LOADER -> createBuiltInsModule(false)
Kind.FALLBACK -> createBuiltInsModule(true)
}
}
@@ -57,7 +57,7 @@ class RuntimeModuleData private constructor(
companion object {
fun create(classLoader: ClassLoader): RuntimeModuleData {
val storageManager = LockBasedStorageManager("RuntimeModuleData")
val builtIns = JvmBuiltIns(storageManager, false)
val builtIns = JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager, builtIns)
builtIns.builtInsModule = module
@@ -93,8 +93,8 @@ class RuntimeModuleData private constructor(
RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT
)
val builtinsProvider = JvmBuiltInsPackageFragmentProvider(
storageManager, reflectKotlinClassFinder, module, notFoundClasses, builtIns.settings, builtIns.settings,
DeserializationConfiguration.Default
storageManager, reflectKotlinClassFinder, module, notFoundClasses, builtIns.settings, builtIns.settings,
DeserializationConfiguration.Default
)
singleModuleClassResolver.resolver = javaDescriptorResolver
@@ -29,7 +29,9 @@ class JvmPlatformKindResolution : IdePlatformKindResolution {
override val resolverForModuleFactory: ResolverForModuleFactory
get() = JvmAnalyzerFacade
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext): KotlinBuiltIns {
return if (settings.sdk != null) JvmBuiltIns(projectContext.storageManager) else DefaultBuiltIns.Instance
}
}
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext): KotlinBuiltIns =
if (settings.sdk != null)
JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
else
DefaultBuiltIns.Instance
}