I think I found issue either in compiler plugins t...
# compiler
g
I think I found issue either in compiler plugins test framework or in compiler itself. I'll attach details in the thread. The main question is: where should I report it? Here? In YouTrack? Both?
h
YouTrack
👌 1
☝️ 1
But you can show the bug here too
g
Yeah, I am describing it here right now. It will take several minutes.
For some reason compiler crashes with
Unhandled intrinsic in ExpressionCodegen: ...
when there is attempt to use generated function from user (real) code. To be specific, here is code of the plugin and it's test (except generated test class):
Copy code
import org.jetbrains.kotlin.GeneratedDeclarationKey
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar.ExtensionStorage
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.plugin.createTopLevelFunction
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.FirParser
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor.SuppressionChecker
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler
import org.jetbrains.kotlin.test.backend.handlers.IrTreeVerifierHandler
import org.jetbrains.kotlin.test.backend.handlers.JvmBoxRunner
import org.jetbrains.kotlin.test.backend.handlers.NoFirCompilationErrorsHandler
import org.jetbrains.kotlin.test.backend.handlers.NoIrCompilationErrorsHandler
import org.jetbrains.kotlin.test.backend.ir.BackendCliJvmFacade
import org.jetbrains.kotlin.test.backend.ir.IrDiagnosticsHandler
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.configureFirHandlersStep
import org.jetbrains.kotlin.test.builders.configureIrHandlersStep
import org.jetbrains.kotlin.test.builders.configureJvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.builders.irHandlersStep
import org.jetbrains.kotlin.test.builders.jvmArtifactsHandlersStep
import org.jetbrains.kotlin.test.configuration.commonBackendHandlersForCodegenTest
import org.jetbrains.kotlin.test.configuration.commonConfigurationForJvmTest
import org.jetbrains.kotlin.test.configuration.setupHandlersForDiagnosticTest
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.directives.TestPhaseDirectives
import org.jetbrains.kotlin.test.directives.configureFirParser
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrCliJvmFacade
import org.jetbrains.kotlin.test.frontend.fir.FirCliJvmFacade
import org.jetbrains.kotlin.test.frontend.fir.handlers.NonSourceErrorMessagesHandler
import org.jetbrains.kotlin.test.frontend.fir.handlers.PsiLightTreeMetaInfoProcessor
import org.jetbrains.kotlin.test.initIdeaConfiguration
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.EnvironmentBasedStandardLibrariesPathProvider
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
import org.jetbrains.kotlin.test.services.KotlinStandardLibrariesPathProvider
import org.jetbrains.kotlin.test.services.PhasedPipelineChecker
import org.jetbrains.kotlin.test.services.TestPhase
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.utils.bind
import org.junit.jupiter.api.BeforeAll
import java.io.File


public abstract class KoneTestRunner2 : AbstractKotlinCompilerTest() {
    public companion object {
        @BeforeAll
        @JvmStatic
        public fun setUp() {
            initIdeaConfiguration()
        }
    }
    
    final override fun createKotlinStandardLibrariesPathProvider(): KotlinStandardLibrariesPathProvider =
        EnvironmentBasedStandardLibrariesPathProvider
}

