From 357e15085eb0ec205fcaffb0a2e887e1127122b5 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 28 Jun 2022 13:52:06 +0200 Subject: [PATCH] Revert "[light classes] drop old light classes and backend: iteration #11" This reverts commit 9d81a4abea4d27a72730ce0194536770e1af28f2. --- .../compiler/CliExtraDiagnosticsProvider.kt | 20 ++++++++- .../jvm/compiler/LightClassDataProvider.kt | 45 ++++++++++++++++++- .../jvm/compiler/duplicateJvmSignatureUtil.kt | 4 +- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt index e9ea6c66ffe..39b06ff067f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt @@ -12,6 +12,8 @@ import com.intellij.psi.util.CachedValuesManager import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject +import org.jetbrains.kotlin.asJava.classes.safeIsLocal +import org.jetbrains.kotlin.asJava.classes.safeScript import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass import org.jetbrains.kotlin.cli.jvm.compiler.builder.InvalidLightClassDataHolder import org.jetbrains.kotlin.cli.jvm.compiler.builder.LightClassDataHolder @@ -19,9 +21,11 @@ import org.jetbrains.kotlin.cli.jvm.compiler.builder.buildLightClass import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.utils.addToStdlib.cast +private val JAVA_API_STUB_FOR_SCRIPT = Key.create>("JAVA_API_STUB_FOR_SCRIPT") private val JAVA_API_STUB = Key.create>("JAVA_API_STUB") private val JAVA_API_STUB_LOCK = Key.create("JAVA_API_STUB_LOCK") @@ -33,7 +37,12 @@ object CliExtraDiagnosticsProvider { return Diagnostics.EMPTY } - val lightClassDataHolder = getLightClassCachedValue(kclass).value + val containingScript = kclass.containingKtFile.safeScript() + val lightClassDataHolder = when { + !kclass.safeIsLocal() && containingScript != null -> getLightClassCachedValue(containingScript).value + else -> getLightClassCachedValue(kclass).value + } + return if (lightClassDataHolder is InvalidLightClassDataHolder) { Diagnostics.EMPTY } else { @@ -68,6 +77,15 @@ object CliExtraDiagnosticsProvider { } } +private fun getLightClassCachedValue(script: KtScript): CachedValue { + return script.getUserData(JAVA_API_STUB_FOR_SCRIPT) ?: createCachedValueForScript(script).also { + script.putUserData(JAVA_API_STUB_FOR_SCRIPT, it) + } +} + +private fun createCachedValueForScript(script: KtScript): CachedValue = + CachedValuesManager.getManager(script.project).createCachedValue(LightClassDataProviderForScript(script), false) + private fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue { val outerClassValue = getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) outerClassValue?.let { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/LightClassDataProvider.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/LightClassDataProvider.kt index 226853627e1..a4064fe0fc3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/LightClassDataProvider.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/LightClassDataProvider.kt @@ -99,10 +99,53 @@ private class ClassFilterForClassOrObject(private val classOrObject: KtClassOrOb override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false } +internal class LightClassDataProviderForScript(private val script: KtScript) : CachedValueProvider { + private fun computeLightClassData(): LightClassDataHolder.ForScript { + return LightClassGenerationSupport.getInstance(script.project) + .cast() + .createDataHolderForScript { constructionContext -> + buildLightClass( + script.fqName.parent(), + listOf(script.containingKtFile), + ClassFilterForScript(script), + constructionContext + ) generate@{ state, files -> + val scriptFile = files.first() + val codegen = state.factory.forPackage(scriptFile.packageFqName, files) + codegen.generate() + state.factory.done() + } + } + } + + override fun compute(): CachedValueProvider.Result = + CachedValueProvider.Result.create( + computeLightClassData(), + KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker + ) + + override fun toString(): String = this::class.java.name + " for ${script.fqName}" +} + +private class ClassFilterForScript(val script: KtScript) : GenerationState.GenerateClassFilter() { + override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = + shouldGenerateClass(processingClassOrObject) + + override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = + processingClassOrObject.isAncestor(script, true) + + override fun shouldGenerateClassMembers(processingClassOrObject: KtClassOrObject): Boolean = true + + override fun shouldGeneratePackagePart(ktFile: KtFile): Boolean = script.containingKtFile === ktFile + + override fun shouldGenerateScript(script: KtScript): Boolean = this.script === script + override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false +} + internal object ClassFilterForFacade : GenerationState.GenerateClassFilter() { override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject) = shouldGenerateClass(processingClassOrObject) override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) = KtPsiUtil.isLocal(processingClassOrObject) override fun shouldGeneratePackagePart(ktFile: KtFile) = true override fun shouldGenerateScript(script: KtScript) = false override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false -} +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/duplicateJvmSignatureUtil.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/duplicateJvmSignatureUtil.kt index cd45b9cd875..0a034e2daf4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/duplicateJvmSignatureUtil.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/duplicateJvmSignatureUtil.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.* -import org.jetbrains.kotlin.utils.addToStdlib.safeAs fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? { fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics { @@ -26,7 +25,8 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic } fun doGetDiagnostics(): Diagnostics? { - if (element.containingFile.safeAs()?.safeIsScript() == true) return null + //TODO: enable this diagnostic when light classes for scripts are ready + if ((element.containingFile as? KtFile)?.safeIsScript() == true) return null var parent = element.parent if (element is KtPropertyAccessor) {