[Analysis API] Add source shadowing for resolve extensions.

KtResolveExtensions are designed to handle IDE analysis use cases where
source might not be available at analysis time, because that source is
generated by an external source generator, such as an annotation
processor or resource compiler. The sources generated by those external
generators can appear in the analysis scope, and cause issues with
source clash - resolution may find the virtual source from the
KtResolveExtension, the on-disk generated source from the external
generator, or both. This can cause issues, because that on-disk
generated source may be stale, and may not have symbols that will exist
the next time the generator is run (or, conversely, may have symbols
that will disappear on the next build).

To solve this, add a `getShadowedScope(): GlobalSearchScope` to
`KtResolveExtension`. Any files in the module that are included in that
scope will be hidden from resolution, allowing the resolve extension to
cleanly replace those files.

^KT-58834 fixed
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt
index 1054002..902a0b4 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt
@@ -6,6 +6,7 @@
 package org.jetbrains.kotlin.analysis.api.descriptors
 
 import com.intellij.openapi.project.Project
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
 import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
 import org.jetbrains.kotlin.analysis.api.components.*
@@ -61,7 +62,8 @@
     override val importOptimizerImpl: KtImportOptimizer = KtFe10ImportOptimizer(this)
     override val jvmTypeMapperImpl: KtJvmTypeMapper = KtFe10JvmTypeMapper(this)
     override val symbolInfoProviderImpl: KtSymbolInfoProvider = KtFe10SymbolInfoProvider(this)
-    override val analysisScopeProviderImpl: KtAnalysisScopeProvider = KtAnalysisScopeProviderImpl(this, token)
+    override val analysisScopeProviderImpl: KtAnalysisScopeProvider =
+        KtAnalysisScopeProviderImpl(this, token, shadowedScope = GlobalSearchScope.EMPTY_SCOPE)
     override val referenceResolveProviderImpl: KtReferenceResolveProvider = KtFe10ReferenceResolveProvider(this)
     override val signatureSubstitutorImpl: KtSignatureSubstitutor = KtFe10SignatureSubstitutor(this)
     override val scopeSubstitutionImpl: KtScopeSubstitution = KtFe10ScopeSubstitution(this)
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt
index 4704c7b..9dcf00c 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt
@@ -114,7 +114,7 @@
 
     override val typesCreatorImpl: KtTypeCreator = KtFirTypeCreator(this, token)
 
-    override val analysisScopeProviderImpl: KtAnalysisScopeProvider = KtAnalysisScopeProviderImpl(this, token)
+    override val analysisScopeProviderImpl: KtAnalysisScopeProvider
 
     override val referenceResolveProviderImpl: KtReferenceResolveProvider = KtFirReferenceResolveProvider(this)
 
@@ -153,9 +153,10 @@
     internal val firSymbolProvider: FirSymbolProvider get() = useSiteSession.symbolProvider
     internal val targetPlatform: TargetPlatform get() = useSiteSession.moduleData.platform
 
-    val useSiteAnalysisScope: GlobalSearchScope = analysisScopeProviderImpl.getAnalysisScope()
-
     val extensionTools: List<LLFirResolveExtensionTool>
+
+    val useSiteAnalysisScope: GlobalSearchScope
+
     val useSiteScopeDeclarationProvider: KotlinDeclarationProvider
     val useSitePackageProvider: KotlinPackageProvider
 
@@ -167,6 +168,20 @@
                 firResolveSession.getSessionFor(dependency).llResolveExtensionTool
             }
         }
+
+        val shadowedScope = GlobalSearchScope.union(
+            buildSet {
+                // Add an empty scope to the shadowed set to give GlobalSearchScope.union something
+                // to work with if there are no extension tools.
+                // If there are extension tools, any empty scopes, whether from shadowedSearchScope
+                // on the extension tools or from this add() call, will be ignored.
+                add(GlobalSearchScope.EMPTY_SCOPE)
+                extensionTools.mapTo(this) { it.shadowedSearchScope }
+            }
+        )
+        analysisScopeProviderImpl = KtAnalysisScopeProviderImpl(this, token, shadowedScope)
+        useSiteAnalysisScope = analysisScopeProviderImpl.getAnalysisScope()
+
         useSiteScopeDeclarationProvider = CompositeKotlinDeclarationProvider.create(
             buildList {
                 add(project.createDeclarationProvider(useSiteAnalysisScope, useSiteModule))
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
index b4ea9b9..e5786dc 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
@@ -68,6 +68,24 @@
         }
 
         @Test
+        @TestMetadata("shadowedDeclaration.kt")
+        public void testShadowedDeclaration() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedDeclaration.kt");
+        }
+
+        @Test
+        @TestMetadata("shadowedJava.kt")
+        public void testShadowedJava() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedJava.kt");
+        }
+
+        @Test
+        @TestMetadata("shadowedOverload.kt")
+        public void testShadowedOverload() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.kt");
+        }
+
+        @Test
         @TestMetadata("topLevelFunction.kt")
         public void testTopLevelFunction() throws Exception {
             runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/topLevelFunction.kt");
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
index 8fa1fd2..9074af9 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
@@ -59,6 +59,24 @@
     }
 
     @Test
