[FIR] Remove duplicate annotations from primary ctor params/properties
If an annotation doesn't specify an explicit use-site target, previously it was added to both, the primary constructor value parameter and the property in the FIR. Then, in FIR2IR, only the "correct" one was added to the IR. Move up the deduplication logic into the frontend. ^KT-56177 Fixed
This commit is contained in:
committed by
Space Team
parent
9268fd0e87
commit
eee66ab43f
+1
-1
@@ -1657,7 +1657,7 @@ class Fir2IrDeclarationStorage(
|
||||
annotationGenerator.generate(this, firAnnotationContainer)
|
||||
if (this is IrFunction && firAnnotationContainer is FirSimpleFunction) {
|
||||
valueParameters.zip(firAnnotationContainer.valueParameters).forEach { (irParameter, firParameter) ->
|
||||
annotationGenerator.generate(irParameter, firParameter, isInConstructor = false)
|
||||
annotationGenerator.generate(irParameter, firParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-24
@@ -24,6 +24,9 @@ import org.jetbrains.kotlin.ir.util.isSetter
|
||||
* need special handling: [AnnotationUseSiteTarget]. In particular, [FirProperty] contains all annotations associated with that property,
|
||||
* whose targets may vary. After all the necessary pieces of IR elements, e.g., backing field, are ready, this generator splits those
|
||||
* annotations to the specified targets.
|
||||
*
|
||||
* Note: Annotations on primary constructor properties are already split between value parameters and properties in FIR. Before this change,
|
||||
* it used to be done here.
|
||||
*/
|
||||
class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComponents by components {
|
||||
|
||||
@@ -40,32 +43,16 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp
|
||||
useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains)
|
||||
|
||||
companion object {
|
||||
// Priority order: constructor parameter (if applicable) -> property -> field. So, for example, if `A`
|
||||
// can be attached to all three, then in a declaration like
|
||||
// class C(@A val x: Int) { @A val y = 1 }
|
||||
// the parameter `x` and the property `y` will have the annotation, while the property `x` and both backing fields will not.
|
||||
private val propertyTargets = listOf(AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD)
|
||||
private val constructorPropertyTargets = listOf(AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER) + propertyTargets
|
||||
private val delegatedPropertyTargets = propertyTargets + listOf(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD)
|
||||
}
|
||||
|
||||
// TODO: third argument should be whether this parameter is a property declaration (though this probably makes no difference)
|
||||
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) {
|
||||
if (isInConstructor) {
|
||||
irValueParameter.annotations += firValueParameter.annotations
|
||||
.filter { it.target(constructorPropertyTargets) == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER }
|
||||
.toIrAnnotations()
|
||||
} else {
|
||||
irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations()
|
||||
}
|
||||
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter) {
|
||||
irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations()
|
||||
}
|
||||
|
||||
fun generate(irProperty: IrProperty, property: FirProperty) {
|
||||
val applicableTargets = when {
|
||||
property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
|
||||
irProperty.isDelegated -> delegatedPropertyTargets
|
||||
else -> propertyTargets
|
||||
}
|
||||
val applicableTargets = if (irProperty.isDelegated) delegatedPropertyTargets else propertyTargets
|
||||
irProperty.annotations += property.annotations
|
||||
.filter { it.target(applicableTargets) == AnnotationUseSiteTarget.PROPERTY }
|
||||
.toIrAnnotations()
|
||||
@@ -73,11 +60,8 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp
|
||||
|
||||
fun generate(irField: IrField, property: FirProperty) {
|
||||
val irProperty = irField.correspondingPropertySymbol?.owner ?: throw AssertionError("$irField is not a property field")
|
||||
val applicableTargets = when {
|
||||
property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
|
||||
irProperty.isDelegated -> delegatedPropertyTargets
|
||||
else -> propertyTargets
|
||||
}
|
||||
|
||||
val applicableTargets = if (irProperty.isDelegated) delegatedPropertyTargets else propertyTargets
|
||||
irField.annotations += property.annotations.filter {
|
||||
val target = it.target(applicableTargets)
|
||||
target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ internal class ClassMemberGenerator(
|
||||
val annotationMode = containingClass?.classKind == ClassKind.ANNOTATION_CLASS && irFunction is IrConstructor
|
||||
for ((valueParameter, firValueParameter) in irParameters.zip(firFunction.valueParameters)) {
|
||||
valueParameter.setDefaultValue(firValueParameter, annotationMode)
|
||||
annotationGenerator.generate(valueParameter, firValueParameter, irFunction is IrConstructor)
|
||||
annotationGenerator.generate(valueParameter, firValueParameter)
|
||||
}
|
||||
annotationGenerator.generate(irFunction, firFunction)
|
||||
}
|
||||
|
||||
+18
@@ -233,6 +233,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/annotations/javaPropertyWithIntInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaTargetOnPrimaryCtorParameter.kt")
|
||||
public void testJavaTargetOnPrimaryCtorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmAnnotationFlags.kt")
|
||||
public void testJvmAnnotationFlags() throws Exception {
|
||||
@@ -371,6 +377,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("targetOnPrimaryCtorParameter.kt")
|
||||
public void testTargetOnPrimaryCtorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("targetOnPrimaryCtorParameterMultiModule.kt")
|
||||
public void testTargetOnPrimaryCtorParameterMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typeAnnotationOnJdk6.kt")
|
||||
public void testTypeAnnotationOnJdk6() throws Exception {
|
||||
|
||||
+18
@@ -233,6 +233,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/annotations/javaPropertyWithIntInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaTargetOnPrimaryCtorParameter.kt")
|
||||
public void testJavaTargetOnPrimaryCtorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmAnnotationFlags.kt")
|
||||
public void testJvmAnnotationFlags() throws Exception {
|
||||
@@ -371,6 +377,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("targetOnPrimaryCtorParameter.kt")
|
||||
public void testTargetOnPrimaryCtorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("targetOnPrimaryCtorParameterMultiModule.kt")
|
||||
public void testTargetOnPrimaryCtorParameterMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typeAnnotationOnJdk6.kt")
|
||||
public void testTypeAnnotationOnJdk6() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user