public fun TestConfigurationBuilder.commonTestRunnerConfiguration2(
    runPipelineTillPhase: TestPhase = TestPhase.BACKEND,
) {
    globalDefaults {
        targetBackend = TargetBackend.JVM_IR
        targetPlatform = JvmPlatforms.defaultJvmPlatform
        dependencyKind = DependencyKind.Binary
    }
    
    defaultDirectives {
        +FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES
        +FirDiagnosticsDirectives.FIR_DUMP
        +JvmEnvironmentConfigurationDirectives.FULL_JDK
        TestPhaseDirectives.LATEST_PHASE_IN_PIPELINE with TestPhase.BACKEND
        TestPhaseDirectives.RUN_PIPELINE_TILL with runPipelineTillPhase
        LanguageSettingsDirectives.LANGUAGE + "+EnableDfaWarningsInK2"
        +CodegenTestDirectives.IGNORE_DEXING
    }
    
    commonConfigurationForJvmTest(
        targetFrontend = FrontendKinds.FIR,
        frontendFacade = ::FirCliJvmFacade,
        frontendToBackendConverter = ::Fir2IrCliJvmFacade,
        backendFacade = ::BackendCliJvmFacade
    )
    configureFirParser(FirParser.Psi)
//    configureCommonDiagnosticTestPaths()
    
    configureFirHandlersStep {
        setupHandlersForDiagnosticTest()
        useHandlers(::NoFirCompilationErrorsHandler)
    }
    
    configureIrHandlersStep {
        useHandlers(::IrDiagnosticsHandler, ::NoIrCompilationErrorsHandler)
    }
    
    configureJvmArtifactsHandlersStep {
        commonBackendHandlersForCodegenTest(includeNoCompilationErrorsHandler = false)
    }
    
    useMetaInfoProcessors(::PsiLightTreeMetaInfoProcessor)
    useAfterAnalysisCheckers(::PhasedPipelineChecker, ::NonSourceErrorMessagesHandler)
    enableMetaInfoHandler()
    useAdditionalService<SuppressionChecker>(::SuppressionChecker.bind(null, null))
}

val testJvmClasspathRoots: List<String> = emptyList()

class PluginRuntimeProvider2(testServices: TestServices) : EnvironmentConfigurator(testServices) {
    override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
        configuration.addJvmClasspathRoots(testJvmClasspathRoots.map { File(it) })
    }
}

abstract class KoneSuppliedTypesTestRunner2 : KoneTestRunner2() {
    protected abstract val runPipelineTillPhase: TestPhase
    @TestInfrastructureInternals
    override fun configureInternal(builder: TestConfigurationBuilder) {
        builder.commonTestRunnerConfiguration2(
            runPipelineTillPhase = runPipelineTillPhase,
        )
        configure(builder)
        builder.useConfigurators(::PluginRuntimeProvider2)
    }
}

class SuppliableFunctionsDuplicatesGenerationExtension2(session: FirSession) : FirDeclarationGenerationExtension(session) {
    object Key : GeneratedDeclarationKey() {
        override fun toString(): String = "SuppliableFunctionsDuplicatesGenerationExtension2.Key"
    }
    
    override fun hasPackage(packageFqName: FqName): Boolean = packageFqName.toString() == "foo.bar"
    
    @OptIn(ExperimentalTopLevelDeclarationsGenerationApi::class)
    override fun getTopLevelCallableIds(): Set<CallableId> = setOf(CallableId(packageName = FqName("foo.bar"), callableName = Name.identifier("baz")))
    
    @OptIn(ExperimentalTopLevelDeclarationsGenerationApi::class)
    override fun generateFunctions(
        callableId: CallableId,
        context: MemberGenerationContext?
    ): List<FirNamedFunctionSymbol> =
        if (context?.declaredScope != null) emptyList()
        else listOf(
            createTopLevelFunction(
                key = Key,
                callableId = callableId,
                returnType = session.builtinTypes.unitType.coneType,
            ) {
                withGeneratedDefaultBody()
            }.symbol
        )
}

