Support forward declarations for Native via hack-ing into built-ins

This commit is contained in:
Simon Ogorodnik
2018-09-13 22:15:17 +03:00
parent 69f5cf7095
commit 35a0b42796
5 changed files with 130 additions and 75 deletions
@@ -18,16 +18,20 @@ 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.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.konan.util.KonanFactories
class NativePlatformKindResolution : IdePlatformKindResolution {
@@ -89,13 +93,45 @@ private fun createKotlinNativeBuiltIns(projectContext: ProjectContext): KotlinBu
metadataReader = CachingIdeMetadataReaderImpl
)
val builtInsModule = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
library,
LanguageVersionSettingsImpl.DEFAULT,
projectContext.storageManager,
// This is to preserve "capabilities" from the original IntelliJ LibraryInfo:
customCapabilities = libraryInfo.capabilities
val libraryProto = library.moduleHeaderData
val moduleName = Name.special(libraryProto.moduleName)
val moduleOrigin = DeserializedKonanModuleOrigin(library)
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.setDependencies(listOf(builtInsModule))
return builtInsModule.builtIns
@@ -70,7 +70,6 @@ object NativeAnalyzerFacade : ResolverForModuleFactory() {
)
fragmentProviders.add(libPackageFragmentProvider)
//TODO: Forward declarations?
}
return ResolverForModule(CompositePackageFragmentProvider(fragmentProviders), container)
@@ -5,9 +5,8 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
@@ -37,4 +36,9 @@ interface KonanDeserializedPackageFragmentsFactory {
moduleDescriptor: ModuleDescriptor,
configuration: DeserializationConfiguration
): PackageFragmentProvider
fun createForwardDeclarationHackPackagePartProvider(
storageManager: StorageManager,
module: ModuleDescriptorImpl
): PackageFragmentProviderImpl
}
@@ -6,9 +6,12 @@
package org.jetbrains.kotlin.serialization.konan.impl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.exportForwardDeclarations
import org.jetbrains.kotlin.konan.library.isInterop
@@ -16,6 +19,7 @@ import org.jetbrains.kotlin.konan.library.packageFqName
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.serialization.deserialization.*
@@ -23,7 +27,9 @@ import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragment
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
@@ -122,6 +128,29 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserialized
return provider
}
override fun createForwardDeclarationHackPackagePartProvider(
storageManager: StorageManager,
module: ModuleDescriptorImpl
): PackageFragmentProviderImpl {
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
ForwardDeclarationsPackageFragmentDescriptor(
storageManager,
module,
fqName,
Name.identifier(supertypeName),
classKind
)
val packageFragmentProvider = PackageFragmentProviderImpl(
listOf(
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
)
)
return packageFragmentProvider
}
}
/**
@@ -193,3 +222,52 @@ class ClassifierAliasingPackageFragmentDescriptor(
override fun getMemberScope(): MemberScope = memberScope
}
/**
* Package fragment which creates descriptors for forward declarations on demand.
*/
private class ForwardDeclarationsPackageFragmentDescriptor(
storageManager: StorageManager,
module: ModuleDescriptor,
fqName: FqName,
supertypeName: Name,
classKind: ClassKind
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
private val supertype by storageManager.createLazyValue {
val descriptor = builtIns.builtInsModule.getPackage(ForwardDeclarationsFqNames.packageName)
.memberScope
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
descriptor.defaultType
}
private fun createDeclaration(name: Name): ClassDescriptor {
return ClassDescriptorImpl(
this@ForwardDeclarationsPackageFragmentDescriptor,
name,
Modality.FINAL,
classKind,
listOf(supertype),
SourceElement.NO_SOURCE,
false,
LockBasedStorageManager.NO_LOCKS
).apply {
this.initialize(MemberScope.Empty, emptySet(), null)
}
}
override fun getContributedClassifier(name: Name, location: LookupLocation) = declarations(name)
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, "{}")
}
}
override fun getMemberScope(): MemberScope = memberScope
}
@@ -85,22 +85,8 @@ class KonanResolvedModuleDescriptorsFactoryImpl(
val name = Name.special("<forward declarations>")
val module = createDescriptorOptionalBuiltsIns(name, storageManager, builtIns, SyntheticModulesOrigin)
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
ForwardDeclarationsPackageFragmentDescriptor(
storageManager,
module,
fqName,
Name.identifier(supertypeName),
classKind
)
val packageFragmentProvider = PackageFragmentProviderImpl(
listOf(
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
)
)
val packageFragmentProvider =
moduleDescriptorFactory.packageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(storageManager, module)
module.initialize(packageFragmentProvider)
module.setDependencies(module)
@@ -144,54 +130,6 @@ class KonanResolvedModuleDescriptorsFactoryImpl(
)
}
/**
* Package fragment which creates descriptors for forward declarations on demand.
*/
private class ForwardDeclarationsPackageFragmentDescriptor(
storageManager: StorageManager,
module: ModuleDescriptor,
fqName: FqName,
supertypeName: Name,
classKind: ClassKind
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
private val supertype by storageManager.createLazyValue {
val descriptor = builtIns.builtInsModule.getPackage(ForwardDeclarationsFqNames.packageName)
.memberScope
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
descriptor.defaultType
}
private fun createDeclaration(name: Name): ClassDescriptor {
return ClassDescriptorImpl(
this@ForwardDeclarationsPackageFragmentDescriptor,
name,
Modality.FINAL,
classKind,
listOf(supertype),
SourceElement.NO_SOURCE,
false,
LockBasedStorageManager.NO_LOCKS
).apply {
this.initialize(MemberScope.Empty, emptySet(), null)
}
}
override fun getContributedClassifier(name: Name, location: LookupLocation) = declarations(name)
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, "{}")
}
}
override fun getMemberScope(): MemberScope = memberScope
}
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
internal object ForwardDeclarationsFqNames {