[SLC] SymbolKotlinAsJavaSupport: implement getKotlinInternalClasses

^KTIJ-24067
This commit is contained in:
Dmitrii Gridin
2023-01-31 16:58:03 +01:00
committed by Space Team
parent e81f34d4b0
commit f9d5534689
15 changed files with 108 additions and 11 deletions
@@ -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<KtFile>
public abstract fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile>
/**
* Currently we want only classes from libraries ([org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile])
*/
public abstract fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile>
}
public abstract class KotlinDeclarationProviderFactory {
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.psi.*
internal class KotlinStaticDeclarationIndex {
internal val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
internal val multiFileClassPartMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
internal val classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
@@ -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<KtFile> {
return index.multiFileClassPartMap[facadeFqName].orEmpty().filter { it.virtualFile in scope }
}
override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
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)
}
@@ -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.
*/
@@ -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<Name>()
override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList<KtFile>()
override fun findFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
}
override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
}
@@ -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<KtFile> = emptyList()
private inline fun <reified T : KtCallableDeclaration> getTopLevelCallables(callableId: CallableId): Collection<T> {
require(callableId.classId == null)
return getTopLevelDeclarations(callableId.packageName, callableId.callableName)
@@ -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<KtMo
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> = error("Should not be called")
//TODO Implement if necessary for symbol
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> = emptyList()
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
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<KtFile> {
return project.createDeclarationProvider(searchScope).findFilesForFacade(facadeFqName)
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -0,0 +1 @@
// NOT_GENERATED
@@ -0,0 +1,6 @@
// test.MultiFile__InternalFacadeClassKt
// WITH_STDLIB
@file:[JvmMultifileClass JvmName("MultiFile")]
package test
val foo = 42
@@ -0,0 +1,5 @@
final class MultiFile__InternalFacadeClassKt /* test.MultiFile__InternalFacadeClassKt*/ {
private static final int foo;
public static final int getFoo();// getFoo()
}
@@ -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");