From ce183a8eeb98738fa6b66596a4e5082b278150da Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 28 Jun 2022 17:57:30 +0200 Subject: [PATCH] Revert "Revert "[light classes] drop old light classes and backend: iteration #3"" This reverts commit 074dd1c19d19236044d0a504d1ad77e0c741c578. --- .../compiler/CliExtraDiagnosticsProvider.kt | 37 +++++++ .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 19 +--- .../KotlinExtraDiagnosticsProvider.java | 25 +++++ .../asJava/builder/LightClassDataProvider.kt | 103 +++++++----------- .../asJava/duplicateJvmSignatureUtil.kt | 40 +------ 5 files changed, 108 insertions(+), 116 deletions(-) create mode 100644 compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt create mode 100644 compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinExtraDiagnosticsProvider.java 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 new file mode 100644 index 00000000000..328602d35dc --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt @@ -0,0 +1,37 @@ +/* + * 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.cli.jvm.compiler + +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.asJava.KotlinExtraDiagnosticsProvider +import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder +import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade +import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration +import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics + +class CliExtraDiagnosticsProvider : KotlinExtraDiagnosticsProvider { + override fun forClassOrObject(kclass: KtClassOrObject): Diagnostics { + val lightClassDataHolder = KtLightClassForSourceDeclaration.getLightClassDataHolder(kclass) + if (lightClassDataHolder is InvalidLightClassDataHolder) { + return Diagnostics.EMPTY + } + + return lightClassDataHolder.extraDiagnostics + } + + override fun forFacade(file: KtFile, moduleScope: GlobalSearchScope): Diagnostics { + val project = file.project + val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName + return LightClassDataProviderForFileFacade(project, facadeFqName, moduleScope) + .compute() + ?.value + ?.extraDiagnostics + ?: Diagnostics.EMPTY + } +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 3d0b14b11b1..9b9f8b8685c 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.cli.jvm.compiler @@ -50,6 +39,7 @@ import com.intellij.util.io.URLUtil import com.intellij.util.lang.UrlClassLoader import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.KotlinExtraDiagnosticsProvider import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.classes.FacadeCache import org.jetbrains.kotlin.asJava.finder.JavaElementFinder @@ -61,7 +51,6 @@ import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension import org.jetbrains.kotlin.cli.common.extensions.ShellExtension import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarFileSystem @@ -70,7 +59,6 @@ import org.jetbrains.kotlin.cli.jvm.index.* import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver -import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension @@ -732,6 +720,7 @@ class KotlinCoreEnvironment private constructor( val traceHolder = CliTraceHolder() val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project) val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) + registerService(KotlinExtraDiagnosticsProvider::class.java, CliExtraDiagnosticsProvider()) registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinExtraDiagnosticsProvider.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinExtraDiagnosticsProvider.java new file mode 100644 index 00000000000..4bab2ecb9a7 --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinExtraDiagnosticsProvider.java @@ -0,0 +1,25 @@ +/* + * 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.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.psi.KtClassOrObject; +import org.jetbrains.kotlin.psi.KtFile; +import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics; + +public interface KotlinExtraDiagnosticsProvider { + @NotNull + Diagnostics forClassOrObject(@NotNull KtClassOrObject kclass); + + @NotNull + Diagnostics forFacade(@NotNull KtFile file, @NotNull GlobalSearchScope moduleScope); + + static @NotNull KotlinExtraDiagnosticsProvider getInstance(@NotNull Project project) { + return project.getService(KotlinExtraDiagnosticsProvider.class); + } +} \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt index 5b1b9db3ae0..272078e6c12 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.builder @@ -36,23 +25,27 @@ import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.org.objectweb.asm.Type class LightClassDataProviderForClassOrObject( - private val classOrObject: KtClassOrObject + private val classOrObject: KtClassOrObject ) : CachedValueProvider { private fun computeLightClassData(): LightClassDataHolder.ForClass { val file = classOrObject.containingKtFile val packageFqName = file.packageFqName - return LightClassGenerationSupport.getInstance(classOrObject.project).createDataHolderForClass(classOrObject) { - constructionContext -> - buildLightClass(packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) { - state, files -> - val packageCodegen = state.factory.forPackage(packageFqName, files) - val packagePartType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file)) - val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file) - MemberCodegen.genClassOrObject(context, getOutermostClassOrObject(classOrObject), state, null) - state.factory.done() + return LightClassGenerationSupport.getInstance(classOrObject.project) + .createDataHolderForClass(classOrObject) { constructionContext -> + buildLightClass( + packageFqName, + listOf(file), + ClassFilterForClassOrObject(classOrObject), + constructionContext + ) { state, files -> + val packageCodegen = state.factory.forPackage(packageFqName, files) + val packagePartType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file)) + val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file) + MemberCodegen.genClassOrObject(context, getOutermostClassOrObject(classOrObject), state, null) + state.factory.done() + } } - } } override fun compute(): CachedValueProvider.Result? { @@ -68,16 +61,14 @@ class LightClassDataProviderForClassOrObject( } } -sealed class LightClassDataProviderForFileFacade constructor( - protected val project: Project, protected val facadeFqName: FqName +class LightClassDataProviderForFileFacade constructor( + private val project: Project, private val facadeFqName: FqName, private val searchScope: GlobalSearchScope ) : CachedValueProvider { - abstract fun findFiles(): Collection + fun findFiles(): Collection = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope) private fun computeLightClassData(files: Collection): LightClassDataHolder.ForFacade { - return LightClassGenerationSupport.getInstance(project).createDataHolderForFacade(files) { - constructionContext -> - buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ { - state, files -> + return LightClassGenerationSupport.getInstance(project).createDataHolderForFacade(files) { constructionContext -> + buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@{ state, files -> val representativeFile = files.first() val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(representativeFile) if (!fileClassInfo.withJvmMultifileClass) { @@ -99,46 +90,26 @@ sealed class LightClassDataProviderForFileFacade constructor( if (files.isEmpty()) return null return CachedValueProvider.Result.create( - computeLightClassData(files), - KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker + computeLightClassData(files), + KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker ) } override fun toString(): String { return this::class.java.name + " for $facadeFqName" } - - // create delegate by relevant files in project source using LightClassGenerationSupport - class ByProjectSource( - project: Project, - facadeFqName: FqName, - private val searchScope: GlobalSearchScope - ) : LightClassDataProviderForFileFacade(project, facadeFqName) { - override fun findFiles() = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope) - } - - // create delegate by single file - class ByFile( - project: Project, - facadeFqName: FqName, - private val file: KtFile - ) : LightClassDataProviderForFileFacade(project, facadeFqName) { - override fun findFiles() = listOf(file) - } } class LightClassDataProviderForScript(private val script: KtScript) : CachedValueProvider { private fun computeLightClassData(): LightClassDataHolder.ForScript { - return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) { - constructionContext -> + return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) { constructionContext -> buildLightClass( - script.fqName.parent(), - listOf(script.containingKtFile), - ClassFilterForScript(script), - constructionContext - ) generate@ { - state, files -> + 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() @@ -148,10 +119,10 @@ class LightClassDataProviderForScript(private val script: KtScript) : CachedValu } override fun compute(): CachedValueProvider.Result? = - CachedValueProvider.Result.create( - computeLightClassData(), - KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker - ) + CachedValueProvider.Result.create( + computeLightClassData(), + KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker + ) override fun toString(): String = this::class.java.name + " for ${script.fqName}" } @@ -197,7 +168,7 @@ private class ClassFilterForClassOrObject(private val classOrObject: KtClassOrOb } override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) - // generate outer classes but not their members + // generate outer classes but not their members = shouldGenerateClassMembers(processingClassOrObject) || processingClassOrObject.isAncestor(classOrObject, true) override fun shouldGenerateScript(script: KtScript) = PsiTreeUtil.isAncestor(script, classOrObject, false) @@ -214,10 +185,10 @@ object ClassFilterForFacade : GenerationState.GenerateClassFilter() { private class ClassFilterForScript(val script: KtScript) : GenerationState.GenerateClassFilter() { override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = - shouldGenerateClass(processingClassOrObject) + shouldGenerateClass(processingClassOrObject) override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = - processingClassOrObject.isAncestor(script, true) + processingClassOrObject.isAncestor(script, true) override fun shouldGenerateClassMembers(processingClassOrObject: KtClassOrObject): Boolean = true diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt index f2780c4ef19..8ed5fd80d36 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt @@ -1,32 +1,17 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder -import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade -import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject import org.jetbrains.kotlin.asJava.classes.safeIsScript import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.Errors.* -import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData @@ -34,25 +19,9 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.* fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? { - fun getDiagnosticsForFileFacade(file: KtFile): Diagnostics? { - val project = file.project - - val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName - - //TODO Maybe it is better to cache this item - return LightClassDataProviderForFileFacade.ByProjectSource(project, facadeFqName, moduleScope) - .compute() - ?.value - ?.extraDiagnostics - } - fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics { val outermostClass = getOutermostClassOrObject(ktClassOrObject) - val lightClassDataHolder = KtLightClassForSourceDeclaration.getLightClassDataHolder(outermostClass) - if (lightClassDataHolder is InvalidLightClassDataHolder) { - return Diagnostics.EMPTY - } - return lightClassDataHolder.extraDiagnostics + return KotlinExtraDiagnosticsProvider.getInstance(ktClassOrObject.project).forClassOrObject(outermostClass) } fun doGetDiagnostics(): Diagnostics? { @@ -76,8 +45,9 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic when (parent) { is KtFile -> { - return getDiagnosticsForFileFacade(parent) + return KotlinExtraDiagnosticsProvider.getInstance(parent.project).forFacade(parent, moduleScope) } + is KtClassBody -> { val parentsParent = parent.getParent()