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:
+56
-68
@@ -12,26 +12,29 @@ import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
|||||||
import com.intellij.openapi.vfs.VfsUtil
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
|
import org.jetbrains.kotlin.analyzer.getCapability
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
|
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
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.konan.DeserializedKonanModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
|
||||||
import org.jetbrains.kotlin.ide.konan.analyzer.NativeAnalyzerFacade
|
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.LibraryInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
|
import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
|
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.file.File
|
||||||
import org.jetbrains.kotlin.konan.library.*
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
import org.jetbrains.kotlin.konan.util.KonanFactories
|
import org.jetbrains.kotlin.konan.util.KonanFactories
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
||||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||||
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
||||||
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
class NativePlatformKindResolution : IdePlatformKindResolution {
|
class NativePlatformKindResolution : IdePlatformKindResolution {
|
||||||
|
|
||||||
@@ -69,84 +72,62 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
|
|||||||
override val resolverForModuleFactory get() = NativeAnalyzerFacade
|
override val resolverForModuleFactory get() = NativeAnalyzerFacade
|
||||||
|
|
||||||
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext) =
|
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.
|
val project = projectContext.project
|
||||||
fun findStdlib(): Pair<String, LibraryInfo>? {
|
val storageManager = projectContext.storageManager
|
||||||
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 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 languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, settings.isReleaseCoroutines)
|
||||||
val library = createKonanLibrary(
|
val deserializationConfiguration = CompilerDeserializationConfiguration(languageSettings)
|
||||||
File(path),
|
|
||||||
KOTLIN_NATIVE_CURRENT_ABI_VERSION,
|
|
||||||
metadataReader = CachingIdeMetadataReaderImpl
|
|
||||||
)
|
|
||||||
|
|
||||||
val libraryProto = library.moduleHeaderData
|
val libraryProto = konanLibrary.moduleHeaderData
|
||||||
|
|
||||||
val moduleName = Name.special(libraryProto.moduleName)
|
val stdlibFragmentProvider = KonanFactories.DefaultPackageFragmentsFactory.createPackageFragmentProvider(
|
||||||
val moduleOrigin = DeserializedKonanModuleOrigin(library)
|
konanLibrary,
|
||||||
|
null,
|
||||||
|
libraryProto.packageFragmentNameList,
|
||||||
|
storageManager,
|
||||||
|
builtInsModule,
|
||||||
|
deserializationConfiguration
|
||||||
|
)
|
||||||
|
|
||||||
val storageManager = projectContext.storageManager
|
builtInsModule.initialize(
|
||||||
val descriptorFactory = KonanFactories.DefaultDescriptorFactory
|
CompositePackageFragmentProvider(
|
||||||
|
listOf(
|
||||||
val builtInsModule = descriptorFactory.createDescriptorAndNewBuiltIns(
|
stdlibFragmentProvider,
|
||||||
moduleName,
|
KonanFactories.DefaultPackageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(
|
||||||
storageManager,
|
storageManager,
|
||||||
moduleOrigin,
|
builtInsModule
|
||||||
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.setDependencies(listOf(builtInsModule))
|
builtInsModule.setDependencies(listOf(builtInsModule))
|
||||||
|
|
||||||
return builtInsModule.builtIns
|
return builtInsModule.builtIns
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultBuiltIns.Instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
private val nativeLibrary = createKonanLibrary(
|
||||||
root,
|
root,
|
||||||
@@ -154,9 +135,11 @@ class NativeLibraryInfo(project: Project, library: Library, private val root: Fi
|
|||||||
metadataReader = CachingIdeMetadataReaderImpl
|
metadataReader = CachingIdeMetadataReaderImpl
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getLibraryRoots(): Collection<String> {
|
private val roots = listOf(root.absolutePath)
|
||||||
return listOf(root.absolutePath)
|
|
||||||
}
|
val isStdlib by lazy { roots.first().endsWith(KONAN_STDLIB_NAME) }
|
||||||
|
|
||||||
|
override fun getLibraryRoots() = roots
|
||||||
|
|
||||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
get() = super.capabilities +
|
get() = super.capabilities +
|
||||||
@@ -165,7 +148,12 @@ class NativeLibraryInfo(project: Project, library: Library, private val root: Fi
|
|||||||
NATIVE_LIBRARY_CAPABILITY to nativeLibrary
|
NATIVE_LIBRARY_CAPABILITY to nativeLibrary
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override val platform: TargetPlatform
|
||||||
|
get() = KonanPlatform
|
||||||
|
|
||||||
|
override fun toString() = "Native" + super.toString()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KonanLibrary>("KonanLibrary")
|
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KonanLibrary>("KonanLibrary")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user