K/N fix: Built-ins initialization refactoring

- Use language settings from IDELanguageSettingsProvider
- Don't use dependencies of root modules to looks up for K/N stdlib
This commit is contained in:
Dmitriy Dolovov
2018-12-03 16:54:36 +07:00
parent 0a55c586d2
commit 33d89005b7
@@ -12,26 +12,29 @@ import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.PathUtil
import org.jetbrains.kotlin.analyzer.getCapability
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.ide.konan.analyzer.NativeAnalyzerFacade
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.util.KonanFactories
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class NativePlatformKindResolution : IdePlatformKindResolution {
@@ -69,84 +72,62 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
override val resolverForModuleFactory get() = NativeAnalyzerFacade
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext) =
createKotlinNativeBuiltIns(projectContext)
createKotlinNativeBuiltIns(settings, projectContext)
}
private fun createKotlinNativeBuiltIns(projectContext: ProjectContext): KotlinBuiltIns {
private fun createKotlinNativeBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext): KotlinBuiltIns {
// TODO: It depends on a random project's stdlib, propagate the actual project here.
fun findStdlib(): Pair<String, LibraryInfo>? {
getModuleInfosFromIdeaModel(projectContext.project, KonanPlatform).forEach { module ->
module.dependencies().forEach { dependency ->
(dependency as? LibraryInfo)?.getLibraryRoots()?.forEach { path ->
if (path.endsWith(KONAN_STDLIB_NAME)) {
return path to dependency
}
}
}
}
return null
}
val project = projectContext.project
val storageManager = projectContext.storageManager
val stdlib: Pair<String, LibraryInfo>? = findStdlib()
val stdlibInfo = findNativeStdlib(project) ?: return DefaultBuiltIns.Instance
val konanLibrary = stdlibInfo.getCapability(NativeLibraryInfo.NATIVE_LIBRARY_CAPABILITY)!!
if (stdlib != null) {
val builtInsModule = KonanFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
KotlinBuiltIns.BUILTINS_MODULE_NAME,
storageManager,
DeserializedKonanModuleOrigin(konanLibrary),
stdlibInfo.capabilities
)
val (path, libraryInfo) = stdlib
val library = createKonanLibrary(
File(path),
KOTLIN_NATIVE_CURRENT_ABI_VERSION,
metadataReader = CachingIdeMetadataReaderImpl
)
val languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, settings.isReleaseCoroutines)
val deserializationConfiguration = CompilerDeserializationConfiguration(languageSettings)
val libraryProto = library.moduleHeaderData
val libraryProto = konanLibrary.moduleHeaderData
val moduleName = Name.special(libraryProto.moduleName)
val moduleOrigin = DeserializedKonanModuleOrigin(library)
val stdlibFragmentProvider = KonanFactories.DefaultPackageFragmentsFactory.createPackageFragmentProvider(
konanLibrary,
null,
libraryProto.packageFragmentNameList,
storageManager,
builtInsModule,
deserializationConfiguration
)
val storageManager = projectContext.storageManager
val descriptorFactory = KonanFactories.DefaultDescriptorFactory
val builtInsModule = descriptorFactory.createDescriptorAndNewBuiltIns(
moduleName,
storageManager,
moduleOrigin,
libraryInfo.capabilities
)
val deserializationConfiguration = CompilerDeserializationConfiguration(LanguageVersionSettingsImpl.DEFAULT)
val provider = KonanFactories.DefaultPackageFragmentsFactory.createPackageFragmentProvider(
library,
null,
libraryProto.packageFragmentNameList,
storageManager,
builtInsModule,
deserializationConfiguration
)
builtInsModule.initialize(
CompositePackageFragmentProvider(
listOf(
provider,
KonanFactories.DefaultPackageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(
storageManager,
builtInsModule
)
builtInsModule.initialize(
CompositePackageFragmentProvider(
listOf(
stdlibFragmentProvider,
KonanFactories.DefaultPackageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(
storageManager,
builtInsModule
)
)
)
)
builtInsModule.setDependencies(listOf(builtInsModule))
builtInsModule.setDependencies(listOf(builtInsModule))
return builtInsModule.builtIns
}
return DefaultBuiltIns.Instance
return builtInsModule.builtIns
}
class NativeLibraryInfo(project: Project, library: Library, private val root: File) : LibraryInfo(project, library) {
// TODO: It depends on a random module's stdlib, propagate the actual module here.
private fun findNativeStdlib(project: Project): NativeLibraryInfo? = getModuleInfosFromIdeaModel(project, KonanPlatform)
.firstNotNullResult { it.asNativeStdlib() }
private fun IdeaModuleInfo.asNativeStdlib(): NativeLibraryInfo? = if ((this as? NativeLibraryInfo)?.isStdlib == true) this else null
class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) {
private val nativeLibrary = createKonanLibrary(
root,
@@ -154,9 +135,11 @@ class NativeLibraryInfo(project: Project, library: Library, private val root: Fi
metadataReader = CachingIdeMetadataReaderImpl
)
override fun getLibraryRoots(): Collection<String> {
return listOf(root.absolutePath)
}
private val roots = listOf(root.absolutePath)
val isStdlib by lazy { roots.first().endsWith(KONAN_STDLIB_NAME) }
override fun getLibraryRoots() = roots
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
get() = super.capabilities +
@@ -165,7 +148,12 @@ class NativeLibraryInfo(project: Project, library: Library, private val root: Fi
NATIVE_LIBRARY_CAPABILITY to nativeLibrary
)
override val platform: TargetPlatform
get() = KonanPlatform
override fun toString() = "Native" + super.toString()
companion object {
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KonanLibrary>("KonanLibrary")
}
}
}