@@ -48,7 +48,7 @@ object FirOptInUsageBaseChecker {
48
48
val severity : Severity ,
49
49
val message : String? ,
50
50
val supertypeName : String? = null ,
51
- val fromSupertype : Boolean = false
51
+ val fromSupertype : Boolean = false ,
52
52
) {
53
53
enum class Severity { WARNING , ERROR }
54
54
companion object {
@@ -77,7 +77,7 @@ object FirOptInUsageBaseChecker {
77
77
// Note: receiver is an OptIn marker class and parameter is an annotated member owner class / self class name
78
78
fun FirRegularClassSymbol.loadExperimentalityForMarkerAnnotation (
79
79
session : FirSession ,
80
- annotatedOwnerClassName : String? = null
80
+ annotatedOwnerClassName : String? = null,
81
81
): Experimentality ? {
82
82
lazyResolveToPhase(FirResolvePhase .BODY_RESOLVE )
83
83
@OptIn(SymbolInternals ::class )
@@ -93,7 +93,7 @@ object FirOptInUsageBaseChecker {
93
93
private fun FirDeclaration.loadExperimentalitiesFromAnnotationTo (
94
94
session : FirSession ,
95
95
result : MutableCollection <Experimentality >,
96
- fromSupertype : Boolean
96
+ fromSupertype : Boolean ,
97
97
) {
98
98
for (annotation in annotations) {
99
99
val annotationType = annotation.annotationTypeRef.coneType as ? ConeClassLikeType ? : continue
@@ -110,26 +110,28 @@ object FirOptInUsageBaseChecker {
110
110
if (fromSupertype) {
111
111
if (annotationType.lookupTag.classId == OptInNames .SUBCLASS_OPT_IN_REQUIRED_CLASS_ID ) {
112
112
val annotationClass = annotation.findArgumentByName(OptInNames .OPT_IN_ANNOTATION_CLASS ) ? : continue
113
- result.addIfNotNull(
114
- annotationClass.extractClassFromArgument(session)
115
- ?.loadExperimentalityForMarkerAnnotation(session)?.copy(fromSupertype = true )
116
- )
113
+ val classes = annotationClass.extractClassesFromArgument(session)
114
+ classes.forEach { klass ->
115
+ result.addIfNotNull(
116
+ klass.loadExperimentalityForMarkerAnnotation(session)?.copy(fromSupertype = true )
117
+ )
118
+ }
117
119
}
118
120
}
119
121
}
120
122
}
121
123
122
124
fun loadExperimentalitiesFromTypeArguments (
123
125
context : CheckerContext ,
124
- typeArguments : List <FirTypeProjection >
126
+ typeArguments : List <FirTypeProjection >,
125
127
): Set <Experimentality > {
126
128
if (typeArguments.isEmpty()) return emptySet()
127
129
return loadExperimentalitiesFromConeArguments(context, typeArguments.map { it.toConeTypeProjection() })
128
130
}
129
131
130
132
fun loadExperimentalitiesFromConeArguments (
131
133
context : CheckerContext ,
132
- typeArguments : List <ConeTypeProjection >
134
+ typeArguments : List <ConeTypeProjection >,
133
135
): Set <Experimentality > {
134
136
if (typeArguments.isEmpty()) return emptySet()
135
137
val result = SmartSet .create<Experimentality >()
@@ -140,7 +142,7 @@ object FirOptInUsageBaseChecker {
140
142
}
141
143
142
144
fun FirBasedSymbol <* >.loadExperimentalities (
143
- context : CheckerContext , fromSetter : Boolean , dispatchReceiverType : ConeKotlinType ?
145
+ context : CheckerContext , fromSetter : Boolean , dispatchReceiverType : ConeKotlinType ? ,
144
146
): Set <Experimentality > = loadExperimentalities(
145
147
context, knownExperimentalities = null , visited = mutableSetOf (), fromSetter, dispatchReceiverType, fromSupertype = false
146
148
)
@@ -199,7 +201,7 @@ object FirOptInUsageBaseChecker {
199
201
visited : MutableSet <FirDeclaration >,
200
202
fromSetter : Boolean ,
201
203
dispatchReceiverType : ConeKotlinType ? ,
202
- result : SmartSet <Experimentality >
204
+ result : SmartSet <Experimentality >,
203
205
) {
204
206
val parentClassSymbol = containingClassLookupTag()?.toRegularClassSymbol(context.session)
205
207
if (this is FirConstructor ) {
@@ -242,7 +244,7 @@ object FirOptInUsageBaseChecker {
242
244
symbol : FirBasedSymbol <* >,
243
245
context : CheckerContext ,
244
246
visited : MutableSet <FirDeclaration >,
245
- result : SmartSet <Experimentality >
247
+ result : SmartSet <Experimentality >,
246
248
) {
247
249
when (this ) {
248
250
is FirRegularClass -> if (symbol is FirRegularClassSymbol ) {
@@ -260,7 +262,7 @@ object FirOptInUsageBaseChecker {
260
262
private fun ConeKotlinType?.addExperimentalities (
261
263
context : CheckerContext ,
262
264
result : SmartSet <Experimentality >,
263
- visited : MutableSet <FirDeclaration > = mutableSetOf()
265
+ visited : MutableSet <FirDeclaration > = mutableSetOf(),
264
266
) {
265
267
if (this !is ConeClassLikeType ) return
266
268
lookupTag.toSymbol(context.session)?.loadExperimentalities(
@@ -274,7 +276,7 @@ object FirOptInUsageBaseChecker {
274
276
// Note: receiver is an OptIn marker class and parameter is an annotated member owner class / self class name
275
277
private fun FirRegularClass.loadExperimentalityForMarkerAnnotation (
276
278
session : FirSession ,
277
- annotatedOwnerClassName : String? = null
279
+ annotatedOwnerClassName : String? = null,
278
280
): Experimentality ? {
279
281
val experimental = getAnnotationByClassId(OptInNames .REQUIRES_OPT_IN_CLASS_ID , session)
280
282
? : return null
@@ -337,7 +339,7 @@ object FirOptInUsageBaseChecker {
337
339
experimentalities : Collection <Experimentality >,
338
340
symbol : FirCallableSymbol <* >,
339
341
context : CheckerContext ,
340
- reporter : DiagnosticReporter
342
+ reporter : DiagnosticReporter ,
341
343
) {
342
344
for ((annotationClassId, severity, markerMessage, supertypeName) in experimentalities) {
343
345
if (! symbol.fir.isExperimentalityAcceptable(context.session, annotationClassId, fromSupertype = false ) &&
@@ -361,7 +363,7 @@ object FirOptInUsageBaseChecker {
361
363
private fun isExperimentalityAcceptableInContext (
362
364
annotationClassId : ClassId ,
363
365
context : CheckerContext ,
364
- fromSupertype : Boolean
366
+ fromSupertype : Boolean ,
365
367
): Boolean {
366
368
val languageVersionSettings = context.session.languageVersionSettings
367
369
val fqNameAsString = annotationClassId.asFqNameString()
@@ -379,7 +381,7 @@ object FirOptInUsageBaseChecker {
379
381
private fun FirAnnotationContainer.isExperimentalityAcceptable (
380
382
session : FirSession ,
381
383
annotationClassId : ClassId ,
382
- fromSupertype : Boolean
384
+ fromSupertype : Boolean ,
383
385
): Boolean {
384
386
return getAnnotationByClassId(annotationClassId, session) != null ||
385
387
isAnnotatedWithOptIn(annotationClassId, session) ||
@@ -396,7 +398,7 @@ object FirOptInUsageBaseChecker {
396
398
@OptIn(SymbolInternals ::class )
397
399
private fun FirAnnotationContainer.primaryConstructorParameterIsExperimentalityAcceptable (
398
400
session : FirSession ,
399
- annotationClassId : ClassId
401
+ annotationClassId : ClassId ,
400
402
): Boolean {
401
403
if (this !is FirProperty ) return false
402
404
val parameterSymbol = correspondingValueParameterFromPrimaryConstructor ? : return false
@@ -420,15 +422,15 @@ object FirOptInUsageBaseChecker {
420
422
421
423
private fun FirAnnotationContainer.isAnnotatedWithSubclassOptInRequired (
422
424
session : FirSession ,
423
- annotationClassId : ClassId
425
+ annotationClassId : ClassId ,
424
426
): Boolean {
425
427
for (annotation in annotations) {
426
428
val coneType = annotation.annotationTypeRef.coneType as ? ConeClassLikeType
427
429
if (coneType?.lookupTag?.classId != OptInNames .SUBCLASS_OPT_IN_REQUIRED_CLASS_ID ) {
428
430
continue
429
431
}
430
432
val annotationClass = annotation.findArgumentByName(OptInNames .OPT_IN_ANNOTATION_CLASS ) ? : continue
431
- if (annotationClass.extractClassFromArgument (session)?. classId == annotationClassId) {
433
+ if (annotationClass.extractClassesFromArgument (session).any { it. classId == annotationClassId } ) {
432
434
return true
433
435
}
434
436
}
0 commit comments