class ExtensionRegistrarConfigurator2(testServices: TestServices) : EnvironmentConfigurator(testServices) {
    @OptIn(ExperimentalCompilerApi::class)
    override fun ExtensionStorage.registerCompilerExtensions(
        module: TestModule,
        configuration: CompilerConfiguration
    ) {
        val messageCollector = configuration.get(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
        
        FirExtensionRegistrarAdapter.registerExtension(FirSuppliedTypeExtensionRegistrar2())
    }
}

class FirSuppliedTypeExtensionRegistrar2 : FirExtensionRegistrar() {
    override fun ExtensionRegistrarContext.configurePlugin() {
        +::SuppliableFunctionsDuplicatesGenerationExtension2
    }
}

open class AbstractTestWithoutPlugin: KoneSuppliedTypesTestRunner2() {
    final override val runPipelineTillPhase: TestPhase = TestPhase.BACKEND
    final override fun configure(builder: TestConfigurationBuilder) = with(builder) {
        defaultDirectives {
            +CodegenTestDirectives.DUMP_IR
        }
        
        irHandlersStep {
            useHandlers(
                ::IrTextDumpHandler,
                ::IrTreeVerifierHandler,
            )
        }
        
        useConfigurators(::ExtensionRegistrarConfigurator2)
        
        useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
        
        jvmArtifactsHandlersStep {
            useHandlers(::JvmBoxRunner)
        }
    }
}
Here is the test Kotlin file:
Copy code
import foo.bar.baz

fun box(): String {
    baz()
    return "OK"
}
And here is the error:
Copy code
Exception while generating code for:
FUN name:box visibility:public modality:FINAL returnType:kotlin.String
  BLOCK_BODY
    CALL 'public final fun baz (): kotlin.Unit declared in foo.bar' type=kotlin.Unit origin=null
    RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>.TestKt'
      CONST String type=kotlin.String value="OK"

java.lang.RuntimeException: Exception while generating code for:
FUN name:box visibility:public modality:FINAL returnType:kotlin.String
  BLOCK_BODY
    CALL 'public final fun baz (): kotlin.Unit declared in foo.bar' type=kotlin.Unit origin=null
    RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>.TestKt'
      CONST String type=kotlin.String value="OK"

	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:57)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate$default(FunctionCodegen.kt:50)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generateMethodNode(ClassCodegen.kt:428)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generateMethod(ClassCodegen.kt:445)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generate(ClassCodegen.kt:168)
	at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.generateFile(JvmIrCodegenFactory.kt:467)
	at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.invokeCodegen(JvmIrCodegenFactory.kt:433)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runCodegen$cli(KotlinToJVMBytecodeCompiler.kt:409)
	at org.jetbrains.kotlin.cli.pipeline.jvm.JvmBackendPipelinePhase.executePhase(JvmBackendPipelinePhase.kt:89)
	at org.jetbrains.kotlin.test.backend.ir.BackendCliJvmFacade.produceGenerationState(BackendCliJvmFacade.kt:31)
	at org.jetbrains.kotlin.test.backend.ir.AbstractJvmIrBackendFacade.transform(JvmIrBackendFacade.kt:41)
	at org.jetbrains.kotlin.test.backend.ir.AbstractJvmIrBackendFacade.transform(JvmIrBackendFacade.kt:30)
	at org.jetbrains.kotlin.test.TestStep$FacadeStep.processModule(TestStep.kt:47)
	at org.jetbrains.kotlin.test.TestRunner.processModule(TestRunner.kt:206)
	at org.jetbrains.kotlin.test.TestRunner.hackyProcessModule(TestRunner.kt:197)
	at org.jetbrains.kotlin.test.TestRunner.processModule(TestRunner.kt:141)
	at org.jetbrains.kotlin.test.TestRunner.runTestPipeline(TestRunner.kt:92)
	at org.jetbrains.kotlin.test.TestRunner.runTestImpl(TestRunner.kt:70)
	at org.jetbrains.kotlin.test.TestRunner.runTest(TestRunner.kt:30)
	at org.jetbrains.kotlin.test.TestRunner.runTest$default(TestRunner.kt:28)
	at org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest.runTest(AbstractKotlinCompilerTest.kt:115)
	at dev.lounres.kone.plugin.suppliedTypes.runners.TestWithoutPluginGenerated.testTest(TestWithoutPluginGenerated.java:27)
