diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt index feb8a02c6fc..60d043d2cee 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -35,6 +35,11 @@ public abstract class KotlinDeclarationProvider { public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection public abstract fun findFilesForFacade(facadeFqName: FqName): Collection + + /** + * Currently we want only classes from libraries ([org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile]) + */ + public abstract fun findInternalFilesForFacade(facadeFqName: FqName): Collection } public abstract class KotlinDeclarationProviderFactory { diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt index bb045a8b2f9..c4b4c46550b 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.psi.* internal class KotlinStaticDeclarationIndex { internal val facadeFileMap: MutableMap> = mutableMapOf() + internal val multiFileClassPartMap: MutableMap> = mutableMapOf() internal val classMap: MutableMap> = mutableMapOf() internal val typeAliasMap: MutableMap> = mutableMapOf() internal val topLevelFunctionMap: MutableMap> = mutableMapOf() diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt index 6ce884aa80c..0e50d57efac 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.providers.impl import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem -import com.intellij.psi.* +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiManager +import com.intellij.psi.SingleRootFileViewProvider import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.stubs.StubElement import com.intellij.util.indexing.FileContent @@ -77,6 +79,10 @@ public class KotlinStaticDeclarationProvider internal constructor( .filter { it.javaFileFacadeFqName == facadeFqName } } + override fun findInternalFilesForFacade(facadeFqName: FqName): Collection { + return index.multiFileClassPartMap[facadeFqName].orEmpty().filter { it.virtualFile in scope } + } + override fun getTopLevelProperties(callableId: CallableId): Collection = index.topLevelPropertyMap[callableId.packageName] ?.filter { ktProperty -> @@ -240,7 +246,18 @@ public class KotlinStaticDeclarationProviderFactory( } loadBuiltIns().forEach { ktFileStub -> - addToFacadeFileMap(ktFileStub.psi) + val ktFile: KtFile = ktFileStub.psi + addToFacadeFileMap(ktFile) + + val partNames = ktFileStub.facadePartSimpleNames + if (partNames != null) { + val packageFqName = ktFileStub.getPackageFqName() + for (partName in partNames) { + val multiFileClassPartFqName: FqName = packageFqName.child(Name.identifier(partName)) + index.multiFileClassPartMap.computeIfAbsent(multiFileClassPartFqName) { mutableSetOf() }.add(ktFile) + } + } + // top-level functions and properties, built-in classes ktFileStub.childrenStubs.forEach(::indexStub) } diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt index 79867ba2d0a..484d62c48ac 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt index 76ee5cdb087..18a2c46de10 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider -import org.jetbrains.kotlin.name.* +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.* internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() { @@ -20,4 +23,5 @@ internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() { override fun getTopLevelCallableNamesInPackage(packageFqName: FqName) = emptySet() override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList() override fun findFilesForFacade(facadeFqName: FqName) = emptyList() -} \ No newline at end of file + override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList() +} diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt index c7a99aa3716..118f15bf764 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt @@ -1,12 +1,15 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.project.structure import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider -import org.jetbrains.kotlin.name.* +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.* import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.yieldIfNotNull @@ -109,6 +112,8 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile return emptyList() } + override fun findInternalFilesForFacade(facadeFqName: FqName): Collection = emptyList() + private inline fun getTopLevelCallables(callableId: CallableId): Collection { require(callableId.classId == null) return getTopLevelDeclarations(callableId.packageName, callableId.callableName) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt index 5149880e877..75e1bcd1e13 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt @@ -11,6 +11,8 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory +import org.jetbrains.kotlin.analysis.decompiled.light.classes.KtLightClassForDecompiledDeclaration +import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile import org.jetbrains.kotlin.analysis.project.structure.* import org.jetbrains.kotlin.analysis.providers.createAllLibrariesModificationTracker import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider @@ -130,8 +132,30 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase = error("Should not be called") - //TODO Implement if necessary for symbol - override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection = emptyList() + override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection { + val facadeKtFiles = project.createDeclarationProvider(scope).findInternalFilesForFacade(fqName) + if (facadeKtFiles.isEmpty()) return emptyList() + + val partShortName = fqName.shortName().asString() + val partClassFileShortName = "$partShortName.class" + + return facadeKtFiles.mapNotNull { facadeKtFile -> + if (facadeKtFile is KtClsFile) { + val partClassFile = facadeKtFile.virtualFile.parent.findChild(partClassFileShortName) ?: return@mapNotNull null + val psiFile = facadeKtFile.manager.findFile(partClassFile) as? KtClsFile ?: facadeKtFile + val javaClsClass = DecompiledLightClassesFactory.createClsJavaClassFromVirtualFile( + mirrorFile = psiFile, + classFile = partClassFile, + correspondingClassOrObject = null, + project = project, + ) ?: return@mapNotNull null + + KtLightClassForDecompiledDeclaration(javaClsClass, javaClsClass.parent, psiFile, null) + } else { + null + } + } + } override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection { return project.createDeclarationProvider(searchScope).findFilesForFacade(facadeFqName) diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByFqNameForLibraryTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByFqNameForLibraryTestGenerated.java index 7391c0b5df1..c15430c8a91 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByFqNameForLibraryTestGenerated.java +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByFqNameForLibraryTestGenerated.java @@ -319,6 +319,12 @@ public class SymbolLightClassesByFqNameForLibraryTestGenerated extends AbstractS runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt"); } + @Test + @TestMetadata("InternalFacadeClass.kt") + public void testInternalFacadeClass() throws Exception { + runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt"); + } + @Test @TestMetadata("MultiFile.kt") public void testMultiFile() throws Exception { diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingForLibraryTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingForLibraryTestGenerated.java index 2d1afe90906..dd975f83ec8 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingForLibraryTestGenerated.java +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingForLibraryTestGenerated.java @@ -319,6 +319,12 @@ public class SymbolLightClassesParentingForLibraryTestGenerated extends Abstract runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt"); } + @Test + @TestMetadata("InternalFacadeClass.kt") + public void testInternalFacadeClass() throws Exception { + runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt"); + } + @Test @TestMetadata("MultiFile.kt") public void testMultiFile() throws Exception { diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByFqNameForSourceTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByFqNameForSourceTestGenerated.java index 69dec8dffa4..62db75c76f2 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByFqNameForSourceTestGenerated.java +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByFqNameForSourceTestGenerated.java @@ -461,6 +461,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt"); } + @Test + @TestMetadata("InternalFacadeClass.kt") + public void testInternalFacadeClass() throws Exception { + runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt"); + } + @Test @TestMetadata("MultiFile.kt") public void testMultiFile() throws Exception { diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingForSourceTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingForSourceTestGenerated.java index 3f4b9ccf0d3..50908ed90d2 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingForSourceTestGenerated.java +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingForSourceTestGenerated.java @@ -461,6 +461,12 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt"); } + @Test + @TestMetadata("InternalFacadeClass.kt") + public void testInternalFacadeClass() throws Exception { + runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt"); + } + @Test @TestMetadata("MultiFile.kt") public void testMultiFile() throws Exception { diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.java new file mode 100644 index 00000000000..ff225862b52 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.java @@ -0,0 +1 @@ +// NOT_GENERATED \ No newline at end of file diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt new file mode 100644 index 00000000000..b1ebf94aff9 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt @@ -0,0 +1,6 @@ +// test.MultiFile__InternalFacadeClassKt +// WITH_STDLIB +@file:[JvmMultifileClass JvmName("MultiFile")] +package test + +val foo = 42 diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.lib.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.lib.java new file mode 100644 index 00000000000..ebbe0b262f7 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.lib.java @@ -0,0 +1,5 @@ +final class MultiFile__InternalFacadeClassKt /* test.MultiFile__InternalFacadeClassKt*/ { + private static final int foo; + + public static final int getFoo();// getFoo() +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/asJava/CompilerLightClassTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/asJava/CompilerLightClassTestGenerated.java index 9a0166194b4..77999498a14 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/asJava/CompilerLightClassTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/asJava/CompilerLightClassTestGenerated.java @@ -407,6 +407,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt"); } + @TestMetadata("InternalFacadeClass.kt") + public void testInternalFacadeClass() throws Exception { + runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/InternalFacadeClass.kt"); + } + @TestMetadata("MultiFile.kt") public void testMultiFile() throws Exception { runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/MultiFile.kt");