[FIR] FirJavaClass: make annotations and deprecationsProvider lazily enhanced
^KT-55387
This commit is contained in:
committed by
Space Team
parent
908dbf32cf
commit
485fad1951
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesByFqNameForLibraryTestGenerated extends AbstractS
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("JavaClassWithAnnotation.kt")
|
||||||
|
public void testJavaClassWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaClassWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("JvmNameOnMember.kt")
|
@TestMetadata("JvmNameOnMember.kt")
|
||||||
public void testJvmNameOnMember() throws Exception {
|
public void testJvmNameOnMember() throws Exception {
|
||||||
|
|||||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesParentingForLibraryTestGenerated extends Abstract
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("JavaClassWithAnnotation.kt")
|
||||||
|
public void testJavaClassWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaClassWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("JvmNameOnMember.kt")
|
@TestMetadata("JvmNameOnMember.kt")
|
||||||
public void testJvmNameOnMember() throws Exception {
|
public void testJvmNameOnMember() throws Exception {
|
||||||
|
|||||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("JavaClassWithAnnotation.kt")
|
||||||
|
public void testJavaClassWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaClassWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("JvmNameOnMember.kt")
|
@TestMetadata("JvmNameOnMember.kt")
|
||||||
public void testJvmNameOnMember() throws Exception {
|
public void testJvmNameOnMember() throws Exception {
|
||||||
|
|||||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("JavaClassWithAnnotation.kt")
|
||||||
|
public void testJavaClassWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaClassWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("JvmNameOnMember.kt")
|
@TestMetadata("JvmNameOnMember.kt")
|
||||||
public void testJvmNameOnMember() throws Exception {
|
public void testJvmNameOnMember() throws Exception {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -172,13 +172,12 @@ abstract class FirJavaFacade(
|
|||||||
val enhancement = FirSignatureEnhancement(firJavaClass, session) { emptyList() }
|
val enhancement = FirSignatureEnhancement(firJavaClass, session) { emptyList() }
|
||||||
val initialBounds = enhancement.performFirstRoundOfBoundsResolution(firJavaClass.typeParameters)
|
val initialBounds = enhancement.performFirstRoundOfBoundsResolution(firJavaClass.typeParameters)
|
||||||
|
|
||||||
// 1. Resolve annotations
|
// 1. (will happen lazily in FirJavaClass.annotations) Resolve annotations
|
||||||
// 2. Enhance type parameter bounds - may refer to each other, take default nullability from annotations
|
// 2. Enhance type parameter bounds - may refer to each other, take default nullability from annotations
|
||||||
// 3. (will happen lazily in FirJavaClass.superTypeRefs) Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
// 3. (will happen lazily in FirJavaClass.superTypeRefs) Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
||||||
|
|
||||||
firJavaClass.setAnnotationsFromJava(session, javaClass, javaTypeParameterStack)
|
|
||||||
enhancement.enhanceTypeParameterBoundsAfterFirstRound(firJavaClass.typeParameters, initialBounds)
|
enhancement.enhanceTypeParameterBoundsAfterFirstRound(firJavaClass.typeParameters, initialBounds)
|
||||||
firJavaClass.replaceDeprecationsProvider(firJavaClass.getDeprecationsProvider(session))
|
|
||||||
return firJavaClass
|
return firJavaClass
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +193,7 @@ abstract class FirJavaFacade(
|
|||||||
val moduleData = getModuleDataForClass(javaClass)
|
val moduleData = getModuleDataForClass(javaClass)
|
||||||
return buildJavaClass {
|
return buildJavaClass {
|
||||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||||
|
javaAnnotations += javaClass.annotations
|
||||||
source = javaClass.toSourceElement()
|
source = javaClass.toSourceElement()
|
||||||
this.moduleData = moduleData
|
this.moduleData = moduleData
|
||||||
symbol = classSymbol
|
symbol = classSymbol
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -15,10 +15,12 @@ import org.jetbrains.kotlin.fir.MutableOrEmptyList
|
|||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||||
|
import org.jetbrains.kotlin.fir.java.convertAnnotationsToFir
|
||||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformInplace
|
import org.jetbrains.kotlin.fir.visitors.transformInplace
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
@@ -39,7 +42,7 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
|||||||
override var resolvePhase: FirResolvePhase,
|
override var resolvePhase: FirResolvePhase,
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
override val origin: FirDeclarationOrigin.Java,
|
override val origin: FirDeclarationOrigin.Java,
|
||||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
private val unEnhancedAnnotations: MutableOrEmptyList<JavaAnnotation>,
|
||||||
override var status: FirDeclarationStatus,
|
override var status: FirDeclarationStatus,
|
||||||
override val classKind: ClassKind,
|
override val classKind: ClassKind,
|
||||||
override val declarations: MutableList<FirDeclaration>,
|
override val declarations: MutableList<FirDeclaration>,
|
||||||
@@ -53,7 +56,6 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
|||||||
) : FirRegularClass() {
|
) : FirRegularClass() {
|
||||||
override val hasLazyNestedClassifiers: Boolean get() = true
|
override val hasLazyNestedClassifiers: Boolean get() = true
|
||||||
override val controlFlowGraphReference: FirControlFlowGraphReference? get() = null
|
override val controlFlowGraphReference: FirControlFlowGraphReference? get() = null
|
||||||
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
|
|
||||||
|
|
||||||
override val contextReceivers: List<FirContextReceiver>
|
override val contextReceivers: List<FirContextReceiver>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
@@ -70,6 +72,16 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
|||||||
enhancement.enhanceSuperTypes(unenhnancedSuperTypes)
|
enhancement.enhanceSuperTypes(unenhnancedSuperTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: the lazy annotations is a workaround for KT-55387, some non-lazy solution should probably be used instead
|
||||||
|
override val annotations: List<FirAnnotation> by lazy {
|
||||||
|
unEnhancedAnnotations.convertAnnotationsToFir(moduleData.session, javaTypeParameterStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: the lazy deprecationsProvider is a workaround for KT-55387, some non-lazy solution should probably be used instead
|
||||||
|
override val deprecationsProvider: DeprecationsProvider by lazy {
|
||||||
|
getDeprecationsProvider(moduleData.session)
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceSuperTypeRefs(newSuperTypeRefs: List<FirTypeRef>) {
|
override fun replaceSuperTypeRefs(newSuperTypeRefs: List<FirTypeRef>) {
|
||||||
error("${::replaceSuperTypeRefs.name} should not be called for ${this::class.simpleName}, ${superTypeRefs::class.simpleName} is lazily calulated")
|
error("${::replaceSuperTypeRefs.name} should not be called for ${this::class.simpleName}, ${superTypeRefs::class.simpleName} is lazily calulated")
|
||||||
}
|
}
|
||||||
@@ -79,7 +91,7 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) {
|
override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) {
|
||||||
deprecationsProvider = newDeprecationsProvider
|
error("${::replaceDeprecationsProvider.name} should not be called for ${this::class.simpleName}, ${deprecationsProvider::class.simpleName} is lazily calculated")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {}
|
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {}
|
||||||
@@ -116,11 +128,10 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||||
annotations = newAnnotations.toMutableOrEmpty()
|
error("${::replaceAnnotations.name} should not be called for ${this::class.simpleName}, ${annotations::class.simpleName} is lazily calculated")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirJavaClass {
|
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirJavaClass {
|
||||||
annotations.transformInplace(transformer, data)
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +160,7 @@ class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationContainerBuil
|
|||||||
|
|
||||||
override var source: KtSourceElement? = null
|
override var source: KtSourceElement? = null
|
||||||
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
|
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
var javaAnnotations: MutableList<JavaAnnotation> = mutableListOf()
|
||||||
override val typeParameters: MutableList<FirTypeParameterRef> = mutableListOf()
|
override val typeParameters: MutableList<FirTypeParameterRef> = mutableListOf()
|
||||||
override val declarations: MutableList<FirDeclaration> = mutableListOf()
|
override val declarations: MutableList<FirDeclaration> = mutableListOf()
|
||||||
|
|
||||||
@@ -157,14 +168,13 @@ class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationContainerBuil
|
|||||||
|
|
||||||
@OptIn(FirImplementationDetail::class)
|
@OptIn(FirImplementationDetail::class)
|
||||||
override fun build(): FirJavaClass {
|
override fun build(): FirJavaClass {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return FirJavaClass(
|
return FirJavaClass(
|
||||||
source,
|
source,
|
||||||
moduleData,
|
moduleData,
|
||||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES,
|
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES,
|
||||||
name,
|
name,
|
||||||
origin = javaOrigin(isFromSource),
|
origin = javaOrigin(isFromSource),
|
||||||
annotations.toMutableOrEmpty(),
|
javaAnnotations.toMutableOrEmpty(),
|
||||||
status,
|
status,
|
||||||
classKind,
|
classKind,
|
||||||
declarations,
|
declarations,
|
||||||
|
|||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public final class KotlinFacadeKt /* one.KotlinFacadeKt*/ {
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String MY_FIELD = "abcd" /* initializer type: java.lang.String */;
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public final class KotlinFacadeKt /* one.KotlinFacadeKt*/ {
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String MY_FIELD;
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
// one.KotlinFacadeKt
|
||||||
|
|
||||||
|
// FILE: KotlinFacade.kt
|
||||||
|
package one
|
||||||
|
|
||||||
|
import one.JavaClass.staticJavaMethod
|
||||||
|
|
||||||
|
private val MY_FIELD = "abcd"
|
||||||
|
|
||||||
|
// FILE: one/JavaClass.java
|
||||||
|
package one;
|
||||||
|
|
||||||
|
import two.Service;
|
||||||
|
|
||||||
|
import static one.KotlinFacadeKt.*;
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
public final class JavaClass {
|
||||||
|
static void staticJavaMethod() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: two/Service.java
|
||||||
|
package two;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Service {
|
||||||
|
Level[] value() default {};
|
||||||
|
|
||||||
|
enum Level {
|
||||||
|
PROJECT
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -169,6 +169,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaBetween.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("JavaClassWithAnnotation.kt")
|
||||||
|
public void testJavaClassWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JavaClassWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("JvmNameOnMember.kt")
|
@TestMetadata("JvmNameOnMember.kt")
|
||||||
public void testJvmNameOnMember() throws Exception {
|
public void testJvmNameOnMember() throws Exception {
|
||||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JvmNameOnMember.kt");
|
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/JvmNameOnMember.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user