[Resolve] Rewrite how built-ins are created

Under COMPOSITE mode we don't have a globally known way to create
built-ins, instead, we have to create them on per-module basis.

So, in this commit we:

1. Use builtInsProvider: (ModuleInfo) -> KotlinBuiltIns instead of
precomputed builtIns instance, in order to be able to calculate
builtIns on per-module basis

2. Introduce new entity, called BuiltInsCache, which, roughly
speaking, is a map of form ModuleInfo -> KotlinBuiltIns, to prevent
creation of multiple builtInsInstances
NB. Actually, it's of form BuiltInsCacheKey -> KotlinBuiltIns, because
we shouldn't create new builtIns for each module. Also, currently,
each platform has its own BuiltInsCacheKey implementation, because
parameters by which built-ins are created, are a bit different across
different platforms. Ideally, we should eliminate those differences
and they use one concrete implementation as a key.
This commit is contained in:
Dmitry Savvinov
2019-06-07 18:08:37 +03:00
parent 9f2a03947c
commit 2b4d70fcf0
11 changed files with 135 additions and 55 deletions
@@ -28,7 +28,9 @@ import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
import org.jetbrains.kotlin.konan.file.File
@@ -39,6 +41,7 @@ import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
import org.jetbrains.kotlin.platform.konan.KonanPlatforms
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.typeUtil.lazyClosure
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class NativePlatformKindResolution : IdePlatformKindResolution {
@@ -97,16 +100,20 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
override val kind get() = NativeIdePlatformKind
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext) =
createKotlinNativeBuiltIns(settings, projectContext)
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey = NativeBuiltInsCacheKey
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext) =
createKotlinNativeBuiltIns(moduleInfo, projectContext)
object NativeBuiltInsCacheKey : BuiltInsCacheKey
}
private fun createKotlinNativeBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext): KotlinBuiltIns {
private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns {
val project = projectContext.project
val storageManager = projectContext.storageManager
val stdlibInfo = findNativeStdlib(project) ?: return DefaultBuiltIns.Instance
val stdlibInfo = moduleInfo.findNativeStdlib(project) ?: return DefaultBuiltIns.Instance
val konanLibrary = stdlibInfo.getCapability(NativeLibraryInfo.NATIVE_LIBRARY_CAPABILITY)!!
val builtInsModule = KonanFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
@@ -116,7 +123,7 @@ private fun createKotlinNativeBuiltIns(settings: PlatformAnalysisSettings, proje
stdlibInfo.capabilities
)
val languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, settings.isReleaseCoroutines)
val languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, isReleaseCoroutines = false)
val deserializationConfiguration = CompilerDeserializationConfiguration(languageSettings)
val libraryProto = konanLibrary.moduleHeaderData
@@ -147,11 +154,10 @@ private fun createKotlinNativeBuiltIns(settings: PlatformAnalysisSettings, proje
return builtInsModule.builtIns
}
// TODO: It depends on a random module's stdlib, propagate the actual module here.
private fun findNativeStdlib(project: Project): NativeLibraryInfo? = getModuleInfosFromIdeaModel(project, KonanPlatforms.defaultKonanPlatform)
.firstNotNullResult { it.asNativeStdlib() }
private fun IdeaModuleInfo.asNativeStdlib(): NativeLibraryInfo? = if ((this as? NativeLibraryInfo)?.isStdlib == true) this else null
private fun ModuleInfo.findNativeStdlib(project: Project): NativeLibraryInfo? =
dependencies().lazyClosure { it.dependencies() }
.filterIsInstance<NativeLibraryInfo>()
.firstOrNull { it.isStdlib }
class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) {