Load JVM built-ins in IDE from module dependencies

Fix built-ins for JVM platform and make them consistent
with module's dependency on standard library. Changes
don't affect non-JVM platforms.

Previously all built-ins in IDE were loaded from classloader
and were based on the same pre-serialized .kotlin_builtins files.
This approach is generally not correct as built-in declarations
differ for different platforms, but it had been working for a while
without immediately observalble effects (see KT-33233 for more info).
After changes in standard library JvmBuiltins started producing
false errors (see KT-39728).

To fix this, JVM built-ins in IDE now utilize the same technique as
applied in CLI: using dependency on standard library as a module
for built-ins instead of artificial module that considers only
.kotlin_builtins.

Change summary:
- Provide JvmBuiltins with kind FROM_DEPENDENCIES
  for all modules with stdlib dependency in IDE
- Add JvmBuiltinsPackageFragmentProvider to JVM-ish module resolvers
  (JVM and Composite with JVM platform) to support their use as
  built-ins module
- Create KotlinBuiltInsMetadataIndex file index for tracking libraries
  containing .kotlin_builtins to support JvmBuiltinsPackageFragmentProvider
- Create KotlinStdlibIndex file index for tracking kotlin-stdlib(-common),
  which looks for "Kotlin-Runtime-Component" manifest attribute
- Add caching service to track LibraryInfo for kotlin-stdlib(-common)
- Put LibraryInfo for kotlin-stdlib(-common) alongside SDKs
  due to the need to resolve that modules in BuiltInsCache
- Update BuiltInsCache to separate JvmBuiltins by module's dependency
  on stdlib and JDK
- Make platform of KotlinSDK common instead of JVM
- Set built-ins module lazily in IDE

^KT-33233 Verification Pending
This commit is contained in:
Pavel Kirpichenkov
2020-12-14 16:30:29 +03:00
parent 1479c7a270
commit c0dd731818
27 changed files with 440 additions and 77 deletions
@@ -125,8 +125,12 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
useInstance(languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState))
if (useBuiltInsProvider) {
useInstance((moduleContext.module.builtIns as JvmBuiltIns).customizer)
val builtIns = moduleContext.module.builtIns
if (useBuiltInsProvider && builtIns is JvmBuiltIns) {
// TODO(dsavvinov): make sure that useBuiltInsProvider == true <=> builtIns is JvmBuiltIns
// Currently, that's not the case at least in IDE unit-tests, because they do not set-up
// dependency on SDK properly, see KT-43828
useInstance(builtIns.customizer)
useImpl<JvmBuiltInsPackageFragmentProvider>()
}
useImpl<OptionalAnnotationPackageFragmentProvider>()
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.container.tryGetService
import org.jetbrains.kotlin.context.ModuleContext
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
@@ -36,12 +38,14 @@ import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.utils.addIfNotNull
class JvmPlatformParameters(
val packagePartProviderFactory: (ModuleContent<*>) -> PackagePartProvider,
val moduleByJavaClass: (JavaClass) -> ModuleInfo?,
// params: referenced module info of target class, context module info of current resolver
val resolverForReferencedModule: ((ModuleInfo, ModuleInfo) -> ResolverForModule?)? = null,
val useBuiltinsProviderForModule: (ModuleInfo) -> Boolean
) : PlatformAnalysisParameters
@@ -111,17 +115,16 @@ class JvmResolverForModuleFactory(
packagePartProvider,
languageVersionSettings,
sealedInheritorsProvider = sealedInheritorsProvider,
useBuiltInsProvider = false // TODO: load built-ins from module dependencies in IDE
useBuiltInsProvider = platformParameters.useBuiltinsProviderForModule(moduleInfo)
)
val resolveSession = container.get<ResolveSession>()
val javaDescriptorResolver = container.get<JavaDescriptorResolver>()
val providersForModule = arrayListOf(
resolveSession.packageFragmentProvider,
javaDescriptorResolver.packageFragmentProvider
container.get<ResolveSession>().packageFragmentProvider,
container.get<JavaDescriptorResolver>().packageFragmentProvider,
)
providersForModule.addIfNotNull(container.tryGetService(JvmBuiltInsPackageFragmentProvider::class.java))
providersForModule +=
PackageFragmentProviderExtension.getInstances(project)
.mapNotNull {