Is there any way to get a `DiagnosticReporter` and...
# compiler
a
Is there any way to get a
DiagnosticReporter
and create error/warning IDE underlines from a backend-ir plugin?
j
No, that is the reason FIR exists
a
Is there a way to pass information gathered in a backend-ir plugin into a FirDeclarationChecker?
j
AFAIK, backend is executed after frontend, so I doubt
There are frontend to backend APIs, but I haven't tried them tho
a
You mean getting a IrCall from a FirCall or something like that?
j
I guess, I haven't tried, but it is called
FirTo***
or something so
a
Is there really no way to do this? What about the DiagnosticSink thing? Is there some obscure way to pull it out of the backend context?
j
FIR means literally frontend intermediate representation, the weird thing would be doing that with the backend. What do you want to achieve?
it should be trivial to add a checker for fir call
a
I'm doing a whole ton of analysis in the backend tracing elements from their identifiers and building up bodies for a ton of empty-implementation elements. There are multiple code paths inside of it that the user needs to be warned about.
j
You should do all of those analysis with FIR except if for some reason it is not possible.
a
@dmitriy.novozhilov Any chance you know of some way I could make compiler error/warning underlines from IrGenerationExtension code? (E.g. using the DiagnosticSink or passing backend-data back to FIR plugins?)
d
There is a
IrPluginContext.messageCollector
recently added in
master
It will be available in 2.1.20-Beta2
🐕 1
E.g. using the DiagnosticSink ...
DiagnosticSink
is K1-specific service. K2 (both frontend and backend) uses
DiagnosticReporter
and it's inheritor
BaseDiagnosticsCollector
(yeah, naming sucks and I plan to rename everything to be reporters)
... or passing backend-data back to FIR plugins?
As Javier mentioned above, it's impossible, as FIR plugins won't be called after fir2ir transformation, and IR plugins are called right after fir2ir
a
I’ll wait for 2.1.20 then. Thanks!
@dmitriy.novozhilov I think I figured out how to summon up the reporter from the backend IR
Copy code
val msgCollector = config.get(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val reporter = DiagnosticReporterFactory.createReporter(msgCollector)
val contextReporter = KtDiagnosticReporterWithImplicitIrBasedContext(reporter, config.languageVersionSettings)
// then later...
<http://contextReporter.at|contextReporter.at>(elem, currentFileRaw).report(MyDiagFactory, msg)
Only when I do this (from a backend-ir plugin) I don't see any warning underlines anywhere. What am I doing wrong?
d
Yep, this should work
a
@dmitriy.novozhilov Maybe I registered the factory wrong?
Copy code
object Diagnostics {
    val DiagFactory: KtDiagnosticFactory1<String> by warning1<PsiElement, String>()
    val Renderer = object: ContextIndependentParameterRenderer<String> {
        override fun render(obj: String): String = obj
    }
    object KtMessages : BaseDiagnosticRendererFactory() {
        override val MAP =
            KtDiagnosticFactoryToRendererMap("Unexpected Stuff").also { map ->
                map.put(DiagFactory, "Unexpected Stuff happened: {0}", Renderer)
            }
    }
}

// and then:
class Registrar: CompilerPluginRegistrar() {
    override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
        RootDiagnosticRendererFactory.registerFactory(KtMessages)
        ...
    }
}
I tried report on an existing message i.e.
Copy code
contextReporter.at(elem.sourceElement(), elem, currentFileRaw).report(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
...and I'm seeing nothing. I've also tried KtDiagnosticReporterWithContext and a bunch of other things. (Goes without saying that K2 mode is enabled) Nothing happens. No red or yellow underlines anywhere and no messages about any of this in the compiler. Seems that the report is completely ignored. @dmitriy.novozhilov Sorry to continue bothering you but any thoughts on where I should be looking in order know why I'm not seeing anything in the IDE? I know this part of the code is being hit because I put MessageCollector.report right next to it and that's working.
d
Please don't ping me directly, I'm tracking all threads I'm participating Also I live in Europe, so it's almost a midnight for me
sorry 1
Check the implementation of the reporter It could be a pending reporter, which don't passes everything to message collector until the flush-like function is called If it is so, use the other reporter (there is something like
SimpleDiagnosticReporter
)
a
Thanks for all the help so far! My reporter is
SimpleDiagnosticsCollectorWithSuppress
and the rawReporter of that is
DiagnosticReporterFactory
. Then I use the
SimpleDiagnosticsCollectorWithSuppress
to create the
KtDiagnosticReporterWithImplicitIrBasedContext
. I tried a whole bunch of different things e.g. checkAndCommitReportsOn i.e:
Copy code
val srcElem = elem.toSourceElement(currentFileRaw) ?: throw IllegalArgumentException("...")
    val ctx = contextReporter.at(srcElem, elem, currentFileRaw)
    ctx.report(DiagFactory, msg)
    contextReporter.checkAndCommitReportsOn(srcElem, ctx)
I even tried flushing on both the reporters:
Copy code
ctx.report(DiagFactory, msg)
    contextReporter.checkAndCommitReportsOn(srcElem, ctx)
    reporter.checkAndCommitReportsOn(srcElem, ctx)
Also tried the ctx with the regular reporter:
Copy code
val ctx = contextReporter.at(srcElem, elem, currentFileRaw)
    reporter.reportOn(srcElem, DiagFactory, msg, ctx)
    reporter.checkAndCommitReportsOn(srcElem, ctx)
Nothing is underlined and the compiler reports nothing. (Ironically reporter.reportToMessageCollector makes it appear immediately but still no red/yellow underlines).
j
If with that IR reporter it is possible to show things on the IDE, why do we need checkers on FIR instead of doing them on IR?
a
I’m guessing for convenience? If you’re just writing a code-checking utility it’s simpler with the standalone FIR checker API.
Also, doesn’t FIR have things in it that IR doesn’t? E.g. imports.
Wait a minute. I'm not even getting red-underlines over my code when I emit a diagnostic from a FirCallChecker in the FirAdditionalCheckersExtension, even though I see the message in my compiler errors. How is this possible? Is there some setting in IntelliJ that I haven't enabled? I've set K2 to mode to "On."
(Also I set kotlin.k2.only.bundled.compiler.plugins.enabled to off but still no underlines)
@Javier You mentioned that here that you've managed to get this to work. Anything else I should try to do? https://kotlinlang.slack.com/archives/C03PK0PE257/p1724005459312539?thread_ts=1723996289.489159&amp;cid=C03PK0PE257
d
Ah, wait. I misread the part of the original question where you mention that you need to report these diagnostics in the IDE. There is no way to do it, IDE doesn't run backend (and backend plugins too)