[SLC] SymbolKotlinAsJavaSupport: implement getKotlinInternalClasses
^KTIJ-24067
This commit is contained in:
committed by
Space Team
parent
e81f34d4b0
commit
f9d5534689
+6
-1
@@ -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.
|
* 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 findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile>
|
||||||
public abstract fun findFilesForFacade(facadeFqName: 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 {
|
public abstract class KotlinDeclarationProviderFactory {
|
||||||
|
|||||||
+1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
|
|
||||||
internal class KotlinStaticDeclarationIndex {
|
internal class KotlinStaticDeclarationIndex {
|
||||||
internal val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
|
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 classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
|
||||||
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
|
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
|
||||||
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
|
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
|
||||||
|
|||||||
+20
-3
@@ -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.
|
* 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.project.Project
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
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.search.GlobalSearchScope
|
||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import com.intellij.util.indexing.FileContent
|
import com.intellij.util.indexing.FileContent
|
||||||
@@ -77,6 +79,10 @@ public class KotlinStaticDeclarationProvider internal constructor(
|
|||||||
.filter { it.javaFileFacadeFqName == facadeFqName }
|
.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> =
|
override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
|
||||||
index.topLevelPropertyMap[callableId.packageName]
|
index.topLevelPropertyMap[callableId.packageName]
|
||||||
?.filter { ktProperty ->
|
?.filter { ktProperty ->
|
||||||
@@ -240,7 +246,18 @@ public class KotlinStaticDeclarationProviderFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadBuiltIns().forEach { ktFileStub ->
|
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
|
// top-level functions and properties, built-in classes
|
||||||
ktFileStub.childrenStubs.forEach(::indexStub)
|
ktFileStub.childrenStubs.forEach(::indexStub)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -6,7 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
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.psi.*
|
||||||
|
|
||||||
internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() {
|
internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() {
|
||||||
@@ -20,4 +23,5 @@ internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() {
|
|||||||
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName) = emptySet<Name>()
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName) = emptySet<Name>()
|
||||||
override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList<KtFile>()
|
override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList<KtFile>()
|
||||||
override fun findFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
override fun findFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
||||||
|
override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
||||||
}
|
}
|
||||||
+7
-2
@@ -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.
|
* 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
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
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.psi.*
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||||
@@ -109,6 +112,8 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile> = emptyList()
|
||||||
|
|
||||||
private inline fun <reified T : KtCallableDeclaration> getTopLevelCallables(callableId: CallableId): Collection<T> {
|
private inline fun <reified T : KtCallableDeclaration> getTopLevelCallables(callableId: CallableId): Collection<T> {
|
||||||
require(callableId.classId == null)
|
require(callableId.classId == null)
|
||||||
return getTopLevelDeclarations(callableId.packageName, callableId.callableName)
|
return getTopLevelDeclarations(callableId.packageName, callableId.callableName)
|
||||||
|
|||||||
+26
-2
@@ -11,6 +11,8 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory
|
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.project.structure.*
|
||||||
import org.jetbrains.kotlin.analysis.providers.createAllLibrariesModificationTracker
|
import org.jetbrains.kotlin.analysis.providers.createAllLibrariesModificationTracker
|
||||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
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")
|
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> {
|
||||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> = emptyList()
|
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> {
|
override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||||
return project.createDeclarationProvider(searchScope).findFilesForFacade(facadeFqName)
|
return project.createDeclarationProvider(searchScope).findFilesForFacade(facadeFqName)
|
||||||
|
|||||||
+6
@@ -319,6 +319,12 @@ public class SymbolLightClassesByFqNameForLibraryTestGenerated extends AbstractS
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt");
|
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
|
@Test
|
||||||
@TestMetadata("MultiFile.kt")
|
@TestMetadata("MultiFile.kt")
|
||||||
public void testMultiFile() throws Exception {
|
public void testMultiFile() throws Exception {
|
||||||
|
|||||||
+6
@@ -319,6 +319,12 @@ public class SymbolLightClassesParentingForLibraryTestGenerated extends Abstract
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt");
|
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
|
@Test
|
||||||
@TestMetadata("MultiFile.kt")
|
@TestMetadata("MultiFile.kt")
|
||||||
public void testMultiFile() throws Exception {
|
public void testMultiFile() throws Exception {
|
||||||
|
|||||||
+6
@@ -461,6 +461,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt");
|
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
|
@Test
|
||||||
@TestMetadata("MultiFile.kt")
|
@TestMetadata("MultiFile.kt")
|
||||||
public void testMultiFile() throws Exception {
|
public void testMultiFile() throws Exception {
|
||||||
|
|||||||
+6
@@ -461,6 +461,12 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt");
|
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
|
@Test
|
||||||
@TestMetadata("MultiFile.kt")
|
@TestMetadata("MultiFile.kt")
|
||||||
public void testMultiFile() throws Exception {
|
public void testMultiFile() throws Exception {
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
// NOT_GENERATED
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// test.MultiFile__InternalFacadeClassKt
|
||||||
|
// WITH_STDLIB
|
||||||
|
@file:[JvmMultifileClass JvmName("MultiFile")]
|
||||||
|
package test
|
||||||
|
|
||||||
|
val foo = 42
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
final class MultiFile__InternalFacadeClassKt /* test.MultiFile__InternalFacadeClassKt*/ {
|
||||||
|
private static final int foo;
|
||||||
|
|
||||||
|
public static final int getFoo();// getFoo()
|
||||||
|
}
|
||||||
+5
@@ -407,6 +407,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/AllPrivate.kt");
|
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")
|
@TestMetadata("MultiFile.kt")
|
||||||
public void testMultiFile() throws Exception {
|
public void testMultiFile() throws Exception {
|
||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/MultiFile.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/facades/MultiFile.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user