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:
@@ -125,8 +125,12 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
|
|||||||
|
|
||||||
useInstance(languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState))
|
useInstance(languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState))
|
||||||
|
|
||||||
if (useBuiltInsProvider) {
|
val builtIns = moduleContext.module.builtIns
|
||||||
useInstance((moduleContext.module.builtIns as JvmBuiltIns).customizer)
|
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<JvmBuiltInsPackageFragmentProvider>()
|
||||||
}
|
}
|
||||||
useImpl<OptionalAnnotationPackageFragmentProvider>()
|
useImpl<OptionalAnnotationPackageFragmentProvider>()
|
||||||
|
|||||||
+9
-6
@@ -17,8 +17,10 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm
|
package org.jetbrains.kotlin.resolve.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
|
import org.jetbrains.kotlin.container.tryGetService
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
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.jvm.extensions.PackageFragmentProviderExtension
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
class JvmPlatformParameters(
|
class JvmPlatformParameters(
|
||||||
val packagePartProviderFactory: (ModuleContent<*>) -> PackagePartProvider,
|
val packagePartProviderFactory: (ModuleContent<*>) -> PackagePartProvider,
|
||||||
val moduleByJavaClass: (JavaClass) -> ModuleInfo?,
|
val moduleByJavaClass: (JavaClass) -> ModuleInfo?,
|
||||||
// params: referenced module info of target class, context module info of current resolver
|
// params: referenced module info of target class, context module info of current resolver
|
||||||
val resolverForReferencedModule: ((ModuleInfo, ModuleInfo) -> ResolverForModule?)? = null,
|
val resolverForReferencedModule: ((ModuleInfo, ModuleInfo) -> ResolverForModule?)? = null,
|
||||||
|
val useBuiltinsProviderForModule: (ModuleInfo) -> Boolean
|
||||||
) : PlatformAnalysisParameters
|
) : PlatformAnalysisParameters
|
||||||
|
|
||||||
|
|
||||||
@@ -111,17 +115,16 @@ class JvmResolverForModuleFactory(
|
|||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
sealedInheritorsProvider = sealedInheritorsProvider,
|
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(
|
val providersForModule = arrayListOf(
|
||||||
resolveSession.packageFragmentProvider,
|
container.get<ResolveSession>().packageFragmentProvider,
|
||||||
javaDescriptorResolver.packageFragmentProvider
|
container.get<JavaDescriptorResolver>().packageFragmentProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
providersForModule.addIfNotNull(container.tryGetService(JvmBuiltInsPackageFragmentProvider::class.java))
|
||||||
|
|
||||||
providersForModule +=
|
providersForModule +=
|
||||||
PackageFragmentProviderExtension.getInstances(project)
|
PackageFragmentProviderExtension.getInstances(project)
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analyzer
|
package org.jetbrains.kotlin.analyzer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleCapability
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
|
||||||
val ModuleDescriptor.moduleInfo: ModuleInfo?
|
val ModuleDescriptor.moduleInfo: ModuleInfo?
|
||||||
@@ -23,3 +24,8 @@ internal fun collectAllExpectedByModules(entryModule: ModuleInfo): Set<ModuleInf
|
|||||||
|
|
||||||
return expectedByModules
|
return expectedByModules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val JDK_CAPABILITY = ModuleCapability<Boolean>("IsJdk")
|
||||||
|
|
||||||
|
val ModuleDescriptor.hasJdkCapability: Boolean
|
||||||
|
get() = getCapability(JDK_CAPABILITY) == true
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analyzer.hasJdkCapability
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
|
||||||
@@ -115,6 +116,13 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
|||||||
|
|
||||||
val dependencies = psi2irContext.moduleDescriptor.allDependencyModules.map {
|
val dependencies = psi2irContext.moduleDescriptor.allDependencyModules.map {
|
||||||
val kotlinLibrary = (it.getCapability(KlibModuleOrigin.CAPABILITY) as? DeserializedKlibModuleOrigin)?.library
|
val kotlinLibrary = (it.getCapability(KlibModuleOrigin.CAPABILITY) as? DeserializedKlibModuleOrigin)?.library
|
||||||
|
if (it.hasJdkCapability) {
|
||||||
|
// For IDE environment only, i.e. when compiling for debugger
|
||||||
|
// Deserializer for built-ins module should exist because built-in types returned from SDK belong to that module,
|
||||||
|
// but JDK's built-ins module might not be in current module's dependencies
|
||||||
|
// We have to ensure that deserializer for built-ins module is created
|
||||||
|
irLinker.deserializeIrModuleHeader(it.builtIns.builtInsModule, null)
|
||||||
|
}
|
||||||
irLinker.deserializeIrModuleHeader(it, kotlinLibrary)
|
irLinker.deserializeIrModuleHeader(it, kotlinLibrary)
|
||||||
}
|
}
|
||||||
val irProviders = listOf(irLinker)
|
val irProviders = listOf(irLinker)
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,6 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.util.ModificationTracker
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
@@ -44,7 +43,8 @@ fun createResolveSessionForFiles(
|
|||||||
TestModule(project, addBuiltIns)
|
TestModule(project, addBuiltIns)
|
||||||
val platformParameters = JvmPlatformParameters(
|
val platformParameters = JvmPlatformParameters(
|
||||||
packagePartProviderFactory = { PackagePartProvider.Empty },
|
packagePartProviderFactory = { PackagePartProvider.Empty },
|
||||||
moduleByJavaClass = { testModule }
|
moduleByJavaClass = { testModule },
|
||||||
|
useBuiltinsProviderForModule = { false }
|
||||||
)
|
)
|
||||||
|
|
||||||
val resolverForProject = ResolverForSingleModuleProject(
|
val resolverForProject = ResolverForSingleModuleProject(
|
||||||
|
|||||||
+2
-1
@@ -88,7 +88,8 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
|
|||||||
moduleByJavaClass = { javaClass ->
|
moduleByJavaClass = { javaClass ->
|
||||||
val moduleName = javaClass.name.asString().toLowerCase().first().toString()
|
val moduleName = javaClass.name.asString().toLowerCase().first().toString()
|
||||||
modules.first { it._name == moduleName }
|
modules.first { it._name == moduleName }
|
||||||
}
|
},
|
||||||
|
useBuiltinsProviderForModule = { false }
|
||||||
)
|
)
|
||||||
|
|
||||||
val resolverForProject = object : AbstractResolverForProject<TestModule>(
|
val resolverForProject = object : AbstractResolverForProject<TestModule>(
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.storage.StorageManager
|
|||||||
import org.jetbrains.kotlin.storage.getValue
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
import org.jetbrains.kotlin.utils.sure
|
import org.jetbrains.kotlin.utils.sure
|
||||||
|
|
||||||
class JvmBuiltIns(storageManager: StorageManager, kind: Kind) : KotlinBuiltIns(storageManager) {
|
class JvmBuiltIns(storageManager: StorageManager, val kind: Kind) : KotlinBuiltIns(storageManager) {
|
||||||
/**
|
/**
|
||||||
* Where built-ins should be loaded from.
|
* Where built-ins should be loaded from.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+4
@@ -60,4 +60,8 @@ class JvmBuiltInsPackageFragmentProvider(
|
|||||||
finder.findBuiltInsData(fqName)?.let { inputStream ->
|
finder.findBuiltInsData(fqName)?.let { inputStream ->
|
||||||
BuiltInsPackageFragmentImpl.create(fqName, storageManager, moduleDescriptor, inputStream, isFallback = false)
|
BuiltInsPackageFragmentImpl.create(fqName, storageManager, moduleDescriptor, inputStream, isFallback = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DOT_BUILTINS_METADATA_FILE_EXTENSION = ".kotlin_builtins"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
|
|||||||
|
|
||||||
public abstract class KotlinBuiltIns {
|
public abstract class KotlinBuiltIns {
|
||||||
private ModuleDescriptorImpl builtInsModule;
|
private ModuleDescriptorImpl builtInsModule;
|
||||||
|
private NotNullLazyValue<ModuleDescriptorImpl> postponedBuiltInsModule;
|
||||||
|
|
||||||
private final NotNullLazyValue<Primitives> primitives;
|
private final NotNullLazyValue<Primitives> primitives;
|
||||||
private final NotNullLazyValue<Collection<PackageViewDescriptor>> builtInPackagesImportedByDefault;
|
private final NotNullLazyValue<Collection<PackageViewDescriptor>> builtInPackagesImportedByDefault;
|
||||||
@@ -56,10 +57,10 @@ public abstract class KotlinBuiltIns {
|
|||||||
@Override
|
@Override
|
||||||
public Collection<PackageViewDescriptor> invoke() {
|
public Collection<PackageViewDescriptor> invoke() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
builtInsModule.getPackage(BUILT_INS_PACKAGE_FQ_NAME),
|
getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME),
|
||||||
builtInsModule.getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
|
getBuiltInsModule().getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
|
||||||
builtInsModule.getPackage(RANGES_PACKAGE_FQ_NAME),
|
getBuiltInsModule().getPackage(RANGES_PACKAGE_FQ_NAME),
|
||||||
builtInsModule.getPackage(ANNOTATION_PACKAGE_FQ_NAME)
|
getBuiltInsModule().getPackage(ANNOTATION_PACKAGE_FQ_NAME)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -123,6 +124,10 @@ public abstract class KotlinBuiltIns {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPostponedBuiltinsModuleComputation(@NotNull Function0<ModuleDescriptorImpl> computation) {
|
||||||
|
postponedBuiltInsModule = storageManager.createLazyValue(computation);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected AdditionalClassPartsProvider getAdditionalClassPartsProvider() {
|
protected AdditionalClassPartsProvider getAdditionalClassPartsProvider() {
|
||||||
return AdditionalClassPartsProvider.None.INSTANCE;
|
return AdditionalClassPartsProvider.None.INSTANCE;
|
||||||
@@ -135,7 +140,8 @@ public abstract class KotlinBuiltIns {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected Iterable<ClassDescriptorFactory> getClassDescriptorFactories() {
|
protected Iterable<ClassDescriptorFactory> getClassDescriptorFactories() {
|
||||||
return Collections.<ClassDescriptorFactory>singletonList(new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule));
|
return Collections.<ClassDescriptorFactory>singletonList(
|
||||||
|
new BuiltInFictitiousFunctionClassFactory(storageManager, getBuiltInsModule()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -161,6 +167,10 @@ public abstract class KotlinBuiltIns {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ModuleDescriptorImpl getBuiltInsModule() {
|
public ModuleDescriptorImpl getBuiltInsModule() {
|
||||||
|
assert builtInsModule != null || postponedBuiltInsModule != null : "Uninitialized built-ins module";
|
||||||
|
if (builtInsModule == null) {
|
||||||
|
builtInsModule = postponedBuiltInsModule.invoke();
|
||||||
|
}
|
||||||
return builtInsModule;
|
return builtInsModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,12 +208,12 @@ public abstract class KotlinBuiltIns {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public MemberScope getBuiltInsPackageScope() {
|
public MemberScope getBuiltInsPackageScope() {
|
||||||
return builtInsModule.getPackage(BUILT_INS_PACKAGE_FQ_NAME).getMemberScope();
|
return getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME).getMemberScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassDescriptor getBuiltInClassByFqName(@NotNull FqName fqName) {
|
public ClassDescriptor getBuiltInClassByFqName(@NotNull FqName fqName) {
|
||||||
ClassDescriptor descriptor = DescriptorUtilKt.resolveClassByFqName(builtInsModule, fqName, NoLookupLocation.FROM_BUILTINS);
|
ClassDescriptor descriptor = DescriptorUtilKt.resolveClassByFqName(getBuiltInsModule(), fqName, NoLookupLocation.FROM_BUILTINS);
|
||||||
assert descriptor != null : "Can't find built-in class " + fqName;
|
assert descriptor != null : "Can't find built-in class " + fqName;
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -53,13 +53,15 @@ class CommonPlatformKindResolution : IdePlatformKindResolution {
|
|||||||
|
|
||||||
override val kind get() = CommonIdePlatformKind
|
override val kind get() = CommonIdePlatformKind
|
||||||
|
|
||||||
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey = BuiltInsCacheKey.DefaultBuiltInsKey
|
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?, stdlibInfo: LibraryInfo?): BuiltInsCacheKey =
|
||||||
|
BuiltInsCacheKey.DefaultBuiltInsKey
|
||||||
|
|
||||||
override fun createBuiltIns(
|
override fun createBuiltIns(
|
||||||
moduleInfo: IdeaModuleInfo,
|
moduleInfo: IdeaModuleInfo,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
sdkDependency: SdkInfo?
|
sdkDependency: SdkInfo?,
|
||||||
|
stdlibDependency: LibraryInfo?,
|
||||||
): KotlinBuiltIns {
|
): KotlinBuiltIns {
|
||||||
return DefaultBuiltIns.Instance
|
return DefaultBuiltIns.Instance
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -8,9 +8,11 @@
|
|||||||
package org.jetbrains.kotlin.caches.resolve
|
package org.jetbrains.kotlin.caches.resolve
|
||||||
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.util.containers.addIfNotNull
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
|
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
|
||||||
import org.jetbrains.kotlin.analyzer.common.configureCommonSpecificComponents
|
import org.jetbrains.kotlin.analyzer.common.configureCommonSpecificComponents
|
||||||
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.container.*
|
import org.jetbrains.kotlin.container.*
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
@@ -22,6 +24,7 @@ import org.jetbrains.kotlin.frontend.di.configureModule
|
|||||||
import org.jetbrains.kotlin.frontend.di.configureStandardResolveComponents
|
import org.jetbrains.kotlin.frontend.di.configureStandardResolveComponents
|
||||||
import org.jetbrains.kotlin.frontend.java.di.configureJavaSpecificComponents
|
import org.jetbrains.kotlin.frontend.java.di.configureJavaSpecificComponents
|
||||||
import org.jetbrains.kotlin.frontend.java.di.initializeJavaSpecificComponents
|
import org.jetbrains.kotlin.frontend.java.di.initializeJavaSpecificComponents
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
||||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
||||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
|
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
|
||||||
@@ -32,6 +35,7 @@ import org.jetbrains.kotlin.platform.*
|
|||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.js.isJs
|
import org.jetbrains.kotlin.platform.js.isJs
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
import org.jetbrains.kotlin.platform.konan.NativePlatform
|
import org.jetbrains.kotlin.platform.konan.NativePlatform
|
||||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
@@ -130,8 +134,14 @@ class CompositeResolverForModuleFactory(
|
|||||||
return listOfNotNull(metadataProvider, klibMetadataProvider)
|
return listOfNotNull(metadataProvider, klibMetadataProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
private fun getJvmProvidersIfAny(container: StorageComponentContainer): List<PackageFragmentProvider> =
|
private fun getJvmProvidersIfAny(container: StorageComponentContainer): List<PackageFragmentProvider> =
|
||||||
if (targetPlatform.has<JvmPlatform>()) listOf(container.get<JavaDescriptorResolver>().packageFragmentProvider) else emptyList()
|
buildList {
|
||||||
|
if (targetPlatform.has<JvmPlatform>()) add(container.get<JavaDescriptorResolver>().packageFragmentProvider)
|
||||||
|
|
||||||
|
// Use JVM built-ins only for completely-JVM modules
|
||||||
|
addIfNotNull(container.tryGetService(JvmBuiltInsPackageFragmentProvider::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
private fun getNativeProvidersIfAny(moduleInfo: ModuleInfo, container: StorageComponentContainer): List<PackageFragmentProvider> {
|
private fun getNativeProvidersIfAny(moduleInfo: ModuleInfo, container: StorageComponentContainer): List<PackageFragmentProvider> {
|
||||||
if (!targetPlatform.has<NativePlatform>()) return emptyList()
|
if (!targetPlatform.has<NativePlatform>()) return emptyList()
|
||||||
@@ -191,9 +201,11 @@ class CompositeResolverForModuleFactory(
|
|||||||
// JVM-specific
|
// JVM-specific
|
||||||
if (targetPlatform.has<JvmPlatform>()) {
|
if (targetPlatform.has<JvmPlatform>()) {
|
||||||
configureJavaSpecificComponents(
|
configureJavaSpecificComponents(
|
||||||
moduleContext, moduleClassResolver!!, languageVersionSettings, configureJavaClassFinder = null,
|
moduleContext, moduleClassResolver!!,
|
||||||
|
languageVersionSettings,
|
||||||
|
configureJavaClassFinder = null,
|
||||||
javaClassTracker = null,
|
javaClassTracker = null,
|
||||||
useBuiltInsProvider = false
|
useBuiltInsProvider = IdeBuiltInsLoadingState.isFromDependenciesForJvm && targetPlatform.isJvm() // use JVM BuiltIns only for completely JVM modules
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -42,12 +42,13 @@ import org.jetbrains.kotlin.storage.StorageManager
|
|||||||
interface IdePlatformKindResolution {
|
interface IdePlatformKindResolution {
|
||||||
val kind: IdePlatformKind<*>
|
val kind: IdePlatformKind<*>
|
||||||
|
|
||||||
fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey
|
fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?, stdlibInfo: LibraryInfo?): BuiltInsCacheKey
|
||||||
fun createBuiltIns(
|
fun createBuiltIns(
|
||||||
moduleInfo: IdeaModuleInfo,
|
moduleInfo: IdeaModuleInfo,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
sdkDependency: SdkInfo?
|
sdkDependency: SdkInfo?,
|
||||||
|
stdlibDependency: LibraryInfo?
|
||||||
): KotlinBuiltIns
|
): KotlinBuiltIns
|
||||||
|
|
||||||
fun createResolverForModuleFactory(
|
fun createResolverForModuleFactory(
|
||||||
|
|||||||
+3
-2
@@ -51,7 +51,7 @@ class JsPlatformKindResolution : IdePlatformKindResolution {
|
|||||||
|
|
||||||
override val kind get() = JsIdePlatformKind
|
override val kind get() = JsIdePlatformKind
|
||||||
|
|
||||||
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey {
|
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?, stdlibInfo: LibraryInfo?): BuiltInsCacheKey {
|
||||||
return BuiltInsCacheKey.DefaultBuiltInsKey
|
return BuiltInsCacheKey.DefaultBuiltInsKey
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,8 @@ class JsPlatformKindResolution : IdePlatformKindResolution {
|
|||||||
moduleInfo: IdeaModuleInfo,
|
moduleInfo: IdeaModuleInfo,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
sdkDependency: SdkInfo?
|
sdkDependency: SdkInfo?,
|
||||||
|
stdlibDependency: LibraryInfo?,
|
||||||
): KotlinBuiltIns {
|
): KotlinBuiltIns {
|
||||||
return DefaultBuiltIns.Instance
|
return DefaultBuiltIns.Instance
|
||||||
}
|
}
|
||||||
|
|||||||
+70
-17
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.caches.resolve
|
package org.jetbrains.kotlin.caches.resolve
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.intellij.openapi.roots.libraries.Library
|
import com.intellij.openapi.roots.libraries.Library
|
||||||
@@ -18,10 +19,12 @@ import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
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.SdkInfo
|
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
|
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.supportsAdditionalBuiltInsMembers
|
import org.jetbrains.kotlin.idea.caches.resolve.supportsAdditionalBuiltInsMembers
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
|
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
|
||||||
@@ -30,6 +33,8 @@ import org.jetbrains.kotlin.resolve.TargetEnvironment
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory
|
import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance(JvmPlatformKindResolution::class.java)
|
||||||
|
|
||||||
class JvmPlatformKindResolution : IdePlatformKindResolution {
|
class JvmPlatformKindResolution : IdePlatformKindResolution {
|
||||||
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
||||||
return false // TODO: No library kind for JVM
|
return false // TODO: No library kind for JVM
|
||||||
@@ -51,32 +56,80 @@ class JvmPlatformKindResolution : IdePlatformKindResolution {
|
|||||||
|
|
||||||
override val kind get() = JvmIdePlatformKind
|
override val kind get() = JvmIdePlatformKind
|
||||||
|
|
||||||
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey {
|
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?, stdlibInfo: LibraryInfo?): BuiltInsCacheKey {
|
||||||
return if (sdkInfo != null) CacheKeyBySdk(sdkInfo.sdk) else BuiltInsCacheKey.DefaultBuiltInsKey
|
if (IdeBuiltInsLoadingState.isFromClassLoader && stdlibInfo != null) {
|
||||||
|
LOG.error("Standard library ${stdlibInfo.displayedName} provided for built-ins, but loading from dependencies is disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (sdkInfo != null)
|
||||||
|
CacheKeyByBuiltInsDependencies(sdkInfo.sdk, stdlibInfo)
|
||||||
|
else BuiltInsCacheKey.DefaultBuiltInsKey
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createBuiltIns(
|
override fun createBuiltIns(
|
||||||
moduleInfo: IdeaModuleInfo,
|
moduleInfo: IdeaModuleInfo,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
sdkDependency: SdkInfo?
|
sdkDependency: SdkInfo?,
|
||||||
|
stdlibDependency: LibraryInfo?,
|
||||||
): KotlinBuiltIns {
|
): KotlinBuiltIns {
|
||||||
return if (sdkDependency != null)
|
return when {
|
||||||
JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER).apply {
|
sdkDependency == null -> DefaultBuiltIns.Instance
|
||||||
setPostponedSettingsComputation {
|
stdlibDependency == null || moduleInfo is SdkInfo ->
|
||||||
// SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns
|
createBuiltInsFromClassLoader(moduleInfo, projectContext, resolverForProject, sdkDependency)
|
||||||
val sdkDescriptor = resolverForProject.descriptorForModule(sdkDependency)
|
else -> createBuiltinsFromModuleDependencies(moduleInfo, projectContext, resolverForProject, sdkDependency, stdlibDependency)
|
||||||
|
}
|
||||||
val isAdditionalBuiltInsFeaturesSupported =
|
|
||||||
moduleInfo.supportsAdditionalBuiltInsMembers(projectContext.project)
|
|
||||||
JvmBuiltIns.Settings(sdkDescriptor, isAdditionalBuiltInsFeaturesSupported)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DefaultBuiltIns.Instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CacheKeyBySdk(val sdk: Sdk) : BuiltInsCacheKey
|
private fun createBuiltInsFromClassLoader(
|
||||||
|
moduleInfo: IdeaModuleInfo,
|
||||||
|
projectContext: ProjectContext,
|
||||||
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
|
sdkDependency: SdkInfo,
|
||||||
|
): JvmBuiltIns {
|
||||||
|
return JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER).apply {
|
||||||
|
setPostponedSettingsComputation {
|
||||||
|
// SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns
|
||||||
|
val sdkDescriptor = resolverForProject.descriptorForModule(sdkDependency)
|
||||||
|
|
||||||
|
val isAdditionalBuiltInsFeaturesSupported =
|
||||||
|
moduleInfo.supportsAdditionalBuiltInsMembers(projectContext.project)
|
||||||
|
JvmBuiltIns.Settings(sdkDescriptor, isAdditionalBuiltInsFeaturesSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createBuiltinsFromModuleDependencies(
|
||||||
|
moduleInfo: IdeaModuleInfo,
|
||||||
|
projectContext: ProjectContext,
|
||||||
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
|
sdkDependency: SdkInfo,
|
||||||
|
stdlibDependency: LibraryInfo,
|
||||||
|
): JvmBuiltIns {
|
||||||
|
if (IdeBuiltInsLoadingState.isFromClassLoader) {
|
||||||
|
LOG.error("Incorrect attempt to create built-ins from module dependencies")
|
||||||
|
}
|
||||||
|
|
||||||
|
return JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES).apply {
|
||||||
|
setPostponedBuiltinsModuleComputation {
|
||||||
|
val stdlibDescriptor = resolverForProject.descriptorForModule(stdlibDependency)
|
||||||
|
|
||||||
|
@Suppress("unchecked_cast")
|
||||||
|
stdlibDescriptor as ModuleDescriptorImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
setPostponedSettingsComputation {
|
||||||
|
val sdkDescriptor = resolverForProject.descriptorForModule(sdkDependency)
|
||||||
|
|
||||||
|
val isAdditionalBuiltInsFeaturesSupported =
|
||||||
|
moduleInfo.supportsAdditionalBuiltInsMembers(projectContext.project)
|
||||||
|
|
||||||
|
JvmBuiltIns.Settings(sdkDescriptor, isAdditionalBuiltInsFeaturesSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class CacheKeyByBuiltInsDependencies(val sdk: Sdk, val stdlib: LibraryInfo?) : BuiltInsCacheKey
|
||||||
}
|
}
|
||||||
|
|
||||||
class JvmLibraryInfo(project: Project, library: Library) : LibraryInfo(project, library) {
|
class JvmLibraryInfo(project: Project, library: Library) : LibraryInfo(project, library) {
|
||||||
|
|||||||
+34
-10
@@ -9,6 +9,7 @@ import com.intellij.openapi.diagnostic.Logger
|
|||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.impl.scopes.LibraryScopeBase
|
import com.intellij.openapi.module.impl.scopes.LibraryScopeBase
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.projectRoots.JavaSdk
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.intellij.openapi.roots.*
|
import com.intellij.openapi.roots.*
|
||||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||||
@@ -23,10 +24,7 @@ import com.intellij.util.SmartList
|
|||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||||
import org.jetbrains.kotlin.analyzer.CombinedModuleInfo
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
import org.jetbrains.kotlin.analyzer.LibraryModuleInfo
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
|
||||||
import org.jetbrains.kotlin.analyzer.TrackableModuleInfo
|
|
||||||
import org.jetbrains.kotlin.caches.project.cacheByClassInvalidatingOnRootModifications
|
import org.jetbrains.kotlin.caches.project.cacheByClassInvalidatingOnRootModifications
|
||||||
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
||||||
import org.jetbrains.kotlin.caches.resolve.resolution
|
import org.jetbrains.kotlin.caches.resolve.resolution
|
||||||
@@ -37,8 +35,10 @@ import org.jetbrains.kotlin.idea.KotlinIdeaAnalysisBundle
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.enlargedSearchScope
|
import org.jetbrains.kotlin.idea.caches.resolve.util.enlargedSearchScope
|
||||||
import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker
|
import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker
|
||||||
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
|
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
|
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
|
||||||
import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
|
import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
|
||||||
|
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
|
||||||
import org.jetbrains.kotlin.idea.framework.effectiveKind
|
import org.jetbrains.kotlin.idea.framework.effectiveKind
|
||||||
import org.jetbrains.kotlin.idea.framework.platform
|
import org.jetbrains.kotlin.idea.framework.platform
|
||||||
import org.jetbrains.kotlin.idea.klib.AbstractKlibLibraryInfo
|
import org.jetbrains.kotlin.idea.klib.AbstractKlibLibraryInfo
|
||||||
@@ -48,11 +48,8 @@ import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
|
|||||||
import org.jetbrains.kotlin.idea.util.rootManager
|
import org.jetbrains.kotlin.idea.util.rootManager
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider
|
import org.jetbrains.kotlin.platform.*
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.platform.compat.toOldPlatform
|
import org.jetbrains.kotlin.platform.compat.toOldPlatform
|
||||||
import org.jetbrains.kotlin.platform.idePlatformKind
|
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
|
||||||
import org.jetbrains.kotlin.platform.js.isJs
|
import org.jetbrains.kotlin.platform.js.isJs
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
@@ -356,7 +353,25 @@ abstract class LibraryInfo(override val project: Project, val library: Library)
|
|||||||
val (libraries, sdks) = LibraryDependenciesCache.getInstance(project).getLibrariesAndSdksUsedWith(this)
|
val (libraries, sdks) = LibraryDependenciesCache.getInstance(project).getLibrariesAndSdksUsedWith(this)
|
||||||
|
|
||||||
result.addAll(sdks)
|
result.addAll(sdks)
|
||||||
result.addAll(libraries)
|
|
||||||
|
/*
|
||||||
|
* When built-ins are created from module dependencies (as opposed to loading them from classloader)
|
||||||
|
* we must resolve Kotlin standard library containing some of the built-ins declarations in the same
|
||||||
|
* resolver for project as JDK. This comes from the following requirements:
|
||||||
|
* - JvmBuiltins need JDK and standard library descriptors -> resolver for project should be able to
|
||||||
|
* resolve them
|
||||||
|
* - Builtins are created in BuiltinsCache -> module descriptors should be resolved under lock of the
|
||||||
|
* SDK resolver to prevent deadlocks
|
||||||
|
* This means we have to maintain dependencies of the standard library manually or effectively drop
|
||||||
|
* resolver for SDK otherwise. Libraries depend on superset of their actual dependencies because of
|
||||||
|
* the inability to get real dependencies from IDEA model. So moving stdlib with all dependencies
|
||||||
|
* down is a questionable option.
|
||||||
|
*/
|
||||||
|
if (!IdeBuiltInsLoadingState.isFromClassLoader && this.isCoreKotlinLibrary(project)) {
|
||||||
|
libraries.filterTo(result) { it.isCoreKotlinLibrary(project) }
|
||||||
|
} else {
|
||||||
|
result.addAll(libraries)
|
||||||
|
}
|
||||||
|
|
||||||
return result.toList()
|
return result.toList()
|
||||||
}
|
}
|
||||||
@@ -432,10 +447,19 @@ data class SdkInfo(override val project: Project, val sdk: Sdk) : IdeaModuleInfo
|
|||||||
override fun dependencies(): List<IdeaModuleInfo> = listOf(this)
|
override fun dependencies(): List<IdeaModuleInfo> = listOf(this)
|
||||||
|
|
||||||
override val platform: TargetPlatform
|
override val platform: TargetPlatform
|
||||||
get() = JvmPlatforms.unspecifiedJvmPlatform // TODO(dsavvinov): provide proper target version
|
get() = when {
|
||||||
|
sdk.sdkType is KotlinSdkType -> CommonPlatforms.defaultCommonPlatform
|
||||||
|
else -> JvmPlatforms.unspecifiedJvmPlatform // TODO(dsavvinov): provide proper target version
|
||||||
|
}
|
||||||
|
|
||||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||||
get() = JvmPlatformAnalyzerServices
|
get() = JvmPlatformAnalyzerServices
|
||||||
|
|
||||||
|
override val capabilities: Map<ModuleCapability<*>, Any?>
|
||||||
|
get() = when (this.sdk.sdkType) {
|
||||||
|
is JavaSdk -> super.capabilities + mapOf(JDK_CAPABILITY to true)
|
||||||
|
else -> super.capabilities
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object NotUnderContentRootModuleInfo : IdeaModuleInfo {
|
object NotUnderContentRootModuleInfo : IdeaModuleInfo {
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.caches.project
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.util.indexing.FileBasedIndex
|
||||||
|
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.idea.vfilefinder.KotlinStdlibIndex
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
interface KotlinStdlibCache {
|
||||||
|
fun isStdlib(libraryInfo: LibraryInfo): Boolean
|
||||||
|
fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(project: Project): KotlinStdlibCache =
|
||||||
|
if (IdeBuiltInsLoadingState.isFromClassLoader) {
|
||||||
|
Disabled
|
||||||
|
} else {
|
||||||
|
ServiceManager.getService(project, KotlinStdlibCache::class.java)
|
||||||
|
?: error("Failed to load service ${KotlinStdlibCache::class.java.name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val Disabled = object : KotlinStdlibCache {
|
||||||
|
override fun isStdlib(libraryInfo: LibraryInfo) = false
|
||||||
|
override fun isStdlibDependency(libraryInfo: LibraryInfo) = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinStdlibCacheImpl(val project: Project) : KotlinStdlibCache {
|
||||||
|
private val stdlibCache = project.cacheInvalidatingOnRootModifications {
|
||||||
|
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val stdlibDependencyCache = project.cacheInvalidatingOnRootModifications {
|
||||||
|
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LibraryScope(
|
||||||
|
project: Project,
|
||||||
|
private val directories: Set<VirtualFile>
|
||||||
|
) : DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
|
||||||
|
private val fileSystems = directories.mapTo(hashSetOf(), VirtualFile::getFileSystem)
|
||||||
|
|
||||||
|
override fun contains(file: VirtualFile): Boolean =
|
||||||
|
file.fileSystem in fileSystems && generateSequence(file, VirtualFile::getParent).any { it in directories }
|
||||||
|
|
||||||
|
override fun toString() = "All files under: $directories"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun libraryScopeContainsIndexedFilesForNames(libraryInfo: LibraryInfo, names: Collection<FqName>) = runReadAction {
|
||||||
|
names.any { name ->
|
||||||
|
FileBasedIndex.getInstance().getContainingFiles(
|
||||||
|
KotlinStdlibIndex.KEY,
|
||||||
|
name,
|
||||||
|
LibraryScope(project, libraryInfo.library.rootProvider.getFiles(OrderRootType.CLASSES).toSet())
|
||||||
|
).isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun libraryScopeContainsIndexedFilesForName(libraryInfo: LibraryInfo, name: FqName) =
|
||||||
|
libraryScopeContainsIndexedFilesForNames(libraryInfo, listOf(name))
|
||||||
|
|
||||||
|
override fun isStdlib(libraryInfo: LibraryInfo): Boolean {
|
||||||
|
return stdlibCache.getOrPut(libraryInfo) {
|
||||||
|
libraryScopeContainsIndexedFilesForName(libraryInfo, KotlinStdlibIndex.KOTLIN_STDLIB_NAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean {
|
||||||
|
return stdlibDependencyCache.getOrPut(libraryInfo) {
|
||||||
|
libraryScopeContainsIndexedFilesForNames(libraryInfo, KotlinStdlibIndex.STANDARD_LIBRARY_DEPENDENCY_NAMES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LibraryInfo.isCoreKotlinLibrary(project: Project): Boolean =
|
||||||
|
isKotlinStdlib(project) || isKotlinStdlibDependency(project)
|
||||||
|
|
||||||
|
fun LibraryInfo.isKotlinStdlib(project: Project): Boolean =
|
||||||
|
KotlinStdlibCache.getInstance(project).isStdlib(this)
|
||||||
|
|
||||||
|
fun LibraryInfo.isKotlinStdlibDependency(project: Project): Boolean =
|
||||||
|
KotlinStdlibCache.getInstance(project).isStdlibDependency(this)
|
||||||
+6
-3
@@ -74,8 +74,8 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
|||||||
val otherLibrary = libraryOrderEntry.library
|
val otherLibrary = libraryOrderEntry.library
|
||||||
if (otherLibrary is LibraryEx && !otherLibrary.isDisposed) {
|
if (otherLibrary is LibraryEx && !otherLibrary.isDisposed) {
|
||||||
val otherLibraryInfos = createLibraryInfo(project, otherLibrary)
|
val otherLibraryInfos = createLibraryInfo(project, otherLibrary)
|
||||||
otherLibraryInfos.firstOrNull()?.platform?.let { otherLibraryPlatform ->
|
otherLibraryInfos.firstOrNull()?.let { otherLibraryInfo ->
|
||||||
if (compatiblePlatforms(platform, otherLibraryPlatform)) {
|
if (compatiblePlatforms(platform, otherLibraryInfo.platform)) {
|
||||||
libraries.addAll(otherLibraryInfos)
|
libraries.addAll(otherLibraryInfos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,10 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
|||||||
|
|
||||||
override fun visitJdkOrderEntry(jdkOrderEntry: JdkOrderEntry, value: Unit) {
|
override fun visitJdkOrderEntry(jdkOrderEntry: JdkOrderEntry, value: Unit) {
|
||||||
val jdk = jdkOrderEntry.jdk ?: return
|
val jdk = jdkOrderEntry.jdk ?: return
|
||||||
sdks += SdkInfo(project, jdk)
|
SdkInfo(project, jdk).also { sdkInfo ->
|
||||||
|
if (compatiblePlatforms(platform, sdkInfo.platform))
|
||||||
|
sdks += sdkInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, Unit)
|
}, Unit)
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-6
@@ -6,14 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.idea.caches.resolve
|
package org.jetbrains.kotlin.idea.caches.resolve
|
||||||
|
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.util.ModificationTracker
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
|
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.caches.resolve.CompositeAnalyzerServices
|
import org.jetbrains.kotlin.caches.resolve.*
|
||||||
import org.jetbrains.kotlin.caches.resolve.CompositeResolverForModuleFactory
|
|
||||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
|
||||||
import org.jetbrains.kotlin.caches.resolve.resolution
|
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.context.withModule
|
import org.jetbrains.kotlin.context.withModule
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
@@ -22,6 +20,7 @@ import org.jetbrains.kotlin.idea.caches.project.*
|
|||||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
||||||
import org.jetbrains.kotlin.idea.compiler.IdeSealedClassInheritorsProvider
|
import org.jetbrains.kotlin.idea.compiler.IdeSealedClassInheritorsProvider
|
||||||
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
||||||
@@ -101,6 +100,9 @@ class IdeaResolverForProject(
|
|||||||
"Unexpected modules passed through JvmPlatformParameters to IDE resolver ($targetModuleInfo, $referencingModuleInfo)"
|
"Unexpected modules passed through JvmPlatformParameters to IDE resolver ($targetModuleInfo, $referencingModuleInfo)"
|
||||||
}
|
}
|
||||||
tryGetResolverForModuleWithResolutionAnchorFallback(targetModuleInfo, referencingModuleInfo)
|
tryGetResolverForModuleWithResolutionAnchorFallback(targetModuleInfo, referencingModuleInfo)
|
||||||
|
},
|
||||||
|
useBuiltinsProviderForModule = {
|
||||||
|
IdeBuiltInsLoadingState.isFromDependenciesForJvm && it is LibraryInfo && it.isKotlinStdlib(projectContext.project)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -132,18 +134,28 @@ class IdeaResolverForProject(
|
|||||||
|
|
||||||
fun getOrCreateIfNeeded(module: IdeaModuleInfo): KotlinBuiltIns = projectContextFromSdkResolver.storageManager.compute {
|
fun getOrCreateIfNeeded(module: IdeaModuleInfo): KotlinBuiltIns = projectContextFromSdkResolver.storageManager.compute {
|
||||||
val sdk = resolverForSdk.sdkDependency(module)
|
val sdk = resolverForSdk.sdkDependency(module)
|
||||||
|
val stdlib = findStdlibForModulesBuiltins(module)
|
||||||
|
|
||||||
val key = module.platform.idePlatformKind.resolution.getKeyForBuiltIns(module, sdk)
|
val key = module.platform.idePlatformKind.resolution.getKeyForBuiltIns(module, sdk, stdlib)
|
||||||
val cachedBuiltIns = cache[key]
|
val cachedBuiltIns = cache[key]
|
||||||
if (cachedBuiltIns != null) return@compute cachedBuiltIns
|
if (cachedBuiltIns != null) return@compute cachedBuiltIns
|
||||||
|
|
||||||
module.platform.idePlatformKind.resolution
|
module.platform.idePlatformKind.resolution
|
||||||
.createBuiltIns(module, projectContextFromSdkResolver, resolverForSdk, sdk)
|
.createBuiltIns(module, projectContextFromSdkResolver, resolverForSdk, sdk, stdlib)
|
||||||
.also {
|
.also {
|
||||||
// TODO: MemoizedFunction should be used here instead, but for proper we also need a module (for LV settings) that is not contained in the key
|
// TODO: MemoizedFunction should be used here instead, but for proper we also need a module (for LV settings) that is not contained in the key
|
||||||
cache[key] = it
|
cache[key] = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun findStdlibForModulesBuiltins(module: IdeaModuleInfo): LibraryInfo? {
|
||||||
|
if (IdeBuiltInsLoadingState.isFromClassLoader)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return module.dependencies().lazyClosure { it.dependencies() }.firstOrNull {
|
||||||
|
it is LibraryInfo && it.isKotlinStdlib(projectContextFromSdkResolver.project)
|
||||||
|
} as? LibraryInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryGetResolverForModuleWithResolutionAnchorFallback(
|
private fun tryGetResolverForModuleWithResolutionAnchorFallback(
|
||||||
|
|||||||
+5
-4
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.context.GlobalContextImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.project.*
|
import org.jetbrains.kotlin.idea.caches.project.*
|
||||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.GlobalFacadeModuleFilters
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.contextWithCompositeExceptionTracker
|
import org.jetbrains.kotlin.idea.caches.resolve.util.contextWithCompositeExceptionTracker
|
||||||
import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount
|
import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount
|
||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
@@ -174,13 +175,13 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private inner class GlobalFacade(settings: PlatformAnalysisSettings) {
|
private inner class GlobalFacade(settings: PlatformAnalysisSettings) {
|
||||||
private val sdkContext = GlobalContext(resolverForSdkName)
|
private val sdkContext = GlobalContext(resolverForSdkName)
|
||||||
|
private val moduleFilters = GlobalFacadeModuleFilters(project)
|
||||||
val facadeForSdk = ProjectResolutionFacade(
|
val facadeForSdk = ProjectResolutionFacade(
|
||||||
"facadeForSdk", "$resolverForSdkName with settings=$settings",
|
"facadeForSdk", "$resolverForSdkName with settings=$settings",
|
||||||
project, sdkContext, settings,
|
project, sdkContext, settings,
|
||||||
moduleFilter = { it is SdkInfo },
|
moduleFilter = moduleFilters::sdkFacadeFilter,
|
||||||
dependencies = listOf(
|
dependencies = listOf(
|
||||||
LibraryModificationTracker.getInstance(project),
|
LibraryModificationTracker.getInstance(project),
|
||||||
ProjectRootModificationTracker.getInstance(project)
|
ProjectRootModificationTracker.getInstance(project)
|
||||||
@@ -194,7 +195,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
"facadeForLibraries", "$resolverForLibrariesName with settings=$settings",
|
"facadeForLibraries", "$resolverForLibrariesName with settings=$settings",
|
||||||
project, librariesContext, settings,
|
project, librariesContext, settings,
|
||||||
reuseDataFrom = facadeForSdk,
|
reuseDataFrom = facadeForSdk,
|
||||||
moduleFilter = { it is LibraryInfo },
|
moduleFilter = moduleFilters::libraryFacadeFilter,
|
||||||
invalidateOnOOCB = false,
|
invalidateOnOOCB = false,
|
||||||
dependencies = listOf(
|
dependencies = listOf(
|
||||||
LibraryModificationTracker.getInstance(project),
|
LibraryModificationTracker.getInstance(project),
|
||||||
@@ -207,7 +208,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
"facadeForModules", "$resolverForModulesName with settings=$settings",
|
"facadeForModules", "$resolverForModulesName with settings=$settings",
|
||||||
project, modulesContext, settings,
|
project, modulesContext, settings,
|
||||||
reuseDataFrom = facadeForLibraries,
|
reuseDataFrom = facadeForLibraries,
|
||||||
moduleFilter = { !it.isLibraryClasses() },
|
moduleFilter = moduleFilters::moduleFacadeFilter,
|
||||||
dependencies = listOf(
|
dependencies = listOf(
|
||||||
LibraryModificationTracker.getInstance(project),
|
LibraryModificationTracker.getInstance(project),
|
||||||
ProjectRootModificationTracker.getInstance(project)
|
ProjectRootModificationTracker.getInstance(project)
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.caches.resolve.util
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.*
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
||||||
|
|
||||||
|
internal interface ModuleFilters {
|
||||||
|
fun sdkFacadeFilter(module: IdeaModuleInfo): Boolean
|
||||||
|
fun libraryFacadeFilter(module: IdeaModuleInfo): Boolean
|
||||||
|
fun moduleFacadeFilter(module: IdeaModuleInfo): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ClassLoaderBuiltInsModuleFilters : ModuleFilters {
|
||||||
|
override fun sdkFacadeFilter(module: IdeaModuleInfo): Boolean = module is SdkInfo
|
||||||
|
override fun libraryFacadeFilter(module: IdeaModuleInfo): Boolean = module is LibraryInfo
|
||||||
|
override fun moduleFacadeFilter(module: IdeaModuleInfo): Boolean = !module.isLibraryClasses()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DependencyBuiltinsModuleFilters(private val project: Project) : ModuleFilters {
|
||||||
|
override fun sdkFacadeFilter(module: IdeaModuleInfo): Boolean =
|
||||||
|
module is SdkInfo || module is LibraryInfo && module.isCoreKotlinLibrary(project)
|
||||||
|
|
||||||
|
override fun libraryFacadeFilter(module: IdeaModuleInfo): Boolean =
|
||||||
|
module is LibraryInfo && !module.isCoreKotlinLibrary(project)
|
||||||
|
|
||||||
|
override fun moduleFacadeFilter(module: IdeaModuleInfo): Boolean = !module.isLibraryClasses()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class GlobalFacadeModuleFilters(project: Project) : ModuleFilters {
|
||||||
|
private val impl = when (IdeBuiltInsLoadingState.state) {
|
||||||
|
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_CLASSLOADER -> ClassLoaderBuiltInsModuleFilters
|
||||||
|
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_DEPENDENCIES_JVM -> DependencyBuiltinsModuleFilters(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sdkFacadeFilter(module: IdeaModuleInfo): Boolean = impl.sdkFacadeFilter(module)
|
||||||
|
override fun libraryFacadeFilter(module: IdeaModuleInfo): Boolean = impl.libraryFacadeFilter(module)
|
||||||
|
override fun moduleFacadeFilter(module: IdeaModuleInfo): Boolean = impl.moduleFacadeFilter(module)
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
object IdeBuiltInsLoadingState {
|
||||||
|
val state: IdeBuiltInsLoading = IdeBuiltInsLoading.FROM_DEPENDENCIES_JVM
|
||||||
|
|
||||||
|
enum class IdeBuiltInsLoading {
|
||||||
|
FROM_CLASSLOADER,
|
||||||
|
FROM_DEPENDENCIES_JVM;
|
||||||
|
}
|
||||||
|
|
||||||
|
val isFromDependenciesForJvm: Boolean
|
||||||
|
get() = state == IdeBuiltInsLoading.FROM_DEPENDENCIES_JVM
|
||||||
|
|
||||||
|
val isFromClassLoader: Boolean
|
||||||
|
get() = state == IdeBuiltInsLoading.FROM_CLASSLOADER
|
||||||
|
}
|
||||||
+7
-6
@@ -18,7 +18,7 @@ import java.io.InputStream
|
|||||||
|
|
||||||
class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFinder() {
|
class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFinder() {
|
||||||
override fun findMetadata(classId: ClassId): InputStream? {
|
override fun findMetadata(classId: ClassId): InputStream? {
|
||||||
val file = findVirtualFileWithHeader(classId, KotlinMetadataFileIndex.KEY) ?: return null
|
val file = findVirtualFileWithHeader(classId.asSingleFqName(), KotlinMetadataFileIndex.KEY) ?: return null
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
file.inputStream
|
file.inputStream
|
||||||
@@ -29,8 +29,8 @@ class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFi
|
|||||||
|
|
||||||
override fun hasMetadataPackage(fqName: FqName): Boolean = KotlinMetadataFilePackageIndex.hasSomethingInPackage(fqName, scope)
|
override fun hasMetadataPackage(fqName: FqName): Boolean = KotlinMetadataFilePackageIndex.hasSomethingInPackage(fqName, scope)
|
||||||
|
|
||||||
// TODO: load built-ins metadata from scope
|
override fun findBuiltInsData(packageFqName: FqName): InputStream? =
|
||||||
override fun findBuiltInsData(packageFqName: FqName): InputStream? = null
|
findVirtualFileWithHeader(packageFqName, KotlinBuiltInsMetadataIndex.KEY)?.inputStream
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.project == null) {
|
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.project == null) {
|
||||||
@@ -38,10 +38,11 @@ class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? = findVirtualFileWithHeader(classId, KotlinClassFileIndex.KEY)
|
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
||||||
|
findVirtualFileWithHeader(classId.asSingleFqName(), KotlinClassFileIndex.KEY)
|
||||||
|
|
||||||
private fun findVirtualFileWithHeader(classId: ClassId, key: ID<FqName, Void>): VirtualFile? =
|
private fun findVirtualFileWithHeader(fqName: FqName, key: ID<FqName, Void>): VirtualFile? =
|
||||||
FileBasedIndex.getInstance().getContainingFiles(key, classId.asSingleFqName(), scope).firstOrNull()
|
FileBasedIndex.getInstance().getContainingFiles(key, fqName, scope).firstOrNull()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOG = Logger.getInstance(IDEVirtualFileFinder::class.java)
|
private val LOG = Logger.getInstance(IDEVirtualFileFinder::class.java)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import com.intellij.util.indexing.*
|
import com.intellij.util.indexing.*
|
||||||
import com.intellij.util.io.IOUtil
|
import com.intellij.util.io.IOUtil
|
||||||
import com.intellij.util.io.KeyDescriptor
|
import com.intellij.util.io.KeyDescriptor
|
||||||
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
||||||
import org.jetbrains.kotlin.idea.decompiler.builtIns.BuiltInDefinitionFile
|
import org.jetbrains.kotlin.idea.decompiler.builtIns.BuiltInDefinitionFile
|
||||||
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType
|
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType
|
||||||
@@ -25,10 +26,12 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment
|
import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||||
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
||||||
|
import org.jetbrains.lang.manifest.ManifestFileType
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.DataInput
|
import java.io.DataInput
|
||||||
import java.io.DataOutput
|
import java.io.DataOutput
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.jar.Manifest
|
||||||
|
|
||||||
abstract class KotlinFileIndexBase<T>(classOfIndex: Class<T>) : ScalarIndexExtension<FqName>() {
|
abstract class KotlinFileIndexBase<T>(classOfIndex: Class<T>) : ScalarIndexExtension<FqName>() {
|
||||||
val KEY: ID<FqName, Void> = ID.create(classOfIndex.canonicalName)
|
val KEY: ID<FqName, Void> = ID.create(classOfIndex.canonicalName)
|
||||||
@@ -142,6 +145,54 @@ object KotlinMetadataFilePackageIndex : KotlinMetadataFileIndexBase<KotlinMetada
|
|||||||
KotlinMetadataFilePackageIndex::class.java, ClassId::getPackageFqName
|
KotlinMetadataFilePackageIndex::class.java, ClassId::getPackageFqName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
object KotlinBuiltInsMetadataIndex : KotlinFileIndexBase<KotlinBuiltInsMetadataIndex>(KotlinBuiltInsMetadataIndex::class.java) {
|
||||||
|
override fun getIndexer() = INDEXER
|
||||||
|
|
||||||
|
override fun getInputFilter() = FileBasedIndex.InputFilter { file -> file.fileType == KotlinBuiltInFileType }
|
||||||
|
|
||||||
|
override fun getVersion() = VERSION
|
||||||
|
|
||||||
|
private val VERSION = 1
|
||||||
|
|
||||||
|
private val INDEXER = indexer { fileContent ->
|
||||||
|
if (fileContent.fileType == KotlinBuiltInFileType &&
|
||||||
|
fileContent.fileName.endsWith(JvmBuiltInsPackageFragmentProvider.DOT_BUILTINS_METADATA_FILE_EXTENSION)) {
|
||||||
|
val builtins = BuiltInDefinitionFile.read(fileContent.content, fileContent.file.parent)
|
||||||
|
(builtins as? BuiltInDefinitionFile)?.packageFqName
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object KotlinStdlibIndex : KotlinFileIndexBase<KotlinStdlibIndex>(KotlinStdlibIndex::class.java) {
|
||||||
|
private const val LIBRARY_NAME_MANIFEST_ATTRIBUTE = "Implementation-Title"
|
||||||
|
private const val STDLIB_TAG_MANIFEST_ATTRIBUTE = "Kotlin-Runtime-Component"
|
||||||
|
val KOTLIN_STDLIB_NAME = FqName("kotlin-stdlib")
|
||||||
|
val KOTLIN_STDLIB_COMMON_NAME = FqName("kotlin-stdlib-common")
|
||||||
|
|
||||||
|
val STANDARD_LIBRARY_DEPENDENCY_NAMES = setOf(
|
||||||
|
KOTLIN_STDLIB_COMMON_NAME,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getIndexer() = INDEXER
|
||||||
|
|
||||||
|
override fun getInputFilter() = FileBasedIndex.InputFilter { file -> file.fileType is ManifestFileType }
|
||||||
|
|
||||||
|
override fun getVersion() = VERSION
|
||||||
|
|
||||||
|
private val VERSION = 1
|
||||||
|
|
||||||
|
// TODO: refactor [KotlinFileIndexBase] and get rid of FqName here, it's never a proper fully qualified name, just a String wrapper
|
||||||
|
private val INDEXER = indexer { fileContent ->
|
||||||
|
if (fileContent.fileType is ManifestFileType) {
|
||||||
|
val manifest = Manifest(ByteArrayInputStream(fileContent.content))
|
||||||
|
val attributes = manifest.mainAttributes
|
||||||
|
attributes.getValue(STDLIB_TAG_MANIFEST_ATTRIBUTE) ?: return@indexer null
|
||||||
|
val libraryName = attributes.getValue(LIBRARY_NAME_MANIFEST_ATTRIBUTE) ?: return@indexer null
|
||||||
|
FqName(libraryName)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object KlibMetaFileIndex : KotlinFileIndexBase<KlibMetaFileIndex>(KlibMetaFileIndex::class.java) {
|
object KlibMetaFileIndex : KotlinFileIndexBase<KlibMetaFileIndex>(KlibMetaFileIndex::class.java) {
|
||||||
|
|
||||||
override fun getIndexer() = INDEXER
|
override fun getIndexer() = INDEXER
|
||||||
|
|||||||
@@ -94,13 +94,14 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
|
|||||||
|
|
||||||
override val kind get() = NativeIdePlatformKind
|
override val kind get() = NativeIdePlatformKind
|
||||||
|
|
||||||
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey = NativeBuiltInsCacheKey
|
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?, stdlibInfo: LibraryInfo?): BuiltInsCacheKey = NativeBuiltInsCacheKey
|
||||||
|
|
||||||
override fun createBuiltIns(
|
override fun createBuiltIns(
|
||||||
moduleInfo: IdeaModuleInfo,
|
moduleInfo: IdeaModuleInfo,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||||
sdkDependency: SdkInfo?
|
sdkDependency: SdkInfo?,
|
||||||
|
stdlibDependency: LibraryInfo?,
|
||||||
) = createKotlinNativeBuiltIns(moduleInfo, projectContext)
|
) = createKotlinNativeBuiltIns(moduleInfo, projectContext)
|
||||||
|
|
||||||
private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns {
|
private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns {
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.lightClasses.ClsJavaStubByVirtualFileCache"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.lightClasses.ClsJavaStubByVirtualFileCache"/>
|
||||||
|
|
||||||
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.caches.project.KotlinStdlibCache"
|
||||||
|
serviceImplementation="org.jetbrains.kotlin.idea.caches.project.KotlinStdlibCacheImpl"/>
|
||||||
|
|
||||||
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
|
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
|
||||||
<applicationService serviceImplementation="org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache"/>
|
<applicationService serviceImplementation="org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache"/>
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinModuleMappingIndex"/>
|
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinModuleMappingIndex"/>
|
||||||
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex"/>
|
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex"/>
|
||||||
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinJvmModuleAnnotationsIndex"/>
|
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinJvmModuleAnnotationsIndex"/>
|
||||||
|
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinBuiltInsMetadataIndex"/>
|
||||||
|
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinStdlibIndex"/>
|
||||||
|
|
||||||
<idIndexer filetype="Kotlin" implementationClass="org.jetbrains.kotlin.idea.search.KotlinIdIndexer"/>
|
<idIndexer filetype="Kotlin" implementationClass="org.jetbrains.kotlin.idea.search.KotlinIdIndexer"/>
|
||||||
<todoIndexer filetype="Kotlin" implementationClass="org.jetbrains.kotlin.idea.search.KotlinTodoIndexer"/>
|
<todoIndexer filetype="Kotlin" implementationClass="org.jetbrains.kotlin.idea.search.KotlinTodoIndexer"/>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fun getKCallable(): KCallable<*> = ::jvmFun
|
|||||||
fun <!LINE_MARKER!>main<!>() {
|
fun <!LINE_MARKER!>main<!>() {
|
||||||
val ref = ::jvmFun
|
val ref = ::jvmFun
|
||||||
val typedRef: KCallable<*> = getKCallable()
|
val typedRef: KCallable<*> = getKCallable()
|
||||||
ref.<!UNRESOLVED_REFERENCE!>call<!>()
|
ref.call()
|
||||||
typedRef.call()
|
typedRef.call()
|
||||||
foo(Foo::bar)
|
foo(Foo::bar)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user