Light classes: use JVM target from the module

Using "JVM_1_8" always resulted in incorrect mapping of Kotlin
annotation targets to Java element types.

The change in AbstractKotlinRenderLogTest is needed because while
CliTraceHolder.module is technically a descriptor leak, it was never
detected by this test accidentally, because of the depth cutoff equal to
10, which started to not be enough after the minor refactoring of
replacing `Delegates.notNull` with `lateinit`.
This commit is contained in:
Alexander Udalov
2021-01-25 18:59:38 +01:00
parent 64e97225b8
commit adfa8c788c
24 changed files with 234 additions and 92 deletions
@@ -23,11 +23,17 @@ import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolderImpl import org.jetbrains.kotlin.asJava.builder.LightClassDataHolderImpl
import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.classes.KtUltraLightSupport
import org.jetbrains.kotlin.asJava.classes.cleanFromAnonymousTypes
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.classes.tryGetPredefinedName
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
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -57,7 +63,8 @@ class CliLightClassGenerationSupport(
private class CliLightClassSupport( private class CliLightClassSupport(
private val project: Project, private val project: Project,
override val languageVersionSettings: LanguageVersionSettings override val languageVersionSettings: LanguageVersionSettings,
private val jvmTarget: JvmTarget
) : KtUltraLightSupport { ) : KtUltraLightSupport {
// This is the way to untie CliLightClassSupport and CliLightClassGenerationSupport to prevent descriptors leak // This is the way to untie CliLightClassSupport and CliLightClassGenerationSupport to prevent descriptors leak
@@ -88,7 +95,7 @@ class CliLightClassGenerationSupport(
moduleName, moduleName,
languageVersionSettings, languageVersionSettings,
useOldInlineClassesManglingScheme = false, useOldInlineClassesManglingScheme = false,
jvmTarget = JvmTarget.JVM_1_8, jvmTarget = jvmTarget,
typePreprocessor = KotlinType::cleanFromAnonymousTypes, typePreprocessor = KotlinType::cleanFromAnonymousTypes,
namePreprocessor = ::tryGetPredefinedName namePreprocessor = ::tryGetPredefinedName
) )
@@ -96,7 +103,7 @@ class CliLightClassGenerationSupport(
} }
private val ultraLightSupport: KtUltraLightSupport by lazyPub { private val ultraLightSupport: KtUltraLightSupport by lazyPub {
CliLightClassSupport(project, traceHolder.languageVersionSettings) CliLightClassSupport(project, traceHolder.languageVersionSettings, traceHolder.jvmTarget)
} }
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport { override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport {
@@ -129,7 +136,9 @@ class CliLightClassGenerationSupport(
} }
private fun getContext(): LightClassConstructionContext = private fun getContext(): LightClassConstructionContext =
LightClassConstructionContext(traceHolder.bindingContext, traceHolder.module) LightClassConstructionContext(
traceHolder.bindingContext, traceHolder.module, null /* TODO: traceHolder.languageVersionSettings? */, traceHolder.jvmTarget
)
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? { override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
@@ -13,30 +14,32 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import org.jetbrains.kotlin.resolve.jvm.JvmCodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
import org.jetbrains.kotlin.util.slicedMap.WritableSlice import org.jetbrains.kotlin.util.slicedMap.WritableSlice
import kotlin.properties.Delegates
class CliTraceHolder : CodeAnalyzerInitializer { class CliTraceHolder : JvmCodeAnalyzerInitializer() {
var bindingContext: BindingContext by Delegates.notNull() lateinit var bindingContext: BindingContext
private set private set
var module: ModuleDescriptor by Delegates.notNull() lateinit var module: ModuleDescriptor
private set private set
var languageVersionSettings: LanguageVersionSettings by Delegates.notNull() lateinit var languageVersionSettings: LanguageVersionSettings
private set
lateinit var jvmTarget: JvmTarget
private set private set
override fun initialize( override fun initialize(
trace: BindingTrace, trace: BindingTrace,
module: ModuleDescriptor, module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer, codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget
) { ) {
this.bindingContext = trace.bindingContext this.bindingContext = trace.bindingContext
this.module = module this.module = module
this.languageVersionSettings = languageVersionSettings this.languageVersionSettings = languageVersionSettings
this.jvmTarget = jvmTarget
if (trace !is CliBindingTrace) { if (trace !is CliBindingTrace) {
throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class") throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class")
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
fun createContainerForLazyResolveWithJava( fun createContainerForLazyResolveWithJava(
@@ -95,7 +94,9 @@ fun createContainerForLazyResolveWithJava(
} }
fun StorageComponentContainer.initializeJavaSpecificComponents(bindingTrace: BindingTrace) { fun StorageComponentContainer.initializeJavaSpecificComponents(bindingTrace: BindingTrace) {
get<AbstractJavaClassFinder>().initialize(bindingTrace, get<KotlinCodeAnalyzer>(), get<LanguageVersionSettings>()) get<AbstractJavaClassFinder>().initialize(
bindingTrace, codeAnalyzer = get(), languageVersionSettings = get(), jvmTarget = get()
)
} }
fun StorageComponentContainer.configureJavaSpecificComponents( fun StorageComponentContainer.configureJavaSpecificComponents(
@@ -20,17 +20,18 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.jvm.JvmCodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.jvm.TopPackageNamesProvider import org.jetbrains.kotlin.resolve.jvm.TopPackageNamesProvider
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import javax.annotation.PostConstruct import javax.annotation.PostConstruct
import javax.inject.Inject import javax.inject.Inject
abstract class AbstractJavaClassFinder : JavaClassFinder { abstract class AbstractJavaClassFinder : JavaClassFinder {
protected lateinit var project: Project protected lateinit var project: Project
protected lateinit var javaSearchScope: GlobalSearchScope protected lateinit var javaSearchScope: GlobalSearchScope
@@ -50,8 +51,15 @@ abstract class AbstractJavaClassFinder : JavaClassFinder {
} }
@PostConstruct @PostConstruct
open fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer, languageVersionSettings: LanguageVersionSettings) { open fun initialize(
CodeAnalyzerInitializer.getInstance(project).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer, languageVersionSettings) trace: BindingTrace,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget,
) {
(CodeAnalyzerInitializer.getInstance(project) as? JvmCodeAnalyzerInitializer)?.initialize(
trace, codeAnalyzer.moduleDescriptor, codeAnalyzer, languageVersionSettings, jvmTarget
)
} }
inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope), inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope),
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2021 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.resolve.jvm
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
abstract class JvmCodeAnalyzerInitializer : CodeAnalyzerInitializer {
abstract fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget,
)
}
@@ -18,35 +18,16 @@ package org.jetbrains.kotlin.resolve
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
interface CodeAnalyzerInitializer { interface CodeAnalyzerInitializer {
fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
)
fun createTrace(): BindingTrace fun createTrace(): BindingTrace
companion object { companion object {
fun getInstance(project: Project): CodeAnalyzerInitializer = fun getInstance(project: Project): CodeAnalyzerInitializer =
ServiceManager.getService<CodeAnalyzerInitializer>(project, CodeAnalyzerInitializer::class.java)!! ServiceManager.getService(project, CodeAnalyzerInitializer::class.java)!!
} }
} }
class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer { class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer {
override fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
) {
// Do nothing
}
override fun createTrace(): BindingTrace = BindingTraceContext(true) override fun createTrace(): BindingTrace = BindingTraceContext(true)
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.javac.components package org.jetbrains.kotlin.javac.components
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder
@@ -25,12 +26,16 @@ import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
class JavacBasedClassFinder : AbstractJavaClassFinder() { class JavacBasedClassFinder : AbstractJavaClassFinder() {
private lateinit var javac: JavacWrapper private lateinit var javac: JavacWrapper
override fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer, languageVersionSettings: LanguageVersionSettings) { override fun initialize(
trace: BindingTrace,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget,
) {
javac = JavacWrapper.getInstance(project) javac = JavacWrapper.getInstance(project)
super.initialize(trace, codeAnalyzer, languageVersionSettings) super.initialize(trace, codeAnalyzer, languageVersionSettings, jvmTarget)
} }
override fun findClass(request: JavaClassFinder.Request) = override fun findClass(request: JavaClassFinder.Request) =
@@ -40,5 +45,4 @@ class JavacBasedClassFinder : AbstractJavaClassFinder() {
override fun findPackage(fqName: FqName) = javac.findPackage(fqName, javaSearchScope) override fun findPackage(fqName: FqName) = javac.findPackage(fqName, javaSearchScope)
override fun knownClassNamesInPackage(packageFqName: FqName) = javac.knownClassNamesInPackage(packageFqName) override fun knownClassNamesInPackage(packageFqName: FqName) = javac.knownClassNamesInPackage(packageFqName)
} }
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -53,6 +54,7 @@ fun buildLightClass(
context.languageVersionSettings?.let { context.languageVersionSettings?.let {
CompilerConfiguration().apply { CompilerConfiguration().apply {
languageVersionSettings = it languageVersionSettings = it
put(JVMConfigurationKeys.JVM_TARGET, context.jvmTarget)
isReadOnly = true isReadOnly = true
} }
} ?: CompilerConfiguration.EMPTY } ?: CompilerConfiguration.EMPTY
@@ -16,12 +16,14 @@
package org.jetbrains.kotlin.asJava.builder package org.jetbrains.kotlin.asJava.builder
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
open class LightClassConstructionContext( open class LightClassConstructionContext(
val bindingContext: BindingContext, val bindingContext: BindingContext,
val module: ModuleDescriptor, val module: ModuleDescriptor,
val languageVersionSettings: LanguageVersionSettings? = null val languageVersionSettings: LanguageVersionSettings?,
val jvmTarget: JvmTarget,
) )
@@ -0,0 +1,11 @@
@java.lang.annotation.Documented()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.SOURCE)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.MustBeDocumented()
@kotlin.annotation.Repeatable()
@kotlin.annotation.Retention(value = kotlin.annotation.AnnotationRetention.SOURCE)
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.TYPE_PARAMETER, kotlin.annotation.AnnotationTarget.TYPE})
public abstract @interface Anno /* Anno*/ {
public abstract int i();// i()
}
@@ -0,0 +1,8 @@
// Anno
// JVM_TARGET: 1.6
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE)
@MustBeDocumented
@Repeatable
annotation class Anno(val i: Int)
@@ -0,0 +1,16 @@
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@kotlin.annotation.Target()
public abstract @interface A0 /* A0*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.TYPE})
public abstract @interface A1 /* A1*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER})
public abstract @interface A2 /* A2*/ {
}
@@ -0,0 +1,9 @@
// CHECK_BY_JAVA_FILE
// JVM_TARGET: 1.6
@Target()
annotation class A0
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE)
annotation class A1
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
annotation class A2
@@ -149,6 +149,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt"); runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
} }
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt") @TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception { public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt"); runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
import org.jetbrains.kotlin.idea.project.IdeaEnvironment import org.jetbrains.kotlin.idea.project.IdeaEnvironment
import org.jetbrains.kotlin.idea.project.ResolveElementCache import org.jetbrains.kotlin.idea.project.ResolveElementCache
import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.stubindex.KotlinOverridableInternalMembersShortNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinOverridableInternalMembersShortNameIndex
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -69,12 +70,13 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.WrappedTypeFactory import org.jetbrains.kotlin.types.WrappedTypeFactory
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
class IDELightClassConstructionContext( class IDELightClassConstructionContext(
bindingContext: BindingContext, module: ModuleDescriptor, bindingContext: BindingContext,
module: ModuleDescriptor,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget,
val mode: Mode val mode: Mode
) : LightClassConstructionContext(bindingContext, module, languageVersionSettings) { ) : LightClassConstructionContext(bindingContext, module, languageVersionSettings, jvmTarget) {
enum class Mode { enum class Mode {
LIGHT, LIGHT,
EXACT EXACT
@@ -106,6 +108,7 @@ internal object IDELightClassContexts {
bindingContext, bindingContext,
resolutionFacade.moduleDescriptor, resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings, classOrObject.languageVersionSettings,
resolutionFacade.jvmTarget,
EXACT EXACT
) )
} }
@@ -122,6 +125,7 @@ internal object IDELightClassContexts {
bindingContext, bindingContext,
resolutionFacade.moduleDescriptor, resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings, classOrObject.languageVersionSettings,
resolutionFacade.jvmTarget,
EXACT EXACT
) )
} }
@@ -132,20 +136,24 @@ internal object IDELightClassContexts {
bindingContext, bindingContext,
resolutionFacade.moduleDescriptor, resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings, classOrObject.languageVersionSettings,
resolutionFacade.jvmTarget,
EXACT EXACT
) )
} }
fun contextForFacade(files: List<KtFile>): LightClassConstructionContext { fun contextForFacade(files: List<KtFile>): LightClassConstructionContext {
val resolutionFacade = files.first().getResolutionFacade()
@OptIn(FrontendInternals::class) @OptIn(FrontendInternals::class)
val resolveSession = files.first().getResolutionFacade().getFrontendService(ResolveSession::class.java) val resolveSession = resolutionFacade.getFrontendService(ResolveSession::class.java)
forceResolvePackageDeclarations(files, resolveSession) forceResolvePackageDeclarations(files, resolveSession)
return IDELightClassConstructionContext( return IDELightClassConstructionContext(
resolveSession.bindingContext, resolveSession.bindingContext,
resolveSession.moduleDescriptor, resolveSession.moduleDescriptor,
files.first().languageVersionSettings, files.first().languageVersionSettings,
resolutionFacade.jvmTarget,
EXACT EXACT
) )
} }
@@ -161,21 +169,26 @@ internal object IDELightClassContexts {
bindingContext, bindingContext,
resolutionFacade.moduleDescriptor, resolutionFacade.moduleDescriptor,
script.languageVersionSettings, script.languageVersionSettings,
resolutionFacade.jvmTarget,
EXACT EXACT
) )
} }
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, script.languageVersionSettings, EXACT) return IDELightClassConstructionContext(
bindingContext, resolutionFacade.moduleDescriptor, script.languageVersionSettings, resolutionFacade.jvmTarget,
EXACT
)
} }
fun lightContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext? { fun lightContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext? {
if (!isDummyResolveApplicable(classOrObject)) return null if (!isDummyResolveApplicable(classOrObject)) return null
val resolutionFacade = classOrObject.getResolutionFacade()
val resolveSession = setupAdHocResolve( val resolveSession = setupAdHocResolve(
classOrObject.project, classOrObject.project,
classOrObject.getResolutionFacade().moduleDescriptor, resolutionFacade.moduleDescriptor,
listOf(classOrObject.containingKtFile) listOf(classOrObject.containingKtFile)
) )
@@ -188,13 +201,15 @@ internal object IDELightClassContexts {
resolveSession.bindingContext, resolveSession.bindingContext,
resolveSession.moduleDescriptor, resolveSession.moduleDescriptor,
classOrObject.languageVersionSettings, classOrObject.languageVersionSettings,
resolutionFacade.jvmTarget,
LIGHT LIGHT
) )
} }
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext { fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
val representativeFile = files.first() val representativeFile = files.first()
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files) val resolutionFacade = representativeFile.getResolutionFacade()
val resolveSession = setupAdHocResolve(representativeFile.project, resolutionFacade.moduleDescriptor, files)
forceResolvePackageDeclarations(files, resolveSession) forceResolvePackageDeclarations(files, resolveSession)
@@ -202,10 +217,15 @@ internal object IDELightClassContexts {
resolveSession.bindingContext, resolveSession.bindingContext,
resolveSession.moduleDescriptor, resolveSession.moduleDescriptor,
files.first().languageVersionSettings, files.first().languageVersionSettings,
resolutionFacade.jvmTarget,
LIGHT LIGHT
) )
} }
@OptIn(FrontendInternals::class)
private val ResolutionFacade.jvmTarget: JvmTarget
get() = getFrontendService(JvmTarget::class.java)
private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean { private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean {
if (classOrObject.hasModifier(KtTokens.INLINE_KEYWORD)) return false if (classOrObject.hasModifier(KtTokens.INLINE_KEYWORD)) return false
@@ -447,4 +467,3 @@ internal object IDELightClassContexts {
} }
} }
} }
@@ -31,9 +31,12 @@ import org.jetbrains.kotlin.idea.FrontendInternals
import org.jetbrains.kotlin.idea.caches.lightClasses.IDELightClassContexts import org.jetbrains.kotlin.idea.caches.lightClasses.IDELightClassContexts
import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder
import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.project.platform
import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JdkPlatform
import org.jetbrains.kotlin.platform.subplatformsOfType
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
@@ -82,7 +85,7 @@ class IDELightClassGenerationSupport(project: Project) : LightClassGenerationSup
BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES,
moduleName, languageVersionSettings, moduleName, languageVersionSettings,
useOldInlineClassesManglingScheme = false, useOldInlineClassesManglingScheme = false,
jvmTarget = JvmTarget.JVM_1_8, jvmTarget = module?.platform?.subplatformsOfType<JdkPlatform>()?.firstOrNull()?.targetVersion ?: JvmTarget.DEFAULT,
typePreprocessor = KotlinType::cleanFromAnonymousTypes, typePreprocessor = KotlinType::cleanFromAnonymousTypes,
namePreprocessor = ::tryGetPredefinedName namePreprocessor = ::tryGetPredefinedName
) )
@@ -29,6 +29,11 @@ public class FirClassLoadingTestGenerated extends AbstractFirClassLoadingTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/asJava/ultraLightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/asJava/ultraLightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true);
} }
@TestMetadata("annotationTargets_1_6.kt")
public void testAnnotationTargets_1_6() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/annotationTargets_1_6.kt");
}
@TestMetadata("annotationWithSetParamPropertyModifier.kt") @TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception { public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/annotationWithSetParamPropertyModifier.kt"); runTest("compiler/testData/asJava/ultraLightClasses/annotationWithSetParamPropertyModifier.kt");
@@ -149,6 +149,11 @@ public class FirLightClassTestGenerated extends AbstractFirLightClassTest {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt"); runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
} }
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt") @TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception { public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt"); runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
@@ -29,6 +29,11 @@ public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClass
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/asJava/ultraLightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/asJava/ultraLightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true);
} }
@TestMetadata("annotationTargets_1_6.kt")
public void testAnnotationTargets_1_6() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/annotationTargets_1_6.kt");
}
@TestMetadata("annotationWithSetParamPropertyModifier.kt") @TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception { public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/annotationWithSetParamPropertyModifier.kt"); runTest("compiler/testData/asJava/ultraLightClasses/annotationWithSetParamPropertyModifier.kt");
@@ -149,6 +149,11 @@ public class UltraLightClassSanityTestGenerated extends AbstractUltraLightClassS
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt"); runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
} }
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt") @TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception { public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt"); runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
import org.jetbrains.kotlin.asJava.builder.StubComputationTracker import org.jetbrains.kotlin.asJava.builder.StubComputationTracker
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
@@ -29,8 +28,10 @@ import org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.Tracke
import org.jetbrains.kotlin.idea.completion.test.withServiceRegistered import org.jetbrains.kotlin.idea.completion.test.withServiceRegistered
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.perf.forceUsingOldLightClassesForTest import org.jetbrains.kotlin.idea.perf.forceUsingOldLightClassesForTest
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.withCustomCompilerOptions
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -39,14 +40,13 @@ import org.jetbrains.kotlin.test.MockLibraryUtilExt
import org.jetbrains.kotlin.test.util.KtTestUtil import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.plugins.groovy.lang.psi.impl.stringValue import org.jetbrains.plugins.groovy.lang.psi.impl.stringValue
import org.junit.Assert
import java.io.File import java.io.File
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
import kotlin.test.assertTrue import kotlin.test.assertTrue
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() { abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
fun doTest(unused: String) { fun doTest(@Suppress("UNUSED_PARAMETER") unused: String) {
forceUsingOldLightClassesForTest() forceUsingOldLightClassesForTest()
val fileName = fileName() val fileName = fileName()
val extraFilePath = when { val extraFilePath = when {
@@ -54,30 +54,31 @@ abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase
else -> error("Invalid test data extension") else -> error("Invalid test data extension")
} }
val testFiles = if (File(testDataPath, extraFilePath).isFile) listOf(fileName, extraFilePath) else listOf(fileName) withCustomCompilerOptions(File(testDataPath, fileName).readText(), project, module) {
val testFiles = if (File(testDataPath, extraFilePath).isFile) listOf(fileName, extraFilePath) else listOf(fileName)
val lazinessMode = lazinessModeByFileText()
myFixture.configureByFiles(*testFiles.toTypedArray())
if ((myFixture.file as? KtFile)?.isScript() == true) {
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file)
}
val lazinessMode = lazinessModeByFileText() val ktFile = myFixture.file as KtFile
myFixture.configureByFiles(*testFiles.toTypedArray()) val testData = testDataFile()
if ((myFixture.file as? KtFile)?.isScript() == true) { testLightClass(
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file) KotlinTestUtils.replaceExtension(testData, "java"),
} testData,
{ LightClassTestCommon.removeEmptyDefaultImpls(it) },
val ktFile = myFixture.file as KtFile { fqName ->
val testData = testDataFile() val tracker = LightClassLazinessChecker.Tracker(fqName)
testLightClass( project.withServiceRegistered<StubComputationTracker, PsiClass?>(tracker) {
KotlinTestUtils.replaceExtension(testData, "java"), findClass(fqName, ktFile, project)?.apply {
testData, LightClassLazinessChecker.check(this as KtLightClass, tracker, lazinessMode)
{ LightClassTestCommon.removeEmptyDefaultImpls(it) }, tracker.allowLevel(EXACT)
{ fqName -> PsiElementChecker.checkPsiElementStructure(this)
val tracker = LightClassLazinessChecker.Tracker(fqName) }
project.withServiceRegistered<StubComputationTracker, PsiClass?>(tracker) {
findClass(fqName, ktFile, project)?.apply {
LightClassLazinessChecker.check(this as KtLightClass, tracker, lazinessMode)
tracker.allowLevel(EXACT)
PsiElementChecker.checkPsiElementStructure(this)
} }
} })
}) }
} }
private fun lazinessModeByFileText(): LightClassLazinessChecker.Mode { private fun lazinessModeByFileText(): LightClassLazinessChecker.Mode {
@@ -105,11 +106,16 @@ abstract class AbstractIdeCompiledLightClassTest : KotlinDaemonAnalyzerTestCase(
val filePathWithoutExtension = "${KtTestUtil.getTestsRoot(this::class.java)}/${getTestName(false)}" val filePathWithoutExtension = "${KtTestUtil.getTestsRoot(this::class.java)}/${getTestName(false)}"
val testFile = val testFile =
File("$filePathWithoutExtension.kt").takeIf { it.exists() } ?: File("$filePathWithoutExtension.kts").takeIf { it.exists() } File("$filePathWithoutExtension.kt").takeIf { it.exists() } ?: File("$filePathWithoutExtension.kts").takeIf { it.exists() }
?: error("Test file not found!")
Assert.assertNotNull("Test file not found!", testFile) val extraOptions = KotlinTestUtils.parseDirectives(testFile.readText())[
CompilerTestDirectives.JVM_TARGET_DIRECTIVE.substringBefore(":")
]?.let { jvmTarget ->
listOf("-jvm-target", jvmTarget)
} ?: emptyList()
val libraryJar = MockLibraryUtilExt.compileJvmLibraryToJar( val libraryJar = MockLibraryUtilExt.compileJvmLibraryToJar(
testFile!!.canonicalPath, libName(), testFile.canonicalPath, libName(),
extraOptions = extraOptions,
extraClasspath = listOf(ForTestCompileRuntime.jetbrainsAnnotationsForTests().path) extraClasspath = listOf(ForTestCompileRuntime.jetbrainsAnnotationsForTests().path)
) )
val jarUrl = "jar://" + FileUtilRt.toSystemIndependentName(libraryJar.absolutePath) + "!/" val jarUrl = "jar://" + FileUtilRt.toSystemIndependentName(libraryJar.absolutePath) + "!/"
@@ -123,11 +129,13 @@ abstract class AbstractIdeCompiledLightClassTest : KotlinDaemonAnalyzerTestCase(
val expectedFile = KotlinTestUtils.replaceExtension( val expectedFile = KotlinTestUtils.replaceExtension(
testDataFile, "compiled.java" testDataFile, "compiled.java"
).let { if (it.exists()) it else KotlinTestUtils.replaceExtension(testDataFile, "java") } ).let { if (it.exists()) it else KotlinTestUtils.replaceExtension(testDataFile, "java") }
testLightClass(expectedFile, testDataFile, { it }, { withCustomCompilerOptions(testDataFile.readText(), project, module) {
findClass(it, null, project)?.apply { testLightClass(expectedFile, testDataFile, { it }, {
PsiElementChecker.checkPsiElementStructure(this) findClass(it, null, project)?.apply {
} PsiElementChecker.checkPsiElementStructure(this)
}) }
})
}
} }
} }
@@ -149,6 +149,11 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt"); runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
} }
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt") @TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception { public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt"); runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
@@ -149,6 +149,11 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt"); runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
} }
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt") @TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception { public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt"); runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
@@ -1,6 +1,5 @@
package org.jetbrains.uast.test.kotlin package org.jetbrains.uast.test.kotlin
import com.intellij.openapi.util.Conditions
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiRecursiveElementVisitor import com.intellij.psi.PsiRecursiveElementVisitor
@@ -9,6 +8,7 @@ import com.intellij.util.PairProcessor
import com.intellij.util.ref.DebugReflectionUtil import com.intellij.util.ref.DebugReflectionUtil
import junit.framework.TestCase import junit.framework.TestCase
import junit.framework.TestCase.* import junit.framework.TestCase.*
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
@@ -152,7 +152,7 @@ fun checkDescriptorsLeak(node: UElement) {
10, 10,
mapOf(node to node.javaClass.name), mapOf(node to node.javaClass.name),
Any::class.java, Any::class.java,
Conditions.alwaysTrue(), { it !is CliTraceHolder },
PairProcessor { value, backLink -> PairProcessor { value, backLink ->
descriptorsClasses.find { it.isInstance(value) }?.let { descriptorsClasses.find { it.isInstance(value) }?.let {
TestCase.fail("""Leaked descriptor ${it.qualifiedName} in ${node.javaClass.name}\n$backLink""") TestCase.fail("""Leaked descriptor ${it.qualifiedName} in ${node.javaClass.name}\n$backLink""")