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.LightClassDataHolder
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.JvmCodegenUtil
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.load.java.components.JavaDeprecationSettings
import org.jetbrains.kotlin.name.Name
@@ -57,7 +63,8 @@ class CliLightClassGenerationSupport(
private class CliLightClassSupport(
private val project: Project,
override val languageVersionSettings: LanguageVersionSettings
override val languageVersionSettings: LanguageVersionSettings,
private val jvmTarget: JvmTarget
) : KtUltraLightSupport {
// This is the way to untie CliLightClassSupport and CliLightClassGenerationSupport to prevent descriptors leak
@@ -88,7 +95,7 @@ class CliLightClassGenerationSupport(
moduleName,
languageVersionSettings,
useOldInlineClassesManglingScheme = false,
jvmTarget = JvmTarget.JVM_1_8,
jvmTarget = jvmTarget,
typePreprocessor = KotlinType::cleanFromAnonymousTypes,
namePreprocessor = ::tryGetPredefinedName
)
@@ -96,7 +103,7 @@ class CliLightClassGenerationSupport(
}
private val ultraLightSupport: KtUltraLightSupport by lazyPub {
CliLightClassSupport(project, traceHolder.languageVersionSettings)
CliLightClassSupport(project, traceHolder.languageVersionSettings, traceHolder.jvmTarget)
}
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport {
@@ -129,7 +136,9 @@ class CliLightClassGenerationSupport(
}
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? {
return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
@@ -140,4 +149,4 @@ class CliLightClassGenerationSupport(
override fun analyzeAnnotation(element: KtAnnotationEntry) = traceHolder.bindingContext.get(BindingContext.ANNOTATION, element)
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
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.BindingTrace
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.util.slicedMap.ReadOnlySlice
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
import kotlin.properties.Delegates
class CliTraceHolder : CodeAnalyzerInitializer {
var bindingContext: BindingContext by Delegates.notNull()
class CliTraceHolder : JvmCodeAnalyzerInitializer() {
lateinit var bindingContext: BindingContext
private set
var module: ModuleDescriptor by Delegates.notNull()
lateinit var module: ModuleDescriptor
private set
var languageVersionSettings: LanguageVersionSettings by Delegates.notNull()
lateinit var languageVersionSettings: LanguageVersionSettings
private set
lateinit var jvmTarget: JvmTarget
private set
override fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget
) {
this.bindingContext = trace.bindingContext
this.module = module
this.languageVersionSettings = languageVersionSettings
this.jvmTarget = jvmTarget
if (trace !is CliBindingTrace) {
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.multiplatform.OptionalAnnotationPackageFragmentProvider
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
fun createContainerForLazyResolveWithJava(
@@ -95,7 +94,9 @@ fun createContainerForLazyResolveWithJava(
}
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(
@@ -20,17 +20,18 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.resolve.BindingTrace
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.lazy.KotlinCodeAnalyzer
import javax.annotation.PostConstruct
import javax.inject.Inject
abstract class AbstractJavaClassFinder : JavaClassFinder {
protected lateinit var project: Project
protected lateinit var javaSearchScope: GlobalSearchScope
@@ -50,8 +51,15 @@ abstract class AbstractJavaClassFinder : JavaClassFinder {
}
@PostConstruct
open fun initialize(trace: BindingTrace, codeAnalyzer: KotlinCodeAnalyzer, languageVersionSettings: LanguageVersionSettings) {
CodeAnalyzerInitializer.getInstance(project).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer, languageVersionSettings)
open fun initialize(
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),
@@ -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.project.Project
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
interface CodeAnalyzerInitializer {
fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
)
fun createTrace(): BindingTrace
companion object {
fun getInstance(project: Project): CodeAnalyzerInitializer =
ServiceManager.getService<CodeAnalyzerInitializer>(project, CodeAnalyzerInitializer::class.java)!!
ServiceManager.getService(project, CodeAnalyzerInitializer::class.java)!!
}
}
class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer {
override fun initialize(
trace: BindingTrace,
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings
) {
// Do nothing
}
override fun createTrace(): BindingTrace = BindingTraceContext(true)
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.javac.components
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder
@@ -25,12 +26,16 @@ import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
class JavacBasedClassFinder : AbstractJavaClassFinder() {
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)
super.initialize(trace, codeAnalyzer, languageVersionSettings)
super.initialize(trace, codeAnalyzer, languageVersionSettings, jvmTarget)
}
override fun findClass(request: JavaClassFinder.Request) =
@@ -40,5 +45,4 @@ class JavacBasedClassFinder : AbstractJavaClassFinder() {
override fun findPackage(fqName: FqName) = javac.findPackage(fqName, javaSearchScope)
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 org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
@@ -53,6 +54,7 @@ fun buildLightClass(
context.languageVersionSettings?.let {
CompilerConfiguration().apply {
languageVersionSettings = it
put(JVMConfigurationKeys.JVM_TARGET, context.jvmTarget)
isReadOnly = true
}
} ?: CompilerConfiguration.EMPTY
@@ -16,12 +16,14 @@
package org.jetbrains.kotlin.asJava.builder
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
open class LightClassConstructionContext(
val bindingContext: BindingContext,
val module: ModuleDescriptor,
val languageVersionSettings: LanguageVersionSettings? = null
)
val bindingContext: BindingContext,
val module: ModuleDescriptor,
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");
}
@TestMetadata("SpecialAnnotationsOnAnnotationClass_1_6.kt")
public void testSpecialAnnotationsOnAnnotationClass_1_6() throws Exception {
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass_1_6.kt");
}
@TestMetadata("StubOrderForOverloads.kt")
public void testStubOrderForOverloads() throws Exception {
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");