Caused by: java.lang.IllegalArgumentException: Unhandled intrinsic in ExpressionCodegen: FUN GENERATED[dev.lounres.kone.plugin.suppliedTypes.test.SuppliableFunctionsDuplicatesGenerationExtension2.Key] name:baz visibility:public modality:FINAL <> () returnType:kotlin.Unit
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitCall(ExpressionCodegen.kt:516)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitCall(ExpressionCodegen.kt:140)
	at org.jetbrains.kotlin.ir.expressions.IrCall.accept(IrCall.kt:24)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitStatementContainer(ExpressionCodegen.kt:491)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitBlockBody(ExpressionCodegen.kt:496)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitBlockBody(ExpressionCodegen.kt:140)
	at org.jetbrains.kotlin.ir.expressions.IrBlockBody.accept(IrBlockBody.kt:20)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.generate(ExpressionCodegen.kt:233)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.doGenerate(FunctionCodegen.kt:135)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:54)
	... 21 more


Unhandled intrinsic in ExpressionCodegen: FUN GENERATED[dev.lounres.kone.plugin.suppliedTypes.test.SuppliableFunctionsDuplicatesGenerationExtension2.Key] name:baz visibility:public modality:FINAL <> () returnType:kotlin.Unit
java.lang.IllegalArgumentException: Unhandled intrinsic in ExpressionCodegen: FUN GENERATED[dev.lounres.kone.plugin.suppliedTypes.test.SuppliableFunctionsDuplicatesGenerationExtension2.Key] name:baz visibility:public modality:FINAL <> () returnType:kotlin.Unit
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitCall(ExpressionCodegen.kt:516)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitCall(ExpressionCodegen.kt:140)
	at org.jetbrains.kotlin.ir.expressions.IrCall.accept(IrCall.kt:24)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitStatementContainer(ExpressionCodegen.kt:491)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitBlockBody(ExpressionCodegen.kt:496)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.visitBlockBody(ExpressionCodegen.kt:140)
	at org.jetbrains.kotlin.ir.expressions.IrBlockBody.accept(IrBlockBody.kt:20)
	at org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen.generate(ExpressionCodegen.kt:233)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.doGenerate(FunctionCodegen.kt:135)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:54)
	at org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate$default(FunctionCodegen.kt:50)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generateMethodNode(ClassCodegen.kt:428)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generateMethod(ClassCodegen.kt:445)
	at org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen.generate(ClassCodegen.kt:168)
	at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.generateFile(JvmIrCodegenFactory.kt:467)
	at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.invokeCodegen(JvmIrCodegenFactory.kt:433)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runCodegen$cli(KotlinToJVMBytecodeCompiler.kt:409)
	at org.jetbrains.kotlin.cli.pipeline.jvm.JvmBackendPipelinePhase.executePhase(JvmBackendPipelinePhase.kt:89)
	at org.jetbrains.kotlin.test.backend.ir.BackendCliJvmFacade.produceGenerationState(BackendCliJvmFacade.kt:31)
	at org.jetbrains.kotlin.test.backend.ir.AbstractJvmIrBackendFacade.transform(JvmIrBackendFacade.kt:41)
	at org.jetbrains.kotlin.test.backend.ir.AbstractJvmIrBackendFacade.transform(JvmIrBackendFacade.kt:30)
	at org.jetbrains.kotlin.test.TestStep$FacadeStep.processModule(TestStep.kt:47)
	at org.jetbrains.kotlin.test.TestRunner.processModule(TestRunner.kt:206)
	at org.jetbrains.kotlin.test.TestRunner.hackyProcessModule(TestRunner.kt:197)
	at org.jetbrains.kotlin.test.TestRunner.processModule(TestRunner.kt:141)
	at org.jetbrains.kotlin.test.TestRunner.runTestPipeline(TestRunner.kt:92)
	at org.jetbrains.kotlin.test.TestRunner.runTestImpl(TestRunner.kt:70)
	at org.jetbrains.kotlin.test.TestRunner.runTest(TestRunner.kt:30)
	at org.jetbrains.kotlin.test.TestRunner.runTest$default(TestRunner.kt:28)
	at org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest.runTest(AbstractKotlinCompilerTest.kt:115)
	at dev.lounres.kone.plugin.suppliedTypes.runners.TestWithoutPluginGenerated.testTest(TestWithoutPluginGenerated.java:27)