[EE-IR] Support inline functions in IR evaluator

Inline functions called by the fragment is detected by the fragment
frontend and the PSI for them is supplied to the compiler backend.

For the purpose of compilation, the inline function is considered as
part of the same source module as the fragment, and then discarded
upon loading the compiled fragment for evaluation.
This commit is contained in:
Kristoffer Andersen
2021-11-08 08:50:18 +01:00
committed by Alexander Udalov
parent 39fee12f32
commit 0dd5ad08f3
2 changed files with 21 additions and 14 deletions
@@ -52,7 +52,7 @@ open class ModuleGenerator(
ExternalDependenciesGenerator(context.symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
}
private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
val irFile = createEmptyIrFile(ktFile, module)
val constantValueGenerator = irDeclarationGenerator.context.constantValueGenerator
@@ -85,7 +85,7 @@ open class ModuleGenerator(
return irFile
}
private fun createEmptyIrFile(ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
fun createEmptyIrFile(ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
val fileEntry = PsiIrFileEntry(ktFile)
val packageFragmentDescriptor = context.moduleDescriptor.findPackageFragmentForFile(ktFile)!!
return IrFileImpl(fileEntry, packageFragmentDescriptor, module).apply {
@@ -12,8 +12,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.psi.KtBlockCodeFragment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
import org.jetbrains.kotlin.psi2ir.generators.*
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
class FragmentModuleGenerator(
@@ -24,18 +23,26 @@ class FragmentModuleGenerator(
override fun generateModuleFragment(
ktFiles: Collection<KtFile>,
): IrModuleFragment {
val ktBlockCodeFragment = ktFiles.singleOrNull() as? KtBlockCodeFragment
?: TODO("Multiple fragments in one compilation not understood and implemented yet")
assert(ktFiles.singleOrNull { it is KtBlockCodeFragment} != null) {
"Amongst all files passed to the FragmentModuleGenerator should be exactly one KtBlockCodeFragment"
}
return IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
val irDeclarationGenerator = FragmentDeclarationGenerator(context, fragmentInfo)
irModule.files.add(
createEmptyIrFile(ktBlockCodeFragment).apply {
declarations.add(
irDeclarationGenerator.generateClassForCodeFragment(ktBlockCodeFragment)
)
patchDeclarationParents()
}
)
ktFiles.forEach { ktFile ->
irModule.files.add(
if (ktFile is KtBlockCodeFragment) {
createEmptyIrFile(ktFile).apply {
declarations.add(
irDeclarationGenerator.generateClassForCodeFragment(ktFile)
)
patchDeclarationParents()
}
} else {
val fileContext = context.createFileScopeContext(ktFile)
generateSingleFile(DeclarationGenerator(fileContext), ktFile, irModule)
}
)
}
}
}