Skip to content

Only apply compiler plugin to test compilations? #319

Description

@ychescale9

The Gradle plugin currently adds Burst runtime dependency to testImplementation, androidTestImplementation, and commonTest configurations but applies the compiler plugin to all compilations.

This usually isn't an issue as the compiler plugin early returns when there's no @Burst annotation.

However since now Burst has FIR checkers that also run in the IDE, incompatibility issue with Studio's bundled Kotlin version can surface in main sourceset (where Burst doesn't care about) too, preventing diagnostics from other FIR checkers meant for the main sourceset to work in IDE.

Here's an example where Burst's FunctionParameterChecker crashes in Studio due to FirSimpleFunction being renamed to FirNamedFunction in Kotlin 2.3.20 while Studio still bundles an older version of Kotlin.

IDE log:

2026-03-31 00:30:40,613 [278490937] SEVERE - #o.j.k.a.l.l.a.f.d.LLFirDiagnosticVisitor$Companion - Android Studio Panda 4 | 2025.3.4 Canary 2  Build #AI-253.32098.37.2534.15100028
2026-03-31 00:30:40,613 [278490937] SEVERE - #o.j.k.a.l.l.a.f.d.LLFirDiagnosticVisitor$Companion - JDK: 21.0.10; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o.
2026-03-31 00:30:40,613 [278490937] SEVERE - #o.j.k.a.l.l.a.f.d.LLFirDiagnosticVisitor$Companion - OS: Mac OS X
2026-03-31 00:30:40,613 [278490937] SEVERE - #o.j.k.a.l.l.a.f.d.LLFirDiagnosticVisitor$Companion - The diagnostic collector has been interrupted by an exception. The result may be incomplete
java.lang.NoClassDefFoundError: org/jetbrains/kotlin/fir/declarations/FirNamedFunction
        at app.cash.burst.kotlin.diagnostic.FunctionParameterChecker.check(ArgumentChecker.kt:63)
        at org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckersDiagnosticComponent.visitSimpleFunction(DeclarationCheckersDiagnosticComponent.kt:189)
        at org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckersDiagnosticComponent.visitSimpleFunction(DeclarationCheckersDiagnosticComponent.kt:25)
        at org.jetbrains.kotlin.fir.declarations.FirSimpleFunction.accept(FirSimpleFunction.kt:51)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.LLFirDiagnosticVisitor.checkElement(LLFirDiagnosticVisitor.kt:44)
        at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.access$checkElement(AbstractDiagnosticCollectorVisitor.kt:37)
        at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitSimpleFunction(AbstractDiagnosticCollectorVisitor.kt:808)
        at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitSimpleFunction(AbstractDiagnosticCollectorVisitor.kt:37)
        at org.jetbrains.kotlin.fir.declarations.FirSimpleFunction.accept(FirSimpleFunction.kt:51)
        at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector.collectDiagnostics(AbstractDiagnosticCollector.kt:36)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnosticsCollectorKt.collectForStructureElement(FileStructureElementDiagnosticsCollector.kt:25)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnosticRetriever.retrieve(FileStructureElementDiagnosticRetriever.kt:48)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics.diagnosticByDefaultCheckers_delegate$lambda$0(FileStructureElementDiagnostics.kt:15)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics.getDiagnosticByDefaultCheckers(FileStructureElementDiagnostics.kt:14)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics.diagnosticsFor(FileStructureElementDiagnostics.kt:29)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.DiagnosticsCollector.getDiagnosticsFor(DiagnosticsCollector.kt:20)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLSourceDiagnosticProvider.getDiagnostics(LLDiagnosticProvider.kt:49)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLResolutionFacade.getDiagnostics$low_level_api_fir(LLResolutionFacade.kt:119)
        at org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeKt.getDiagnostics(LowLevelFirApiFacade.kt:82)
        at org.jetbrains.kotlin.analysis.api.fir.components.KaFirDiagnosticProvider.diagnostics(KaFirDiagnosticProvider.kt:25)
        at org.jetbrains.kotlin.analysis.api.impl.base.KaBaseSession.diagnostics(KaBaseSession.kt)
        at org.jetbrains.kotlin.idea.highlighting.visitor.KotlinDiagnosticHighlightVisitor$triggerCollectingDiagnostics$1.invokeSuspend$lambda$0(KotlinDiagnosticHighlightVisitor.kt:176)
        at com.intellij.openapi.application.rw.InternalReadAction.insideReadAction(InternalReadAction.kt:111)
        at com.intellij.openapi.application.rw.InternalReadAction.tryReadCancellable$lambda$0(InternalReadAction.kt:101)
        at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal$lambda$0$0$0(cancellableReadAction.kt:32)
        at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.tryRunReadAction(NestedLocksThreadingSupport.kt:901)
        at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1237)
        at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal$lambda$0$0(cancellableReadAction.kt:30)
        at com.intellij.openapi.progress.util.ProgressIndicatorUtilService.runActionAndCancelBeforeWrite(ProgressIndicatorUtilService.java:73)
        at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:152)
        at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal$lambda$0(cancellableReadAction.kt:28)
        at com.intellij.concurrency.ThreadContext.installThreadContext(threadContext.kt:305)
        at com.intellij.concurrency.ThreadContext.installThreadContext$default(threadContext.kt:303)
        at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal(cancellableReadAction.kt:24)
        at com.intellij.openapi.application.rw.InternalReadAction.tryReadCancellable(InternalReadAction.kt:100)
        at com.intellij.openapi.application.rw.InternalReadAction.tryReadAction(InternalReadAction.kt:86)
        at com.intellij.openapi.application.rw.InternalReadAction.readLoop(InternalReadAction.kt:73)
        at com.intellij.openapi.application.rw.InternalReadAction.access$readLoop(InternalReadAction.kt:15)
        at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$6.invokeSuspend(InternalReadAction.kt:52)
        at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$6.invoke(InternalReadAction.kt)
        at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$6.invoke(InternalReadAction.kt)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:44)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:166)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
        at com.intellij.openapi.application.rw.InternalReadAction.runReadAction(InternalReadAction.kt:50)
        at com.intellij.openapi.application.rw.PlatformReadWriteActionSupport.executeReadAction(PlatformReadWriteActionSupport.kt:66)
        at com.intellij.openapi.application.ReadWriteActionSupport.executeReadAction$default(ReadWriteActionSupport.kt:15)
        at com.intellij.openapi.application.CoroutinesKt.constrainedReadAction(coroutines.kt:60)
        at com.intellij.openapi.application.CoroutinesKt.readAction(coroutines.kt:27)
        at org.jetbrains.kotlin.idea.highlighting.visitor.KotlinDiagnosticHighlightVisitor$triggerCollectingDiagnostics$1.invokeSuspend(KotlinDiagnosticHighlightVisitor.kt:172)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:610)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runDefaultDispatcherTask(CoroutineScheduler.kt:1194)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:906)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:775)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:762)
Caused by: java.lang.ClassNotFoundException: org.jetbrains.kotlin.fir.declarations.FirNamedFunction

I understand that dealing with IDE compatibility is painful (Metro deals with these issues with its compiler-compat), but I think it doesn't hurt if Burst only applies its compiler plugin to the test compilations so at least any such compatibility issues won't affect non-test code in IDE.

Happy to send a PR if you're ok with this.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions