[Diagnostics] Forbid the term "useless" in diagnostic messages and IDs

#KT-80925 Fixed
diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArgumentsConfigurator.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArgumentsConfigurator.kt
index 859bfb6..d1de456 100644
--- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArgumentsConfigurator.kt
+++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArgumentsConfigurator.kt
@@ -257,7 +257,10 @@
             )
         }
     } else if (suppressApiVersionGreaterThanLanguageVersionError) {
-        collector.report(WARNING, "Useless suppress -Xsuppress-api-version-greater-than-language-version-error.")
+        collector.report(
+            WARNING,
+            "-Xsuppress-api-version-greater-than-language-version-error was passed, but the API version (${apiVersion.versionString}) is not greater than the language version (${languageVersion.versionString})."
+        )
     }
 }
 
diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt
index a4ca199..f392a33 100644
--- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt
+++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt
@@ -200,7 +200,7 @@
         )
         map.put(JS_STATIC_NOT_IN_CLASS_COMPANION, "Only members of class companion objects can be annotated with '@JsStatic'.")
         map.put(JS_STATIC_ON_NON_PUBLIC_MEMBER, "Only public members of class companion objects can be annotated with '@JsStatic'.")
-        map.put(JS_STATIC_ON_CONST, "'@JsStatic' annotation is useless for const.")
+        map.put(JS_STATIC_ON_CONST, "'@JsStatic' annotation is redundant for const properties.")
 
         map.put(
             EXPOSED_NOT_EXPORTED_SUPER_INTERFACE,
diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt
index c1524f3..de356dd 100644
--- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt
+++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt
@@ -310,7 +310,7 @@
         )
         map.put(
             JVM_STATIC_ON_CONST_OR_JVM_FIELD,
-            "'@JvmStatic' annotation is useless for const or '@JvmField' properties.",
+            "'@JvmStatic' annotation is redundant for const or '@JvmField' properties.",
         )
         map.put(
             JVM_STATIC_ON_EXTERNAL_IN_INTERFACE,
@@ -328,7 +328,7 @@
         map.put(INAPPLICABLE_JVM_EXPOSE_BOXED_WITH_NAME, "'@JvmExposeBoxed' with name is applicable only to functions, getters and setters.")
         map.put(
             USELESS_JVM_EXPOSE_BOXED,
-            "Useless '@JvmExposeBoxed', it is a callable declaration with no inline value class in its signature."
+            "'@JvmExposeBoxed' has no effect when applied to a callable declaration with no inline value class in its signature."
         )
         map.put(
             JVM_EXPOSE_BOXED_CANNOT_EXPOSE_SUSPEND,
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt
index 2870df9..37aff08 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt
@@ -2744,7 +2744,7 @@
             ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE,
             "Anonymous functions cannot specify default values for their parameters."
         )
-        map.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless.")
+        map.put(USELESS_VARARG_ON_PARAMETER, "The 'vararg' modifier is ignored on parameters of anonymous functions.")
         map.put(
             FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS,
             "Functional interface must have exactly one abstract function."
@@ -3251,8 +3251,8 @@
         map.put(NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION, "Non-null assertion (!!) called on a lambda expression.")
         map.put(NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE, "Non-null assertion (!!) called on a callable reference expression.")
         map.put(USELESS_ELVIS, "Elvis operator (?:) always returns the left operand of non-nullable type ''{0}''.", RENDER_TYPE)
-        map.put(USELESS_ELVIS_RIGHT_IS_NULL, "Right operand of elvis operator (?:) is useless if it is null.")
-        map.put(USELESS_ELVIS_LEFT_IS_NULL, "Elvis operator (?:) is useless if the left operand is null.")
+        map.put(USELESS_ELVIS_RIGHT_IS_NULL, "Elvis operator (?:) is redundant if the right operand is always null.")
+        map.put(USELESS_ELVIS_LEFT_IS_NULL, "Elvis operator (?:) is redundant if the left operand is always null.")
 
         // Casts and is-checks
         map.put(CANNOT_CHECK_FOR_ERASED, "Cannot check for instance of erased type ''{0}''.", RENDER_TYPE)
diff --git a/compiler/testData/cli/jvm/apiVersion/apiVersionGreaterThanLanguageSuppressUseless.out b/compiler/testData/cli/jvm/apiVersion/apiVersionGreaterThanLanguageSuppressUseless.out
index e434355..badb909 100644
--- a/compiler/testData/cli/jvm/apiVersion/apiVersionGreaterThanLanguageSuppressUseless.out
+++ b/compiler/testData/cli/jvm/apiVersion/apiVersionGreaterThanLanguageSuppressUseless.out
@@ -1,2 +1,2 @@
-warning: useless suppress -Xsuppress-api-version-greater-than-language-version-error.
+warning: -Xsuppress-api-version-greater-than-language-version-error was passed, but the API version (2.2) is not greater than the language version (2.2).
 OK
diff --git a/compiler/tests-common-new/testFixtures/org/jetbrains/kotlin/test/utils/FirErrorsDefaultMessagesHelper.kt b/compiler/tests-common-new/testFixtures/org/jetbrains/kotlin/test/utils/FirErrorsDefaultMessagesHelper.kt
index 7699d04..5637a88 100644
--- a/compiler/tests-common-new/testFixtures/org/jetbrains/kotlin/test/utils/FirErrorsDefaultMessagesHelper.kt
+++ b/compiler/tests-common-new/testFixtures/org/jetbrains/kotlin/test/utils/FirErrorsDefaultMessagesHelper.kt
@@ -8,6 +8,8 @@
 import org.jetbrains.kotlin.diagnostics.*
 import org.jetbrains.kotlin.diagnostics.rendering.BaseSourcelessDiagnosticRendererFactory
 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
+import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
+import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
 import org.junit.Assert
 import kotlin.reflect.KProperty
 import kotlin.reflect.full.memberProperties
@@ -58,6 +60,18 @@
     FirErrors.CONTEXT_CLASS_OR_CONSTRUCTOR.name,
 )
 
+private val uselessInIdExclusions = listOf(
+    FirErrors.USELESS_CAST.name,
+    FirErrors.USELESS_ELVIS.name,
+    FirErrors.USELESS_ELVIS_LEFT_IS_NULL.name,
+    FirErrors.USELESS_ELVIS_RIGHT_IS_NULL.name,
+    FirErrors.USELESS_IS_CHECK.name,
+    FirErrors.USELESS_VARARG_ON_PARAMETER.name,
+    FirErrors.USELESS_CALL_ON_NOT_NULL.name,
+    FirJvmErrors.USELESS_JVM_EXPOSE_BOXED.name,
+    FirJsErrors.JS_NO_RUNTIME_USELESS_ON_EXTERNAL_INTERFACE.name,
+)
+
 fun KtDiagnosticFactoryToRendererMap.verifyMessageForFactory(
     factory: AbstractKtDiagnosticFactory,
     property: KProperty<*>,
@@ -186,6 +200,18 @@
         """\bmust not\b""".toRegex(RegexOption.IGNORE_CASE),
         "uses 'must not'. Replace with 'cannot'",
     )
+
+    checkRule(
+        name,
+        message,
+        """\buseless\b""".toRegex(RegexOption.IGNORE_CASE),
+        "uses 'useless'. Use 'redundant' if the problem doesn't affect the compilation result " +
+                "or describe the problem more precisely (e.g. 'unreachable else' instead of 'useless else'",
+    )
+
+    if (name.contains("useless", ignoreCase = true) && name !in uselessInIdExclusions) {
+        add("Diagnostic ID '$name' contains the term 'useless'.")
+    }
 }