[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
|
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.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
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.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() {
|
object FirOptInUsageQualifierChecker : FirResolvedQualifierChecker() {
|
||||||
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
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
|
val symbol = expression.symbol ?: return
|
||||||
with(FirOptInUsageBaseChecker) {
|
with(FirOptInUsageBaseChecker) {
|
||||||
val experimentalities = symbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType = null)
|
val experimentalities = symbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType = null)
|
||||||
reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter)
|
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 NestedClass() {
|
||||||
class NestedClass2
|
class NestedClass2
|
||||||
|
|
||||||
fun f12(m: NestedClass2){}
|
fun f12(m: NestedClass2){
|
||||||
|
val x = value
|
||||||
|
bar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val value = 42
|
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)
|
// 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<!>) {
|
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<!>) {}
|
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 NestedClass() {
|
||||||
class NestedClass2
|
class NestedClass2
|
||||||
|
|
||||||
fun f12(m: NestedClass2){}
|
fun f12(m: NestedClass2){
|
||||||
|
val x = value
|
||||||
|
bar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val value = 42
|
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)
|
// 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) {
|
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) {}
|
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 {
|
public companion object Companion {
|
||||||
private constructor Companion()
|
private constructor Companion()
|
||||||
public const final val value: kotlin.Int = 42
|
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 equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
Reference in New Issue
Block a user