diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt index 039cde9ddcd..c7e4e2c4cee 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt @@ -129,4 +129,7 @@ class CliKotlinAsJavaSupport( PsiSearchScopeUtil.isInScope(searchScope, it) }.orEmpty() } + + override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = + error("Should not be called") } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/KJKComplexHierarchyWithNested.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/KJKComplexHierarchyWithNested.kt index b56220f6c3b..c061c4a9804 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/KJKComplexHierarchyWithNested.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/KJKComplexHierarchyWithNested.kt @@ -1,3 +1,4 @@ +// FIR_IDE_IGNORE // FILE: K1.kt class KSub : J1() diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt index fd4e68a37d7..aac4c278872 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt @@ -8,9 +8,11 @@ package org.jetbrains.kotlin.asJava import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiClass +import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile @@ -56,6 +58,8 @@ abstract class KotlinAsJavaSupport { abstract fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass + abstract fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass + companion object { @JvmStatic fun getInstance(project: Project): KotlinAsJavaSupport { diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeImpl.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeImpl.kt index c02b8d26912..30b39da87d1 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeImpl.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeImpl.kt @@ -282,15 +282,15 @@ open class KtLightClassForFacadeImpl constructor( } fun createForSyntheticFile( - manager: PsiManager, facadeClassFqName: FqName, file: KtFile ): KtLightClassForFacade { + val project = file.project // TODO: refactor, using cached value doesn't make sense for this case - val cachedValue = CachedValuesManager.getManager(manager.project).createCachedValue( - LightClassDataProviderForFileFacade.ByFile(manager.project, facadeClassFqName, file), false + val cachedValue = CachedValuesManager.getManager(project).createCachedValue( + LightClassDataProviderForFileFacade.ByFile(project, facadeClassFqName, file), false ) - return KtLightClassForFacadeImpl(manager, facadeClassFqName, cachedValue, listOf(file)) + return KtLightClassForFacadeImpl(PsiManager.getInstance(project), facadeClassFqName, cachedValue, listOf(file)) } } } diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt deleted file mode 100644 index 967838f95fe..00000000000 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2000-2018 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 - -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiManager -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass -import org.jetbrains.kotlin.asJava.classes.KtLightClass -import org.jetbrains.kotlin.idea.asJava.KtFirBasedFakeLightClass -import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightClass -import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightFacade -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtScript - -class IDEKotlinAsJavaFirSupport(project: Project) : IDEKotlinAsJavaSupport(project) { - - override fun createLightClassForFacade(manager: PsiManager, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClass? { - val sources = findFilesForFacade(facadeClassFqName, searchScope) - .filterNot { it.isCompiled } - - if (sources.isEmpty()) return null - - return getOrCreateFirLightFacade(sources, facadeClassFqName) - } - - override fun createLightClassForScript(script: KtScript): KtLightClass? = null - - override fun createLightClassForSourceDeclaration(classOrObject: KtClassOrObject): KtLightClass? = - getOrCreateFirLightClass(classOrObject) - - override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = - KtFirBasedFakeLightClass(classOrObject) -} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts b/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts index dca8f14e100..2f05e1796c0 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { compile(project(":compiler:fir:java")) compile(project(":compiler:fir:jvm")) compile(project(":compiler:backend.common.jvm")) + testCompile(project(":idea-frontend-fir")) implementation(project(":compiler:ir.psi2ir")) implementation(project(":compiler:fir:entrypoint")) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/DeclarationProviderBase.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/DeclarationProviderBase.kt index ad04d23b7e0..8c18ea7ab26 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/DeclarationProviderBase.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/DeclarationProviderBase.kt @@ -12,10 +12,7 @@ import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtTypeAlias +import org.jetbrains.kotlin.psi.* abstract class DeclarationProvider { abstract val searchScope: GlobalSearchScope @@ -31,6 +28,8 @@ abstract class DeclarationProvider { abstract fun getPropertyNamesInPackage(packageFqName: FqName): Set abstract fun getFunctionsNamesInPackage(packageFqName: FqName): Set + abstract fun getFacadeFilesInPackage(packageFqName: FqName): Collection + abstract fun findFilesForFacade(facadeFqName: FqName): Collection } abstract class KtDeclarationProviderFactory { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/KtPackageProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/KtPackageProvider.kt index a845dc274f1..5b37141b49a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/KtPackageProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/KtPackageProvider.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.platform.TargetPlatform abstract class KtPackageProvider { abstract fun isPackageExists(packageFqName: FqName): Boolean - abstract fun getJavaAndKotlinSubPackageFqNames(packageFqName: FqName, targetPlatform: TargetPlatform): Set + abstract fun getKotlinSubPackageFqNames(packageFqName: FqName): Set } abstract class KtPackageProviderFactory { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/compiler/based/AbstractCompilerBasedTest.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/compiler/based/AbstractCompilerBasedTest.kt index 4020b1fce15..9039a17e429 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/compiler/based/AbstractCompilerBasedTest.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/compiler/based/AbstractCompilerBasedTest.kt @@ -7,31 +7,33 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based import com.intellij.mock.MockProject import com.intellij.openapi.Disposable +import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import com.intellij.psi.PsiElementFinder import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.ProjectScope -import org.jetbrains.annotations.NotNull import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.finder.JavaElementFinder -import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots -import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.fir.DependencyListForCliModule import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider -import org.jetbrains.kotlin.fir.java.FirJavaElementFinder import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData +import org.jetbrains.kotlin.idea.asJava.IDEKotlinAsJavaFirSupport import org.jetbrains.kotlin.idea.fir.low.level.api.* -import org.jetbrains.kotlin.idea.fir.low.level.api.api.* -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession +import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter +import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveStateConfigurator +import org.jetbrains.kotlin.idea.fir.low.level.api.api.KotlinOutOfBlockModificationTrackerFactory +import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirFile +import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.* +import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiTest.Companion.reRegisterJavaElementFinder import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.DeclarationProviderTestImpl import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.KotlinOutOfBlockModificationTrackerFactoryTestImpl import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.KtPackageProviderTestImpl @@ -44,22 +46,21 @@ import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.test.TestConfiguration import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.testConfiguration import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.model.DirectivesContainer -import org.jetbrains.kotlin.test.frontend.fir.* +import org.jetbrains.kotlin.test.frontend.fir.FirModuleInfoProvider +import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact +import org.jetbrains.kotlin.test.frontend.fir.firModuleInfoProvider +import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest import org.jetbrains.kotlin.test.services.* import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.TestInfo -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.io.path.nameWithoutExtension abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() { private var _disposable: Disposable? = null @@ -104,7 +105,8 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() { override fun analyze(module: TestModule): FirOutputArtifact { val project = testServices.compilerConfigurationProvider.getProject(module) val ktFiles = testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project) - PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java) + + reRegisterJavaElementFinder(project) val moduleInfo = TestModuleInfo(module) testServices.firModuleInfoProvider.registerModuleData(module, FirModuleInfoBasedModuleData(moduleInfo)) @@ -241,7 +243,6 @@ class FirModuleResolveStateConfiguratorForSingleModuleTestImpl( } override fun configureSourceSession(session: FirSession) { - PsiElementFinder.EP.getPoint(project).registerExtension(FirJavaElementFinder(session, project), parentDisposable) } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/AbstractLowLevelApiTest.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/AbstractLowLevelApiTest.kt index 986120a261b..5bd8b56f5aa 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/AbstractLowLevelApiTest.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/AbstractLowLevelApiTest.kt @@ -6,14 +6,18 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.test.base import com.intellij.mock.MockProject -import com.intellij.openapi.Disposable -import com.intellij.openapi.util.Disposer +import com.intellij.openapi.project.Project import com.intellij.psi.PsiElementFinder +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData +import org.jetbrains.kotlin.idea.asJava.IDEKotlinAsJavaFirSupport import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FirModuleResolveStateConfiguratorForSingleModuleTestImpl import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.TestModuleInfo import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.registerTestServices +import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProvider +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSessionProvider import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder @@ -32,7 +36,7 @@ import java.nio.file.Path import java.nio.file.Paths import kotlin.io.path.nameWithoutExtension -abstract class AbstractLowLevelApiTest: TestWithDisposable() { +abstract class AbstractLowLevelApiTest : TestWithDisposable() { private lateinit var testInfo: KotlinTestInfo private val configure: TestConfigurationBuilder.() -> Unit = { @@ -66,6 +70,24 @@ abstract class AbstractLowLevelApiTest: TestWithDisposable() { open fun configureTest(builder: TestConfigurationBuilder) {} + companion object { + @OptIn(InvalidWayOfUsingAnalysisSession::class) + fun reRegisterJavaElementFinder(project: Project) { + PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java) + with(project as MockProject) { + picoContainer.registerComponentInstance( + KtAnalysisSessionProvider::class.qualifiedName, + KtFirAnalysisSessionProvider(this) + ) + picoContainer.unregisterComponent(KotlinAsJavaSupport::class.qualifiedName) + picoContainer.registerComponentInstance( + KotlinAsJavaSupport::class.qualifiedName, + IDEKotlinAsJavaFirSupport(project) + ) + } + PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(project)) + } + } protected fun runTest(path: String) { testDataPath = Paths.get(path) @@ -82,7 +104,7 @@ abstract class AbstractLowLevelApiTest: TestWithDisposable() { val project = testServices.compilerConfigurationProvider.getProject(singleModule) val ktFiles = testServices.sourceFileProvider.getKtFilesForSourceFiles(singleModule.files, project) - PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java) + reRegisterJavaElementFinder(project) val moduleInfo = TestModuleInfo(singleModule) testServices.firModuleInfoProvider.registerModuleData(singleModule, FirModuleInfoBasedModuleData(moduleInfo)) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/DeclarationProviderTestImpl.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/DeclarationProviderTestImpl.kt index a47fe4f5e5f..1521f599d88 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/DeclarationProviderTestImpl.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/DeclarationProviderTestImpl.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.test.base import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId @@ -59,6 +60,17 @@ internal class DeclarationProviderTestImpl( .filterIsInstance() .mapNotNullTo(mutableSetOf()) { it.nameAsName } + override fun getFacadeFilesInPackage(packageFqName: FqName): Collection = + filesByPackage(packageFqName) + .filter { file -> file.hasTopLevelCallables() } + .toSet() + + override fun findFilesForFacade(facadeFqName: FqName): Collection { + if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList() + return getFacadeFilesInPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName + .filter { it.javaFileFacadeFqName == facadeFqName } + } + override fun getTopLevelProperties(callableId: CallableId): Collection = filesByPackage(callableId.packageName) .flatMap { it.declarations } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/KtPackageProviderTestImpl.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/KtPackageProviderTestImpl.kt index 8c77bce512d..59d9bab569d 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/KtPackageProviderTestImpl.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/test/base/KtPackageProviderTestImpl.kt @@ -9,7 +9,6 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.idea.fir.low.level.api.KtPackageProvider import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.KtFile internal class KtPackageProviderTestImpl( @@ -22,7 +21,7 @@ internal class KtPackageProviderTestImpl( return filesInScope.any { it.packageFqName == packageFqName } } - override fun getJavaAndKotlinSubPackageFqNames(packageFqName: FqName, targetPlatform: TargetPlatform): Set { + override fun getKotlinSubPackageFqNames(packageFqName: FqName): Set { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/IDEKotlinAsJavaFirSupport.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/IDEKotlinAsJavaFirSupport.kt new file mode 100644 index 00000000000..e7c4f764966 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/IDEKotlinAsJavaFirSupport.kt @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2018 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.asJava + +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiClass +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.util.SmartList +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName +import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightClass +import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightFacade +import org.jetbrains.kotlin.idea.fir.low.level.api.createDeclarationProvider +import org.jetbrains.kotlin.idea.fir.low.level.api.createPackageProvider +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.parentOrNull +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtScript +import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty + +class IDEKotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupport() { + + override fun findClassOrObjectDeclarationsInPackage( + packageFqName: FqName, + searchScope: GlobalSearchScope + ): Collection = project.createDeclarationProvider(searchScope).run { + getClassNamesInPackage(packageFqName).flatMap { + getClassesByClassId(ClassId.topLevel(packageFqName.child(it))) + } + } + + @OptIn(ExperimentalStdlibApi::class) + override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection = + buildSet { + addAll(project.createDeclarationProvider(searchScope).getFacadeFilesInPackage(fqName)) + findClassOrObjectDeclarationsInPackage(fqName, searchScope).mapTo(this) { + it.containingKtFile + } + } + + private fun FqName.toClassIdSequence(): Sequence { + var currentName = shortNameOrSpecial() + if (currentName.isSpecial) return emptySequence() + var currentParent = parentOrNull() ?: return emptySequence() + var currentRelativeName = currentName.asString() + + return sequence { + while (true) { + yield(ClassId(currentParent, FqName(currentRelativeName), false)) + currentName = currentParent.shortNameOrSpecial() + if (currentName.isSpecial) break + currentParent = currentParent.parentOrNull() ?: break + currentRelativeName = "${currentName.asString()}.$currentRelativeName" + } + } + } + + override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection = + fqName.toClassIdSequence().flatMap { + project.createDeclarationProvider(searchScope).getClassesByClassId(it) + }.toSet() + + override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean = + project.createPackageProvider(scope).isPackageExists(fqName) + + override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection = + project.createPackageProvider(scope) + .getKotlinSubPackageFqNames(fqn) + .map { fqn.child(it) } + + override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = + getOrCreateFirLightClass(classOrObject) + + override fun getLightClassForScript(script: KtScript): KtLightClass = + error("Should not be called") + + override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection = + //TODO Split by modules + findFilesForFacade(facadeFqName, scope).ifNotEmpty { + listOfNotNull(getOrCreateFirLightFacade(this.toList(), facadeFqName)) + } ?: emptyList() + + override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection = + error("Should not be called") + + override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection = + emptyList() //TODO Implement if necessary for fir + + override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection = + project.createDeclarationProvider(scope) + .getFacadeFilesInPackage(packageFqName) + .groupBy { it.javaFileFacadeFqName } + .mapNotNull { getOrCreateFirLightFacade(it.value, it.key) } + + override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection = + project.createDeclarationProvider(scope) + .getFacadeFilesInPackage(packageFqName) + .mapTo(mutableSetOf()) { it.javaFileFacadeFqName.shortName().asString() } + + override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection = + project.createDeclarationProvider(scope) + .findFilesForFacade(facadeFqName) + + override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = + KtFirBasedFakeLightClass(classOrObject) + + override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = + TODO("Not implemented") +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirPackageScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirPackageScope.kt index 15ad21b79fa..12bbfd85889 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirPackageScope.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirPackageScope.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.scopes import com.intellij.openapi.project.Project -import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.idea.fir.low.level.api.createDeclarationProvider @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.jvm.isJvm internal class KtFirPackageScope( override val fqName: FqName, @@ -73,9 +74,23 @@ internal class KtFirPackageScope( } override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { - packageProvider.getJavaAndKotlinSubPackageFqNames(fqName, targetPlatform) - .filter(nameFilter) - .map { builder.createPackageSymbol(fqName.child(it)) } - .asSequence() + sequence { + if (targetPlatform.isJvm()) { + val javaPackage = JavaPsiFacade.getInstance(project).findPackage(fqName.asString()) + if (javaPackage != null) { + for (psiPackage in javaPackage.getSubPackages(searchScope)) { + val fqName = FqName(psiPackage.qualifiedName) + if (nameFilter(fqName.shortName())) { + yield(builder.createPackageSymbol(fqName)) + } + } + } + } + packageProvider.getKotlinSubPackageFqNames(fqName).forEach { + if (nameFilter(it)) { + yield(builder.createPackageSymbol(fqName.child(it))) + } + } + } } } diff --git a/idea/resources-fir/META-INF/plugin.xml b/idea/resources-fir/META-INF/plugin.xml index c914b1fb2f5..c882042d081 100644 --- a/idea/resources-fir/META-INF/plugin.xml +++ b/idea/resources-fir/META-INF/plugin.xml @@ -263,7 +263,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu + serviceImplementation="org.jetbrains.kotlin.idea.asJava.IDEKotlinAsJavaFirSupport"/>