[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() 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 irFile = createEmptyIrFile(ktFile, module)
val constantValueGenerator = irDeclarationGenerator.context.constantValueGenerator val constantValueGenerator = irDeclarationGenerator.context.constantValueGenerator
@@ -85,7 +85,7 @@ open class ModuleGenerator(
return irFile return irFile
} }
private fun createEmptyIrFile(ktFile: KtFile, module: IrModuleFragment): IrFileImpl { fun createEmptyIrFile(ktFile: KtFile, module: IrModuleFragment): IrFileImpl {
val fileEntry = PsiIrFileEntry(ktFile) val fileEntry = PsiIrFileEntry(ktFile)
val packageFragmentDescriptor = context.moduleDescriptor.findPackageFragmentForFile(ktFile)!! val packageFragmentDescriptor = context.moduleDescriptor.findPackageFragmentForFile(ktFile)!!
return IrFileImpl(fileEntry, packageFragmentDescriptor, module).apply { 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.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.psi.KtBlockCodeFragment import org.jetbrains.kotlin.psi.KtBlockCodeFragment
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.*
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
class FragmentModuleGenerator( class FragmentModuleGenerator(
@@ -24,18 +23,26 @@ class FragmentModuleGenerator(
override fun generateModuleFragment( override fun generateModuleFragment(
ktFiles: Collection<KtFile>, ktFiles: Collection<KtFile>,
): IrModuleFragment { ): IrModuleFragment {
val ktBlockCodeFragment = ktFiles.singleOrNull() as? KtBlockCodeFragment assert(ktFiles.singleOrNull { it is KtBlockCodeFragment} != null) {
?: TODO("Multiple fragments in one compilation not understood and implemented yet") "Amongst all files passed to the FragmentModuleGenerator should be exactly one KtBlockCodeFragment"
}
return IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule -> return IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
val irDeclarationGenerator = FragmentDeclarationGenerator(context, fragmentInfo) val irDeclarationGenerator = FragmentDeclarationGenerator(context, fragmentInfo)
irModule.files.add( ktFiles.forEach { ktFile ->
createEmptyIrFile(ktBlockCodeFragment).apply { irModule.files.add(
declarations.add( if (ktFile is KtBlockCodeFragment) {
irDeclarationGenerator.generateClassForCodeFragment(ktBlockCodeFragment) createEmptyIrFile(ktFile).apply {
) declarations.add(
patchDeclarationParents() irDeclarationGenerator.generateClassForCodeFragment(ktFile)
} )
) patchDeclarationParents()
}
} else {
val fileContext = context.createFileScopeContext(ktFile)
generateSingleFile(DeclarationGenerator(fileContext), ktFile, irModule)
}
)
}
} }
} }