[K2] Disappeared OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN (4)
Added checking usages of markers as qualifiers in properties and function calls. ^KT-59998
This commit is contained in:
committed by
Space Team
parent
72d69e16c4
commit
93ebd83ecd
+33
@@ -5,16 +5,49 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker.isExperimentalMarker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.getContainingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
|
||||
object FirOptInUsageQualifierChecker : FirResolvedQualifierChecker() {
|
||||
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
checkNotAcceptedExperimentalities(expression, context, reporter)
|
||||
checkMarkerUsedAsQualifier(expression, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkNotAcceptedExperimentalities(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val symbol = expression.symbol ?: return
|
||||
with(FirOptInUsageBaseChecker) {
|
||||
val experimentalities = symbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType = null)
|
||||
reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkMarkerUsedAsQualifier(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val containingElements = context.containingElements
|
||||
val parentExpression = containingElements.lastOrNull { it is FirQualifiedAccessExpression && it.dispatchReceiver == expression }
|
||||
val source = parentExpression?.source ?: return
|
||||
expression.symbol?.checkContainingClasses(source, context, reporter)
|
||||
}
|
||||
|
||||
private tailrec fun FirClassLikeSymbol<*>.checkContainingClasses(
|
||||
source: KtSourceElement,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
) {
|
||||
if (isExperimentalMarker(context.session) && context.containingDeclarations.none { it.symbol == this }) {
|
||||
reporter.reportOn(source, FirErrors.OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN, context)
|
||||
}
|
||||
|
||||
val containingClassSymbol = this.getContainingClassLookupTag()?.toSymbol(context.session) ?: return
|
||||
containingClassSymbol.checkContainingClasses(source, context, reporter)
|
||||
}
|
||||
}
|
||||
+10
-2
@@ -51,11 +51,16 @@ object A {
|
||||
class NestedClass() {
|
||||
class NestedClass2
|
||||
|
||||
fun f12(m: NestedClass2){}
|
||||
fun f12(m: NestedClass2){
|
||||
val x = value
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val value = 42
|
||||
|
||||
fun bar(){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +79,10 @@ fun f9(m: <!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>
|
||||
// Usages of markers as qualifiers are errors as well (we can lift this restriction for select cases)
|
||||
|
||||
fun f10(m: <!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.NestedClass<!>) {
|
||||
A.Marker.value
|
||||
val a = <!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.value<!>
|
||||
<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.Companion.value<!>
|
||||
<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.bar()<!>
|
||||
<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.Companion.bar()<!>
|
||||
}
|
||||
|
||||
fun f11(m: <!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>A.Marker.NestedClass.NestedClass2<!>) {}
|
||||
|
||||
+10
-2
@@ -51,11 +51,16 @@ object A {
|
||||
class NestedClass() {
|
||||
class NestedClass2
|
||||
|
||||
fun f12(m: NestedClass2){}
|
||||
fun f12(m: NestedClass2){
|
||||
val x = value
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val value = 42
|
||||
|
||||
fun bar(){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +79,10 @@ fun f9(m: <!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>
|
||||
// Usages of markers as qualifiers are errors as well (we can lift this restriction for select cases)
|
||||
|
||||
fun f10(m: A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.NestedClass) {
|
||||
A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.value
|
||||
val a = A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.value
|
||||
A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.Companion.value
|
||||
A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.bar()
|
||||
A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.Companion.bar()
|
||||
}
|
||||
|
||||
fun f11(m: A.<!OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN!>Marker<!>.NestedClass.NestedClass2) {}
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ package test {
|
||||
public companion object Companion {
|
||||
private constructor Companion()
|
||||
public const final val value: kotlin.Int = 42
|
||||
public final fun bar(): kotlin.Unit
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user