[FIR] Generate annotations to data class copy method parameters

#KT-57003 Fixed
This commit is contained in:
Kirill Rakhman
2023-05-15 13:45:27 +02:00
committed by Space Team
parent 5ae3a93084
commit 0ac02be534
25 changed files with 255 additions and 43 deletions
@@ -164,18 +164,21 @@ internal fun deserializeClassToSymbol(
if (classOrObject.isData() && firPrimaryConstructor != null) { if (classOrObject.isData() && firPrimaryConstructor != null) {
val zippedParameters = val zippedParameters =
classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() } zip declarations.filterIsInstance<FirProperty>() classOrObject.primaryConstructorParameters zip declarations.filterIsInstance<FirProperty>()
addDeclaration(createDataClassCopyFunction(classId, classOrObject, context.dispatchReceiver, zippedParameters, addDeclaration(
createClassTypeRefWithSourceKind = { createDataClassCopyFunction(
firPrimaryConstructor.returnTypeRef.copyWithNewSourceKind( classId,
it classOrObject,
) context.dispatchReceiver,
}, zippedParameters,
createParameterTypeRefWithSourceKind = { property, newKind -> createClassTypeRefWithSourceKind = { firPrimaryConstructor.returnTypeRef.copyWithNewSourceKind(it) },
property.returnTypeRef.copyWithNewSourceKind(newKind) createParameterTypeRefWithSourceKind = { property, newKind ->
}) { src, kind -> property.returnTypeRef.copyWithNewSourceKind(newKind)
KtFakeSourceElement(src as PsiElement, kind) },
}) toFirSource = { src, kind -> KtFakeSourceElement(src as PsiElement, kind) },
addValueParameterAnnotations = { annotations += context.annotationDeserializer.loadAnnotations(it) },
)
)
} }
addCloneForArrayIfNeeded(classId, context.dispatchReceiver) addCloneForArrayIfNeeded(classId, context.dispatchReceiver)
@@ -1446,6 +1446,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt"); runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt");
} }
@Test
@TestMetadata("annotationsOnDataClassCopy.kt")
public void testAnnotationsOnDataClassCopy() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/annotationsOnDataClassCopy.kt");
}
@Test @Test
@TestMetadata("annotationsOnLambdaAsCallArgument.kt") @TestMetadata("annotationsOnLambdaAsCallArgument.kt")
public void testAnnotationsOnLambdaAsCallArgument() throws Exception { public void testAnnotationsOnLambdaAsCallArgument() throws Exception {
@@ -1446,6 +1446,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt"); runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt");
} }
@Test
@TestMetadata("annotationsOnDataClassCopy.kt")
public void testAnnotationsOnDataClassCopy() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/annotationsOnDataClassCopy.kt");
}
@Test @Test
@TestMetadata("annotationsOnLambdaAsCallArgument.kt") @TestMetadata("annotationsOnLambdaAsCallArgument.kt")
public void testAnnotationsOnLambdaAsCallArgument() throws Exception { public void testAnnotationsOnLambdaAsCallArgument() throws Exception {
@@ -1,4 +1,5 @@
// ISSUE: KT-44554 // ISSUE: KT-44554
// FIR_DUMP
data class Foo(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>a: Int<!>, val b: Int) { data class Foo(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>a: Int<!>, val b: Int) {
val c = 4 val c = 4
@@ -15,7 +15,7 @@ FILE: test.kt
public final operator fun component1(): R|kotlin/String| public final operator fun component1(): R|kotlin/String|
public final fun copy(message: R|kotlin/String| = this@R|/KotlinResult|.R|/KotlinResult.message|): R|KotlinResult| public final fun copy(@R|KotlinMessage|() message: R|kotlin/String| = this@R|/KotlinResult|.R|/KotlinResult.message|): R|KotlinResult|
} }
public open class Some : R|kotlin/Any| { public open class Some : R|kotlin/Any| {
@@ -1446,6 +1446,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt"); runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt");
} }
@Test
@TestMetadata("annotationsOnDataClassCopy.kt")
public void testAnnotationsOnDataClassCopy() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/annotationsOnDataClassCopy.kt");
}
@Test @Test
@TestMetadata("annotationsOnLambdaAsCallArgument.kt") @TestMetadata("annotationsOnLambdaAsCallArgument.kt")
public void testAnnotationsOnLambdaAsCallArgument() throws Exception { public void testAnnotationsOnLambdaAsCallArgument() throws Exception {
@@ -1446,6 +1446,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt"); runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt");
} }
@Test
@TestMetadata("annotationsOnDataClassCopy.kt")
public void testAnnotationsOnDataClassCopy() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/annotationsOnDataClassCopy.kt");
}
@Test @Test
@TestMetadata("annotationsOnLambdaAsCallArgument.kt") @TestMetadata("annotationsOnLambdaAsCallArgument.kt")
public void testAnnotationsOnLambdaAsCallArgument() throws Exception { public void testAnnotationsOnLambdaAsCallArgument() throws Exception {
@@ -599,6 +599,13 @@ class DeclarationsConverter(
context.className, context.className,
createClassTypeRefWithSourceKind = { firPrimaryConstructor.returnTypeRef }, createClassTypeRefWithSourceKind = { firPrimaryConstructor.returnTypeRef },
createParameterTypeRefWithSourceKind = { property, _ -> property.returnTypeRef }, createParameterTypeRefWithSourceKind = { property, _ -> property.returnTypeRef },
addValueParameterAnnotations = { valueParam ->
valueParam.forEachChildren {
if (it.tokenType == MODIFIER_LIST) convertModifierList(it).annotations.filterTo(annotations) {
it.useSiteTarget.appliesToPrimaryConstructorParameter()
}
}
},
).generate() ).generate()
} }
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.builder.Context import org.jetbrains.kotlin.fir.builder.Context
import org.jetbrains.kotlin.fir.builder.appliesToPrimaryConstructorParameter
import org.jetbrains.kotlin.fir.builder.filterUseSiteTarget import org.jetbrains.kotlin.fir.builder.filterUseSiteTarget
import org.jetbrains.kotlin.fir.builder.initContainingClassAttr import org.jetbrains.kotlin.fir.builder.initContainingClassAttr
import org.jetbrains.kotlin.fir.copy import org.jetbrains.kotlin.fir.copy
@@ -67,10 +67,7 @@ class ValueParameter(
if (!isFromPrimaryConstructor) if (!isFromPrimaryConstructor)
addAll(modifiers.annotations) addAll(modifiers.annotations)
else else
modifiers.annotations.filterTo(this) { modifiers.annotations.filterTo(this) { it.useSiteTarget.appliesToPrimaryConstructorParameter() }
val useSiteTarget = it.useSiteTarget
useSiteTarget == null || useSiteTarget == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER || useSiteTarget == AnnotationUseSiteTarget.RECEIVER || useSiteTarget == AnnotationUseSiteTarget.FILE
}
addAll(additionalAnnotations) addAll(additionalAnnotations)
} }
} }
@@ -162,7 +159,7 @@ class ValueParameter(
symbol, symbol,
).also { ).also {
it.initContainingClassAttr(context) it.initContainingClassAttr(context)
it.replaceAnnotations(modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.PROPERTY_GETTER)) it.replaceAnnotations(modifiers.annotations.filterUseSiteTarget(PROPERTY_GETTER))
} }
setter = if (this.isVar) FirDefaultPropertySetter( setter = if (this.isVar) FirDefaultPropertySetter(
defaultAccessorSource, defaultAccessorSource,
@@ -171,10 +168,10 @@ class ValueParameter(
type.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor), type.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor),
modifiers.getVisibility(), modifiers.getVisibility(),
symbol, symbol,
parameterAnnotations = modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.SETTER_PARAMETER) parameterAnnotations = modifiers.annotations.filterUseSiteTarget(SETTER_PARAMETER)
).also { ).also {
it.initContainingClassAttr(context) it.initContainingClassAttr(context)
it.replaceAnnotations(modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.PROPERTY_SETTER)) it.replaceAnnotations(modifiers.annotations.filterUseSiteTarget(PROPERTY_SETTER))
} else null } else null
}.apply { }.apply {
if (firValueParameter.isVararg) { if (firValueParameter.isVararg) {
@@ -604,21 +604,24 @@ open class RawFirBuilder(
isNoinline = hasModifier(NOINLINE_KEYWORD) isNoinline = hasModifier(NOINLINE_KEYWORD)
isVararg = isVarArg isVararg = isVarArg
containingFunctionSymbol = functionSymbol containingFunctionSymbol = functionSymbol
val isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR addAnnotationsFrom(
for (annotationEntry in annotationEntries) { this@toFirValueParameter,
annotationEntry.convert<FirAnnotation>().takeIf { isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR
!isFromPrimaryConstructor || it.useSiteTarget == null || )
it.useSiteTarget == CONSTRUCTOR_PARAMETER ||
it.useSiteTarget == RECEIVER ||
it.useSiteTarget == FILE
}?.let {
this.annotations += it
}
}
annotations += additionalAnnotations annotations += additionalAnnotations
} }
} }
private fun FirValueParameterBuilder.addAnnotationsFrom(ktParameter: KtParameter, isFromPrimaryConstructor: Boolean) {
for (annotationEntry in ktParameter.annotationEntries) {
annotationEntry.convert<FirAnnotation>().takeIf {
!isFromPrimaryConstructor || it.useSiteTarget.appliesToPrimaryConstructorParameter()
}?.let {
annotations += it
}
}
}
private fun KtParameter.toFirProperty(firParameter: FirValueParameter): FirProperty { private fun KtParameter.toFirProperty(firParameter: FirValueParameter): FirProperty {
require(hasValOrVar()) require(hasValOrVar())
val type = typeReference.convertSafe<FirTypeRef>() ?: createNoTypeForParameterTypeRef() val type = typeReference.convertSafe<FirTypeRef>() ?: createNoTypeForParameterTypeRef()
@@ -1323,6 +1326,7 @@ open class RawFirBuilder(
(property.returnTypeRef.psi as KtTypeReference?).toFirOrImplicitType() (property.returnTypeRef.psi as KtTypeReference?).toFirOrImplicitType()
} }
}, },
addValueParameterAnnotations = { addAnnotationsFrom(it as KtParameter, isFromPrimaryConstructor = true) },
).generate() ).generate()
} }
@@ -855,6 +855,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
private val classFqName: FqName, private val classFqName: FqName,
private val createClassTypeRefWithSourceKind: (KtFakeSourceElementKind) -> FirTypeRef, private val createClassTypeRefWithSourceKind: (KtFakeSourceElementKind) -> FirTypeRef,
private val createParameterTypeRefWithSourceKind: (FirProperty, KtFakeSourceElementKind) -> FirTypeRef, private val createParameterTypeRefWithSourceKind: (FirProperty, KtFakeSourceElementKind) -> FirTypeRef,
private val addValueParameterAnnotations: FirValueParameterBuilder.(T) -> Unit,
) { ) {
fun generate() { fun generate() {
if (classBuilder.classKind != ClassKind.OBJECT) { if (classBuilder.classKind != ClassKind.OBJECT) {
@@ -870,9 +871,8 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
if (!firProperty.isVal && !firProperty.isVar) continue if (!firProperty.isVal && !firProperty.isVar) continue
val name = Name.identifier("component$componentIndex") val name = Name.identifier("component$componentIndex")
componentIndex++ componentIndex++
val parameterSource = sourceNode?.toFirSourceElement()
val componentFunction = buildSimpleFunction { val componentFunction = buildSimpleFunction {
source = parameterSource?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers) source = sourceNode?.toFirSourceElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
returnTypeRef = firProperty.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers) returnTypeRef = firProperty.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers)
@@ -898,8 +898,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
currentDispatchReceiverType(), currentDispatchReceiverType(),
zippedParameters, zippedParameters,
createClassTypeRefWithSourceKind, createClassTypeRefWithSourceKind,
createParameterTypeRefWithSourceKind createParameterTypeRefWithSourceKind,
) { src, kind -> src?.toFirSourceElement(kind) } { src, kind -> src?.toFirSourceElement(kind) },
addValueParameterAnnotations,
)
) )
} }
} }
@@ -1033,7 +1035,8 @@ fun <T> FirRegularClassBuilder.createDataClassCopyFunction(
zippedParameters: List<Pair<T, FirProperty>>, zippedParameters: List<Pair<T, FirProperty>>,
createClassTypeRefWithSourceKind: (KtFakeSourceElementKind) -> FirTypeRef, createClassTypeRefWithSourceKind: (KtFakeSourceElementKind) -> FirTypeRef,
createParameterTypeRefWithSourceKind: (FirProperty, KtFakeSourceElementKind) -> FirTypeRef, createParameterTypeRefWithSourceKind: (FirProperty, KtFakeSourceElementKind) -> FirTypeRef,
toFirSource: (T?, KtFakeSourceElementKind) -> KtSourceElement? toFirSource: (T?, KtFakeSourceElementKind) -> KtSourceElement?,
addValueParameterAnnotations: FirValueParameterBuilder.(T) -> Unit,
): FirSimpleFunction { ): FirSimpleFunction {
fun generateComponentAccess( fun generateComponentAccess(
parameterSource: KtSourceElement?, parameterSource: KtSourceElement?,
@@ -1086,6 +1089,10 @@ fun <T> FirRegularClassBuilder.createDataClassCopyFunction(
isCrossinline = false isCrossinline = false
isNoinline = false isNoinline = false
isVararg = false isVararg = false
addValueParameterAnnotations(ktParameter)
for (annotation in annotations) {
annotation.replaceUseSiteTarget(null)
}
} }
} }
// Refer to FIR backend ClassMemberGenerator for body generation. // Refer to FIR backend ClassMemberGenerator for body generation.
@@ -659,3 +659,8 @@ fun buildBalancedOrExpressionTree(conditions: List<FirExpression>, lower: Int =
(leftNode.source ?: rightNode.source)?.fakeElement(KtFakeSourceElementKind.WhenCondition) (leftNode.source ?: rightNode.source)?.fakeElement(KtFakeSourceElementKind.WhenCondition)
) )
} }
fun AnnotationUseSiteTarget?.appliesToPrimaryConstructorParameter() = this == null ||
this == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER ||
this == AnnotationUseSiteTarget.RECEIVER ||
this == AnnotationUseSiteTarget.FILE
@@ -9,6 +9,7 @@ import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
@@ -248,9 +249,20 @@ open class FirTypeResolveTransformer(
withScopeCleanup { withScopeCleanup {
withDeclaration(simpleFunction) { withDeclaration(simpleFunction) {
addTypeParametersScope(simpleFunction) addTypeParametersScope(simpleFunction)
transformDeclaration(simpleFunction, data).also { val result = transformDeclaration(simpleFunction, data).also {
unboundCyclesInTypeParametersSupertypes(it as FirTypeParametersOwner) unboundCyclesInTypeParametersSupertypes(it as FirTypeParametersOwner)
} }
if (result.source?.kind == KtFakeSourceElementKind.DataClassGeneratedMembers &&
result is FirSimpleFunction &&
result.name == StandardNames.DATA_CLASS_COPY
) {
for (valueParameter in result.valueParameters) {
valueParameter.moveOrDeleteIrrelevantAnnotations()
}
}
result
} }
} as FirSimpleFunction } as FirSimpleFunction
} }
@@ -521,3 +533,20 @@ open class FirTypeResolveTransformer(
private fun annotationShouldBeMovedToField(allowedTargets: Set<AnnotationUseSiteTarget>): Boolean = private fun annotationShouldBeMovedToField(allowedTargets: Set<AnnotationUseSiteTarget>): Boolean =
(FIELD in allowedTargets || PROPERTY_DELEGATE_FIELD in allowedTargets) && PROPERTY !in allowedTargets (FIELD in allowedTargets || PROPERTY_DELEGATE_FIELD in allowedTargets) && PROPERTY !in allowedTargets
} }
annotation class NoTarget
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Param
@Target(AnnotationTarget.PROPERTY)
annotation class Prop
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class Both
data class Foo(
@NoTarget @Param @Prop @Both val p1: Int,
@param:NoTarget @param:Both val p2: String,
@property:NoTarget @property:Both val p3: Boolean,
)
@@ -36,6 +36,8 @@ abstract class FirAnnotation : FirExpression() {
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
abstract fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?)
abstract fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) abstract fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract fun replaceArgumentMapping(newArgumentMapping: FirAnnotationArgumentMapping) abstract fun replaceArgumentMapping(newArgumentMapping: FirAnnotationArgumentMapping)
@@ -40,6 +40,8 @@ abstract class FirAnnotationCall : FirAnnotation(), FirCall, FirResolvable {
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
abstract override fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?)
abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
@@ -43,6 +43,8 @@ abstract class FirErrorAnnotationCall : FirAnnotationCall(), FirDiagnosticHolder
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
abstract override fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?)
abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
internal class FirAnnotationCallImpl( internal class FirAnnotationCallImpl(
override val source: KtSourceElement?, override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?, override var useSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef, override var annotationTypeRef: FirTypeRef,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>, override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
override var argumentList: FirArgumentList, override var argumentList: FirArgumentList,
@@ -77,6 +77,10 @@ internal class FirAnnotationCallImpl(
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {} override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
override fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?) {
useSiteTarget = newUseSiteTarget
}
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) { override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef annotationTypeRef = newAnnotationTypeRef
} }
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
internal class FirAnnotationImpl( internal class FirAnnotationImpl(
override val source: KtSourceElement?, override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?, override var useSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef, override var annotationTypeRef: FirTypeRef,
override var argumentMapping: FirAnnotationArgumentMapping, override var argumentMapping: FirAnnotationArgumentMapping,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>, override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
@@ -63,6 +63,10 @@ internal class FirAnnotationImpl(
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {} override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
override fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?) {
useSiteTarget = newUseSiteTarget
}
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) { override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef annotationTypeRef = newAnnotationTypeRef
} }
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
internal class FirErrorAnnotationCallImpl( internal class FirErrorAnnotationCallImpl(
override val source: KtSourceElement?, override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?, override var useSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef, override var annotationTypeRef: FirTypeRef,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>, override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
override var argumentList: FirArgumentList, override var argumentList: FirArgumentList,
@@ -79,6 +79,10 @@ internal class FirErrorAnnotationCallImpl(
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {} override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
override fun replaceUseSiteTarget(newUseSiteTarget: AnnotationUseSiteTarget?) {
useSiteTarget = newUseSiteTarget
}
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) { override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef annotationTypeRef = newAnnotationTypeRef
} }
@@ -519,7 +519,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
} }
annotation.configure { annotation.configure {
+field("useSiteTarget", annotationUseSiteTargetType, nullable = true) +field("useSiteTarget", annotationUseSiteTargetType, nullable = true, withReplace = true)
+field("annotationTypeRef", typeRef, withReplace = true).withTransform() +field("annotationTypeRef", typeRef, withReplace = true).withTransform()
+field("argumentMapping", annotationArgumentMapping, withReplace = true) +field("argumentMapping", annotationArgumentMapping, withReplace = true)
+typeArguments.withTransform() +typeArguments.withTransform()
@@ -28,7 +28,7 @@ object KotlinStubVersions {
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed // Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder). // or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files). // Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
private const val BINARY_STUB_VERSION = 90 private const val BINARY_STUB_VERSION = 91
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile) // Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
// Increasing this version will lead to reindexing of all classfiles. // Increasing this version will lead to reindexing of all classfiles.
@@ -0,0 +1,48 @@
FILE: annotationsOnDataClassCopy.kt
public final annotation class NoTarget : R|kotlin/Annotation| {
public constructor(): R|NoTarget| {
super<R|kotlin/Any|>()
}
}
@R|kotlin/annotation/Target|(allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|)) public final annotation class Param : R|kotlin/Annotation| {
public constructor(): R|Param| {
super<R|kotlin/Any|>()
}
}
@R|kotlin/annotation/Target|(allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY|)) public final annotation class Prop : R|kotlin/Annotation| {
public constructor(): R|Prop| {
super<R|kotlin/Any|>()
}
}
@R|kotlin/annotation/Target|(allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|)) public final annotation class Both : R|kotlin/Annotation| {
public constructor(): R|Both| {
super<R|kotlin/Any|>()
}
}
public final data class Foo : R|kotlin/Any| {
public constructor(@R|NoTarget|() @R|Param|() @R|Both|() p1: R|kotlin/Int|, @CONSTRUCTOR_PARAMETER:R|NoTarget|() @CONSTRUCTOR_PARAMETER:R|Both|() p2: R|kotlin/String|, p3: R|kotlin/Boolean|): R|Foo| {
super<R|kotlin/Any|>()
}
@R|Prop|() public final val p1: R|kotlin/Int| = R|<local>/p1|
public get(): R|kotlin/Int|
public final val p2: R|kotlin/String| = R|<local>/p2|
public get(): R|kotlin/String|
@PROPERTY:R|NoTarget|() @PROPERTY:R|Both|() public final val p3: R|kotlin/Boolean| = R|<local>/p3|
public get(): R|kotlin/Boolean|
public final operator fun component1(): R|kotlin/Int|
public final operator fun component2(): R|kotlin/String|
public final operator fun component3(): R|kotlin/Boolean|
public final fun copy(@R|NoTarget|() @R|Param|() @R|Both|() p1: R|kotlin/Int| = this@R|/Foo|.R|/Foo.p1|, @R|NoTarget|() @R|Both|() p2: R|kotlin/String| = this@R|/Foo|.R|/Foo.p2|, p3: R|kotlin/Boolean| = this@R|/Foo|.R|/Foo.p3|): R|Foo|
}
@@ -0,0 +1,19 @@
// FIR_IDENTICAL
// FIR_DUMP
annotation class NoTarget
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Param
@Target(AnnotationTarget.PROPERTY)
annotation class Prop
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class Both
data class Foo(
@NoTarget @Param @Prop @Both val p1: Int,
@param:NoTarget @param:Both val p2: String,
@property:NoTarget @property:Both val p3: Boolean,
)
@@ -0,0 +1,44 @@
package
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER}) public final annotation class Both : kotlin.Annotation {
public constructor Both()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final data class Foo {
public constructor Foo(/*0*/ @NoTarget @Param @Both p1: kotlin.Int, /*1*/ @NoTarget @Both p2: kotlin.String, /*2*/ p3: kotlin.Boolean)
@Prop public final val p1: kotlin.Int
public final val p2: kotlin.String
@NoTarget @Both public final val p3: kotlin.Boolean
public final operator /*synthesized*/ fun component1(): kotlin.Int
public final operator /*synthesized*/ fun component2(): kotlin.String
public final operator /*synthesized*/ fun component3(): kotlin.Boolean
public final /*synthesized*/ fun copy(/*0*/ @NoTarget @Param @Both p1: kotlin.Int = ..., /*1*/ @NoTarget @Both p2: kotlin.String = ..., /*2*/ p3: kotlin.Boolean = ...): Foo
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
public final annotation class NoTarget : kotlin.Annotation {
public constructor NoTarget()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) public final annotation class Param : kotlin.Annotation {
public constructor Param()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY}) public final annotation class Prop : kotlin.Annotation {
public constructor Prop()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1446,6 +1446,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt"); runTest("compiler/testData/diagnostics/tests/annotations/AnnotationsForPropertyTypeParameter.kt");
} }
@Test
@TestMetadata("annotationsOnDataClassCopy.kt")
public void testAnnotationsOnDataClassCopy() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/annotationsOnDataClassCopy.kt");
}
@Test @Test
@TestMetadata("annotationsOnLambdaAsCallArgument.kt") @TestMetadata("annotationsOnLambdaAsCallArgument.kt")
public void testAnnotationsOnLambdaAsCallArgument() throws Exception { public void testAnnotationsOnLambdaAsCallArgument() throws Exception {