[light classes] drop old light classes and backend: iteration #12
drop LightClassDataHolder ^KT-48773
This commit is contained in:
+42
-62
@@ -8,24 +8,21 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
|||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.CachedValue
|
import com.intellij.psi.util.CachedValue
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||||
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.InvalidLightClassDataHolder
|
import org.jetbrains.kotlin.cli.jvm.compiler.builder.extraJvmDiagnosticsFromBackend
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.LightClassDataHolder
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.buildLightClass
|
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
private val JAVA_API_STUB = Key.create<CachedValue<LightClassDataHolder.ForClass>>("JAVA_API_STUB")
|
private val JAVA_API_STUB = Key.create<CachedValue<Diagnostics>>("JAVA_API_STUB")
|
||||||
private val JAVA_API_STUB_LOCK = Key.create<Any>("JAVA_API_STUB_LOCK")
|
|
||||||
|
|
||||||
private val javaApiStubInitIsRunning: ThreadLocal<Boolean> = ThreadLocal.withInitial { false }
|
|
||||||
|
|
||||||
object CliExtraDiagnosticsProvider {
|
object CliExtraDiagnosticsProvider {
|
||||||
fun forClassOrObject(kclass: KtClassOrObject): Diagnostics {
|
fun forClassOrObject(kclass: KtClassOrObject): Diagnostics {
|
||||||
@@ -33,82 +30,65 @@ object CliExtraDiagnosticsProvider {
|
|||||||
return Diagnostics.EMPTY
|
return Diagnostics.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
val lightClassDataHolder = getLightClassCachedValue(kclass).value
|
return getLightClassCachedValue(kclass).value
|
||||||
return if (lightClassDataHolder is InvalidLightClassDataHolder) {
|
|
||||||
Diagnostics.EMPTY
|
|
||||||
} else {
|
|
||||||
lightClassDataHolder.extraDiagnostics
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun forFacade(file: KtFile, moduleScope: GlobalSearchScope): Diagnostics {
|
fun forFacade(file: KtFile): Diagnostics = CachedValuesManager.getCachedValue(file) {
|
||||||
|
CachedValueProvider.Result.create(
|
||||||
|
calculateForFacade(file),
|
||||||
|
KotlinModificationTrackerService.getInstance(file.project).outOfBlockModificationTracker,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateForFacade(file: KtFile): Diagnostics {
|
||||||
val project = file.project
|
val project = file.project
|
||||||
val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName
|
val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName
|
||||||
val files = KotlinAsJavaSupport.getInstance(project)
|
val facadeCollection = KotlinAsJavaSupport.getInstance(project)
|
||||||
.findFilesForFacade(facadeFqName, moduleScope)
|
.findFilesForFacade(facadeFqName, GlobalSearchScope.allScope(project))
|
||||||
.ifEmpty { return Diagnostics.EMPTY }
|
.ifEmpty { return Diagnostics.EMPTY }
|
||||||
|
|
||||||
return LightClassGenerationSupport.getInstance(project).cast<CliLightClassGenerationSupport>()
|
val context = LightClassGenerationSupport.getInstance(project).cast<CliLightClassGenerationSupport>().context
|
||||||
.createDataHolderForFacade { constructionContext ->
|
val (_, _, diagnostics) = extraJvmDiagnosticsFromBackend(
|
||||||
buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@{ state, files ->
|
facadeFqName.parent(),
|
||||||
val representativeFile = files.first()
|
facadeCollection,
|
||||||
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(representativeFile)
|
ClassFilterForFacade,
|
||||||
if (!fileClassInfo.withJvmMultifileClass) {
|
context,
|
||||||
val codegen = state.factory.forPackage(representativeFile.packageFqName, files)
|
) generate@{ state, files ->
|
||||||
codegen.generate()
|
val representativeFile = files.first()
|
||||||
state.factory.done()
|
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(representativeFile)
|
||||||
return@generate
|
if (!fileClassInfo.withJvmMultifileClass) {
|
||||||
}
|
val codegen = state.factory.forPackage(representativeFile.packageFqName, files)
|
||||||
|
codegen.generate()
|
||||||
|
state.factory.done()
|
||||||
|
return@generate
|
||||||
|
}
|
||||||
|
|
||||||
val codegen = state.factory.forMultifileClass(facadeFqName, files)
|
val codegen = state.factory.forMultifileClass(facadeFqName, files)
|
||||||
codegen.generate()
|
codegen.generate()
|
||||||
state.factory.done()
|
state.factory.done()
|
||||||
}
|
}
|
||||||
}.extraDiagnostics
|
|
||||||
|
return diagnostics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
|
private fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<Diagnostics> {
|
||||||
val outerClassValue = getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB)
|
val outerClassValue = getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB)
|
||||||
outerClassValue?.let {
|
outerClassValue?.let {
|
||||||
// stub computed for outer class can be used for inner/nested
|
// stub computed for outer class can be used for inner/nested
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
// the idea behind this locking approach:
|
|
||||||
// Thread T1 starts to calculate value for A it acquires lock for A
|
|
||||||
//
|
|
||||||
// Assumption 1: Lets say A calculation requires another value e.g. B to be calculated
|
|
||||||
// Assumption 2: Thread T2 wants to calculate value for B
|
|
||||||
|
|
||||||
// to avoid dead-lock case we mark thread as doing calculation and acquire lock only once per thread
|
return computeLightClassCachedValue(classOrObject)
|
||||||
// as a trade-off to prevent dependent value could be calculated several time
|
|
||||||
// due to CAS (within putUserDataIfAbsent etc) the same instance of calculated value will be used
|
|
||||||
val value: CachedValue<LightClassDataHolder.ForClass> = if (!javaApiStubInitIsRunning.get()) {
|
|
||||||
classOrObject.getUserData(JAVA_API_STUB) ?: run {
|
|
||||||
val lock = classOrObject.putUserDataIfAbsent(JAVA_API_STUB_LOCK, Object())
|
|
||||||
synchronized(lock) {
|
|
||||||
try {
|
|
||||||
javaApiStubInitIsRunning.set(true)
|
|
||||||
computeLightClassCachedValue(classOrObject)
|
|
||||||
} finally {
|
|
||||||
javaApiStubInitIsRunning.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
computeLightClassCachedValue(classOrObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
return value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
|
private fun computeLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<Diagnostics> {
|
||||||
val value = classOrObject.getUserData(JAVA_API_STUB) ?: run {
|
val value = classOrObject.getUserData(JAVA_API_STUB) ?: run {
|
||||||
val manager = CachedValuesManager.getManager(classOrObject.project)
|
val manager = CachedValuesManager.getManager(classOrObject.project)
|
||||||
val cachedValue = manager.createCachedValue(
|
val cachedValue = manager.createCachedValue(LightClassDataProviderForClassOrObject(classOrObject))
|
||||||
LightClassDataProviderForClassOrObject(classOrObject), false
|
|
||||||
)
|
|
||||||
classOrObject.putUserDataIfAbsent(JAVA_API_STUB, cachedValue)
|
classOrObject.putUserDataIfAbsent(JAVA_API_STUB, cachedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
+7
-27
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.asJava.classes.KtUltraLightSupport
|
|||||||
import org.jetbrains.kotlin.asJava.classes.cleanFromAnonymousTypes
|
import org.jetbrains.kotlin.asJava.classes.cleanFromAnonymousTypes
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.classes.tryGetPredefinedName
|
import org.jetbrains.kotlin.asJava.classes.tryGetPredefinedName
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.*
|
import org.jetbrains.kotlin.cli.jvm.compiler.builder.LightClassConstructionContext
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
@@ -89,30 +89,12 @@ class CliLightClassGenerationSupport(
|
|||||||
return ultraLightSupport
|
return ultraLightSupport
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
|
internal val context: LightClassConstructionContext
|
||||||
//force resolve companion for light class generation
|
get() = LightClassConstructionContext(
|
||||||
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
traceHolder.bindingContext,
|
||||||
|
traceHolder.module,
|
||||||
val (_, bindingContext, diagnostics) = builder(getContext())
|
traceHolder.languageVersionSettings,
|
||||||
|
traceHolder.jvmTarget,
|
||||||
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
|
||||||
|
|
||||||
return LightClassDataHolderImpl(diagnostics)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createDataHolderForFacade(builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
|
||||||
val (_, _, diagnostics) = builder(getContext())
|
|
||||||
return LightClassDataHolderImpl(diagnostics)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createDataHolderForScript(builder: LightClassBuilder): LightClassDataHolder.ForScript {
|
|
||||||
val (_, _, diagnostics) = builder(getContext())
|
|
||||||
return LightClassDataHolderImpl(diagnostics)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getContext(): LightClassConstructionContext =
|
|
||||||
LightClassConstructionContext(
|
|
||||||
traceHolder.bindingContext, traceHolder.module, null /* TODO: traceHolder.languageVersionSettings? */, traceHolder.jvmTarget
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||||
@@ -125,5 +107,3 @@ class CliLightClassGenerationSupport(
|
|||||||
|
|
||||||
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
|
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
|
|
||||||
|
|||||||
@@ -12,40 +12,45 @@ import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
|||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||||
import org.jetbrains.kotlin.asJava.classes.safeIsLocal
|
import org.jetbrains.kotlin.asJava.classes.safeIsLocal
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.LightClassDataHolder
|
import org.jetbrains.kotlin.cli.jvm.compiler.builder.extraJvmDiagnosticsFromBackend
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.builder.buildLightClass
|
|
||||||
import org.jetbrains.kotlin.codegen.MemberCodegen
|
import org.jetbrains.kotlin.codegen.MemberCodegen
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
internal class LightClassDataProviderForClassOrObject(
|
internal class LightClassDataProviderForClassOrObject(
|
||||||
private val classOrObject: KtClassOrObject
|
private val classOrObject: KtClassOrObject
|
||||||
) : CachedValueProvider<LightClassDataHolder.ForClass> {
|
) : CachedValueProvider<Diagnostics> {
|
||||||
private fun computeLightClassData(): LightClassDataHolder.ForClass {
|
private fun computeLightClassData(): Diagnostics {
|
||||||
val file = classOrObject.containingKtFile
|
val file = classOrObject.containingKtFile
|
||||||
val packageFqName = file.packageFqName
|
val packageFqName = file.packageFqName
|
||||||
return LightClassGenerationSupport.getInstance(classOrObject.project).cast<CliLightClassGenerationSupport>()
|
val cliSupport = LightClassGenerationSupport.getInstance(classOrObject.project).cast<CliLightClassGenerationSupport>()
|
||||||
.createDataHolderForClass(classOrObject) { constructionContext ->
|
|
||||||
buildLightClass(
|
//force resolve companion for light class generation
|
||||||
packageFqName,
|
cliSupport.traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||||
listOf(file),
|
|
||||||
ClassFilterForClassOrObject(classOrObject),
|
val (_, bindingContext, diagnostics) = extraJvmDiagnosticsFromBackend(
|
||||||
constructionContext
|
packageFqName,
|
||||||
) { state, files ->
|
listOf(file),
|
||||||
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
ClassFilterForClassOrObject(classOrObject),
|
||||||
val packagePartType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file))
|
cliSupport.context,
|
||||||
val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file)
|
) { state, files ->
|
||||||
MemberCodegen.genClassOrObject(context, getOutermostClassOrObject(classOrObject), state, null)
|
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
||||||
state.factory.done()
|
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 diagnostics.takeIf { bindingContext.get(BindingContext.CLASS, classOrObject) != null } ?: Diagnostics.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun compute(): CachedValueProvider.Result<LightClassDataHolder.ForClass> {
|
override fun compute(): CachedValueProvider.Result<Diagnostics> {
|
||||||
val trackerService = KotlinModificationTrackerService.getInstance(classOrObject.project)
|
val trackerService = KotlinModificationTrackerService.getInstance(classOrObject.project)
|
||||||
return CachedValueProvider.Result.create(
|
return CachedValueProvider.Result.create(
|
||||||
computeLightClassData(),
|
computeLightClassData(),
|
||||||
|
|||||||
+8
-19
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.cli.jvm.compiler.builder
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.openapi.util.registry.Registry
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||||
@@ -23,22 +22,18 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
|
|
||||||
data class LightClassBuilderResult(val stub: PsiJavaFileStub, val bindingContext: BindingContext, val diagnostics: Diagnostics)
|
data class CodeGenerationResult(val stub: PsiJavaFileStub, val bindingContext: BindingContext, val diagnostics: Diagnostics)
|
||||||
|
|
||||||
fun buildLightClass(
|
fun extraJvmDiagnosticsFromBackend(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
files: Collection<KtFile>,
|
files: Collection<KtFile>,
|
||||||
generateClassFilter: GenerationState.GenerateClassFilter,
|
generateClassFilter: GenerationState.GenerateClassFilter,
|
||||||
context: LightClassConstructionContext,
|
context: LightClassConstructionContext,
|
||||||
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
|
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit,
|
||||||
): LightClassBuilderResult {
|
): CodeGenerationResult {
|
||||||
val project = files.first().project
|
val project = files.first().project
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Registry.`is`("kotlin.ultra.light.classes.error.on.old.backend", false)) {
|
|
||||||
error("Access to backend detected")
|
|
||||||
}
|
|
||||||
|
|
||||||
val classBuilderFactory = KotlinLightClassBuilderFactory(createJavaFileStub(packageFqName, files))
|
val classBuilderFactory = KotlinLightClassBuilderFactory(createJavaFileStub(packageFqName, files))
|
||||||
val state = GenerationState.Builder(
|
val state = GenerationState.Builder(
|
||||||
project,
|
project,
|
||||||
@@ -51,8 +46,7 @@ fun buildLightClass(
|
|||||||
put(JVMConfigurationKeys.JVM_TARGET, context.jvmTarget)
|
put(JVMConfigurationKeys.JVM_TARGET, context.jvmTarget)
|
||||||
isReadOnly = true
|
isReadOnly = true
|
||||||
}
|
}
|
||||||
} ?: CompilerConfiguration.EMPTY
|
} ?: CompilerConfiguration.EMPTY,
|
||||||
|
|
||||||
).generateDeclaredClassFilter(generateClassFilter).wantsDiagnostics(false).build()
|
).generateDeclaredClassFilter(generateClassFilter).wantsDiagnostics(false).build()
|
||||||
state.beforeCompile()
|
state.beforeCompile()
|
||||||
state.oldBEInitTrace(files)
|
state.oldBEInitTrace(files)
|
||||||
@@ -60,7 +54,7 @@ fun buildLightClass(
|
|||||||
generate(state, files)
|
generate(state, files)
|
||||||
|
|
||||||
val javaFileStub = classBuilderFactory.result()
|
val javaFileStub = classBuilderFactory.result()
|
||||||
return LightClassBuilderResult(javaFileStub, context.bindingContext, state.collectedExtraJvmDiagnostics)
|
return CodeGenerationResult(javaFileStub, context.bindingContext, state.collectedExtraJvmDiagnostics)
|
||||||
} catch (e: ProcessCanceledException) {
|
} catch (e: ProcessCanceledException) {
|
||||||
throw e
|
throw e
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
@@ -75,14 +69,9 @@ private fun createJavaFileStub(packageFqName: FqName, files: Collection<KtFile>)
|
|||||||
|
|
||||||
val fakeFile = object : ClsFileImpl(files.first().viewProvider) {
|
val fakeFile = object : ClsFileImpl(files.first().viewProvider) {
|
||||||
override fun getStub() = javaFileStub
|
override fun getStub() = javaFileStub
|
||||||
|
|
||||||
override fun getPackageName() = packageFqName.asString()
|
override fun getPackageName() = packageFqName.asString()
|
||||||
|
|
||||||
override fun isPhysical() = false
|
override fun isPhysical() = false
|
||||||
|
override fun getText(): String = files.singleOrNull()?.text ?: super.getText()
|
||||||
override fun getText(): String {
|
|
||||||
return files.singleOrNull()?.text ?: super.getText()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
javaFileStub.psi = fakeFile
|
javaFileStub.psi = fakeFile
|
||||||
@@ -98,4 +87,4 @@ private fun logErrorWithOSInfo(cause: Throwable?, fqName: FqName, virtualFile: V
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LOG = Logger.getInstance(LightClassBuilderResult::class.java)
|
private val LOG = Logger.getInstance(CodeGenerationResult::class.java)
|
||||||
-26
@@ -1,26 +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.cli.jvm.compiler.builder
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
|
||||||
|
|
||||||
interface LightClassDataHolder {
|
|
||||||
val extraDiagnostics: Diagnostics
|
|
||||||
|
|
||||||
interface ForClass : LightClassDataHolder
|
|
||||||
interface ForFacade : LightClassDataHolder
|
|
||||||
interface ForScript : ForClass
|
|
||||||
}
|
|
||||||
|
|
||||||
object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
|
|
||||||
override val extraDiagnostics: Diagnostics get() = shouldNotBeCalled()
|
|
||||||
|
|
||||||
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
class LightClassDataHolderImpl(
|
|
||||||
override val extraDiagnostics: Diagnostics
|
|
||||||
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
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
|
||||||
@@ -19,7 +18,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.*
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? {
|
fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics): Diagnostics? {
|
||||||
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
|
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
|
||||||
val outermostClass = getOutermostClassOrObject(ktClassOrObject)
|
val outermostClass = getOutermostClassOrObject(ktClassOrObject)
|
||||||
return CliExtraDiagnosticsProvider.forClassOrObject(outermostClass)
|
return CliExtraDiagnosticsProvider.forClassOrObject(outermostClass)
|
||||||
@@ -45,7 +44,7 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
|
|||||||
|
|
||||||
when (parent) {
|
when (parent) {
|
||||||
is KtFile -> {
|
is KtFile -> {
|
||||||
return CliExtraDiagnosticsProvider.forFacade(parent, moduleScope)
|
return CliExtraDiagnosticsProvider.forFacade(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtClassBody -> {
|
is KtClassBody -> {
|
||||||
|
|||||||
+1
-3
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.frontend.classic.handlers
|
package org.jetbrains.kotlin.test.frontend.classic.handlers
|
||||||
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.checkers.diagnostics.SyntaxErrorDiagnostic
|
import org.jetbrains.kotlin.checkers.diagnostics.SyntaxErrorDiagnostic
|
||||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||||
@@ -77,7 +76,6 @@ class ClassicDiagnosticsHandler(testServices: TestServices) : ClassicFrontendAna
|
|||||||
if (testServices.moduleStructure.modules.any { !it.targetPlatform.isJvm() }) return emptySet()
|
if (testServices.moduleStructure.modules.any { !it.targetPlatform.isJvm() }) return emptySet()
|
||||||
if (REPORT_JVM_DIAGNOSTICS_ON_FRONTEND !in testServices.moduleStructure.allDirectives) return emptySet()
|
if (REPORT_JVM_DIAGNOSTICS_ON_FRONTEND !in testServices.moduleStructure.allDirectives) return emptySet()
|
||||||
val bindingContext = info.analysisResult.bindingContext
|
val bindingContext = info.analysisResult.bindingContext
|
||||||
val project = info.project
|
|
||||||
val jvmSignatureDiagnostics = HashSet<Diagnostic>()
|
val jvmSignatureDiagnostics = HashSet<Diagnostic>()
|
||||||
for (ktFile in info.ktFiles.values) {
|
for (ktFile in info.ktFiles.values) {
|
||||||
val declarations = PsiTreeUtil.findChildrenOfType(ktFile, KtDeclaration::class.java)
|
val declarations = PsiTreeUtil.findChildrenOfType(ktFile, KtDeclaration::class.java)
|
||||||
@@ -85,8 +83,8 @@ class ClassicDiagnosticsHandler(testServices: TestServices) : ClassicFrontendAna
|
|||||||
val diagnostics = getJvmSignatureDiagnostics(
|
val diagnostics = getJvmSignatureDiagnostics(
|
||||||
declaration,
|
declaration,
|
||||||
bindingContext.diagnostics,
|
bindingContext.diagnostics,
|
||||||
GlobalSearchScope.allScope(project)
|
|
||||||
) ?: continue
|
) ?: continue
|
||||||
|
|
||||||
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration))
|
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.util.Condition
|
import com.intellij.openapi.util.Condition
|
||||||
import com.intellij.openapi.util.Conditions
|
import com.intellij.openapi.util.Conditions
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile
|
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile
|
||||||
@@ -330,10 +329,12 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val message = "Unexpected ${diagnostic.description}${PsiDiagnosticUtils.atLocation(
|
val message = "Unexpected ${diagnostic.description}${
|
||||||
ktFile,
|
PsiDiagnosticUtils.atLocation(
|
||||||
TextRange(actualStart, actualEnd)
|
ktFile,
|
||||||
)}"
|
TextRange(actualStart, actualEnd)
|
||||||
|
)
|
||||||
|
}"
|
||||||
System.err.println(message)
|
System.err.println(message)
|
||||||
ok[0] = false
|
ok[0] = false
|
||||||
}
|
}
|
||||||
@@ -375,8 +376,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
val diagnostics = getJvmSignatureDiagnostics(
|
val diagnostics = getJvmSignatureDiagnostics(
|
||||||
declaration,
|
declaration,
|
||||||
bindingContext.diagnostics,
|
bindingContext.diagnostics,
|
||||||
GlobalSearchScope.allScope(project)
|
|
||||||
) ?: continue
|
) ?: continue
|
||||||
|
|
||||||
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration).map { ActualDiagnostic(it, null, newInferenceEnabled) })
|
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration).map { ActualDiagnostic(it, null, newInferenceEnabled) })
|
||||||
}
|
}
|
||||||
return jvmSignatureDiagnostics
|
return jvmSignatureDiagnostics
|
||||||
@@ -490,6 +491,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
}
|
}
|
||||||
condition = newCondition
|
condition = newCondition
|
||||||
}
|
}
|
||||||
|
|
||||||
"+" -> condition = Conditions.or(condition, newCondition)
|
"+" -> condition = Conditions.or(condition, newCondition)
|
||||||
"-" -> condition = Conditions.and(condition, Conditions.not(newCondition))
|
"-" -> condition = Conditions.and(condition, Conditions.not(newCondition))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user