[kotlin] fix completion from builtins in common sourcest

The problem was in fact that common stdlib does not contain builtins. In this case, builtin declarations should be resolved to the bundled builtins.

Completion works via `KtScopeProviderMixIn.getScopeContextForPosition`.
Builtins should come via default star-importing scope.
To collect callable and classifier names there, `IdeKotlinDeclarationProvider.getTopLevel(KotlinClassLikeDeclaration/Callables)NamesInPackage` are used which use the scope provided by `IdeKotlinByModulesResolutionScopeProvider`.

An additional change in `IdeKotlinByModulesResolutionScopeProvider` is needed to ensure that for the declarations from builtins we get `KtBuiltinsModule` instead of `KtNotUnderContentRootModule`

Tests were added in the previous commits as a part of KTIJ-28550

^KTIJ-29826 fixed

GitOrigin-RevId: 819b4c70c6c135e51b232ac8d5e22d165da4debe
This commit is contained in:
Ilya Kirillov
2024-05-03 19:19:50 +02:00
committed by intellij-monorepo-bot
parent 860f311e27
commit b9122da1cd
2 changed files with 46 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.base.analysisApiPlatform
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinResolutionScopeProvider
import org.jetbrains.kotlin.analysis.api.projectStructure.KaDanglingFileModule
@@ -8,6 +9,7 @@ import org.jetbrains.kotlin.analysis.api.projectStructure.KaLibrarySourceModule
import org.jetbrains.kotlin.analysis.api.projectStructure.KaModule
import org.jetbrains.kotlin.analysis.api.projectStructure.KaSourceModule
import org.jetbrains.kotlin.analysis.api.projectStructure.allDirectDependencies
import org.jetbrains.kotlin.analysis.project.structure.utils.BuiltInsVirtualFileProvider
import org.jetbrains.kotlin.idea.base.projectStructure.KtSourceModuleByModuleInfoForOutsider
import org.jetbrains.kotlin.idea.base.projectStructure.ModuleDependencyCollector
import org.jetbrains.kotlin.idea.base.projectStructure.collectDependencies
@@ -27,11 +29,8 @@ internal class IdeKotlinByModulesResolutionScopeProvider : KotlinResolutionScope
val moduleInfo = module.moduleInfo as ModuleSourceInfo
val includeTests = moduleInfo is ModuleTestSourceInfo
val scope = excludeIgnoredModulesByKotlinProjectModel(moduleInfo, module, includeTests)
return if (module is KtSourceModuleByModuleInfoForOutsider) {
module.adjustContentScope(scope)
} else {
scope
}
return adjustScope(scope, module)
}
is KaDanglingFileModule -> {
@@ -57,6 +56,22 @@ internal class IdeKotlinByModulesResolutionScopeProvider : KotlinResolutionScope
}
}
private fun adjustScope(baseScope: GlobalSearchScope, module: KtSourceModule): GlobalSearchScope {
var scope = baseScope
if (module is KtSourceModuleByModuleInfoForOutsider) {
scope = module.adjustContentScope(scope)
}
// every module depends on a builtin module, so builtins are always visible
scope = scope.withBuiltInsScope(module.project)
return scope
}
private fun GlobalSearchScope.withBuiltInsScope(project: Project): GlobalSearchScope {
val builtInFiles = BuiltInsVirtualFileProvider.getInstance().getBuiltInVirtualFiles()
val builtinsScope = GlobalSearchScope.filesScope(project, builtInFiles)
return GlobalSearchScope.union(listOf(this, builtinsScope))
}
/**
* Some dependencies from order entities might be filtered by [org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.SourceModuleDependenciesFilter]
* Those entries would still be present in the [GlobalSearchScope.moduleWithDependenciesAndLibrariesScope].

View File

@@ -12,9 +12,11 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.parentOfType
import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
import org.jetbrains.kotlin.analysis.decompiler.psi.BuiltInsVirtualFileProvider
import org.jetbrains.kotlin.analysis.api.KaPlatformInterface
import org.jetbrains.kotlin.analysis.api.platform.modification.KotlinModificationTrackerFactory
import org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinProjectStructureProvider
@@ -28,11 +30,14 @@ import org.jetbrains.kotlin.analysis.api.projectStructure.KaScriptModule
import org.jetbrains.kotlin.analysis.api.projectStructure.KaSourceModule
import org.jetbrains.kotlin.analysis.api.projectStructure.danglingFileResolutionMode
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.idea.base.facet.platform.platform
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.*
import org.jetbrains.kotlin.idea.base.util.getOutsiderFileOrigin
import org.jetbrains.kotlin.idea.base.util.isOutsiderFile
import org.jetbrains.kotlin.parsing.KotlinParserDefinition.Companion.STD_SCRIPT_EXT
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
@@ -127,19 +132,37 @@ internal class ProjectStructureProviderIdeImpl(private val project: Project) : K
val moduleInfo = computeModuleInfoForOrdinaryModule(psiElement, contextualModule, virtualFile)
if (moduleInfo == null && virtualFile != null) {
computeBuiltinKtModule(virtualFile, psiElement)?.let { return it }
}
if (virtualFile != null && isOutsiderFile(virtualFile) && moduleInfo is ModuleSourceInfo) {
val originalFile = getOutsiderFileOrigin(project, virtualFile)
return KtSourceModuleByModuleInfoForOutsider(virtualFile, originalFile, moduleInfo)
}
return getKtModuleByModuleInfo(moduleInfo)
return getKtModuleByModuleInfo(moduleInfo ?: NotUnderContentRootModuleInfo(project, psiElement.containingFile as? KtFile))
}
private fun computeBuiltinKtModule(virtualFile: VirtualFile, psiElement: PsiElement): KtBuiltinsModule? {
if (virtualFile in BuiltInsVirtualFileProvider.getInstance().getBuiltInVirtualFiles()) {
val ktElement = psiElement.parentOfType<KtElement>(withSelf = true)
if (ktElement != null) {
return KtBuiltinsModule(
ktElement.platform,
JvmPlatformAnalyzerServices /* unused, will be removed as a part of KT-67969 */,
project
)
}
}
return null
}
private fun <T> computeModuleInfoForOrdinaryModule(
psiElement: PsiElement,
contextualModule: T?,
virtualFile: VirtualFile?
): ModuleInfo where T : KaModule, T : KtModuleByModuleInfoBase {
): IdeaModuleInfo? where T : KaModule, T : KtModuleByModuleInfoBase {
val infoProvider = ModuleInfoProvider.getInstance(project)
val config = ModuleInfoProvider.Configuration(
@@ -162,7 +185,7 @@ internal class ProjectStructureProviderIdeImpl(private val project: Project) : K
}
}
return NotUnderContentRootModuleInfo(project, psiElement.containingFile as? KtFile)
return null
}
companion object {