Split property use-site targets during FIR building

This commit is contained in:
Mikhail Glukhikh
2021-10-06 15:36:52 +03:00
committed by teamcityserver
parent 2a9a1dbb86
commit 7243d30869
26 changed files with 227 additions and 138 deletions
@@ -36,13 +36,8 @@ KtFirKotlinPropertySymbol:
KtFirKotlinPropertySymbol: KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int annotatedType: [] kotlin/Int
annotationClassIds: [ annotationClassIds: []
kotlin/Deprecated annotations: []
]
annotations: [
kotlin/Deprecated(message = don't use getter of i2)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /i2 callableIdIfNonLocal: /i2
dispatchType: null dispatchType: null
getter: KtFirPropertyGetterSymbol(<getter>) getter: KtFirPropertyGetterSymbol(<getter>)
@@ -72,13 +67,8 @@ KtFirKotlinPropertySymbol:
KtFirKotlinPropertySymbol: KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int annotatedType: [] kotlin/Int
annotationClassIds: [ annotationClassIds: []
kotlin/Deprecated annotations: []
]
annotations: [
kotlin/Deprecated(message = don't use getter of i3)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /i3 callableIdIfNonLocal: /i3
dispatchType: null dispatchType: null
getter: KtFirPropertyGetterSymbol(<getter>) getter: KtFirPropertyGetterSymbol(<getter>)
@@ -108,16 +98,8 @@ KtFirKotlinPropertySymbol:
KtFirKotlinPropertySymbol: KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int annotatedType: [] kotlin/Int
annotationClassIds: [ annotationClassIds: []
kotlin/Deprecated annotations: []
kotlin/Deprecated
]
annotations: [
kotlin/Deprecated(message = don't use getter of i4)
psi: KtAnnotationEntry
kotlin/Deprecated(message = don't use getter of i4)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /i4 callableIdIfNonLocal: /i4
dispatchType: null dispatchType: null
getter: KtFirPropertyGetterSymbol(<getter>) getter: KtFirPropertyGetterSymbol(<getter>)
@@ -1,15 +1,7 @@
KtFirKotlinPropertySymbol: KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int annotatedType: [] kotlin/Int
annotationClassIds: [ annotationClassIds: []
kotlin/jvm/JvmName annotations: []
kotlin/jvm/JvmName
]
annotations: [
kotlin/jvm/JvmName(name = getMyI)
psi: KtAnnotationEntry
kotlin/jvm/JvmName(name = setMyI)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /Foo.i callableIdIfNonLocal: /Foo.i
dispatchType: Foo dispatchType: Foo
getter: KtFirPropertyGetterSymbol(<getter>) getter: KtFirPropertyGetterSymbol(<getter>)
@@ -93,7 +93,9 @@ internal open class FirElementsRecorder : FirVisitor<Unit, MutableMap<KtElement,
private fun cacheElement(element: FirElement, cache: MutableMap<KtElement, FirElement>) { private fun cacheElement(element: FirElement, cache: MutableMap<KtElement, FirElement>) {
val psi = element.source val psi = element.source
?.takeIf { ?.takeIf {
it.kind == FirFakeSourceElementKind.ReferenceInAtomicQualifiedAccess || it is FirRealPsiSourceElement it is FirRealPsiSourceElement ||
it.kind == FirFakeSourceElementKind.ReferenceInAtomicQualifiedAccess ||
it.kind == FirFakeSourceElementKind.FromUseSiteTarget
}.psi as? KtElement }.psi as? KtElement
?: return ?: return
cache(psi, element, cache) cache(psi, element, cache)
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
@@ -98,14 +99,16 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
override fun convertValueParameter( override fun convertValueParameter(
valueParameter: KtParameter, valueParameter: KtParameter,
defaultTypeRef: FirTypeRef?, defaultTypeRef: FirTypeRef?,
valueParameterDeclaration: ValueParameterDeclaration valueParameterDeclaration: ValueParameterDeclaration,
additionalAnnotations: List<FirAnnotation>
): FirValueParameter { ): FirValueParameter {
val replacementParameter = replacementApplier?.tryReplace(valueParameter) ?: valueParameter val replacementParameter = replacementApplier?.tryReplace(valueParameter) ?: valueParameter
check(replacementParameter is KtParameter) check(replacementParameter is KtParameter)
return super.convertValueParameter( return super.convertValueParameter(
valueParameter = replacementParameter, valueParameter = replacementParameter,
defaultTypeRef = defaultTypeRef, defaultTypeRef = defaultTypeRef,
valueParameterDeclaration = valueParameterDeclaration valueParameterDeclaration = valueParameterDeclaration,
additionalAnnotations = additionalAnnotations
) )
} }
} }
@@ -6,12 +6,12 @@ FILE: test.kt
} }
public final data class KotlinResult : R|kotlin/Any| { public final data class KotlinResult : R|kotlin/Any| {
@R|KotlinMessage|() public constructor(@PROPERTY_GETTER:R|KotlinMessage|() @R|KotlinMessage|() message: R|kotlin/String| = String()): R|KotlinResult| { @R|KotlinMessage|() public constructor(@R|KotlinMessage|() message: R|kotlin/String| = String()): R|KotlinResult| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
@PROPERTY_GETTER:R|KotlinMessage|() @R|KotlinMessage|() public final val message: R|kotlin/String| = R|<local>/message| @R|KotlinMessage|() public final val message: R|kotlin/String| = R|<local>/message|
public get(): R|kotlin/String| @PROPERTY_GETTER:R|KotlinMessage|() public get(): R|kotlin/String|
public final operator fun component1(): R|kotlin/String| public final operator fun component1(): R|kotlin/String|
@@ -28,8 +28,8 @@ FILE: test.kt
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
@PROPERTY_GETTER:R|kotlin/jvm/JvmName|(name = String(getInstance)) public open val INSTANCE: R|kotlin/String| public open val INSTANCE: R|kotlin/String|
public get(): R|kotlin/String| { @PROPERTY_GETTER:R|kotlin/jvm/JvmName|(name = String(getInstance)) public get(): R|kotlin/String| {
^ String(Omega) ^ String(Omega)
} }
@@ -2,11 +2,11 @@
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR) @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR)
annotation class KotlinMessage annotation class KotlinMessage
data class KotlinResult @KotlinMessage constructor(@get:KotlinMessage <!REPEATED_ANNOTATION!>@KotlinMessage<!> val message: String = "") data class KotlinResult @KotlinMessage constructor(@get:KotlinMessage @KotlinMessage val message: String = "")
open class Some { open class Some {
companion object { companion object {
<!INAPPLICABLE_JVM_NAME!>@get:JvmName("getInstance")<!> @get:JvmName("getInstance")
<!NON_FINAL_MEMBER_IN_OBJECT!>open<!> val INSTANCE: String <!NON_FINAL_MEMBER_IN_OBJECT!>open<!> val INSTANCE: String
get() = "Omega" get() = "Omega"
} }
@@ -113,7 +113,7 @@ fun checkRepeatedAnnotation(
) { ) {
val duplicated = useSiteTarget in existingTargetsForAnnotation val duplicated = useSiteTarget in existingTargetsForAnnotation
|| existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) } || existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) }
if (duplicated && !annotation.isRepeatable(context.session) && annotation.source?.kind !is FirFakeSourceElementKind) { if (duplicated && !annotation.isRepeatable(context.session)) {
reporter.reportOn(annotation.source, FirErrors.REPEATED_ANNOTATION, context) reporter.reportOn(annotation.source, FirErrors.REPEATED_ANNOTATION, context)
} }
} }
@@ -77,10 +77,6 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
if (declaration is FirValueParameter && declaration.source?.hasValOrVar() == true) {
// This will be checked later as property
return
}
val actualTargets = getActualTargetList(declaration) val actualTargets = getActualTargetList(declaration)
val applicableTargets = annotation.getAllowedAnnotationTargets(context.session) val applicableTargets = annotation.getAllowedAnnotationTargets(context.session)
val useSiteTarget = annotation.useSiteTarget val useSiteTarget = annotation.useSiteTarget
@@ -114,6 +110,7 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
context context
) )
} else { } else {
if (declaration is FirProperty && declaration.source?.kind == FirFakeSourceElementKind.PropertyFromParameter) return
reporter.reportOn( reporter.reportOn(
annotation.source, annotation.source,
FirErrors.WRONG_ANNOTATION_TARGET, FirErrors.WRONG_ANNOTATION_TARGET,
@@ -130,6 +127,7 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
if (annotation.source?.kind == FirFakeSourceElementKind.FromUseSiteTarget) return
when (target) { when (target) {
AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.PROPERTY,
AnnotationUseSiteTarget.PROPERTY_GETTER -> { AnnotationUseSiteTarget.PROPERTY_GETTER -> {
@@ -156,7 +154,9 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
annotated is FirValueParameter -> { annotated is FirValueParameter -> {
val container = context.containingDeclarations.lastOrNull() val container = context.containingDeclarations.lastOrNull()
if (container is FirConstructor && container.isPrimary) { if (container is FirConstructor && container.isPrimary) {
reporter.reportOn(annotation.source, FirErrors.REDUNDANT_ANNOTATION_TARGET, target.renderName, context) if (annotated.source?.hasValOrVar() != true) {
reporter.reportOn(annotation.source, FirErrors.REDUNDANT_ANNOTATION_TARGET, target.renderName, context)
}
} else { } else {
reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context) reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context)
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
@@ -63,18 +62,15 @@ object FirOptInUsageBaseChecker {
private fun FirAnnotatedDeclaration.loadExperimentalitiesFromAnnotationTo( private fun FirAnnotatedDeclaration.loadExperimentalitiesFromAnnotationTo(
session: FirSession, session: FirSession,
result: MutableCollection<Experimentality>, result: MutableCollection<Experimentality>
fromSetter: Boolean = false
) { ) {
for (annotation in annotations) { for (annotation in annotations) {
val annotationType = annotation.annotationTypeRef.coneTypeSafe<ConeClassLikeType>() val annotationType = annotation.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
if (annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY_SETTER || fromSetter) { result.addIfNotNull(
result.addIfNotNull( annotationType?.lookupTag?.toFirRegularClassSymbol(
annotationType?.lookupTag?.toFirRegularClassSymbol( session
session )?.loadExperimentalityForMarkerAnnotation()
)?.loadExperimentalityForMarkerAnnotation() )
)
}
} }
} }
@@ -157,7 +153,7 @@ object FirOptInUsageBaseChecker {
parentClassSymbol?.loadExperimentalities(context, result, visited, fromSetter = false, dispatchReceiverType = null) parentClassSymbol?.loadExperimentalities(context, result, visited, fromSetter = false, dispatchReceiverType = null)
} }
fir.loadExperimentalitiesFromAnnotationTo(session, result, fromSetter) fir.loadExperimentalitiesFromAnnotationTo(session, result)
if (fir is FirTypeAlias) { if (fir is FirTypeAlias) {
fir.expandedTypeRef.coneType.addExperimentalities(context, result, visited) fir.expandedTypeRef.coneType.addExperimentalities(context, result, visited)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree.converter
import com.intellij.lang.LighterASTNode import com.intellij.lang.LighterASTNode
import com.intellij.psi.TokenType import com.intellij.psi.TokenType
import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtNodeTypes.* import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
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.*
import org.jetbrains.kotlin.fir.builder.* import org.jetbrains.kotlin.fir.builder.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -56,11 +58,9 @@ class DeclarationsConverter(
session: FirSession, session: FirSession,
private val baseScopeProvider: FirScopeProvider, private val baseScopeProvider: FirScopeProvider,
tree: FlyweightCapableTreeStructure<LighterASTNode>, tree: FlyweightCapableTreeStructure<LighterASTNode>,
offset: Int = 0, @set:PrivateForInline override var offset: Int = 0,
context: Context<LighterASTNode> = Context() context: Context<LighterASTNode> = Context()
) : BaseConverter(session, tree, context) { ) : BaseConverter(session, tree, context) {
@set:PrivateForInline
override var offset: Int = offset
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <R> withOffset(newOffset: Int, block: () -> R): R { inline fun <R> withOffset(newOffset: Int, block: () -> R): R {
@@ -99,7 +99,7 @@ class DeclarationsConverter(
IMPORT_LIST -> importList += convertImportDirectives(it) IMPORT_LIST -> importList += convertImportDirectives(it)
CLASS -> firDeclarationList += convertClass(it) CLASS -> firDeclarationList += convertClass(it)
FUN -> firDeclarationList += convertFunctionDeclaration(it) as FirDeclaration FUN -> firDeclarationList += convertFunctionDeclaration(it) as FirDeclaration
PROPERTY -> firDeclarationList += convertPropertyDeclaration(it) KtNodeTypes.PROPERTY -> firDeclarationList += convertPropertyDeclaration(it)
TYPEALIAS -> firDeclarationList += convertTypeAlias(it) TYPEALIAS -> firDeclarationList += convertTypeAlias(it)
OBJECT_DECLARATION -> firDeclarationList += convertClass(it) OBJECT_DECLARATION -> firDeclarationList += convertClass(it)
SCRIPT -> { SCRIPT -> {
@@ -132,7 +132,7 @@ class DeclarationsConverter(
when (node.tokenType) { when (node.tokenType) {
CLASS, OBJECT_DECLARATION -> container += convertClass(node) as FirStatement CLASS, OBJECT_DECLARATION -> container += convertClass(node) as FirStatement
FUN -> container += convertFunctionDeclaration(node) FUN -> container += convertFunctionDeclaration(node)
PROPERTY -> container += convertPropertyDeclaration(node) as FirStatement KtNodeTypes.PROPERTY -> container += convertPropertyDeclaration(node) as FirStatement
DESTRUCTURING_DECLARATION -> container += convertDestructingDeclaration(node).toFirDestructingDeclaration(baseModuleData) DESTRUCTURING_DECLARATION -> container += convertDestructingDeclaration(node).toFirDestructingDeclaration(baseModuleData)
TYPEALIAS -> container += convertTypeAlias(node) as FirStatement TYPEALIAS -> container += convertTypeAlias(node) as FirStatement
CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) as FirStatement CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) as FirStatement
@@ -299,7 +299,7 @@ class DeclarationsConverter(
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationOrList * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationOrList
*/ */
fun convertAnnotation(annotationNode: LighterASTNode): List<FirAnnotation> { fun convertAnnotation(annotationNode: LighterASTNode): List<FirAnnotationCall> {
var annotationTarget: AnnotationUseSiteTarget? = null var annotationTarget: AnnotationUseSiteTarget? = null
return annotationNode.forEachChildrenReturnList { node, container -> return annotationNode.forEachChildrenReturnList { node, container ->
when (node.tokenType) { when (node.tokenType) {
@@ -316,15 +316,15 @@ class DeclarationsConverter(
lateinit var annotationTarget: AnnotationUseSiteTarget lateinit var annotationTarget: AnnotationUseSiteTarget
annotationUseSiteTarget.forEachChildren { annotationUseSiteTarget.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
FIELD_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.FIELD FIELD_KEYWORD -> annotationTarget = FIELD
FILE_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.FILE FILE_KEYWORD -> annotationTarget = FILE
PROPERTY_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY PROPERTY_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY
GET_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY_GETTER GET_KEYWORD -> annotationTarget = PROPERTY_GETTER
SET_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY_SETTER SET_KEYWORD -> annotationTarget = PROPERTY_SETTER
RECEIVER_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.RECEIVER RECEIVER_KEYWORD -> annotationTarget = RECEIVER
PARAM_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER PARAM_KEYWORD -> annotationTarget = CONSTRUCTOR_PARAMETER
SETPARAM_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.SETTER_PARAMETER SETPARAM_KEYWORD -> annotationTarget = SETTER_PARAMETER
DELEGATE_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD DELEGATE_KEYWORD -> annotationTarget = PROPERTY_DELEGATE_FIELD
} }
} }
@@ -338,7 +338,7 @@ class DeclarationsConverter(
fun convertAnnotationEntry( fun convertAnnotationEntry(
unescapedAnnotation: LighterASTNode, unescapedAnnotation: LighterASTNode,
defaultAnnotationUseSiteTarget: AnnotationUseSiteTarget? = null defaultAnnotationUseSiteTarget: AnnotationUseSiteTarget? = null
): FirAnnotation { ): FirAnnotationCall {
var annotationUseSiteTarget: AnnotationUseSiteTarget? = null var annotationUseSiteTarget: AnnotationUseSiteTarget? = null
lateinit var constructorCalleePair: Pair<FirTypeRef, List<FirExpression>> lateinit var constructorCalleePair: Pair<FirTypeRef, List<FirExpression>>
unescapedAnnotation.forEachChildren { unescapedAnnotation.forEachChildren {
@@ -766,7 +766,7 @@ class DeclarationsConverter(
ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper) ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper)
CLASS -> container += convertClass(node) CLASS -> container += convertClass(node)
FUN -> container += convertFunctionDeclaration(node) as FirDeclaration FUN -> container += convertFunctionDeclaration(node) as FirDeclaration
PROPERTY -> container += convertPropertyDeclaration(node, classWrapper) KtNodeTypes.PROPERTY -> container += convertPropertyDeclaration(node, classWrapper)
TYPEALIAS -> container += convertTypeAlias(node) TYPEALIAS -> container += convertTypeAlias(node)
OBJECT_DECLARATION -> container += convertClass(node) OBJECT_DECLARATION -> container += convertClass(node)
CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) //anonymousInitializer CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) //anonymousInitializer
@@ -797,7 +797,7 @@ class DeclarationsConverter(
primaryConstructor?.forEachChildren { primaryConstructor?.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
MODIFIER_LIST -> modifiers = convertModifierList(it) MODIFIER_LIST -> modifiers = convertModifierList(it)
VALUE_PARAMETER_LIST -> valueParameters += convertValueParameters(it) VALUE_PARAMETER_LIST -> valueParameters += convertValueParameters(it, ValueParameterDeclaration.PRIMARY_CONSTRUCTOR)
} }
} }
@@ -1150,6 +1150,7 @@ class DeclarationsConverter(
symbol, symbol,
).also { ).also {
it.status = defaultAccessorStatus() it.status = defaultAccessorStatus()
it.annotations += modifiers.annotations.filterUseSiteTarget(PROPERTY_GETTER)
it.initContainingClassAttr() it.initContainingClassAttr()
} }
// NOTE: We still need the setter even for a val property so we can report errors (e.g., VAL_WITH_SETTER). // NOTE: We still need the setter even for a val property so we can report errors (e.g., VAL_WITH_SETTER).
@@ -1160,9 +1161,12 @@ class DeclarationsConverter(
moduleData, moduleData,
FirDeclarationOrigin.Source, FirDeclarationOrigin.Source,
returnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), returnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
propertyVisibility, symbol, propertyVisibility,
symbol,
parameterAnnotations = modifiers.annotations.filterUseSiteTarget(SETTER_PARAMETER)
).also { ).also {
it.status = defaultAccessorStatus() it.status = defaultAccessorStatus()
it.annotations += modifiers.annotations.filterUseSiteTarget(PROPERTY_SETTER)
it.initContainingClassAttr() it.initContainingClassAttr()
} }
} else null } else null
@@ -1190,7 +1194,10 @@ class DeclarationsConverter(
) )
} }
} }
annotations += modifiers.annotations annotations += if (isLocal) modifiers.annotations else modifiers.annotations.filter {
it.useSiteTarget != PROPERTY_GETTER &&
(!isVar || it.useSiteTarget != SETTER_PARAMETER && it.useSiteTarget != PROPERTY_SETTER)
}
}.also { }.also {
fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it) fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
} }
@@ -1287,7 +1294,9 @@ class DeclarationsConverter(
SET_KEYWORD -> isGetter = false SET_KEYWORD -> isGetter = false
MODIFIER_LIST -> modifiers = convertModifierList(it) MODIFIER_LIST -> modifiers = convertModifierList(it)
TYPE_REFERENCE -> returnType = convertType(it) TYPE_REFERENCE -> returnType = convertType(it)
VALUE_PARAMETER_LIST -> firValueParameters = convertSetterParameter(it, propertyTypeRefToUse) VALUE_PARAMETER_LIST -> firValueParameters = convertSetterParameter(
it, propertyTypeRefToUse, propertyModifiers.annotations.filterUseSiteTarget(SETTER_PARAMETER)
)
CONTRACT_EFFECT_LIST -> outerContractDescription = obtainContractDescription(it) CONTRACT_EFFECT_LIST -> outerContractDescription = obtainContractDescription(it)
BLOCK -> block = it BLOCK -> block = it
else -> if (it.isExpression()) expression = it else -> if (it.isExpression()) expression = it
@@ -1305,6 +1314,10 @@ class DeclarationsConverter(
isExternal = propertyModifiers.hasExternal() || modifiers.hasExternal() isExternal = propertyModifiers.hasExternal() || modifiers.hasExternal()
} }
val sourceElement = getterOrSetter.toFirSourceElement() val sourceElement = getterOrSetter.toFirSourceElement()
val accessorAdditionalAnnotations = propertyModifiers.annotations.filterUseSiteTarget(
if (isGetter) PROPERTY_GETTER
else PROPERTY_SETTER
)
if (block == null && expression == null) { if (block == null && expression == null) {
return FirDefaultPropertyAccessor return FirDefaultPropertyAccessor
.createGetterOrSetter( .createGetterOrSetter(
@@ -1318,6 +1331,7 @@ class DeclarationsConverter(
) )
.also { accessor -> .also { accessor ->
accessor.annotations += modifiers.annotations accessor.annotations += modifiers.annotations
accessor.annotations += accessorAdditionalAnnotations
accessor.status = status accessor.status = status
accessor.initContainingClassAttr() accessor.initContainingClassAttr()
} }
@@ -1333,6 +1347,7 @@ class DeclarationsConverter(
this.status = status this.status = status
context.firFunctionTargets += target context.firFunctionTargets += target
annotations += modifiers.annotations annotations += modifiers.annotations
annotations += accessorAdditionalAnnotations
if (!isGetter) { if (!isGetter) {
valueParameters += firValueParameters valueParameters += firValueParameters
@@ -1398,7 +1413,7 @@ class DeclarationsConverter(
} else { } else {
FirDefaultPropertyBackingField( FirDefaultPropertyBackingField(
moduleData = baseModuleData, moduleData = baseModuleData,
annotations = modifiers.annotations, annotations = mutableListOf(),
returnTypeRef = propertyReturnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), returnTypeRef = propertyReturnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
isVar = isVar, isVar = isVar,
propertySymbol = propertySymbol, propertySymbol = propertySymbol,
@@ -1420,7 +1435,7 @@ class DeclarationsConverter(
} }
} }
private fun obtainContractDescription(rawContractDescription: LighterASTNode): FirContractDescription? = private fun obtainContractDescription(rawContractDescription: LighterASTNode): FirContractDescription =
buildRawContractDescription { buildRawContractDescription {
source = rawContractDescription.toFirSourceElement() source = rawContractDescription.toFirSourceElement()
extractRawEffects(rawContractDescription, rawEffects) extractRawEffects(rawContractDescription, rawEffects)
@@ -1452,7 +1467,11 @@ class DeclarationsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter * @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.toFirValueParameter * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.toFirValueParameter
*/ */
private fun convertSetterParameter(setterParameter: LighterASTNode, propertyTypeRef: FirTypeRef): FirValueParameter { private fun convertSetterParameter(
setterParameter: LighterASTNode,
propertyTypeRef: FirTypeRef,
additionalAnnotations: List<FirAnnotation>
): FirValueParameter {
var modifiers = Modifier() var modifiers = Modifier()
lateinit var firValueParameter: FirValueParameter lateinit var firValueParameter: FirValueParameter
setterParameter.forEachChildren { setterParameter.forEachChildren {
@@ -1473,7 +1492,8 @@ class DeclarationsConverter(
isCrossinline = modifiers.hasCrossinline() || firValueParameter.isCrossinline isCrossinline = modifiers.hasCrossinline() || firValueParameter.isCrossinline
isNoinline = modifiers.hasNoinline() || firValueParameter.isNoinline isNoinline = modifiers.hasNoinline() || firValueParameter.isNoinline
isVararg = modifiers.hasVararg() || firValueParameter.isVararg isVararg = modifiers.hasVararg() || firValueParameter.isVararg
annotations += modifiers.annotations + firValueParameter.annotations annotations += firValueParameter.annotations
annotations += additionalAnnotations
} }
} }
@@ -2081,11 +2101,12 @@ class DeclarationsConverter(
*/ */
fun convertValueParameters( fun convertValueParameters(
valueParameters: LighterASTNode, valueParameters: LighterASTNode,
valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER,
additionalAnnotations: List<FirAnnotation> = emptyList()
): List<ValueParameter> { ): List<ValueParameter> {
return valueParameters.forEachChildrenReturnList { node, container -> return valueParameters.forEachChildrenReturnList { node, container ->
when (node.tokenType) { when (node.tokenType) {
VALUE_PARAMETER -> container += convertValueParameter(node, valueParameterDeclaration) VALUE_PARAMETER -> container += convertValueParameter(node, valueParameterDeclaration, additionalAnnotations)
} }
} }
} }
@@ -2095,7 +2116,8 @@ class DeclarationsConverter(
*/ */
fun convertValueParameter( fun convertValueParameter(
valueParameter: LighterASTNode, valueParameter: LighterASTNode,
valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER,
additionalAnnotations: List<FirAnnotation> = emptyList()
): ValueParameter { ): ValueParameter {
var modifiers = Modifier() var modifiers = Modifier()
var isVal = false var isVal = false
@@ -2128,7 +2150,14 @@ class DeclarationsConverter(
isCrossinline = modifiers.hasCrossinline() isCrossinline = modifiers.hasCrossinline()
isNoinline = modifiers.hasNoinline() isNoinline = modifiers.hasNoinline()
isVararg = modifiers.hasVararg() isVararg = modifiers.hasVararg()
annotations += modifiers.annotations val isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR
annotations += modifiers.annotations.filter {
!isFromPrimaryConstructor || it.useSiteTarget == null ||
it.useSiteTarget == CONSTRUCTOR_PARAMETER ||
it.useSiteTarget == RECEIVER ||
it.useSiteTarget == FILE
}
annotations += additionalAnnotations
} }
return ValueParameter(isVal, isVar, modifiers, firValueParameter, destructuringDeclaration) return ValueParameter(isVal, isVar, modifiers, firValueParameter, destructuringDeclaration)
} }
@@ -5,8 +5,10 @@
package org.jetbrains.kotlin.fir.lightTree.fir package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.Context import org.jetbrains.kotlin.fir.builder.Context
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.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
@@ -77,7 +79,11 @@ class ValueParameter(
isConst = modifiers.hasConst() isConst = modifiers.hasConst()
isLateInit = false isLateInit = false
} }
annotations += this@ValueParameter.firValueParameter.annotations annotations += modifiers.annotations.filter {
it.useSiteTarget == null || it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY ||
it.useSiteTarget == AnnotationUseSiteTarget.FIELD ||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
}
val defaultAccessorSource = propertySource?.fakeElement(FirFakeSourceElementKind.DefaultAccessor) val defaultAccessorSource = propertySource?.fakeElement(FirFakeSourceElementKind.DefaultAccessor)
getter = FirDefaultPropertyGetter( getter = FirDefaultPropertyGetter(
defaultAccessorSource, defaultAccessorSource,
@@ -86,7 +92,10 @@ class ValueParameter(
type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
modifiers.getVisibility(), modifiers.getVisibility(),
symbol, symbol,
).also { it.initContainingClassAttr(context) } ).also {
it.initContainingClassAttr(context)
it.annotations += modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.PROPERTY_GETTER)
}
setter = if (this.isVar) FirDefaultPropertySetter( setter = if (this.isVar) FirDefaultPropertySetter(
defaultAccessorSource, defaultAccessorSource,
moduleData, moduleData,
@@ -94,7 +103,11 @@ class ValueParameter(
type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
modifiers.getVisibility(), modifiers.getVisibility(),
symbol, symbol,
).also { it.initContainingClassAttr(context) } else null parameterAnnotations = modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.SETTER_PARAMETER)
).also {
it.initContainingClassAttr(context)
it.annotations += modifiers.annotations.filterUseSiteTarget(AnnotationUseSiteTarget.PROPERTY_SETTER)
} else null
}.apply { }.apply {
if (firValueParameter.isVararg) { if (firValueParameter.isVararg) {
this.isFromVararg = true this.isFromVararg = true
@@ -9,12 +9,12 @@ import com.intellij.lang.LighterASTNode
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
open class Modifier(var modifiers: Long = ModifierFlag.NONE.value) { open class Modifier(var modifiers: Long = ModifierFlag.NONE.value) {
val annotations: MutableList<FirAnnotation> = mutableListOf() val annotations: MutableList<FirAnnotationCall> = mutableListOf()
fun addModifier(modifier: LighterASTNode, isInClass: Boolean = false) { fun addModifier(modifier: LighterASTNode, isInClass: Boolean = false) {
when (val tokenType = modifier.tokenType) { when (val tokenType = modifier.tokenType) {
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.builder.buildRawContractDescription import org.jetbrains.kotlin.fir.contracts.builder.buildRawContractDescription
@@ -44,7 +45,6 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -183,8 +183,9 @@ open class RawFirBuilder(
open fun convertValueParameter( open fun convertValueParameter(
valueParameter: KtParameter, valueParameter: KtParameter,
defaultTypeRef: FirTypeRef? = null, defaultTypeRef: FirTypeRef? = null,
valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER,
): FirValueParameter = valueParameter.toFirValueParameter(defaultTypeRef, valueParameterDeclaration) additionalAnnotations: List<FirAnnotation> = emptyList()
): FirValueParameter = valueParameter.toFirValueParameter(defaultTypeRef, valueParameterDeclaration, additionalAnnotations)
private fun KtTypeReference?.toFirOrImplicitType(): FirTypeRef = private fun KtTypeReference?.toFirOrImplicitType(): FirTypeRef =
convertSafe() ?: buildImplicitTypeRef { convertSafe() ?: buildImplicitTypeRef {
@@ -365,6 +366,8 @@ open class RawFirBuilder(
propertyTypeRef: FirTypeRef, propertyTypeRef: FirTypeRef,
propertySymbol: FirPropertySymbol, propertySymbol: FirPropertySymbol,
isGetter: Boolean, isGetter: Boolean,
accessorAnnotationsFromProperty: List<FirAnnotation>,
parameterAnnotationsFromProperty: List<FirAnnotation>,
): FirPropertyAccessor? { ): FirPropertyAccessor? {
val accessorVisibility = val accessorVisibility =
if (this?.visibility != null && this.visibility != Visibilities.Unknown) this.visibility else property.visibility if (this?.visibility != null && this.visibility != Visibilities.Unknown) this.visibility else property.visibility
@@ -395,8 +398,11 @@ open class RawFirBuilder(
this.isGetter = isGetter this.isGetter = isGetter
this.status = status this.status = status
extractAnnotationsTo(this) extractAnnotationsTo(this)
annotations += accessorAnnotationsFromProperty
this@RawFirBuilder.context.firFunctionTargets += accessorTarget this@RawFirBuilder.context.firFunctionTargets += accessorTarget
extractValueParametersTo(this, propertyTypeRefToUse) extractValueParametersTo(
this, ValueParameterDeclaration.OTHER, propertyTypeRefToUse, parameterAnnotationsFromProperty
)
if (!isGetter && valueParameters.isEmpty()) { if (!isGetter && valueParameters.isEmpty()) {
valueParameters += buildDefaultSetterValueParameter { valueParameters += buildDefaultSetterValueParameter {
this.source = source.fakeElement(FirFakeSourceElementKind.DefaultAccessor) this.source = source.fakeElement(FirFakeSourceElementKind.DefaultAccessor)
@@ -404,6 +410,7 @@ open class RawFirBuilder(
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
returnTypeRef = propertyTypeRefToUse returnTypeRef = propertyTypeRefToUse
symbol = FirValueParameterSymbol(DEFAULT_VALUE_PARAMETER) symbol = FirValueParameterSymbol(DEFAULT_VALUE_PARAMETER)
annotations += parameterAnnotationsFromProperty
} }
} }
symbol = FirPropertyAccessorSymbol() symbol = FirPropertyAccessorSymbol()
@@ -433,12 +440,14 @@ open class RawFirBuilder(
propertyTypeRefToUse, propertyTypeRefToUse,
accessorVisibility, accessorVisibility,
propertySymbol, propertySymbol,
isGetter isGetter,
parameterAnnotations = parameterAnnotationsFromProperty
) )
.also { .also {
if (this != null) { if (this != null) {
it.extractAnnotationsFrom(this) it.extractAnnotationsFrom(this)
} }
it.annotations += accessorAnnotationsFromProperty
it.status = status it.status = status
it.initContainingClassAttr() it.initContainingClassAttr()
} }
@@ -512,8 +521,9 @@ open class RawFirBuilder(
} }
private fun KtParameter.toFirValueParameter( private fun KtParameter.toFirValueParameter(
defaultTypeRef: FirTypeRef? = null, defaultTypeRef: FirTypeRef?,
valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER valueParameterDeclaration: ValueParameterDeclaration,
additionalAnnotations: List<FirAnnotation>
): FirValueParameter { ): FirValueParameter {
val name = convertValueParameterName(nameAsSafeName, nameIdentifier?.node?.text, valueParameterDeclaration) val name = convertValueParameterName(nameAsSafeName, nameIdentifier?.node?.text, valueParameterDeclaration)
return buildValueParameter { return buildValueParameter {
@@ -533,7 +543,18 @@ open class RawFirBuilder(
isCrossinline = hasModifier(CROSSINLINE_KEYWORD) isCrossinline = hasModifier(CROSSINLINE_KEYWORD)
isNoinline = hasModifier(NOINLINE_KEYWORD) isNoinline = hasModifier(NOINLINE_KEYWORD)
isVararg = isVarArg isVararg = isVarArg
extractAnnotationsTo(this) val isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR
for (annotationEntry in annotationEntries) {
annotationEntry.convert<FirAnnotation>().takeIf {
!isFromPrimaryConstructor || it.useSiteTarget == null ||
it.useSiteTarget == CONSTRUCTOR_PARAMETER ||
it.useSiteTarget == RECEIVER ||
it.useSiteTarget == FILE
}?.let {
this.annotations += it
}
}
annotations += additionalAnnotations
} }
} }
@@ -549,6 +570,10 @@ open class RawFirBuilder(
} }
val propertySource = toFirSourceElement(FirFakeSourceElementKind.PropertyFromParameter) val propertySource = toFirSourceElement(FirFakeSourceElementKind.PropertyFromParameter)
val propertyName = nameAsSafeName val propertyName = nameAsSafeName
val parameterAnnotations = mutableListOf<FirAnnotationCall>()
for (annotationEntry in annotationEntries) {
parameterAnnotations += annotationEntry.convert<FirAnnotationCall>()
}
return buildProperty { return buildProperty {
source = propertySource source = propertySource
moduleData = baseModuleData moduleData = baseModuleData
@@ -576,7 +601,10 @@ open class RawFirBuilder(
type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
visibility, visibility,
symbol, symbol,
).also { it.initContainingClassAttr() } ).also { getter ->
getter.initContainingClassAttr()
getter.annotations += parameterAnnotations.filterUseSiteTarget(PROPERTY_GETTER)
}
setter = if (isMutable) FirDefaultPropertySetter( setter = if (isMutable) FirDefaultPropertySetter(
defaultAccessorSource, defaultAccessorSource,
baseModuleData, baseModuleData,
@@ -584,8 +612,16 @@ open class RawFirBuilder(
type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), type.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
visibility, visibility,
symbol, symbol,
).also { it.initContainingClassAttr() } else null parameterAnnotations = parameterAnnotations.filterUseSiteTarget(SETTER_PARAMETER)
extractAnnotationsTo(this) ).also { setter ->
setter.initContainingClassAttr()
setter.annotations += parameterAnnotations.filterUseSiteTarget(PROPERTY_SETTER)
} else null
annotations += parameterAnnotations.filter {
it.useSiteTarget == null || it.useSiteTarget == PROPERTY ||
it.useSiteTarget == FIELD ||
it.useSiteTarget == PROPERTY_DELEGATE_FIELD
}
dispatchReceiverType = currentDispatchReceiverType() dispatchReceiverType = currentDispatchReceiverType()
}.apply { }.apply {
@@ -678,10 +714,14 @@ open class RawFirBuilder(
private fun KtDeclarationWithBody.extractValueParametersTo( private fun KtDeclarationWithBody.extractValueParametersTo(
container: FirFunctionBuilder, container: FirFunctionBuilder,
valueParameterDeclaration: ValueParameterDeclaration,
defaultTypeRef: FirTypeRef? = null, defaultTypeRef: FirTypeRef? = null,
additionalAnnotations: List<FirAnnotation> = emptyList(),
) { ) {
for (valueParameter in valueParameters) { for (valueParameter in valueParameters) {
container.valueParameters += convertValueParameter(valueParameter, defaultTypeRef) container.valueParameters += convertValueParameter(
valueParameter, defaultTypeRef, valueParameterDeclaration, additionalAnnotations = additionalAnnotations
)
} }
} }
@@ -852,7 +892,7 @@ open class RawFirBuilder(
delegatedConstructor = firDelegatedCall delegatedConstructor = firDelegatedCall
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters) typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
this@toFirConstructor?.extractAnnotationsTo(this) this@toFirConstructor?.extractAnnotationsTo(this)
this@toFirConstructor?.extractValueParametersTo(this) this@toFirConstructor?.extractValueParametersTo(this, ValueParameterDeclaration.PRIMARY_CONSTRUCTOR)
this.body = body this.body = body
}.apply { }.apply {
containingClassForStaticMemberAttr = currentDispatchReceiverType()!!.lookupTag containingClassForStaticMemberAttr = currentDispatchReceiverType()!!.lookupTag
@@ -1401,7 +1441,7 @@ open class RawFirBuilder(
this@RawFirBuilder.context.firFunctionTargets += target this@RawFirBuilder.context.firFunctionTargets += target
extractAnnotationsTo(this) extractAnnotationsTo(this)
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters) typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
extractValueParametersTo(this) extractValueParametersTo(this, ValueParameterDeclaration.OTHER)
val (body, _) = buildFirBody() val (body, _) = buildFirBody()
@@ -1478,6 +1518,10 @@ open class RawFirBuilder(
initializer = propertyInitializer initializer = propertyInitializer
val propertyAnnotations = mutableListOf<FirAnnotationCall>()
for (annotationEntry in annotationEntries) {
propertyAnnotations += annotationEntry.convert<FirAnnotationCall>()
}
if (this@toFirProperty.isLocal) { if (this@toFirProperty.isLocal) {
isLocal = true isLocal = true
symbol = FirPropertySymbol(propertyName) symbol = FirPropertySymbol(propertyName)
@@ -1529,13 +1573,17 @@ open class RawFirBuilder(
this@toFirProperty, this@toFirProperty,
propertyType, propertyType,
propertySymbol = symbol, propertySymbol = symbol,
isGetter = true isGetter = true,
accessorAnnotationsFromProperty = propertyAnnotations.filterUseSiteTarget(PROPERTY_GETTER),
parameterAnnotationsFromProperty = emptyList()
) )
setter = this@toFirProperty.setter.toFirPropertyAccessor( setter = this@toFirProperty.setter.toFirPropertyAccessor(
this@toFirProperty, this@toFirProperty,
propertyType, propertyType,
propertySymbol = symbol, propertySymbol = symbol,
isGetter = false isGetter = false,
accessorAnnotationsFromProperty = propertyAnnotations.filterUseSiteTarget(PROPERTY_SETTER),
parameterAnnotationsFromProperty = propertyAnnotations.filterUseSiteTarget(SETTER_PARAMETER)
) )
status = FirDeclarationStatusImpl(visibility, modality).apply { status = FirDeclarationStatusImpl(visibility, modality).apply {
@@ -1575,7 +1623,10 @@ open class RawFirBuilder(
} }
} }
} }
extractAnnotationsTo(this) annotations += if (isLocal) propertyAnnotations else propertyAnnotations.filter {
it.useSiteTarget != PROPERTY_GETTER &&
(!isVar || it.useSiteTarget != SETTER_PARAMETER && it.useSiteTarget != PROPERTY_SETTER)
}
}.also { }.also {
if (!isLocal) { if (!isLocal) {
fillDanglingConstraintsTo(it) fillDanglingConstraintsTo(it)
@@ -1261,6 +1261,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
enum class ValueParameterDeclaration { enum class ValueParameterDeclaration {
OTHER, OTHER,
LAMBDA, LAMBDA,
CATCH CATCH,
PRIMARY_CONSTRUCTOR,
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.builder.buildLegacyRawContractDescription import org.jetbrains.kotlin.fir.contracts.builder.buildLegacyRawContractDescription
@@ -474,6 +475,7 @@ fun <T> FirPropertyBuilder.generateAccessorsByDelegate(
} }
if (isVar && (setter == null || setter is FirDefaultPropertyAccessor)) { if (isVar && (setter == null || setter is FirDefaultPropertyAccessor)) {
val annotations = setter?.annotations val annotations = setter?.annotations
val parameterAnnotations = setter?.valueParameters?.firstOrNull()?.annotations
setter = buildPropertyAccessor { setter = buildPropertyAccessor {
this.source = fakeSource this.source = fakeSource
this.moduleData = moduleData this.moduleData = moduleData
@@ -493,6 +495,9 @@ fun <T> FirPropertyBuilder.generateAccessorsByDelegate(
isCrossinline = false isCrossinline = false
isNoinline = false isNoinline = false
isVararg = false isVararg = false
if (parameterAnnotations != null) {
this.annotations.addAll(parameterAnnotations)
}
} }
valueParameters += parameter valueParameters += parameter
symbol = FirPropertyAccessorSymbol() symbol = FirPropertyAccessorSymbol()
@@ -580,6 +585,19 @@ fun FirQualifiedAccess.wrapWithSafeCall(receiver: FirExpression, source: FirSour
} }
} }
fun List<FirAnnotationCall>.filterUseSiteTarget(target: AnnotationUseSiteTarget): List<FirAnnotationCall> =
mapNotNull {
if (it.useSiteTarget != target) null
else buildAnnotationCall {
source = it.source?.fakeElement(FirFakeSourceElementKind.FromUseSiteTarget)
useSiteTarget = it.useSiteTarget
annotationTypeRef = it.annotationTypeRef
argumentList = it.argumentList
calleeReference = it.calleeReference
argumentMapping = it.argumentMapping
}
}
fun <T> FirCallableDeclaration.initContainingClassAttr(context: Context<T>) { fun <T> FirCallableDeclaration.initContainingClassAttr(context: Context<T>) {
containingClassForStaticMemberAttr = currentDispatchReceiverType(context)?.lookupTag ?: return containingClassForStaticMemberAttr = currentDispatchReceiverType(context)?.lookupTag ?: return
} }
@@ -69,8 +69,12 @@ fun getDeprecationsFromAccessors(
currentVersion: ApiVersion currentVersion: ApiVersion
): DeprecationsPerUseSite { ): DeprecationsPerUseSite {
val perUseSite = buildMap<AnnotationUseSiteTarget, DeprecationInfo> { val perUseSite = buildMap<AnnotationUseSiteTarget, DeprecationInfo> {
setter?.getDeprecationInfos(currentVersion)?.all?.let { put(AnnotationUseSiteTarget.PROPERTY_SETTER, it) } val setterDeprecations = setter?.getDeprecationInfos(currentVersion)
getter?.getDeprecationInfos(currentVersion)?.all?.let { put(AnnotationUseSiteTarget.PROPERTY_GETTER, it) } setterDeprecations?.all?.let { put(AnnotationUseSiteTarget.PROPERTY_SETTER, it) }
setterDeprecations?.bySpecificSite?.let { putAll(it) }
val getterDeprecations = getter?.getDeprecationInfos(currentVersion)
getterDeprecations?.all?.let { put(AnnotationUseSiteTarget.PROPERTY_GETTER, it) }
getterDeprecations?.bySpecificSite?.let { putAll(it) }
} }
return if (perUseSite.isEmpty()) EmptyDeprecationsPerUseSite else DeprecationsPerUseSite(null, perUseSite) return if (perUseSite.isEmpty()) EmptyDeprecationsPerUseSite else DeprecationsPerUseSite(null, perUseSite)
} }
@@ -180,6 +180,9 @@ sealed class FirFakeSourceElementKind : FirSourceElementKind() {
// for the implicit field storing the delegated object for class delegation // for the implicit field storing the delegated object for class delegation
// with a fake source that refers to the KtExpression that creates the delegate // with a fake source that refers to the KtExpression that creates the delegate
object ClassDelegationField : FirFakeSourceElementKind() object ClassDelegationField : FirFakeSourceElementKind()
// for annotation moved to another element due to annotation use-site target
object FromUseSiteTarget : FirFakeSourceElementKind()
} }
sealed class FirSourceElement { sealed class FirSourceElement {
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildDefaultSetterValueParameter import org.jetbrains.kotlin.fir.declarations.builder.buildDefaultSetterValueParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
@@ -72,12 +73,16 @@ abstract class FirDefaultPropertyAccessor(
propertyTypeRef: FirTypeRef, propertyTypeRef: FirTypeRef,
visibility: Visibility, visibility: Visibility,
propertySymbol: FirPropertySymbol, propertySymbol: FirPropertySymbol,
isGetter: Boolean isGetter: Boolean,
parameterAnnotations: List<FirAnnotation> = emptyList(),
): FirDefaultPropertyAccessor { ): FirDefaultPropertyAccessor {
return if (isGetter) { return if (isGetter) {
FirDefaultPropertyGetter(source, moduleData, origin, propertyTypeRef, visibility, propertySymbol, Modality.FINAL) FirDefaultPropertyGetter(source, moduleData, origin, propertyTypeRef, visibility, propertySymbol, Modality.FINAL)
} else { } else {
FirDefaultPropertySetter(source, moduleData, origin, propertyTypeRef, visibility, propertySymbol, Modality.FINAL) FirDefaultPropertySetter(
source, moduleData, origin, propertyTypeRef, visibility, propertySymbol, Modality.FINAL,
parameterAnnotations = parameterAnnotations
)
} }
} }
} }
@@ -116,7 +121,8 @@ class FirDefaultPropertySetter(
propertySymbol: FirPropertySymbol, propertySymbol: FirPropertySymbol,
modality: Modality = Modality.FINAL, modality: Modality = Modality.FINAL,
effectiveVisibility: EffectiveVisibility? = null, effectiveVisibility: EffectiveVisibility? = null,
symbol: FirPropertyAccessorSymbol = FirPropertyAccessorSymbol() symbol: FirPropertyAccessorSymbol = FirPropertyAccessorSymbol(),
parameterAnnotations: List<FirAnnotation> = emptyList(),
) : FirDefaultPropertyAccessor( ) : FirDefaultPropertyAccessor(
source, source,
moduleData, moduleData,
@@ -129,6 +135,7 @@ class FirDefaultPropertySetter(
this@builder.origin = origin this@builder.origin = origin
this@builder.returnTypeRef = propertyTypeRef this@builder.returnTypeRef = propertyTypeRef
this@builder.symbol = FirValueParameterSymbol(Name.special("<default-setter-parameter>")) this@builder.symbol = FirValueParameterSymbol(Name.special("<default-setter-parameter>"))
this@builder.annotations += parameterAnnotations
} }
), ),
propertySymbol, propertySymbol,
@@ -1,5 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER // !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +ProhibitRepeatedUseSiteTargetAnnotations // !LANGUAGE: -ProhibitRepeatedUseSiteTargetAnnotations
// Ann is not repeatable // Ann is not repeatable
annotation class Ann(val x: Int) annotation class Ann(val x: Int)
@@ -17,6 +17,6 @@ var c = " "
set(@Ann(20) x) {} set(@Ann(20) x) {}
<!REPEATED_ANNOTATION!>@get:Ann(10)<!> <!REPEATED_ANNOTATION!>@get:Ann(10)<!>
<!REPEATED_ANNOTATION, REPEATED_ANNOTATION!>@get:Ann(20)<!> <!REPEATED_ANNOTATION!>@get:Ann(20)<!>
val d: String val d: String
@Ann(30) <!REPEATED_ANNOTATION!>@Ann(40)<!> get() = "foo" @Ann(30) <!REPEATED_ANNOTATION!>@Ann(40)<!> get() = "foo"
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER // !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: -ProhibitRepeatedUseSiteTargetAnnotations // !LANGUAGE: -ProhibitRepeatedUseSiteTargetAnnotations
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER // !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +ProhibitRepeatedUseSiteTargetAnnotations // !LANGUAGE: +ProhibitRepeatedUseSiteTargetAnnotations
@@ -46,12 +46,12 @@ annotation class fieldOrPropAnn
annotation class getSetAndParamAnn annotation class getSetAndParamAnn
public class B(<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@param:fieldOrPropAnn<!> @fieldOrPropAnn val x: Int, public class B(<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@param:fieldOrPropAnn<!> @fieldOrPropAnn val x: Int,
@property:fieldOrPropAnn <!REPEATED_ANNOTATION, REPEATED_ANNOTATION!>@fieldOrPropAnn<!> val y: Int) { @property:fieldOrPropAnn <!REPEATED_ANNOTATION!>@fieldOrPropAnn<!> val y: Int) {
@fieldOrPropAnn @field:fieldOrPropAnn @fieldOrPropAnn @field:fieldOrPropAnn
val z: Int = 42 val z: Int = 42
<!WRONG_ANNOTATION_TARGET!>@getSetAndParamAnn<!> <!WRONG_ANNOTATION_TARGET!>@getSetAndParamAnn<!>
<!REPEATED_ANNOTATION!>@setparam:getSetAndParamAnn<!> @setparam:getSetAndParamAnn
var w: Int var w: Int
@getSetAndParamAnn <!REPEATED_ANNOTATION!>@get:getSetAndParamAnn<!> get() = 0 @getSetAndParamAnn <!REPEATED_ANNOTATION!>@get:getSetAndParamAnn<!> get() = 0
// See KT-15470: fake INAPPLICABLE_TARGET_ON_PROPERTY // See KT-15470: fake INAPPLICABLE_TARGET_ON_PROPERTY
@@ -1,13 +0,0 @@
interface Test {
<!JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION!>@get:JvmStatic
val a: Int<!>
@get:JvmName("1")
val b: Int
@get:Synchronized
val c: Int
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@get:JvmOverloads<!>
val d: Int
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface Test { interface Test {
<!JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION!>@get:JvmStatic <!JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION!>@get:JvmStatic
val a: Int<!> val a: Int<!>
@@ -89,7 +89,7 @@ class D: AB() {
} }
interface Intf { interface Intf {
@get:JvmName("getBar") // no error in IDE <!INAPPLICABLE_JVM_NAME!>@get:JvmName("getBar")<!> // no error in IDE
@set:JvmName("setBar") // no error in IDE <!INAPPLICABLE_JVM_NAME!>@set:JvmName("setBar")<!> // no error in IDE
var foo: Int var foo: Int
} }
@@ -19,6 +19,6 @@ var z: Int = 44
fun user(): Int { fun user(): Int {
<!OPT_IN_USAGE_ERROR!>x<!> = 10 <!OPT_IN_USAGE_ERROR!>x<!> = 10
<!OPT_IN_USAGE_ERROR!>y<!> = 5 <!OPT_IN_USAGE_ERROR!>y<!> = 5
<!OPT_IN_USAGE_ERROR!>x<!> = 15 <!OPT_IN_USAGE_ERROR!>z<!> = 15
return x + <!OPT_IN_USAGE_ERROR!>y<!> + z return x + <!OPT_IN_USAGE_ERROR!>y<!> + z
} }