diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt index 8a45ec983ce..896348d86f4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt @@ -206,8 +206,10 @@ object FirOptInUsageBaseChecker { Experimentality.Severity.WARNING -> FirErrors.OPT_IN_USAGE to "should" Experimentality.Severity.ERROR -> FirErrors.OPT_IN_USAGE_ERROR to "must" } - val reportedMessage = message?.takeIf { it.isNotBlank() } ?: "This declaration is experimental and its usage $verb be marked" - reporter.reportOn(element.source, diagnostic, annotationClassId.asSingleFqName(), reportedMessage, context) + val fqName = annotationClassId.asSingleFqName() + val reportedMessage = message?.takeIf { it.isNotBlank() } + ?: OptInNames.buildDefaultDiagnosticMessage(OptInNames.buildMessagePrefix(verb), fqName) + reporter.reportOn(element.source, diagnostic, fqName, reportedMessage, context) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index d4588f04d7c..5a5855d581c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -118,18 +118,18 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { private val WARNING_LEVEL = Name.identifier("WARNING") private val ERROR_LEVEL = Name.identifier("ERROR") - internal fun getDefaultDiagnosticMessage(prefix: String) = fun(fqName: FqName): String { - return "$prefix with '@${fqName.asString()}' or '@OptIn(${fqName.asString()}::class)'" + internal fun getDefaultDiagnosticMessage(prefix: String): (FqName) -> String = { fqName: FqName -> + OptInNames.buildDefaultDiagnosticMessage(prefix, fqName) } private val USAGE_DIAGNOSTICS = ExperimentalityDiagnostics( warning = ExperimentalityDiagnostic2( Errors.OPT_IN_USAGE, - getDefaultDiagnosticMessage("This declaration is experimental and its usage should be marked") + getDefaultDiagnosticMessage(OptInNames.buildMessagePrefix("should")) ), error = ExperimentalityDiagnostic2( Errors.OPT_IN_USAGE_ERROR, - getDefaultDiagnosticMessage("This declaration is experimental and its usage must be marked") + getDefaultDiagnosticMessage(OptInNames.buildMessagePrefix("must")) ), futureError = ExperimentalityDiagnostic2( Errors.OPT_IN_USAGE_FUTURE_ERROR, diff --git a/compiler/testData/cli/jvm/optInEmptyMessage.out b/compiler/testData/cli/jvm/optInEmptyMessage.out index d9ea1ee1b33..168a6ceb01f 100644 --- a/compiler/testData/cli/jvm/optInEmptyMessage.out +++ b/compiler/testData/cli/jvm/optInEmptyMessage.out @@ -1,4 +1,4 @@ -compiler/testData/cli/jvm/optInEmptyMessage.kt:8:5: error: this declaration is experimental and its usage must be marked with '@EmptyMarker' or '@OptIn(EmptyMarker::class)' +compiler/testData/cli/jvm/optInEmptyMessage.kt:8:5: error: this declaration needs OptIn. Its usage must be marked with '@EmptyMarker' or '@OptIn(EmptyMarker::class)' foo() ^ COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/optInEmptyMessageFir.args b/compiler/testData/cli/jvm/optInEmptyMessageFir.args index 360bd46a8dd..f9f8c27de5f 100644 --- a/compiler/testData/cli/jvm/optInEmptyMessageFir.args +++ b/compiler/testData/cli/jvm/optInEmptyMessageFir.args @@ -1,4 +1,4 @@ -$TESTDATA_DIR$/optInEmptyMessage.kt +$TESTDATA_DIR$/optInEmptyMessageFir.kt -d $TEMP_DIR$ -opt-in=kotlin.RequiresOptIn diff --git a/compiler/testData/cli/jvm/optInEmptyMessageFir.out b/compiler/testData/cli/jvm/optInEmptyMessageFir.out index 09585a6ac28..a3a60f4d360 100644 --- a/compiler/testData/cli/jvm/optInEmptyMessageFir.out +++ b/compiler/testData/cli/jvm/optInEmptyMessageFir.out @@ -1,7 +1,7 @@ warning: ATTENTION! This build uses in-dev FIR: -Xuse-fir -compiler/testData/cli/jvm/optInEmptyMessage.kt:8:5: error: this declaration is experimental and its usage must be marked +compiler/testData/cli/jvm/optInEmptyMessage.kt:8:5: error: this declaration needs OptIn. Its usage must be marked with '@EmptyMarker' or '@OptIn(EmptyMarker::class)' foo() ^ COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.out b/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.out index e1c6fceaf63..d96ed48710c 100644 --- a/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.out +++ b/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.out @@ -1,17 +1,17 @@ warning: language version 1.4 is deprecated and its support will be removed in a future version of Kotlin -compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:2:13: warning: this declaration is experimental and its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:2:13: warning: this declaration needs OptIn. Its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' fun test(p: ULong) { ^ -compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:3:12: warning: this declaration is experimental and its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:3:12: warning: this declaration needs OptIn. Its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' val z: ULong = p ^ -compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:3:20: warning: this declaration is experimental and its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:3:20: warning: this declaration needs OptIn. Its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' val z: ULong = p ^ -compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:4:5: warning: this declaration is experimental and its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:4:5: warning: this declaration needs OptIn. Its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' z.inv() ^ -compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:4:7: warning: this declaration is experimental and its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker2.kt:4:7: warning: this declaration needs OptIn. Its usage should be marked with '@kotlin.ExperimentalUnsignedTypes' or '@OptIn(kotlin.ExperimentalUnsignedTypes::class)' z.inv() ^ OK diff --git a/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/OptInNames.kt b/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/OptInNames.kt index 47769f356eb..2ef0955a402 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/OptInNames.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/OptInNames.kt @@ -38,4 +38,11 @@ object OptInNames { ) @Suppress("unused") val USE_EXPERIMENTAL_FQ_NAMES = OPT_IN_FQ_NAMES + + fun buildDefaultDiagnosticMessage(prefix: String, fqName: FqName): String { + return "$prefix with '@${fqName.asString()}' or '@OptIn(${fqName.asString()}::class)'" + } + + fun buildMessagePrefix(verb: String): String = + "This declaration needs OptIn. Its usage $verb be marked" } \ No newline at end of file