Repository: JetBrains/kotlin
File: compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt (Kotlin)

Code before:
        irProviders: List<IrProvider>,
        linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
        expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
    ): IrModuleFragment {
        val moduleGenerator = ModuleGenerator(context, expectDescriptorToSymbol)
        val irModule = moduleGenerator.generateModuleFragment(ktFiles)

        val deserializers = irProviders.filterIsInstance<IrDeserializer>()
        deserializers.forEach { it.init(irModule, linkerExtensions) }

        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)

        deserializers.forEach { it.postProcess() }
        context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n")

        postprocessingSteps.forEach { it.invoke(irModule) }
//        assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference

        // TODO: remove it once plugin API improved
        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
        deserializers.forEach { it.postProcess() }

        return irModule
    }

    // TODO - De-duplicate this code from generateModuleFragment
    fun generateEvaluatorModuleFragment(
        context: GeneratorContext,
        ktFile: KtBlockCodeFragment,
        irProviders: List<IrProvider>,
        linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
        fragmentInfo: EvaluatorFragmentInfo
    ): IrModuleFragment {
        val moduleGenerator = FragmentModuleGenerator(context, fragmentInfo)
        val irModule = moduleGenerator.generateEvaluatorModuleFragment(ktFile)

        val deserializers = irProviders.filterIsInstance<IrDeserializer>()
        deserializers.forEach { it.init(irModule, linkerExtensions) }

        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)

        deserializers.forEach { it.postProcess() }
        context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n")

        postprocessingSteps.forEach { it.invoke(irModule) }

        // TODO: remove it once plugin API improved
        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
        deserializers.forEach { it.postProcess() }

        return irModule

Review comment (refactor):
Similarly to deduplicating `JvmIrCodegenFactory`, I'd prefer to do this right away, by passing extra parameters to the existing `generateEvaluatorModuleFragment`. And then, eventually, maybe extract it to a separate method, if it proves to be worthwhile

Code after:
            fragmentContext
        )
    }

    fun generateModuleFragment(
        context: GeneratorContext,
        ktFiles: Collection<KtFile>,
        irProviders: List<IrProvider>,
        linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
        expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
        fragmentInfo: EvaluatorFragmentInfo? = null
    ): IrModuleFragment {
        val moduleGenerator = fragmentInfo?.let {
            FragmentModuleGenerator(context, it)
        } ?: ModuleGenerator(context, expectDescriptorToSymbol)

        val irModule = moduleGenerator.generateModuleFragment(ktFiles)

        val deserializers = irProviders.filterIsInstance<IrDeserializer>()
        deserializers.forEach { it.init(irModule, linkerExtensions) }

        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)

        deserializers.forEach { it.postProcess() }
        context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n")

        postprocessingSteps.forEach { it.invoke(irModule) }
//        assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference

        // TODO: remove it once plugin API improved
        moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
        deserializers.forEach { it.postProcess() }

        return irModule
    }
}