[lc] introduce KotlinAsJavaSupportBase with new common facade logic
^KT-53543
This commit is contained in:
+2
-4
@@ -8,20 +8,19 @@ package org.jetbrains.kotlin.analysis.api.fe10.test.configurator
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.CliFe10AnalysisFacade
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.ReadWriteAccessCheckerDescriptorsImpl
|
||||
import org.jetbrains.kotlin.references.fe10.base.KtFe10KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.references.fe10.base.KtFe10KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
@@ -37,7 +36,6 @@ object AnalysisApiFe10TestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
registerService(Fe10AnalysisFacade::class.java, CliFe10AnalysisFacade(project))
|
||||
registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(enabled = true))
|
||||
|
||||
registerService(SymbolLightClassFacadeCache::class.java)
|
||||
registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerDescriptorsImpl())
|
||||
}
|
||||
AnalysisHandlerExtension.registerExtension(project, KtFe10AnalysisHandlerExtension())
|
||||
|
||||
+3
-9
@@ -10,14 +10,12 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -60,18 +58,14 @@ abstract class AbstractAnalysisApiPsiTypeProviderTest : AbstractAnalysisApiSingl
|
||||
private fun getFacadeLightClass(
|
||||
ktFile: KtFile,
|
||||
project: Project,
|
||||
): KtLightClass? {
|
||||
val mainKtFileFqName = ktFile.packageFqName.child(Name.identifier(ktFile.name))
|
||||
return project.getService(SymbolLightClassFacadeCache::class.java)
|
||||
.getOrCreateSymbolLightFacade(listOf(ktFile), mainKtFileFqName)
|
||||
}
|
||||
): KtLightClass? = project.getService(KotlinAsJavaSupport::class.java).getLightFacade(ktFile)
|
||||
|
||||
private fun createLightClassByContainingClass(
|
||||
declaration: KtDeclaration,
|
||||
project: Project
|
||||
): KtLightClass? {
|
||||
val containingClass = declaration.parents.firstIsInstanceOrNull<KtClassOrObject>() ?: return null
|
||||
return project.getService(KotlinAsJavaSupport::class.java).getLightClass(containingClass)
|
||||
return KotlinAsJavaSupport.getInstance(project).getLightClass(containingClass)
|
||||
}
|
||||
|
||||
private fun KtLightClass.findLightDeclarationContext(ktDeclaration: KtDeclaration): KtLightElement<*, *>? {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class KotlinDeclarationProvider {
|
||||
|
||||
public abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>
|
||||
|
||||
public abstract fun getFacadeFilesInPackage(packageFqName: FqName): Collection<KtFile>
|
||||
public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile>
|
||||
public abstract fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile>
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,7 @@ public class KotlinStaticDeclarationProvider internal constructor(
|
||||
}
|
||||
|
||||
|
||||
override fun getFacadeFilesInPackage(packageFqName: FqName): Collection<KtFile> =
|
||||
override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile> =
|
||||
index.facadeFileMap[packageFqName]
|
||||
?.filter { ktFile ->
|
||||
ktFile.virtualFile in scope
|
||||
@@ -76,7 +76,7 @@ public class KotlinStaticDeclarationProvider internal constructor(
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
|
||||
if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList()
|
||||
return getFacadeFilesInPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName
|
||||
return findFilesForFacadeByPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName
|
||||
.filter { it.javaFileFacadeFqName == facadeFqName }
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker
|
||||
import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -150,7 +149,6 @@ public class StandaloneAnalysisAPISessionBuilder(
|
||||
}
|
||||
)
|
||||
|
||||
registerService(SymbolLightClassFacadeCache::class.java, SymbolLightClassFacadeCache(this))
|
||||
registerService(ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache())
|
||||
registerService(KotlinAsJavaSupport::class.java, SymbolKotlinAsJavaSupport(this))
|
||||
registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl())
|
||||
|
||||
-6
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
|
||||
import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -70,7 +69,6 @@ public fun configureApplicationEnvironment(app: MockApplication) {
|
||||
* In particular, this will register:
|
||||
* * [KtAnalysisSessionProvider]
|
||||
* * [SymbolKotlinAsJavaSupport]
|
||||
* * [SymbolLightClassFacadeCache] for FIR light class support
|
||||
* * [ClsJavaStubByVirtualFileCache]
|
||||
* * [KotlinModificationTrackerFactory]
|
||||
* * [KotlinAnnotationsResolverFactory]
|
||||
@@ -114,10 +112,6 @@ internal fun configureProjectEnvironment(
|
||||
)
|
||||
|
||||
// FIR LC
|
||||
project.registerService(
|
||||
SymbolLightClassFacadeCache::class.java,
|
||||
SymbolLightClassFacadeCache(project)
|
||||
)
|
||||
project.registerService(
|
||||
ClsJavaStubByVirtualFileCache::class.java,
|
||||
ClsJavaStubByVirtualFileCache()
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.psi.PsiClass
|
||||
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
|
||||
@@ -21,12 +22,13 @@ abstract class KotlinAsJavaSupport {
|
||||
|
||||
abstract fun getLightClassForScript(script: KtScript): KtLightClass?
|
||||
|
||||
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass
|
||||
|
||||
abstract fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass
|
||||
abstract fun getLightFacade(file: KtFile): KtLightClassForFacade?
|
||||
|
||||
abstract fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade
|
||||
|
||||
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtLightClassForFacade>
|
||||
|
||||
// Returns only immediately declared classes/objects, package classes are not included (they have no declarations)
|
||||
abstract fun findClassOrObjectDeclarationsInPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
@@ -38,7 +40,11 @@ abstract class KotlinAsJavaSupport {
|
||||
*
|
||||
* If the resulting collection is empty, it means that this package has not other declarations than sub-packages
|
||||
*/
|
||||
abstract fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
abstract fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
|
||||
@@ -50,12 +56,10 @@ abstract class KotlinAsJavaSupport {
|
||||
|
||||
abstract fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<KtLightClassForFacade>
|
||||
|
||||
abstract fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String>
|
||||
|
||||
abstract fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(project: Project): KotlinAsJavaSupport {
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.asJava
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project) : KotlinAsJavaSupport() {
|
||||
fun createLightFacade(file: KtFile): KtLightClassForFacade? {
|
||||
if (file.isScript()) return null
|
||||
|
||||
val module = file.findModule().takeIf { facadeIsApplicable(it, file) } ?: return null
|
||||
val facadeFqName = file.javaFileFacadeFqName
|
||||
val facadeFiles = if (file.isJvmMultifileClassFile) {
|
||||
findFilesForFacade(facadeFqName, module.contentSearchScope).filter(KtFile::isJvmMultifileClassFile)
|
||||
} else {
|
||||
listOf(file)
|
||||
}
|
||||
|
||||
if (facadeFiles.none(KtFile::hasTopLevelCallables)) return null
|
||||
return when {
|
||||
facadeFiles.none(KtFile::isCompiled) -> createInstanceOfLightFacade(facadeFqName, facadeFiles, module)
|
||||
facadeFiles.all(KtFile::isCompiled) -> createInstanceOfDecompiledLightFacade(facadeFqName, facadeFiles, module)
|
||||
else -> error("Source and compiled files are mixed: $facadeFiles")
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun KtFile.findModule(): TModule
|
||||
abstract fun facadeIsApplicable(module: TModule, file: KtFile): Boolean
|
||||
abstract val TModule.contentSearchScope: GlobalSearchScope
|
||||
|
||||
abstract fun createInstanceOfLightFacade(facadeFqName: FqName, files: List<KtFile>, module: TModule): KtLightClassForFacade
|
||||
abstract fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List<KtFile>, module: TModule): KtLightClassForFacade?
|
||||
|
||||
override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade {
|
||||
return createInstanceOfLightFacade(file.javaFileFacadeFqName, listOf(file), file.findModule())
|
||||
}
|
||||
|
||||
override fun getLightFacade(file: KtFile): KtLightClassForFacade? = CachedValuesManager.getCachedValue(file) {
|
||||
CachedValueProvider.Result.create(
|
||||
createLightFacade(file),
|
||||
tracker(file),
|
||||
)
|
||||
}
|
||||
|
||||
open fun tracker(file: KtFile): ModificationTracker {
|
||||
return KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker
|
||||
}
|
||||
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<KtLightClassForFacade> {
|
||||
return findFilesForFacadeByPackage(packageFqName, scope).toFacadeClasses()
|
||||
}
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtLightClassForFacade> {
|
||||
return findFilesForFacade(facadeFqName, scope).toFacadeClasses()
|
||||
}
|
||||
|
||||
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> {
|
||||
return findFilesForFacadeByPackage(packageFqName, scope).mapNotNullTo(mutableSetOf()) { file ->
|
||||
file.takeIf { facadeIsApplicable(it.findModule(), file) }?.javaFileFacadeFqName?.shortName()?.asString()
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
private fun Collection<KtFile>.toFacadeClasses(): List<KtLightClassForFacade> = groupBy {
|
||||
FacadeKey(it.javaFileFacadeFqName, it.isJvmMultifileClassFile, it.findModule())
|
||||
}.mapNotNull { (key, files) ->
|
||||
files.firstOrNull { facadeIsApplicable(key.module, it) }?.let(::getLightFacade)
|
||||
}
|
||||
|
||||
private data class FacadeKey<TModule>(val fqName: FqName, val isMultifile: Boolean, val module: TModule)
|
||||
}
|
||||
|
||||
-14
@@ -8,17 +8,11 @@
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
|
||||
interface KotlinLightClassFactory {
|
||||
fun createClass(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration?
|
||||
fun createFacade(project: Project, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade?
|
||||
fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade
|
||||
fun createScript(script: KtScript): KtLightClassForScript?
|
||||
|
||||
companion object {
|
||||
@@ -29,14 +23,6 @@ interface KotlinLightClassFactory {
|
||||
return instance.createClass(classOrObject)
|
||||
}
|
||||
|
||||
fun createFacade(project: Project, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? {
|
||||
return instance.createFacade(project, facadeClassFqName, searchScope)
|
||||
}
|
||||
|
||||
fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade {
|
||||
return instance.createFacadeForSyntheticFile(facadeClassFqName, file)
|
||||
}
|
||||
|
||||
fun createScript(script: KtScript): KtLightClassForScript? {
|
||||
return instance.createScript(script)
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@ import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.JvmNames
|
||||
import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -36,7 +36,7 @@ abstract class KtLightClassForFacadeBase constructor(
|
||||
private val firstFileInFacade by lazyPub { files.first() }
|
||||
|
||||
val isMultiFileClass: Boolean by lazyPub {
|
||||
files.size > 1 || JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(firstFileInFacade, JvmNames.JVM_MULTIFILE_CLASS_SHORT) != null
|
||||
files.size > 1 || firstFileInFacade.isJvmMultifileClassFile
|
||||
}
|
||||
|
||||
private val _modifierList: PsiModifierList by lazyPub {
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.intellij.psi.*
|
||||
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.asJava.elements.*
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -40,9 +39,7 @@ fun KtClassOrObject.toLightClassWithBuiltinMapping(): PsiClass? {
|
||||
|
||||
fun KtClassOrObject.toFakeLightClass(): KtFakeLightClass = KotlinAsJavaSupport.getInstance(project).getFakeLightClass(this)
|
||||
|
||||
fun KtFile.findFacadeClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project)
|
||||
.getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project))
|
||||
.firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass
|
||||
fun KtFile.findFacadeClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project).getLightFacade(this)
|
||||
|
||||
fun KtScript.toLightClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project).getLightClassForScript(this)
|
||||
|
||||
|
||||
-2
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker
|
||||
import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.impl.testConfiguration
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
@@ -52,7 +51,6 @@ object AnalysisApiFirTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
registerService(LLFirBuiltinsSessionFactory::class.java)
|
||||
registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices))
|
||||
|
||||
registerService(SymbolLightClassFacadeCache::class.java)
|
||||
registerService(KotlinAsJavaSupport::class.java, SymbolKotlinAsJavaSupport(project))
|
||||
registerService(KtCompilerPluginsProvider::class.java, KtCompilerPluginsProviderForTests(project))
|
||||
registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl())
|
||||
|
||||
+49
-54
@@ -6,20 +6,24 @@
|
||||
package org.jetbrains.kotlin.light.classes.symbol
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.analysis.providers.createAllLibrariesModificationTracker
|
||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
||||
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupportBase
|
||||
import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolBasedFakeLightClass
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForFacade
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.analyzeForLightClasses
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.getOrCreateSymbolLightClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -30,7 +34,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
|
||||
class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport() {
|
||||
class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase<KtModule>(project) {
|
||||
override fun findClassOrObjectDeclarationsInPackage(
|
||||
packageFqName: FqName,
|
||||
searchScope: GlobalSearchScope
|
||||
@@ -40,13 +44,18 @@ class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupp
|
||||
}
|
||||
}
|
||||
|
||||
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> =
|
||||
buildSet {
|
||||
addAll(project.createDeclarationProvider(searchScope).getFacadeFilesInPackage(fqName))
|
||||
findClassOrObjectDeclarationsInPackage(fqName, searchScope).mapTo(this) {
|
||||
it.containingKtFile
|
||||
}
|
||||
override fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> = buildSet {
|
||||
addAll(project.createDeclarationProvider(searchScope).findFilesForFacadeByPackage(packageFqName))
|
||||
findClassOrObjectDeclarationsInPackage(packageFqName, searchScope).mapTo(this) {
|
||||
it.containingKtFile
|
||||
}
|
||||
}
|
||||
|
||||
override fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return project.createDeclarationProvider(searchScope)
|
||||
.findFilesForFacadeByPackage(packageFqName)
|
||||
.filter { it.isFromSourceOrLibraryBinary(project) }
|
||||
}
|
||||
|
||||
private fun FqName.toClassIdSequence(): Sequence<ClassId> {
|
||||
var currentName = shortNameOrSpecial()
|
||||
@@ -88,64 +97,50 @@ class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupp
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClass =
|
||||
error("Should not be called")
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClass = error("Should not be called")
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
val filesForFacade = findFilesForFacade(facadeFqName, scope)
|
||||
override fun KtFile.findModule(): KtModule = getKtModule(project)
|
||||
|
||||
return getFacadeClassesForFiles(facadeFqName, filesForFacade)
|
||||
override fun createInstanceOfDecompiledLightFacade(
|
||||
facadeFqName: FqName,
|
||||
files: List<KtFile>,
|
||||
module: KtModule,
|
||||
): KtLightClassForFacade? = DecompiledLightClassesFactory.createLightFacadeForDecompiledKotlinFile(project, facadeFqName, files)
|
||||
|
||||
override fun tracker(file: KtFile): ModificationTracker = when (val module = file.getKtModule(project)) {
|
||||
is KtSourceModule -> module.createModuleWithoutDependenciesOutOfBlockModificationTracker(project)
|
||||
is KtLibraryModule -> project.createAllLibrariesModificationTracker()
|
||||
else -> super.tracker(file)
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> =
|
||||
error("Should not be called")
|
||||
override fun createInstanceOfLightFacade(
|
||||
facadeFqName: FqName,
|
||||
files: List<KtFile>,
|
||||
module: KtModule,
|
||||
): KtLightClassForFacade = analyzeForLightClasses(files.first()) {
|
||||
SymbolLightClassForFacade(facadeFqName, files)
|
||||
}
|
||||
|
||||
override val KtModule.contentSearchScope: GlobalSearchScope get() = this.contentScope
|
||||
|
||||
override fun facadeIsApplicable(module: KtModule, file: KtFile): Boolean = module.isFromSourceOrLibraryBinary()
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> = error("Should not be called")
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> =
|
||||
emptyList() //TODO Implement if necessary for symbol
|
||||
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> =
|
||||
project.createDeclarationProvider(scope)
|
||||
.getFacadeFilesInPackage(packageFqName)
|
||||
.asSequence()
|
||||
.filter { it.isFromSourceOrLibraryBinary(project) }
|
||||
.groupBy { it.javaFileFacadeFqName }
|
||||
.flatMap { (fqName, files) -> getFacadeClassesForFiles(fqName, files) }
|
||||
|
||||
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> =
|
||||
project.createDeclarationProvider(scope)
|
||||
.getFacadeFilesInPackage(packageFqName)
|
||||
.filter { it.isFromSourceOrLibraryBinary(project) }
|
||||
.mapTo(mutableSetOf()) { it.javaFileFacadeFqName.shortName().asString() }
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> {
|
||||
return project.createDeclarationProvider(scope)
|
||||
override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return project.createDeclarationProvider(searchScope)
|
||||
.findFilesForFacade(facadeFqName)
|
||||
.filter { it.isFromSourceOrLibraryBinary(project) }
|
||||
}
|
||||
|
||||
override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass =
|
||||
SymbolBasedFakeLightClass(classOrObject)
|
||||
override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = SymbolBasedFakeLightClass(classOrObject)
|
||||
|
||||
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass =
|
||||
TODO("Not implemented")
|
||||
private fun KtElement.isFromSourceOrLibraryBinary(project: Project): Boolean = getKtModule(project).isFromSourceOrLibraryBinary()
|
||||
|
||||
private fun getFacadeClassesForFiles(facadeFqName: FqName, allFiles: Collection<KtFile>): Collection<PsiClass> {
|
||||
if (allFiles.isEmpty()) return emptyList()
|
||||
val filesByModule = allFiles.groupBy { it.getKtModule(project) }
|
||||
|
||||
val lightClassFacadeCache = project.getService(SymbolLightClassFacadeCache::class.java)
|
||||
|
||||
return filesByModule.mapNotNull { (module, files) ->
|
||||
analyzeForLightClasses(module) {
|
||||
lightClassFacadeCache.getOrCreateSymbolLightFacade(files, facadeFqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun KtElement.isFromSourceOrLibraryBinary(project: Project): Boolean {
|
||||
return when (getKtModule(project)) {
|
||||
private fun KtModule.isFromSourceOrLibraryBinary() = when (this) {
|
||||
is KtSourceModule -> true
|
||||
is KtLibraryModule -> true
|
||||
else -> false
|
||||
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.light.classes.symbol.caches
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
||||
import org.jetbrains.kotlin.analysis.utils.caches.getValue
|
||||
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
|
||||
import org.jetbrains.kotlin.analysis.utils.collections.ConcurrentMapBasedCache
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForFacade
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.analyzeForLightClasses
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class SymbolLightClassFacadeCache(private val project: Project) {
|
||||
private val cache by softCachedValue(
|
||||
project,
|
||||
project.createProjectWideOutOfBlockModificationTracker()
|
||||
) {
|
||||
ConcurrentMapBasedCache<FacadeKey, KtLightClassForFacade?>(ConcurrentHashMap())
|
||||
}
|
||||
|
||||
fun getOrCreateSymbolLightFacade(
|
||||
ktFiles: List<KtFile>,
|
||||
facadeClassFqName: FqName,
|
||||
): KtLightClassForFacade? {
|
||||
val ktFilesWithoutScript = ktFiles.filterNot { it.isScript() }
|
||||
if (ktFilesWithoutScript.isEmpty()) return null
|
||||
val key = FacadeKey(facadeClassFqName, ktFilesWithoutScript.toSet())
|
||||
return cache.getOrPut(key) {
|
||||
getOrCreateSymbolLightFacadeNoCache(ktFilesWithoutScript, facadeClassFqName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOrCreateSymbolLightFacadeNoCache(
|
||||
ktFiles: List<KtFile>,
|
||||
facadeClassFqName: FqName,
|
||||
): KtLightClassForFacade? {
|
||||
val firstFile = ktFiles.first()
|
||||
return when {
|
||||
ktFiles.none { it.isCompiled } ->
|
||||
analyzeForLightClasses(firstFile) {
|
||||
SymbolLightClassForFacade(firstFile.manager, facadeClassFqName, ktFiles)
|
||||
}
|
||||
|
||||
ktFiles.all { it.isCompiled } -> {
|
||||
DecompiledLightClassesFactory.createLightFacadeForDecompiledKotlinFile(project, facadeClassFqName, ktFiles)
|
||||
}
|
||||
|
||||
else ->
|
||||
error("Source and compiled files are mixed: $ktFiles}")
|
||||
}
|
||||
}
|
||||
|
||||
private data class FacadeKey(val fqName: FqName, val files: Set<KtFile>)
|
||||
}
|
||||
+5
-10
@@ -40,10 +40,9 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
context(KtAnalysisSession)
|
||||
class SymbolLightClassForFacade(
|
||||
manager: PsiManager,
|
||||
override val facadeClassFqName: FqName,
|
||||
override val files: Collection<KtFile>
|
||||
) : SymbolLightClassBase(manager), KtLightClassForFacade {
|
||||
) : SymbolLightClassBase(files.first().manager), KtLightClassForFacade {
|
||||
|
||||
init {
|
||||
require(files.isNotEmpty())
|
||||
@@ -158,17 +157,13 @@ class SymbolLightClassForFacade(
|
||||
|
||||
override fun getOwnMethods() = _ownMethods
|
||||
|
||||
override fun copy(): SymbolLightClassForFacade =
|
||||
SymbolLightClassForFacade(manager, facadeClassFqName, files)
|
||||
override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files)
|
||||
|
||||
private val packageFqName: FqName =
|
||||
facadeClassFqName.parent()
|
||||
private val packageFqName: FqName = facadeClassFqName.parent()
|
||||
|
||||
private val modifierList: PsiModifierList =
|
||||
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
|
||||
private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
|
||||
|
||||
private val implementsList: LightEmptyImplementsList =
|
||||
LightEmptyImplementsList(manager)
|
||||
private val implementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager)
|
||||
|
||||
private val packageClsFile = FakeFileForLightClass(
|
||||
firstFileInFacade,
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.extraJvmDiagnosticsFromBackend
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
@@ -42,7 +43,7 @@ object CliExtraDiagnosticsProvider {
|
||||
|
||||
private fun calculateForFacade(file: KtFile): Diagnostics {
|
||||
val project = file.project
|
||||
val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName
|
||||
val facadeFqName = file.javaFileFacadeFqName
|
||||
val facadeCollection = KotlinAsJavaSupport.getInstance(project)
|
||||
.findFilesForFacade(facadeFqName, GlobalSearchScope.allScope(project))
|
||||
.ifEmpty { return Diagnostics.EMPTY }
|
||||
|
||||
@@ -10,10 +10,10 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupportBase
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
@@ -25,32 +25,33 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
|
||||
class CliKotlinAsJavaSupport(
|
||||
private val project: Project,
|
||||
private val traceHolder: CliTraceHolder
|
||||
) : KotlinAsJavaSupport() {
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return findFacadeFilesInPackage(packageFqName, scope)
|
||||
.groupBy { it.javaFileFacadeFqName }
|
||||
.mapNotNull { (facadeClassFqName, _) ->
|
||||
KotlinLightClassFactory.createFacade(project, facadeClassFqName, scope)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> {
|
||||
return findFacadeFilesInPackage(packageFqName, scope)
|
||||
.map { it.javaFileFacadeFqName.shortName().asString() }
|
||||
}
|
||||
|
||||
private fun findFacadeFilesInPackage(
|
||||
class CliKotlinAsJavaSupport(project: Project, private val traceHolder: CliTraceHolder) : KotlinAsJavaSupportBase<KtFile>(project) {
|
||||
override fun findFilesForFacadeByPackage(
|
||||
packageFqName: FqName,
|
||||
scope: GlobalSearchScope
|
||||
searchScope: GlobalSearchScope
|
||||
) = traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_PACKAGE_NAME, packageFqName)
|
||||
?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
|
||||
?.filter { PsiSearchScopeUtil.isInScope(searchScope, it) }
|
||||
.orEmpty()
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return listOfNotNull(KotlinLightClassFactory.createFacade(project, facadeFqName, scope))
|
||||
override fun KtFile.findModule(): KtFile = this
|
||||
|
||||
override fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List<KtFile>, module: KtFile): KtLightClassForFacade? {
|
||||
error("Should not be called")
|
||||
}
|
||||
|
||||
override fun createInstanceOfLightFacade(facadeFqName: FqName, files: List<KtFile>, module: KtFile): KtLightClassForFacade {
|
||||
return LightClassGenerationSupport.getInstance(files.first().project).createUltraLightClassForFacade(facadeFqName, files)
|
||||
}
|
||||
|
||||
override val KtFile.contentSearchScope: GlobalSearchScope get() = GlobalSearchScope.allScope(project)
|
||||
override fun facadeIsApplicable(module: KtFile, file: KtFile): Boolean = !module.isCompiled
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): List<KtFile> {
|
||||
if (facadeFqName.isRoot) return emptyList()
|
||||
|
||||
return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(searchScope, it)
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
@@ -59,24 +60,13 @@ class CliKotlinAsJavaSupport(
|
||||
}
|
||||
|
||||
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
|
||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) }
|
||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { getLightClassForScript(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return emptyList()
|
||||
}
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> = emptyList()
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> {
|
||||
if (facadeFqName.isRoot) return emptyList()
|
||||
|
||||
return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(scope, it)
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass =
|
||||
KtDescriptorBasedFakeLightClass(classOrObject)
|
||||
override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = KtDescriptorBasedFakeLightClass(classOrObject)
|
||||
|
||||
override fun findClassOrObjectDeclarationsInPackage(
|
||||
packageFqName: FqName, searchScope: GlobalSearchScope
|
||||
@@ -90,12 +80,11 @@ class CliKotlinAsJavaSupport(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean {
|
||||
return !traceHolder.module.getPackage(fqName).isEmpty()
|
||||
}
|
||||
override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean = !traceHolder.module.getPackage(fqName).isEmpty()
|
||||
|
||||
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> {
|
||||
val packageView = traceHolder.module.getPackage(fqn)
|
||||
@@ -118,11 +107,11 @@ class CliKotlinAsJavaSupport(
|
||||
}
|
||||
}
|
||||
|
||||
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter {
|
||||
override fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, packageFqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(searchScope, it)
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = error("Should not be called")
|
||||
override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade = error("Should not be called")
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.intellij.util.lang.UrlClassLoader
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.FacadeCache
|
||||
import org.jetbrains.kotlin.asJava.classes.KotlinK1LightClassFactory
|
||||
import org.jetbrains.kotlin.asJava.classes.KotlinLightClassFactory
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
@@ -717,7 +716,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
fun registerProjectServices(project: MockProject) {
|
||||
with(project) {
|
||||
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
|
||||
registerService(FacadeCache::class.java, FacadeCache(this))
|
||||
registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver())
|
||||
}
|
||||
}
|
||||
@@ -735,7 +733,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
with(project) {
|
||||
val traceHolder = CliTraceHolder()
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
|
||||
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
|
||||
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(project, traceHolder)
|
||||
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport)
|
||||
|
||||
+5
-3
@@ -70,7 +70,7 @@ object JvmFileClassUtil {
|
||||
|
||||
if (jvmName == null && jvmPackageName == null) return null
|
||||
|
||||
val isMultifileClass = findAnnotationEntryOnFileNoResolve(file, JVM_MULTIFILE_CLASS_SHORT) != null
|
||||
val isMultifileClass = file.isJvmMultifileClassFile
|
||||
|
||||
return ParsedJvmFileClassAnnotations(jvmName, jvmPackageName, isMultifileClass)
|
||||
}
|
||||
@@ -122,10 +122,12 @@ val KtFile.javaFileFacadeFqName: FqName
|
||||
return facadeFqName
|
||||
}
|
||||
|
||||
val KtFile.isJvmMultifileClassFile: Boolean
|
||||
get() = JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(this, JVM_MULTIFILE_CLASS_SHORT) != null
|
||||
|
||||
private val LOG = Logger.getInstance("JvmFileClassUtil")
|
||||
|
||||
fun KtDeclaration.isInsideJvmMultifileClassFile() =
|
||||
JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(containingKtFile, JVM_MULTIFILE_CLASS_SHORT) != null
|
||||
fun KtDeclaration.isInsideJvmMultifileClassFile() = containingKtFile.isJvmMultifileClassFile
|
||||
|
||||
val FqName.internalNameWithoutInnerClasses: String
|
||||
get() = JvmClassName.byFqNameWithoutInnerClasses(this).internalName
|
||||
|
||||
+1
-5
@@ -33,11 +33,7 @@ abstract class LightClassGenerationSupport {
|
||||
ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
|
||||
}
|
||||
|
||||
internal fun canCreateUltraLightClassForFacade(files: Collection<KtFile>): Boolean = files.none { it.isScript() }
|
||||
|
||||
fun createUltraLightClassForFacade(facadeClassFqName: FqName, files: Collection<KtFile>): KtUltraLightClassForFacade? {
|
||||
if (!canCreateUltraLightClassForFacade(files)) return null
|
||||
|
||||
fun createUltraLightClassForFacade(facadeClassFqName: FqName, files: Collection<KtFile>): KtUltraLightClassForFacade {
|
||||
val filesToSupports: List<Pair<KtFile, KtUltraLightSupport>> = files.map {
|
||||
it to getUltraLightClassSupport(it)
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.asJava.classes
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.util.containers.SLRUCache
|
||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
private data class FacadeCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope)
|
||||
|
||||
private data class ValueWrapper(val value: KtLightClassForFacade?) {
|
||||
companion object {
|
||||
val Null = ValueWrapper(null)
|
||||
}
|
||||
}
|
||||
|
||||
class FacadeCache(private val project: Project) {
|
||||
private inner class FacadeCacheData {
|
||||
val cache = object : SLRUCache<FacadeCacheKey, ValueWrapper>(20, 30) {
|
||||
override fun createValue(key: FacadeCacheKey): ValueWrapper =
|
||||
KotlinK1LightClassFactory.createFacadeNoCache(key.fqName, key.searchScope, project)
|
||||
?.let { ValueWrapper(it) }
|
||||
?: ValueWrapper.Null
|
||||
}
|
||||
}
|
||||
|
||||
private val cachedValue: CachedValue<FacadeCacheData> = CachedValuesManager.getManager(project).createCachedValue(
|
||||
{
|
||||
CachedValueProvider.Result.create(
|
||||
FacadeCacheData(),
|
||||
KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker
|
||||
)
|
||||
}, false
|
||||
)
|
||||
|
||||
operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? {
|
||||
synchronized(cachedValue) {
|
||||
return cachedValue.value.cache.get(FacadeCacheKey(qualifiedName, searchScope)).value
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): FacadeCache {
|
||||
return ServiceManager.getService(project, FacadeCache::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-36
@@ -5,17 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
|
||||
class KotlinK1LightClassFactory : KotlinLightClassFactory {
|
||||
@@ -27,18 +22,6 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory {
|
||||
)
|
||||
}
|
||||
|
||||
override fun createFacade(
|
||||
project: Project,
|
||||
facadeClassFqName: FqName,
|
||||
searchScope: GlobalSearchScope,
|
||||
): KtLightClassForFacade? = FacadeCache.getInstance(project)[facadeClassFqName, searchScope]
|
||||
|
||||
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade {
|
||||
return LightClassGenerationSupport.getInstance(file.project).run {
|
||||
createUltraLightClassForFacade(facadeClassFqName, listOf(file)) ?: error { "Unable to create UL class for facade" }
|
||||
}
|
||||
}
|
||||
|
||||
override fun createScript(script: KtScript): KtLightClassForScript? = CachedValuesManager.getCachedValue(script) {
|
||||
CachedValueProvider.Result.create(
|
||||
createScriptNoCache(script),
|
||||
@@ -54,9 +37,7 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory {
|
||||
return null
|
||||
}
|
||||
|
||||
return LightClassGenerationSupport.getInstance(script.project).run {
|
||||
createUltraLightClassForScript(script)
|
||||
}
|
||||
return LightClassGenerationSupport.getInstance(script.project).createUltraLightClassForScript(script)
|
||||
}
|
||||
|
||||
fun createClassNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||
@@ -70,22 +51,7 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory {
|
||||
return null
|
||||
}
|
||||
|
||||
return LightClassGenerationSupport.getInstance(classOrObject.project).run {
|
||||
createUltraLightClass(classOrObject)
|
||||
}
|
||||
}
|
||||
|
||||
fun createFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? {
|
||||
val sources = KotlinAsJavaSupport.getInstance(project)
|
||||
.findFilesForFacade(fqName, searchScope)
|
||||
.filterNot { it.isCompiled || it.isScript() }
|
||||
|
||||
if (sources.isEmpty()) return null
|
||||
return LightClassGenerationSupport.getInstance(project).run {
|
||||
if (!canCreateUltraLightClassForFacade(sources)) return null
|
||||
createUltraLightClassForFacade(fqName, sources)
|
||||
?: error("Unable to create UL class for facade: $fqName for ${sources.joinToString { it.virtualFilePath }}")
|
||||
}
|
||||
return LightClassGenerationSupport.getInstance(classOrObject.project).createUltraLightClass(classOrObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user