Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.cli.CliDiagnostics
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.progress.CompilationCanceledException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ object FirDiagnosticsCompilerResultsReporter {
reporter: MessageCollector,
renderDiagnosticName: Boolean
) {
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
val severity = diagnostic.severity.toCompilerMessageSeverity()
val message = diagnostic.renderMessage()
val textToRender = when (renderDiagnosticName) {
true -> "[${diagnostic.factoryName}] $message"
Expand All @@ -128,7 +128,7 @@ object FirDiagnosticsCompilerResultsReporter {
messageRenderer: MessageRenderer
) {
if (diagnostic.severity == Severity.ERROR) {
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
val severity = diagnostic.severity.toCompilerMessageSeverity()
val message = diagnostic.renderMessage()
val diagnosticText = messageRenderer.render(severity, message, location)
throw IllegalStateException("${diagnostic.factory.name}: $diagnosticText")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,6 @@ class AnalyzerWithCompilerReport(
}

companion object {

fun convertSeverity(severity: Severity): CompilerMessageSeverity = when (severity) {
Severity.INFO -> INFO
Severity.ERROR -> ERROR
Severity.WARNING -> WARNING
Severity.FIXED_WARNING -> FIXED_WARNING
}

private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR)

private fun reportDiagnostic(diagnostic: Diagnostic, reporter: DiagnosticMessageReporter, renderDiagnosticName: Boolean): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
val messageCollector: MessageCollector

override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
diagnostic.severity.toCompilerMessageSeverity(),
render,
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumnRange(diagnostic))
)
Expand Down
10 changes: 2 additions & 8 deletions compiler/cli/src/org/jetbrains/kotlin/cli/common/utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.config.messageCollector
import org.jetbrains.kotlin.diagnostics.DiagnosticBaseContext
import org.jetbrains.kotlin.diagnostics.KtSourcelessDiagnosticFactory
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.packageFqName
Expand Down Expand Up @@ -157,10 +155,6 @@ fun disposeRootInWriteAction(disposable: Disposable) {
}

fun CompilerConfiguration.reportIfNeeded(factory: KtSourcelessDiagnosticFactory, message: String) {
val diagnostic = factory.create(message, object : DiagnosticBaseContext {
override val languageVersionSettings: LanguageVersionSettings
get() = [email protected]

}) ?: return
messageCollector.report(AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity), message)
val effectiveSeverity = factory.getEffectiveSeverity([email protected]) ?: return
messageCollector.report(effectiveSeverity.toCompilerMessageSeverity(), message)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

package org.jetbrains.kotlin.fir.analysis.checkers.config

import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics
import org.jetbrains.kotlin.fir.declarations.hasAnnotationWithClassId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.PackageResolutionResult
Expand Down Expand Up @@ -36,25 +36,31 @@ object FirOptInLanguageVersionSettingsChecker : FirLanguageVersionSettingsChecke
val symbol = (packageOrClass as? PackageResolutionResult.PackageOrClass)?.classSymbol

if (symbol == null) {
reporter.reportWarning(
"Opt-in requirement marker $fqNameAsString is unresolved. Please make sure it's present in the module dependencies"
reporter.reportIfNeeded(
CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED,
"Opt-in requirement marker $fqNameAsString is unresolved. Please make sure it's present in the module dependencies",
context,
)
return
}

if (!symbol.hasAnnotationWithClassId(OptInNames.REQUIRES_OPT_IN_CLASS_ID, context.session)) {
reporter.reportWarning("Class $fqNameAsString is not an opt-in requirement marker")
reporter.reportIfNeeded(
CliDiagnostics.CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER,
"Class $fqNameAsString is not an opt-in requirement marker",
context,
)
return
}
val deprecationInfo = symbol.getOwnDeprecation(context.languageVersionSettings)?.all ?: return
val severity = when (deprecationInfo.deprecationLevel) {
DeprecationLevelValue.WARNING -> CompilerMessageSeverity.WARNING
else -> CompilerMessageSeverity.ERROR
}
reporter.report(
"Opt-in requirement marker $fqNameAsString is deprecated" +
deprecationInfo.getMessage(context.session)?.let { ". $it" }.orEmpty(),
severity
val diagnosticFactory = if (deprecationInfo.deprecationLevel == DeprecationLevelValue.WARNING)
CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED
else
CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR
reporter.reportIfNeeded(
diagnosticFactory,
"Opt-in requirement marker $fqNameAsString is deprecated" + deprecationInfo.getMessage(context.session)?.let { ". $it" }.orEmpty(),
context,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package org.jetbrains.kotlin.fir.analysis.diagnostics

import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.KtDiagnosticsContainer
import org.jetbrains.kotlin.diagnostics.KtSourcelessDiagnosticFactory
import org.jetbrains.kotlin.diagnostics.errorWithoutSource
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
import org.jetbrains.kotlin.diagnostics.rendering.BaseSourcelessDiagnosticFactory
import org.jetbrains.kotlin.diagnostics.warningWithoutSource
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics.CLI_COMPILER_PLUGIN_IS_EXPERIMENTAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics.CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics.CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED
import kotlin.getValue

object CliDiagnostics : KtDiagnosticsContainer() {
val CLI_COMPILER_PLUGIN_IS_EXPERIMENTAL: KtSourcelessDiagnosticFactory by warningWithoutSource()
val CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED: KtSourcelessDiagnosticFactory by warningWithoutSource()
val CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER: KtSourcelessDiagnosticFactory by warningWithoutSource()
val CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED: KtSourcelessDiagnosticFactory by warningWithoutSource()
val CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR: KtSourcelessDiagnosticFactory by errorWithoutSource()
Comment on lines +23 to +27
Copy link
Contributor Author

@KvanTTT KvanTTT Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if CLI_ prefixes are needed here. It probably makes sense to remove them.


override fun getRendererFactory(): BaseDiagnosticRendererFactory = KtDiagnosticMessagesCli
}

object KtDiagnosticMessagesCli : BaseSourcelessDiagnosticFactory() {
override val MAP: KtDiagnosticFactoryToRendererMap by KtDiagnosticFactoryToRendererMap("CLI") { map ->
map.put(CLI_COMPILER_PLUGIN_IS_EXPERIMENTAL, MESSAGE_PLACEHOLDER)
map.put(CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED, MESSAGE_PLACEHOLDER)
map.put(CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER, MESSAGE_PLACEHOLDER)
map.put(CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED, MESSAGE_PLACEHOLDER)
map.put(CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR, MESSAGE_PLACEHOLDER)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.FirInlineCheckerPlatformSpecif
import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTrackerImpl
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirGenericArrayClassLiteralSupport
import org.jetbrains.kotlin.fir.analysis.diagnostics.CliDiagnostics
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirComposedDiagnosticRendererFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.diagnosticRendererFactory
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
Expand All @@ -24,7 +25,6 @@ import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerCompone
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory
import org.jetbrains.kotlin.fir.cli.CliDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ sealed class AbstractKtDiagnosticFactory(
get() = rendererFactory.MAP[this]
?: error("Renderer is not found for factory $this inside ${rendererFactory.MAP.name} renderer map")

protected fun getEffectiveSeverity(languageVersionSettings: LanguageVersionSettings): Severity? {
fun getEffectiveSeverity(languageVersionSettings: LanguageVersionSettings): Severity? {
return when (languageVersionSettings.getFlag(AnalysisFlags.warningLevels)[name]) {
WarningLevel.Error -> Severity.ERROR
WarningLevel.Warning -> Severity.FIXED_WARNING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package org.jetbrains.kotlin.diagnostics

import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity

enum class Severity {
INFO,
ERROR,
Expand All @@ -13,5 +15,12 @@ enum class Severity {
/**
* see [org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.FIXED_WARNING]
*/
FIXED_WARNING,
FIXED_WARNING;

fun toCompilerMessageSeverity(): CompilerMessageSeverity = when (this) {
INFO -> CompilerMessageSeverity.INFO
ERROR -> CompilerMessageSeverity.ERROR
WARNING -> CompilerMessageSeverity.WARNING
FIXED_WARNING -> CompilerMessageSeverity.FIXED_WARNING
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
package org.jetbrains.kotlin.diagnostics.impl

import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.diagnostics.DiagnosticBaseContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.KtSourcelessDiagnosticFactory

abstract class BaseDiagnosticsCollector : DiagnosticReporter() {
abstract val diagnostics: List<KtDiagnostic>
Expand All @@ -22,12 +24,17 @@ abstract class BaseDiagnosticsCollector : DiagnosticReporter() {

fun report(message: String, severity: CompilerMessageSeverity)

fun reportWarning(message: String) {
report(message, CompilerMessageSeverity.WARNING)
}

fun reportError(message: String) {
report(message, CompilerMessageSeverity.ERROR)
}

fun reportIfNeeded(
factory: KtSourcelessDiagnosticFactory,
message: String,
context: DiagnosticBaseContext,
) {
val refinedSeverity = factory.getEffectiveSeverity(context.languageVersionSettings)?.toCompilerMessageSeverity() ?: return
report(message, refinedSeverity)
}
}
}
10 changes: 10 additions & 0 deletions compiler/testData/cli/metadata/optInDiagnostics.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface NotAnAnnotation

@Deprecated("Warning", level = DeprecationLevel.WARNING)
@RequiresOptIn
@Retention(AnnotationRetention.BINARY)
annotation class Warning

@Deprecated("Error", level = DeprecationLevel.ERROR)
@RequiresOptIn
annotation class Error
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$TESTDATA_DIR$/optInDiagnostics.kt
-d
$TEMP_DIR$
-cp
$TESTDATA_DIR$/../../../../dist/common/kotlin-stdlib-common.klib
-Xtarget-platform=JVM,JS,WasmJs,WasmWasi,Native
-opt-in=Error
-Xwarning-level=CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR\:disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: diagnostic "CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED_ERROR" is an error. Changing the severity of errors is prohibited
COMPILATION_ERROR
14 changes: 14 additions & 0 deletions compiler/testData/cli/metadata/optInWarningsAreDisabled.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
$TESTDATA_DIR$/optInDiagnostics.kt
-d
$TEMP_DIR$
-cp
$TESTDATA_DIR$/../../../../dist/common/kotlin-stdlib-common.klib
-Xtarget-platform=JVM,JS,WasmJs,WasmWasi,Native
-opt-in=Unresolved
-opt-in=NotAnAnnotation
-opt-in=kotlin.RequiresOptIn
-opt-in=Warning
-Werror
-Xwarning-level=CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED\:disabled
-Xwarning-level=CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER\:disabled
-Xwarning-level=CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED\:disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OK
13 changes: 13 additions & 0 deletions compiler/testData/cli/metadata/optInWarningsAsErrors.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$TESTDATA_DIR$/optInDiagnostics.kt
-d
$TEMP_DIR$
-cp
$TESTDATA_DIR$/../../../../dist/common/kotlin-stdlib-common.klib
-Xtarget-platform=JVM,JS,WasmJs,WasmWasi,Native
-opt-in=Unresolved
-opt-in=NotAnAnnotation
-opt-in=kotlin.RequiresOptIn
-opt-in=Warning
-Xwarning-level=CLI_OPT_IN_REQUIREMENT_MARKER_IS_UNRESOLVED\:error
-Xwarning-level=CLI_NOT_AN_OPT_IN_REQUIREMENT_MARKER\:error
-Xwarning-level=CLI_OPT_IN_REQUIREMENT_MARKER_IS_DEPRECATED\:error
4 changes: 4 additions & 0 deletions compiler/testData/cli/metadata/optInWarningsAsErrors.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: opt-in requirement marker Unresolved is unresolved. Please make sure it's present in the module dependencies
error: class NotAnAnnotation is not an opt-in requirement marker
error: opt-in requirement marker Warning is deprecated. Warning
COMPILATION_ERROR
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.test.backend.handlers

import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.cli.common.fir.SequentialPositionFinder
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.codeMetaInfo.model.DiagnosticCodeMetaInfo
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Severity
Expand Down Expand Up @@ -115,7 +114,7 @@ fun BinaryArtifactHandler<*>.checkFullDiagnosticRender() {
}

private fun renderDiagnosticMessage(fileName: String, severity: Severity, message: String?, line: Int, column: Int): String {
val severityString = AnalyzerWithCompilerReport.convertSeverity(severity).toString().toLowerCaseAsciiOnly()
val severityString = severity.toCompilerMessageSeverity().toString().toLowerCaseAsciiOnly()
return "/${fileName}:$line:$column: $severityString: $message"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package org.jetbrains.kotlin.test.backend.handlers

import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.model.BackendInputHandler
Expand Down Expand Up @@ -39,7 +38,7 @@ class NoIrCompilationErrorsHandler(testServices: TestServices) : BackendInputHan
diagnostic.severity == Severity.ERROR &&
diagnosticsService.shouldRenderDiagnostic(module, diagnostic.factoryName, diagnostic.severity)
) {
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity).toString().toLowerCaseAsciiOnly()
val severity = diagnostic.severity.toCompilerMessageSeverity().toString().toLowerCaseAsciiOnly()
val message = diagnostic.renderMessage()
error("/$file:${diagnostic.firstRange}: $severity: $message")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.frontend.fir.handlers
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.checkers.utils.TypeOfCall
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.pipeline.metadata.MetadataFrontendPipelineArtifact
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.*
Expand Down Expand Up @@ -116,7 +115,7 @@ class FullDiagnosticsRenderer(private val directive: SimpleDirective) {
is KtDiagnosticWithSource -> it.textRanges
is KtDiagnosticWithoutSource -> listOf(it.firstRange)
},
severity = AnalyzerWithCompilerReport.convertSeverity(it.severity).toString().toLowerCaseAsciiOnly(),
severity = it.severity.toCompilerMessageSeverity().toString().toLowerCaseAsciiOnly(),
message = it.renderMessage()
)
}
Expand Down
Loading