+    @TestMetadata("shadowedDeclaration.kt")
+    public void testShadowedDeclaration() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedDeclaration.kt");
+    }
+
+    @Test
+    @TestMetadata("shadowedJava.kt")
+    public void testShadowedJava() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedJava.kt");
+    }
+
+    @Test
+    @TestMetadata("shadowedOverload.kt")
+    public void testShadowedOverload() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.kt");
+    }
+
+    @Test
     @TestMetadata("topLevelFunction.kt")
     public void testTopLevelFunction() throws Exception {
         runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/topLevelFunction.kt");
diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtAnalysisScopeProviderImpl.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtAnalysisScopeProviderImpl.kt
index 24c4136..715e40d 100644
--- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtAnalysisScopeProviderImpl.kt
+++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/KtAnalysisScopeProviderImpl.kt
@@ -23,7 +23,8 @@
 
 class KtAnalysisScopeProviderImpl(
     override val analysisSession: KtAnalysisSession,
-    override val token: KtLifetimeToken
+    override val token: KtLifetimeToken,
+    private val shadowedScope: GlobalSearchScope
 ) : KtAnalysisScopeProvider() {
 
     private val baseResolveScope by lazy(LazyThreadSafetyMode.PUBLICATION) {
@@ -31,13 +32,13 @@
     }
 
     private val resolveScope by lazy(LazyThreadSafetyMode.PUBLICATION) {
-        KtAnalysisScopeProviderResolveScope(baseResolveScope, analysisSession.useSiteModule)
+        KtAnalysisScopeProviderResolveScope(baseResolveScope, analysisSession.useSiteModule, shadowedScope)
     }
 
     override fun getAnalysisScope(): GlobalSearchScope = resolveScope
 
     override fun canBeAnalysed(psi: PsiElement): Boolean {
-        return baseResolveScope.contains(psi)
+        return (baseResolveScope.contains(psi) && !shadowedScope.contains(psi))
                 || psi.isFromGeneratedModule()
     }
 
@@ -49,12 +50,17 @@
 
 private class KtAnalysisScopeProviderResolveScope(
     private val base: GlobalSearchScope,
-    private val useSiteModule: KtModule
+    private val useSiteModule: KtModule,
+    private val shadowed: GlobalSearchScope,
 ) : GlobalSearchScope() {
     override fun getProject(): Project? = base.project
     override fun isSearchInModuleContent(aModule: Module): Boolean = base.isSearchInModuleContent(aModule)
     override fun isSearchInLibraries(): Boolean = base.isSearchInLibraries
-    override fun contains(file: VirtualFile): Boolean = base.contains(file) || file.isFromGeneratedModule(useSiteModule)
+    override fun contains(file: VirtualFile): Boolean =
+        (base.contains(file) && !shadowed.contains(file)) || file.isFromGeneratedModule(useSiteModule)
+
+    override fun toString() =
+        "Analysis scope for $useSiteModule (base: $base, shadowed: $shadowed)"
 }
 
 @OptIn(KtModuleStructureInternals::class)
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractMultiModuleReferenceResolveWithResolveExtensionTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractMultiModuleReferenceResolveWithResolveExtensionTest.kt
index e94af32..4f58b7b 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractMultiModuleReferenceResolveWithResolveExtensionTest.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractMultiModuleReferenceResolveWithResolveExtensionTest.kt
@@ -5,6 +5,7 @@
 
 package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
 
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtMultiModuleResolveExtensionProviderForTest
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
@@ -12,6 +13,12 @@
 import org.jetbrains.kotlin.name.FqName
 
 abstract class AbstractMultiModuleReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveWithResolveExtensionTest() {
-    override fun createResolveExtensionProvider(files: List<KtResolveExtensionFile>, packages: Set<FqName>): KtResolveExtensionProvider =
-        KtMultiModuleResolveExtensionProviderForTest(files, packages) { it is KtSourceModule && it.moduleName == "extendedModule" }
+    override fun createResolveExtensionProvider(
+        files: List<KtResolveExtensionFile>,
+        packages: Set<FqName>,
+        shadowedScope: GlobalSearchScope,
+    ): KtResolveExtensionProvider =
+        KtMultiModuleResolveExtensionProviderForTest(files, packages, shadowedScope) { module ->
+            module is KtSourceModule && module.moduleName == "extendedModule"
+        }
 }
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveWithResolveExtensionTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveWithResolveExtensionTest.kt
index 08df27a..9253a97 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveWithResolveExtensionTest.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractReferenceResolveWithResolveExtensionTest.kt
@@ -5,6 +5,9 @@
 
 package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
 
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionFileForTests
 import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionProviderForTestPreAnalysisHandler
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
@@ -17,17 +20,22 @@
     abstract fun createResolveExtensionProvider(
         files: List<KtResolveExtensionFile>,
         packages: Set<FqName>,
+        shadowedScope: GlobalSearchScope,
     ): KtResolveExtensionProvider
 
     override fun configureTest(builder: TestConfigurationBuilder) {
         super.configureTest(builder)
         val provider = createResolveExtensionProvider(
-            listOf(
+            files = listOf(
                 KtResolveExtensionFileForTests(
                     "extension1.kt",
                     packageName = FqName("generated"),
                     topLevelClassifiersNames = setOf("GeneratedClass1"),
-                    topLevelCallableNames = setOf("generatedTopLevelFunction1", "generatedTopLevelExtensionFunction1"),
+                    topLevelCallableNames = setOf(
+                        "generatedTopLevelFunction1",
+                        "generatedTopLevelExtensionFunction1",
+                        "generatedOverloadedExtensionFunction",
+                    ),
                     fileText = """|package generated
                        |
                        |class GeneratedClass1 {
@@ -37,6 +45,8 @@
                        |fun generatedTopLevelFunction1(): GeneratedClass2
                        |
                        |fun String.generatedTopLevelExtensionFunction1(boolean: Boolean): Int
+                       |
+                       |fun Any.generatedOverloadedExtensionFunction(): Int
                     """.trimMargin()
                 ),
                 KtResolveExtensionFileForTests(
@@ -52,7 +62,14 @@
                     """.trimMargin(),
                 )
             ),
-            setOf(FqName("generated"))
+            packages = setOf(FqName("generated")),
+            shadowedScope = object : GlobalSearchScope() {
+                override fun contains(file: VirtualFile): Boolean = ".hidden." in file.name
+
+                override fun isSearchInModuleContent(aModule: Module): Boolean = false
+
+                override fun isSearchInLibraries(): Boolean = false
+            }
         )
         with(builder) {
             usePreAnalysisHandlers(::KtResolveExtensionProviderForTestPreAnalysisHandler.bind(listOf(provider)))
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractSingleModuleReferenceResolveWithResolveExtensionTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractSingleModuleReferenceResolveWithResolveExtensionTest.kt
index fa88458..4b5b3e3 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractSingleModuleReferenceResolveWithResolveExtensionTest.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/references/AbstractSingleModuleReferenceResolveWithResolveExtensionTest.kt
@@ -5,12 +5,17 @@
 
 package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
 
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtSingleModuleResolveExtensionProviderForTest
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
 import org.jetbrains.kotlin.name.FqName
 
 abstract class AbstractSingleModuleReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveWithResolveExtensionTest() {
-    override fun createResolveExtensionProvider(files: List<KtResolveExtensionFile>, packages: Set<FqName>): KtResolveExtensionProvider =
-        KtSingleModuleResolveExtensionProviderForTest(files, packages)
+    override fun createResolveExtensionProvider(
+        files: List<KtResolveExtensionFile>,
+        packages: Set<FqName>,
+        shadowedScope: GlobalSearchScope,
+    ): KtResolveExtensionProvider =
+        KtSingleModuleResolveExtensionProviderForTest(files, packages, shadowedScope)
 }
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/util/KtResolveExtensionForTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/util/KtResolveExtensionForTest.kt
index 183e9e1..ce0ae39 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/util/KtResolveExtensionForTest.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/util/KtResolveExtensionForTest.kt
@@ -8,6 +8,7 @@
 import com.intellij.mock.MockProject
 import com.intellij.openapi.util.ModificationTracker
 import com.intellij.psi.PsiElement
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
@@ -25,20 +26,22 @@
 class KtSingleModuleResolveExtensionProviderForTest(
     private val files: List<KtResolveExtensionFile>,
     private val packages: Set<FqName>,
+    private val shadowedScope: GlobalSearchScope,
 ) : KtResolveExtensionProvider() {
     override fun provideExtensionsFor(module: KtModule): List<KtResolveExtension> {
-        return listOf(KtResolveExtensionForTest(files, packages))
+        return listOf(KtResolveExtensionForTest(files, packages, shadowedScope))
     }
 }
 
 class KtMultiModuleResolveExtensionProviderForTest(
     private val files: List<KtResolveExtensionFile>,
     private val packages: Set<FqName>,
+    private val shadowedScope: GlobalSearchScope,
     private val hasResolveExtension: (KtModule) -> Boolean,
 ) : KtResolveExtensionProvider() {
     override fun provideExtensionsFor(module: KtModule): List<KtResolveExtension> {
         if (!hasResolveExtension(module)) return emptyList()
-        return listOf(KtResolveExtensionForTest(files, packages))
+        return listOf(KtResolveExtensionForTest(files, packages, shadowedScope))
     }
 }
 
@@ -59,10 +62,12 @@
 class KtResolveExtensionForTest(
     private val files: List<KtResolveExtensionFile>,
     private val packages: Set<FqName>,
+    private val shadowedScope: GlobalSearchScope,
 ) : KtResolveExtension() {
     override fun getKtFiles(): List<KtResolveExtensionFile> = files
     override fun getModificationTracker(): ModificationTracker = ModificationTracker.NEVER_CHANGED
     override fun getContainedPackages(): Set<FqName> = packages
+    override fun getShadowedScope(): GlobalSearchScope = shadowedScope
 }
 
 class KtResolveExtensionFileForTests(
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
index 726735a..76967f1 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated.java
@@ -68,6 +68,24 @@
         }
 
         @Test
+        @TestMetadata("shadowedDeclaration.kt")
+        public void testShadowedDeclaration() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedDeclaration.kt");
+        }
+
+        @Test
+        @TestMetadata("shadowedJava.kt")
+        public void testShadowedJava() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedJava.kt");
+        }
+
+        @Test
+        @TestMetadata("shadowedOverload.kt")
+        public void testShadowedOverload() throws Exception {
+            runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.kt");
+        }
+
+        @Test
         @TestMetadata("topLevelFunction.kt")
         public void testTopLevelFunction() throws Exception {
             runTest("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/topLevelFunction.kt");
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
index 57c5698..4e746e0 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated.java
@@ -59,6 +59,24 @@
     }
 
     @Test
+    @TestMetadata("shadowedDeclaration.kt")
+    public void testShadowedDeclaration() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedDeclaration.kt");
+    }
+
+    @Test
+    @TestMetadata("shadowedJava.kt")
+    public void testShadowedJava() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedJava.kt");
+    }
+
+    @Test
+    @TestMetadata("shadowedOverload.kt")
+    public void testShadowedOverload() throws Exception {
+        runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.kt");
+    }
+
+    @Test
     @TestMetadata("topLevelFunction.kt")
     public void testTopLevelFunction() throws Exception {
         runTest("analysis/analysis-api/testData/resolveExtensions/referenceResolve/topLevelFunction.kt");
diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtension.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtension.kt
index 6615394..6fbd2e4 100644
--- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtension.kt
+++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtension.kt
@@ -6,6 +6,7 @@
 package org.jetbrains.kotlin.analysis.api.resolve.extensions
 
 import com.intellij.openapi.util.ModificationTracker
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.name.FqName
 
 /**
@@ -53,4 +54,17 @@
      * @see KtResolveExtension
      */
     public abstract fun getContainedPackages(): Set<FqName>
+
+    /**
+     * Returns the scope of files that should be shadowed by the files provided by [getKtFiles].
+     *
+     * Any files in the module that are included in this scope will be removed from analysis results. This allows the files provided by
+     * [getKtFiles] to cleanly replace those files from the module.
+     *
+     * If this resolve extension is being used to generate declarations that would normally be provided by sources generated by an external
+     * build task, such as a resource compiler or annotation processor, the resolve extension should provide a scope here that covers those
+     * externally generated sources. This will prevent collisions between the definitions provided by [getKtFiles] and those provided by the
+     * (potentially stale) externally generated sources.
+     */
+    public open fun getShadowedScope(): GlobalSearchScope = GlobalSearchScope.EMPTY_SCOPE
 }
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedDeclaration.kt b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedDeclaration.kt
new file mode 100644
index 0000000..efff20c
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedDeclaration.kt
@@ -0,0 +1,15 @@
+// UNRESOLVED_REFERENCE
+
+// MODULE: extendedModule
+// FILE: declarations.hidden.kt
+package foo
+
+fun bar() = "baz"
+
+// MODULE: dependency2
+
+// MODULE: main(extendedModule, dependency2)()()
+// FILE: main.kt
+fun main() {
+    val x = foo.<caret>bar()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedJava.kt b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedJava.kt
new file mode 100644
index 0000000..a47c38e
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedJava.kt
@@ -0,0 +1,19 @@
+// UNRESOLVED_REFERENCE
+
+// MODULE: extendedModule
+// FILE: TestClass.hidden.java
+package foo;
+
+public class TestClass {
+    public TestClass() {}
+}
+
+// MODULE: dependency2
+
+// MODULE: main(extendedModule, dependency2)()()
+// FILE: main.kt
+package foo
+
+fun main() {
+    val x = <caret>TestClass()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.kt b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.kt
new file mode 100644
index 0000000..03d24c7
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.kt
@@ -0,0 +1,15 @@
+// MODULE: extendedModule
+// FILE: generated.hidden.kt
+package generated
+
+fun String.generatedOverloadedExtensionFunction(): Int = TODO()
+
+// MODULE: dependency2
+
+// MODULE: main(extendedModule, dependency2)()()
+// FILE: main.kt
+import generated.*
+
+fun main() {
+    "string".generatedOverloadedExtension<caret>Function()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.txt b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.txt
new file mode 100644
index 0000000..fbdbb1d
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve/extendedModuleDependency/shadowedOverload.txt
@@ -0,0 +1,2 @@
+Resolved to:
+0: (in generated) fun kotlin.Any.generatedOverloadedExtensionFunction(): kotlin.Int
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedDeclaration.kt b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedDeclaration.kt
new file mode 100644
index 0000000..94a6ec3
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedDeclaration.kt
@@ -0,0 +1,11 @@
+// UNRESOLVED_REFERENCE
+
+// FILE: declarations.hidden.kt
+package foo
+
+fun bar() = "baz"
+
+// FILE: main.kt
+fun main() {
+    val x = foo.<caret>bar()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedJava.kt b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedJava.kt
new file mode 100644
index 0000000..36a4a5b
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedJava.kt
@@ -0,0 +1,15 @@
+// UNRESOLVED_REFERENCE
+
+// FILE: TestClass.hidden.java
+package foo;
+
+public class TestClass {
+    public TestClass() {}
+}
+
+// FILE: main.kt
+package foo
+
+fun main() {
+    val x = <caret>TestClass()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.kt b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.kt
new file mode 100644
index 0000000..2354781
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.kt
@@ -0,0 +1,11 @@
+// FILE: generated.hidden.kt
+package generated
+
+fun String.generatedOverloadedExtensionFunction(): Int = TODO()
+
+// FILE: main.kt
+import generated.*
+
+fun main() {
+    "string".generatedOverloadedExtension<caret>Function()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.txt b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.txt
new file mode 100644
index 0000000..fbdbb1d
--- /dev/null
+++ b/analysis/analysis-api/testData/resolveExtensions/referenceResolve/shadowedOverload.txt
@@ -0,0 +1,2 @@
+Resolved to:
+0: (in generated) fun kotlin.Any.generatedOverloadedExtensionFunction(): kotlin.Int
\ No newline at end of file
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/sessionFactoryHelpers.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/sessionFactoryHelpers.kt
index 5889958..60c9085 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/sessionFactoryHelpers.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/sessionFactoryHelpers.kt
@@ -92,15 +92,3 @@
     )
 
 }
-
-internal fun createJavaSymbolProvider(
-    firSession: FirSession,
-    moduleData: LLFirModuleData,
-    project: Project,
-    contentScope: GlobalSearchScope
-): JavaSymbolProvider {
-    return JavaSymbolProvider(
-        firSession,
-        FirJavaFacadeForSource(firSession, moduleData, project.createJavaClassFinder(contentScope))
-    )
-}
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt
index 54a7f45..5a7781a 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt
@@ -90,9 +90,9 @@
     override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
 
     companion object {
-        fun merge(session: FirSession, project: Project, providers: List<JavaSymbolProvider>): FirSymbolProvider? =
+        fun merge(session: FirSession, project: Project, providers: List<LLFirJavaSymbolProvider>): FirSymbolProvider? =
             if (providers.size > 1) {
-                val combinedScope = GlobalSearchScope.union(providers.map { it.session.llFirModuleData.ktModule.contentScope })
+                val combinedScope = GlobalSearchScope.union(providers.map { it.searchScope })
                 val javaClassFinder = project.createJavaClassFinder(combinedScope)
                 LLFirCombinedJavaSymbolProvider(session, project, providers, javaClassFinder)
             } else providers.singleOrNull()
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirJavaSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirJavaSymbolProvider.kt
new file mode 100644
index 0000000..d1b7eda
--- /dev/null
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirJavaSymbolProvider.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2023 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.analysis.low.level.api.fir.providers
+
+import com.intellij.openapi.project.Project
+import com.intellij.psi.search.GlobalSearchScope
+import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
+import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
+import org.jetbrains.kotlin.load.java.createJavaClassFinder
+
+internal class LLFirJavaSymbolProvider(
+    firSession: FirSession,
+    moduleData: LLFirModuleData,
+    project: Project,
+    val searchScope: GlobalSearchScope
+) : JavaSymbolProvider(
+    firSession,
+    FirJavaFacadeForSource(firSession, moduleData, project.createJavaClassFinder(searchScope))
+)
\ No newline at end of file
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt
index 22f8a8b..e01eec4 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt
@@ -5,11 +5,11 @@
 
 package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
 
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
+import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
 import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.SyntheticFirClassProvider
 import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
-import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
-import org.jetbrains.kotlin.fir.FirSession
 import org.jetbrains.kotlin.fir.NoMutableState
 import org.jetbrains.kotlin.fir.ThreadSafeMutableState
 import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
@@ -29,22 +29,23 @@
 
 @ThreadSafeMutableState
 internal class LLFirProvider(
-    val session: FirSession,
+    val session: LLFirSession,
     private val moduleComponents: LLFirModuleResolveComponents,
-    private val declarationProvider: KotlinDeclarationProvider,
-    packageProvider: KotlinPackageProvider,
     canContainKotlinPackage: Boolean,
+    declarationProviderFactory: (GlobalSearchScope) -> KotlinDeclarationProvider?,
 ) : FirProvider() {
     override val symbolProvider: FirSymbolProvider = SymbolProvider()
 
     private val providerHelper = LLFirProviderHelper(
         session,
         moduleComponents.firFileBuilder,
-        declarationProvider,
-        packageProvider,
         canContainKotlinPackage,
+        declarationProviderFactory,
     )
 
+    val searchScope: GlobalSearchScope
+        get() = providerHelper.searchScope
+
     override val isPhasedFirAllowed: Boolean get() = true
 
     override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? =
@@ -103,9 +104,7 @@
 
     override fun getFirFilesByPackage(fqName: FqName): List<FirFile> = error("Should not be called in FIR IDE")
 
-
-    override fun getClassNamesInPackage(fqName: FqName): Set<Name> =
-        declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
+    override fun getClassNamesInPackage(fqName: FqName): Set<Name> = providerHelper.getTopLevelClassNamesInPackage(fqName)
 
     @NoMutableState
     internal inner class SymbolProvider : LLFirKotlinSymbolProvider(session) {
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt
index c47e006..2a3b629 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt
@@ -5,18 +5,19 @@
 
 package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
 
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBuilder
 import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.CompositeKotlinPackageProvider
 import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool
 import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.llResolveExtensionTool
+import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
 import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
 import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirKotlinSymbolNamesProvider
 import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
-import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
+import org.jetbrains.kotlin.analysis.providers.createPackageProvider
 import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.CompositeKotlinDeclarationProvider
 import org.jetbrains.kotlin.builtins.StandardNames
 import org.jetbrains.kotlin.config.AnalysisFlags
-import org.jetbrains.kotlin.fir.FirSession
 import org.jetbrains.kotlin.fir.caches.firCachesFactory
 import org.jetbrains.kotlin.fir.caches.getValue
 import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
@@ -35,27 +36,37 @@
 import org.jetbrains.kotlin.psi.KtFile
 
 internal class LLFirProviderHelper(
-    firSession: FirSession,
+    firSession: LLFirSession,
     private val firFileBuilder: LLFirFileBuilder,
-    mainDeclarationProvider: KotlinDeclarationProvider,
-    mainPackageProvider: KotlinPackageProvider,
     canContainKotlinPackage: Boolean,
+    declarationProviderFactory: (GlobalSearchScope) -> KotlinDeclarationProvider?
 ) {
     private val extensionTool: LLFirResolveExtensionTool? = firSession.llResolveExtensionTool
 
+    val searchScope: GlobalSearchScope =
+        firSession.ktModule.contentScope.run {
+            val notShadowedScope = extensionTool?.shadowedSearchScope?.let { GlobalSearchScope.notScope(it) }
+            if (notShadowedScope != null) {
+                this.intersectWith(notShadowedScope)
+            } else {
+                this
+            }
+        }
+
     val declarationProvider = CompositeKotlinDeclarationProvider.create(
         listOfNotNull(
-            mainDeclarationProvider,
+            declarationProviderFactory(searchScope),
             extensionTool?.declarationProvider,
         )
     )
 
     private val packageProvider = CompositeKotlinPackageProvider.create(
         listOfNotNull(
-            mainPackageProvider,
+            firSession.project.createPackageProvider(searchScope),
             extensionTool?.packageProvider,
         )
     )
+
     private val allowKotlinPackage = canContainKotlinPackage ||
             firSession.languageVersionSettings.getFlag(AnalysisFlags.allowKotlinPackage)
 
@@ -100,6 +111,11 @@
         return classifierByClassId.getValue(classId, classLikeDeclaration)
     }
 
+    fun getTopLevelClassNamesInPackage(packageFqName: FqName): Set<Name> {
+        if (!allowKotlinPackage && packageFqName.isKotlinPackage()) return emptySet()
+        return declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(packageFqName)
+    }
+
     fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
         if (!allowKotlinPackage && packageFqName.isKotlinPackage()) return emptyList()
         val callableId = CallableId(packageFqName, name)
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt
index 30bee09..23aa10a 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt
@@ -8,6 +8,7 @@
 import com.intellij.openapi.util.Key
 import com.intellij.openapi.util.ModificationTracker
 import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.analysis.api.KtAnalysisAllowanceManager
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension
 import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
@@ -40,6 +41,7 @@
     abstract val declarationProvider: LLFirResolveExtensionToolDeclarationProvider
     abstract val packageProvider: KotlinPackageProvider
     abstract val packageFilter: LLFirResolveExtensionToolPackageFilter
+    abstract val shadowedSearchScope: GlobalSearchScope
     internal abstract val symbolNamesProvider: FirSymbolNamesProvider
 }
 
@@ -57,13 +59,19 @@
 
     override val packageFilter = LLFirResolveExtensionToolPackageFilter(extensions)
 
-    override val modificationTrackers by lazy { extensions.map { it.getModificationTracker() } }
+    override val modificationTrackers by lazy { forbidAnalysis { extensions.map { it.getModificationTracker() } } }
 
     override val declarationProvider: LLFirResolveExtensionToolDeclarationProvider =
         LLFirResolveExtensionToolDeclarationProvider(fileProvider, session.ktModule)
 
     override val packageProvider: KotlinPackageProvider = LLFirResolveExtensionToolPackageProvider(packageFilter)
 
+    override val shadowedSearchScope by lazy {
+        forbidAnalysis {
+            GlobalSearchScope.union(extensions.mapTo(mutableSetOf()) { it.getShadowedScope() })
+        }
+    }
+
     override val symbolNamesProvider: FirSymbolNamesProvider = LLFirResolveExtensionToolSymbolNamesProvider(packageFilter, fileProvider)
 }
 
@@ -310,7 +318,7 @@
             .filter { it.getFilePackageName() == packageFqName }
     }
 
-    fun getAllFiles(): Sequence<KtResolveExtensionFile> {
+    fun getAllFiles(): Sequence<KtResolveExtensionFile> = forbidAnalysis {
         return extensions
             .asSequence()
             .flatMap { it.getKtFiles() }
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt
index d0cf098..13e95a5 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt
@@ -15,11 +15,11 @@
 import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.*
 import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
 import org.jetbrains.kotlin.analysis.project.structure.*
+import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
 import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
 import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
-import org.jetbrains.kotlin.analysis.providers.createPackageProvider
-import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.EmptyKotlinDeclarationProvider
 import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.FileBasedKotlinDeclarationProvider
+import org.jetbrains.kotlin.analysis.providers.impl.util.mergeInto
 import org.jetbrains.kotlin.analysis.utils.trackers.CompositeModificationTracker
 import org.jetbrains.kotlin.config.LanguageFeature
 import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -48,7 +48,6 @@
 import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
 import kotlin.script.experimental.host.ScriptingHostConfiguration
 import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
-import org.jetbrains.kotlin.analysis.providers.impl.util.mergeInto
 
 @OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
 internal abstract class LLFirAbstractSessionFactory(protected val project: Project) {
@@ -66,7 +65,6 @@
         val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
 
         val components = LLFirModuleResolveComponents(module, globalResolveComponents, scopeProvider)
-        val contentScope = module.contentScope
 
         val dependencies = collectSourceModuleDependencies(module)
         val dependencyTracker = createSourceModuleDependencyTracker(module, dependencies)
@@ -90,10 +88,10 @@
             val provider = LLFirProvider(
                 this,
                 components,
-                FileBasedKotlinDeclarationProvider(module.file),
-                project.createPackageProvider(contentScope),
                 canContainKotlinPackage = true,
-            )
+            ) { scope ->
+                scope.createScopedDeclarationProviderForFile(module.file)
+            }
 
             register(FirProvider::class, provider)
             register(FirLazyDeclarationResolver::class, LLFirLazyDeclarationResolver())
@@ -103,7 +101,7 @@
                 add(builtinsSession.symbolProvider)
             })
 
-            val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope)
+            val javaSymbolProvider = LLFirJavaSymbolProvider(this, moduleData, project, provider.searchScope)
             register(JavaSymbolProvider::class, javaSymbolProvider)
 
             register(
@@ -170,10 +168,10 @@
             val provider = LLFirProvider(
                 this,
                 components,
-                if (ktFile != null) FileBasedKotlinDeclarationProvider(ktFile) else EmptyKotlinDeclarationProvider,
-                project.createPackageProvider(module.contentScope),
                 canContainKotlinPackage = true,
-            )
+            ) { scope ->
+                ktFile?.let { scope.createScopedDeclarationProviderForFile(it) }
+            }
 
             register(FirProvider::class, provider)
             register(FirLazyDeclarationResolver::class, LLFirLazyDeclarationResolver())
@@ -226,8 +224,6 @@
         components.session = session
 
         val moduleData = createModuleData(session)
-        val contentScope = module.contentScope
-
 
         return session.apply {
             registerModuleData(moduleData)
@@ -240,16 +236,16 @@
             val firProvider = LLFirProvider(
                 this,
                 components,
-                project.createDeclarationProvider(contentScope, module),
-                project.createPackageProvider(contentScope),
                 /* Source modules can contain `kotlin` package only if `-Xallow-kotlin-package` is specified, this is handled in LLFirProvider */
                 canContainKotlinPackage = false,
-            )
+            ) { scope ->
+                project.createDeclarationProvider(scope, module)
+            }
 
             register(FirProvider::class, firProvider)
             register(FirLazyDeclarationResolver::class, LLFirLazyDeclarationResolver())
 
-            registerCompilerPluginServices(contentScope, project, module)
+            registerCompilerPluginServices(firProvider.searchScope, project, module)
             registerCompilerPluginExtensions(project, module)
             registerCommonComponentsAfterExtensionsAreConfigured()
 
@@ -273,7 +269,7 @@
                 }
 
             val context = SourceSessionCreationContext(
-                moduleData, contentScope, firProvider, dependencyProvider, syntheticFunctionInterfaceProvider,
+                moduleData, firProvider.searchScope, firProvider, dependencyProvider, syntheticFunctionInterfaceProvider,
                 switchableExtensionDeclarationsSymbolProvider,
             )
             additionalSessionConfiguration(context)
@@ -320,22 +316,20 @@
             registerCommonComponentsAfterExtensionsAreConfigured()
             registerResolveComponents()
 
-            val contentScope = module.contentScope
-
             val firProvider = LLFirProvider(
                 this,
                 components,
-                project.createDeclarationProvider(contentScope, module),
-                project.createPackageProvider(contentScope),
                 canContainKotlinPackage = true,
-            )
+            ) { scope ->
+                project.createDeclarationProvider(scope, module)
+            }
 
             register(FirProvider::class, firProvider)
 
             register(FirLazyDeclarationResolver::class, LLFirLazyDeclarationResolver())
 
             // We need FirRegisteredPluginAnnotations during extensions' registration process
-            val annotationsResolver = project.createAnnotationResolver(contentScope)
+            val annotationsResolver = project.createAnnotationResolver(firProvider.searchScope)
             register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this, annotationsResolver))
             register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider)
 
@@ -360,7 +354,7 @@
             register(DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY, dependencyProvider)
             register(LLFirFirClassByPsiClassProvider::class, LLFirFirClassByPsiClassProvider(this))
 
-            val context = LibrarySessionCreationContext(moduleData, contentScope, firProvider, dependencyProvider)
+            val context = LibrarySessionCreationContext(moduleData, firProvider.searchScope, firProvider, dependencyProvider)
             additionalSessionConfiguration(context)
 
             LLFirSessionConfigurator.configure(this)
@@ -504,8 +498,21 @@
     ) {
         mergeInto(destination) {
             merge<LLFirProvider.SymbolProvider> { LLFirCombinedKotlinSymbolProvider.merge(session, project, it) }
-            merge<JavaSymbolProvider> { LLFirCombinedJavaSymbolProvider.merge(session, project, it) }
+            merge<LLFirJavaSymbolProvider> { LLFirCombinedJavaSymbolProvider.merge(session, project, it) }
             merge<FirExtensionSyntheticFunctionInterfaceProvider> { LLFirCombinedSyntheticFunctionSymbolProvider.merge(session, it) }
         }
     }
+
+    /**
+     * Creates a single-file [KotlinDeclarationProvider] for the provided file, if it is in the search scope.
+     *
+     * Otherwise, returns `null`.
+     */
+    private fun GlobalSearchScope.createScopedDeclarationProviderForFile(file: KtFile): KotlinDeclarationProvider? =
+        // KtFiles without a backing VirtualFile can't be covered by a shadow scope, and are thus assumed in-scope.
+        if (file.virtualFile == null || contains(file.virtualFile)) {
+            FileBasedKotlinDeclarationProvider(file)
+        } else {
+            null
+        }
 }
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt
index 1c82bef..6e3cf81 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt
@@ -25,7 +25,7 @@
         return doCreateSourcesSession(module, FirKotlinScopeProvider(::wrapScopeWithJvmMapped)) { context ->
             registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
             registerJavaSpecificResolveComponents()
-            val javaSymbolProvider = createJavaSymbolProvider(this, context.moduleData, project, context.contentScope)
+            val javaSymbolProvider = LLFirJavaSymbolProvider(this, context.moduleData, project, context.contentScope)
             register(JavaSymbolProvider::class, javaSymbolProvider)
 
             register(
@@ -50,7 +50,7 @@
         return doCreateLibrarySession(module) { context ->
             registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
             registerJavaSpecificResolveComponents()
-            val javaSymbolProvider = createJavaSymbolProvider(this, context.moduleData, project, context.contentScope)
+            val javaSymbolProvider = LLFirJavaSymbolProvider(this, context.moduleData, project, context.contentScope)
             register(
                 FirSymbolProvider::class,
                 LLFirModuleWithDependenciesSymbolProvider(
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt
index 1e37eb9..87225c4 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt
@@ -13,7 +13,7 @@
 import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
 import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.JvmFirDeserializedSymbolProviderFactory
 import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
-import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.createJavaSymbolProvider
+import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirJavaSymbolProvider
 import org.jetbrains.kotlin.fir.FirSession
 import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
 import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
@@ -56,7 +56,7 @@
                     FirDeclarationOrigin.Library
                 )
             )
-            add(createJavaSymbolProvider(session, moduleData, project, scope))
+            add(LLFirJavaSymbolProvider(session, moduleData, project, scope))
         }
     }
 }
\ No newline at end of file
diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt
index 58148c4..c19ab2c 100644
--- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt
+++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt
@@ -25,7 +25,7 @@
 // For library and incremental compilation sessions use `KotlinDeserializedJvmSymbolsProvider`
 // in order to load Kotlin classes as well.
 //Also used in IDE for loading java classes separately from stub based kotlin classes
-class JavaSymbolProvider(
+open class JavaSymbolProvider(
     session: FirSession,
     private val javaFacade: FirJavaFacade,
 ) : FirSymbolProvider(session) {