Revert "Revert "[light classes] drop old light classes and backend: iteration #3""

This reverts commit 074dd1c19d.
This commit is contained in:
Dmitry Gridin
2022-06-28 17:57:30 +02:00
parent dd824aacb6
commit ce183a8eeb
5 changed files with 108 additions and 116 deletions
@@ -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
}
}
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.cli.jvm.compiler package org.jetbrains.kotlin.cli.jvm.compiler
@@ -50,6 +39,7 @@ import com.intellij.util.io.URLUtil
import com.intellij.util.lang.UrlClassLoader import com.intellij.util.lang.UrlClassLoader
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.KotlinExtraDiagnosticsProvider
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.FacadeCache import org.jetbrains.kotlin.asJava.classes.FacadeCache
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder 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.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity 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.CompilerMessageSeverity.STRONG_WARNING
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarFileSystem 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.javac.JavacWrapperRegistrar
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver 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.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
@@ -732,6 +720,7 @@ class KotlinCoreEnvironment private constructor(
val traceHolder = CliTraceHolder() val traceHolder = CliTraceHolder()
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project) val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
registerService(KotlinExtraDiagnosticsProvider::class.java, CliExtraDiagnosticsProvider())
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport)
@@ -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);
}
}
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.asJava.builder package org.jetbrains.kotlin.asJava.builder
@@ -42,10 +31,14 @@ class LightClassDataProviderForClassOrObject(
private fun computeLightClassData(): LightClassDataHolder.ForClass { private fun computeLightClassData(): LightClassDataHolder.ForClass {
val file = classOrObject.containingKtFile val file = classOrObject.containingKtFile
val packageFqName = file.packageFqName val packageFqName = file.packageFqName
return LightClassGenerationSupport.getInstance(classOrObject.project).createDataHolderForClass(classOrObject) { return LightClassGenerationSupport.getInstance(classOrObject.project)
constructionContext -> .createDataHolderForClass(classOrObject) { constructionContext ->
buildLightClass(packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) { buildLightClass(
state, files -> packageFqName,
listOf(file),
ClassFilterForClassOrObject(classOrObject),
constructionContext
) { state, files ->
val packageCodegen = state.factory.forPackage(packageFqName, files) val packageCodegen = state.factory.forPackage(packageFqName, files)
val packagePartType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file)) val packagePartType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file))
val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file) val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file)
@@ -68,16 +61,14 @@ class LightClassDataProviderForClassOrObject(
} }
} }
sealed class LightClassDataProviderForFileFacade constructor( class LightClassDataProviderForFileFacade constructor(
protected val project: Project, protected val facadeFqName: FqName private val project: Project, private val facadeFqName: FqName, private val searchScope: GlobalSearchScope
) : CachedValueProvider<LightClassDataHolder.ForFacade> { ) : CachedValueProvider<LightClassDataHolder.ForFacade> {
abstract fun findFiles(): Collection<KtFile> fun findFiles(): Collection<KtFile> = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope)
private fun computeLightClassData(files: Collection<KtFile>): LightClassDataHolder.ForFacade { private fun computeLightClassData(files: Collection<KtFile>): LightClassDataHolder.ForFacade {
return LightClassGenerationSupport.getInstance(project).createDataHolderForFacade(files) { return LightClassGenerationSupport.getInstance(project).createDataHolderForFacade(files) { constructionContext ->
constructionContext -> buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@{ state, files ->
buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ {
state, files ->
val representativeFile = files.first() val representativeFile = files.first()
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(representativeFile) val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(representativeFile)
if (!fileClassInfo.withJvmMultifileClass) { if (!fileClassInfo.withJvmMultifileClass) {
@@ -107,38 +98,18 @@ sealed class LightClassDataProviderForFileFacade constructor(
override fun toString(): String { override fun toString(): String {
return this::class.java.name + " for $facadeFqName" 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<LightClassDataHolder.ForScript> { class LightClassDataProviderForScript(private val script: KtScript) : CachedValueProvider<LightClassDataHolder.ForScript> {
private fun computeLightClassData(): LightClassDataHolder.ForScript { private fun computeLightClassData(): LightClassDataHolder.ForScript {
return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) { return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) { constructionContext ->
constructionContext ->
buildLightClass( buildLightClass(
script.fqName.parent(), script.fqName.parent(),
listOf(script.containingKtFile), listOf(script.containingKtFile),
ClassFilterForScript(script), ClassFilterForScript(script),
constructionContext constructionContext
) generate@ { ) generate@{ state, files ->
state, files ->
val scriptFile = files.first() val scriptFile = files.first()
val codegen = state.factory.forPackage(scriptFile.packageFqName, files) val codegen = state.factory.forPackage(scriptFile.packageFqName, files)
codegen.generate() codegen.generate()
@@ -1,32 +1,17 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.asJava package org.jetbrains.kotlin.asJava
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.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.getOutermostClassOrObject
import org.jetbrains.kotlin.asJava.classes.safeIsScript import org.jetbrains.kotlin.asJava.classes.safeIsScript
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData 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.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? { 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 { fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
val outermostClass = getOutermostClassOrObject(ktClassOrObject) val outermostClass = getOutermostClassOrObject(ktClassOrObject)
val lightClassDataHolder = KtLightClassForSourceDeclaration.getLightClassDataHolder(outermostClass) return KotlinExtraDiagnosticsProvider.getInstance(ktClassOrObject.project).forClassOrObject(outermostClass)
if (lightClassDataHolder is InvalidLightClassDataHolder) {
return Diagnostics.EMPTY
}
return lightClassDataHolder.extraDiagnostics
} }
fun doGetDiagnostics(): Diagnostics? { fun doGetDiagnostics(): Diagnostics? {
@@ -76,8 +45,9 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
when (parent) { when (parent) {
is KtFile -> { is KtFile -> {
return getDiagnosticsForFileFacade(parent) return KotlinExtraDiagnosticsProvider.getInstance(parent.project).forFacade(parent, moduleScope)
} }
is KtClassBody -> { is KtClassBody -> {
val parentsParent = parent.getParent() val parentsParent = parent.getParent()