From 35a0b427963d10d3ea271bfcfe3778173920c57e Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 13 Sep 2018 22:15:17 +0300 Subject: [PATCH] Support forward declarations for Native via hack-ing into built-ins --- .../ide/konan/NativePlatformKindResolution.kt | 50 ++++++++++-- .../konan/analyzer/NativeAnalyzerFacade.kt | 1 - ...onanDeserializedPackageFragmentsFactory.kt | 10 ++- ...DeserializedPackageFragmentsFactoryImpl.kt | 78 +++++++++++++++++++ ...nanResolvedModuleDescriptorsFactoryImpl.kt | 66 +--------------- 5 files changed, 130 insertions(+), 75 deletions(-) diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt index bbc3c4b4d84..f21f0cf6f9a 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt @@ -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 diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeAnalyzerFacade.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeAnalyzerFacade.kt index 2aee68aaa87..0c7a596df11 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeAnalyzerFacade.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeAnalyzerFacade.kt @@ -70,7 +70,6 @@ object NativeAnalyzerFacade : ResolverForModuleFactory() { ) fragmentProviders.add(libPackageFragmentProvider) - //TODO: Forward declarations? } return ResolverForModule(CompositePackageFragmentProvider(fragmentProviders), container) diff --git a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/KonanDeserializedPackageFragmentsFactory.kt b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/KonanDeserializedPackageFragmentsFactory.kt index c74ff4dcb9a..b85ad56450d 100644 --- a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/KonanDeserializedPackageFragmentsFactory.kt +++ b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/KonanDeserializedPackageFragmentsFactory.kt @@ -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 } diff --git a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanDeserializedPackageFragmentsFactoryImpl.kt b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanDeserializedPackageFragmentsFactoryImpl.kt index 424113a98d6..0bdb4a8f258 100644 --- a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanDeserializedPackageFragmentsFactoryImpl.kt +++ b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanDeserializedPackageFragmentsFactoryImpl.kt @@ -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 +} \ No newline at end of file diff --git a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanResolvedModuleDescriptorsFactoryImpl.kt b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanResolvedModuleDescriptorsFactoryImpl.kt index 9aacb35c632..dce56920078 100644 --- a/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanResolvedModuleDescriptorsFactoryImpl.kt +++ b/konan/library-reader/src/org/jetbrains/kotlin/serialization/konan/impl/KonanResolvedModuleDescriptorsFactoryImpl.kt @@ -85,22 +85,8 @@ class KonanResolvedModuleDescriptorsFactoryImpl( val name = Name.special("") 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 {