[lc] KotlinAsJavaSupportBase: implement getLightClassForScript

^KT-50241
This commit is contained in:
Dmitry Gridin
2022-09-01 18:59:18 +02:00
committed by Space
parent 46548e5443
commit e58b98bb5c
7 changed files with 29 additions and 66 deletions
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.analysisContext
import org.jetbrains.kotlin.psi.*
abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project) : KotlinAsJavaSupport() {
fun createLightFacade(file: KtFile): Pair<KtLightClassForFacade?, ModificationTracker>? {
@@ -168,6 +165,25 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
CachedValueProvider.Result.createSingleDependency(clazz, tracker)
}
}
fun createLightScript(script: KtScript): Pair<KtLightClass?, ModificationTracker>? {
val containingFile = script.containingFile
if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments
return null
}
return createInstanceOfLightScript(script) to projectWideOutOfBlockModificationTracker()
}
protected abstract fun createInstanceOfLightScript(script: KtScript): KtLightClass?
override fun getLightClassForScript(script: KtScript): KtLightClass? = ifValid(script) {
CachedValuesManager.getCachedValue(script) {
val (lightScript, tracker) = createLightScript(script) ?: (null to projectWideOutOfBlockModificationTracker())
CachedValueProvider.Result.createSingleDependency(lightScript, tracker)
}
}
}
private fun <T : PsiElement, V> ifValid(element: T, action: () -> V?): V? {
@@ -1,21 +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.
*/
@file:Suppress("unused")
package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.components.ServiceManager
import org.jetbrains.kotlin.psi.KtScript
interface KotlinLightClassFactory {
fun createScript(script: KtScript): KtLightClassForScript?
companion object {
fun createScript(script: KtScript): KtLightClassForScript? {
return ServiceManager.getService(KotlinLightClassFactory::class.java).createScript(script)
}
}
}
@@ -87,7 +87,7 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase<KtMo
.getKotlinSubPackageFqNames(fqn)
.map { fqn.child(it) }
override fun getLightClassForScript(script: KtScript): KtLightClass = error("Should not be called")
override fun createInstanceOfLightScript(script: KtScript): KtLightClass? = error("Should not be called")
override fun KtFile.findModule(): KtModule = getKtModule(project)
@@ -12,7 +12,10 @@ import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupportBase
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.asJava.classes.KtDescriptorBasedFakeLightClass
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.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
import org.jetbrains.kotlin.name.FqName
@@ -94,7 +97,9 @@ class CliKotlinAsJavaSupport(project: Project, private val traceHolder: CliTrace
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
}
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KotlinLightClassFactory.createScript(script)
override fun createInstanceOfLightScript(script: KtScript): KtLightClass {
return LightClassGenerationSupport.getInstance(script.project).createUltraLightClassForScript(script)
}
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
@@ -42,8 +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.KotlinK1LightClassFactory
import org.jetbrains.kotlin.asJava.classes.KotlinLightClassFactory
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.cli.common.*
@@ -674,7 +672,6 @@ class KotlinCoreEnvironment private constructor(
// ability to get text from annotations xml files
applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml")
applicationEnvironment.registerParserDefinition(JavaParserDefinition())
applicationEnvironment.registerApplicationService(KotlinLightClassFactory::class.java, KotlinK1LightClassFactory())
}
// made public for Upsource
@@ -1,34 +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.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtScript
class KotlinK1LightClassFactory : KotlinLightClassFactory {
override fun createScript(script: KtScript): KtLightClassForScript? = CachedValuesManager.getCachedValue(script) {
CachedValueProvider.Result.create(
createScriptNoCache(script),
KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker,
)
}
companion object {
fun createScriptNoCache(script: KtScript): KtLightClassForScript? {
val containingFile = script.containingFile
if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments
return null
}
return LightClassGenerationSupport.getInstance(script.project).createUltraLightClassForScript(script)
}
}
}
@@ -489,7 +489,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
val containingBlock = classOrObject.parent as? KtBlockExpression
val containingScript = containingBlock?.parent as? KtScript
containingScript?.let { return KotlinLightClassFactory.createScript(it) }
containingScript?.let { return it.toLightClass() }
return null
}