IR: introduce StubGeneratorExtensions for ExternalDependenciesGenerator

This is a refactoring to simplify the API of
ExternalDependenciesGenerator and to constrain future additions of
platform-specific stub generator extensions.
This commit is contained in:
Alexander Udalov
2019-11-18 16:02:47 +01:00
parent c3af2d5a10
commit 608449f41d
13 changed files with 114 additions and 134 deletions
@@ -56,6 +56,7 @@ object Fir2IrConverter {
symbolTable: SymbolTable,
builtIns: IrBuiltIns
) {
// TODO: provide StubGeneratorExtensions for correct lazy stub IR generation on JVM
ExternalDependenciesGenerator(irModule.descriptor, symbolTable, builtIns).generateUnboundSymbolsAsDependencies()
}
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.backend.js
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.config.CompilerConfiguration
@@ -18,6 +17,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.DFS
@@ -57,12 +57,7 @@ fun compile(
// Load declarations referenced during `context` initialization
dependencyModules.forEach {
ExternalDependenciesGenerator(
it.descriptor,
symbolTable,
irBuiltIns,
deserializer = deserializer
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(it.descriptor, symbolTable, irBuiltIns, deserializer).generateUnboundSymbolsAsDependencies()
}
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
@@ -71,11 +66,7 @@ fun compile(
moduleFragment.files += irFiles
// Create stubs
ExternalDependenciesGenerator(
moduleDescriptor = moduleDescriptor,
symbolTable = symbolTable,
irBuiltIns = irBuiltIns
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
moduleFragment.patchDeclarationParents()
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
@@ -6,27 +6,20 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object JvmBackendFacade {
fun doGenerateFiles(
@@ -35,12 +28,12 @@ object JvmBackendFacade {
errorHandler: CompilationErrorHandler,
phaseConfig: PhaseConfig
) {
val facadeGenerator = FacadeClassGenerator()
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, facadeClassGenerator = facadeGenerator::generate)
val psi2ir = Psi2IrTranslator(state.languageVersionSettings)
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
val extensions = JvmStubGeneratorExtensions()
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, stubGeneratorExtensions = extensions)
doGenerateFilesInternal(
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, facadeGenerator
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, extensions
)
}
@@ -51,7 +44,7 @@ object JvmBackendFacade {
symbolTable: SymbolTable,
sourceManager: PsiSourceManager,
phaseConfig: PhaseConfig,
facadeGenerator: FacadeClassGenerator = FacadeClassGenerator()
extensions: JvmStubGeneratorExtensions = JvmStubGeneratorExtensions()
) {
val context = JvmBackendContext(
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig
@@ -62,15 +55,15 @@ object JvmBackendFacade {
state.mapInlineClass = { descriptor ->
context.typeMapper.mapType(context.referenceClass(descriptor).defaultType)
}
//TODO
ExternalDependenciesGenerator(
irModuleFragment.descriptor,
symbolTable,
irModuleFragment.irBuiltins,
JvmGeneratorExtensions.externalDeclarationOrigin,
facadeClassGenerator = facadeGenerator::generate
extensions = extensions
).generateUnboundSymbolsAsDependencies()
context.classNameOverride = facadeGenerator.classNameOverride
context.classNameOverride = extensions.classNameOverride
for (irFile in irModuleFragment.files) {
for (extension in IrGenerationExtension.getInstances(context.state.project)) {
@@ -107,20 +100,4 @@ object JvmBackendFacade {
}
}
}
internal class FacadeClassGenerator {
val classNameOverride = mutableMapOf<IrClass, JvmClassName>()
fun generate(source: DeserializedContainerSource): IrClass? {
val jvmPackagePartSource = source.safeAs<JvmPackagePartSource>() ?: return null
val facadeName = jvmPackagePartSource.facadeClassName ?: jvmPackagePartSource.className
return buildClass {
origin = IrDeclarationOrigin.FILE_CLASS
name = facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName()
}.also {
it.createParameterDeclarations()
classNameOverride[it] = facadeName
}
}
}
}
@@ -5,31 +5,31 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
object JvmGeneratorExtensions : GeneratorExtensions() {
override val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = { descriptor ->
if (descriptor is JavaCallableMemberDescriptor)
IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
else
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
}
override val samConversion: SamConversion
get() = JvmSamConversion
@@ -66,3 +66,25 @@ object JvmGeneratorExtensions : GeneratorExtensions() {
else
null
}
class JvmStubGeneratorExtensions : StubGeneratorExtensions() {
val classNameOverride = mutableMapOf<IrClass, JvmClassName>()
override fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? =
if (descriptor is JavaCallableMemberDescriptor)
IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
else
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
override fun generateFacadeClass(source: DeserializedContainerSource): IrClass? {
val jvmPackagePartSource = source as? JvmPackagePartSource ?: return null
val facadeName = jvmPackagePartSource.facadeClassName ?: jvmPackagePartSource.className
return buildClass {
origin = IrDeclarationOrigin.FILE_CLASS
name = facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName()
}.also {
it.createParameterDeclarations()
classNameOverride[it] = facadeName
}
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.backend.wasm
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.wasm.codegen.IrModuleToWasm
@@ -15,6 +14,7 @@ import org.jetbrains.kotlin.ir.backend.js.loadIr
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
@@ -37,12 +37,7 @@ fun compileWasm(
// Load declarations referenced during `context` initialization
dependencyModules.forEach {
ExternalDependenciesGenerator(
it.descriptor,
symbolTable,
irBuiltIns,
deserializer = deserializer
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(it.descriptor, symbolTable, irBuiltIns, deserializer).generateUnboundSymbolsAsDependencies()
}
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
@@ -51,14 +46,10 @@ fun compileWasm(
moduleFragment.files += irFiles
// Create stubs
ExternalDependenciesGenerator(
moduleDescriptor = moduleDescriptor,
symbolTable = symbolTable,
irBuiltIns = irBuiltIns
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
moduleFragment.patchDeclarationParents()
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
return IrModuleToWasm(context).generateModule(moduleFragment)
}
}
@@ -19,12 +19,8 @@ package org.jetbrains.kotlin.psi2ir
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.IrProvider
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.AnnotationGenerator
@@ -33,13 +29,11 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.SmartList
class Psi2IrTranslator(
val languageVersionSettings: LanguageVersionSettings,
val configuration: Psi2IrConfiguration = Psi2IrConfiguration(),
val facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
val configuration: Psi2IrConfiguration = Psi2IrConfiguration()
) {
interface PostprocessingStep {
fun postprocess(context: GeneratorContext, irElement: IrElement)
@@ -55,10 +49,11 @@ class Psi2IrTranslator(
moduleDescriptor: ModuleDescriptor,
ktFiles: Collection<KtFile>,
bindingContext: BindingContext,
generatorExtensions: GeneratorExtensions
generatorExtensions: GeneratorExtensions,
stubGeneratorExtensions: StubGeneratorExtensions
): IrModuleFragment {
val context = createGeneratorContext(moduleDescriptor, bindingContext, extensions = generatorExtensions)
return generateModuleFragment(context, ktFiles)
return generateModuleFragment(context, ktFiles, stubGeneratorExtensions = stubGeneratorExtensions)
}
fun createGeneratorContext(
@@ -73,17 +68,18 @@ class Psi2IrTranslator(
context: GeneratorContext,
ktFiles: Collection<KtFile>,
deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList()
irProviders: List<IrProvider> = emptyList(),
stubGeneratorExtensions: StubGeneratorExtensions = StubGeneratorExtensions()
): IrModuleFragment {
val moduleGenerator = ModuleGenerator(context)
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
val irModule = moduleGenerator.generateModuleFragment(ktFiles)
// This is required for implicit casts insertion on IrTypes (work-in-progress).
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, facadeClassGenerator)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
irModule.patchDeclarationParents()
postprocess(context, irModule)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, facadeClassGenerator)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
return irModule
}
@@ -6,16 +6,11 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.types.KotlinType
open class GeneratorExtensions {
open val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)?
get() = null
open val samConversion: SamConversion
get() = SamConversion
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.MetadataSource
@@ -26,10 +25,10 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.IrProvider
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addIfNotNull
class ModuleGenerator(override val context: GeneratorContext) : Generator {
@@ -37,11 +36,6 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
private val constantValueGenerator = context.constantValueGenerator
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
generateUnboundSymbolsAsDependencies(irModule)
}
fun generateModuleFragmentWithoutDependencies(ktFiles: Collection<KtFile>): IrModuleFragment =
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
irModule.files.addAll(generateFiles(ktFiles))
}
@@ -50,16 +44,10 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
irModule: IrModuleFragment,
deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList(),
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
) {
ExternalDependenciesGenerator(
irModule.descriptor,
context.symbolTable,
context.irBuiltIns,
context.extensions.externalDeclarationOrigin,
deserializer,
irProviders,
facadeClassGenerator
irModule.descriptor, context.symbolTable, context.irBuiltIns, deserializer, irProviders, extensions
).generateUnboundSymbolsAsDependencies()
}
@@ -36,9 +36,8 @@ class DeclarationStubGenerator(
moduleDescriptor: ModuleDescriptor,
val symbolTable: SymbolTable,
languageVersionSettings: LanguageVersionSettings,
private val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
private val irProviders: List<IrProvider> = emptyList(),
private val facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
private val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
) {
private val lazyTable = symbolTable.lazyWrapper
@@ -49,7 +48,8 @@ class DeclarationStubGenerator(
}
val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
val typeTranslator =
TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable)
private val facadeClassMap = mutableMapOf<DeserializedContainerSource, IrClass?>()
@@ -79,7 +79,7 @@ class DeclarationStubGenerator(
val packageFragment = directMember.containingDeclaration as? PackageFragmentDescriptor ?: return null
val containerSource = directMember.safeAs<DescriptorWithContainerSource>()?.containerSource ?: return null
return facadeClassMap.getOrPut(containerSource) {
facadeClassGenerator(containerSource)?.also { facade ->
extensions.generateFacadeClass(containerSource)?.also { facade ->
val packageStub = generateOrGetEmptyExternalPackageFragmentStub(packageFragment)
facade.parent = packageStub
packageStub.declarations.add(facade)
@@ -106,7 +106,7 @@ class DeclarationStubGenerator(
}
private fun computeOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin =
externalDeclarationOrigin?.invoke(descriptor) ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
extensions.computeExternalDeclarationOrigin(descriptor) ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
internal fun generatePropertyStub(
descriptor: PropertyDescriptor,
@@ -16,34 +16,28 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import kotlin.math.min
class ExternalDependenciesGenerator(
moduleDescriptor: ModuleDescriptor,
val symbolTable: SymbolTable,
val irBuiltIns: IrBuiltIns,
externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
private val deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList(),
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
) {
private val stubGenerator = DeclarationStubGenerator(
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, externalDeclarationOrigin,
listOfNotNull(deserializer) + irProviders, facadeClassGenerator
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, listOfNotNull(deserializer) + irProviders, extensions
)
fun generateUnboundSymbolsAsDependencies() {
stubGenerator.unboundSymbolGeneration = true
do {
fun <T> haveNotStabilized(prev: ArrayList<T>, cur: Set<T>) =
cur.isNotEmpty() && (prev.size != cur.size || prev.any { !cur.contains(it) })
cur.isNotEmpty() && (prev.size != cur.size || prev.any { !cur.contains(it) })
val unboundClasses = ArrayList(symbolTable.unboundClasses)
val unboundConstructors = ArrayList(symbolTable.unboundConstructors)
@@ -89,4 +83,4 @@ class ExternalDependenciesGenerator(
s.toList().subList(0, min(10, s.size)).joinToString(separator = "\n") { it.descriptor.toString() }
}
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
open class StubGeneratorExtensions {
open fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? = null
open fun generateFacadeClass(source: DeserializedContainerSource): IrClass? = null
companion object {
@JvmField
val EMPTY = StubGeneratorExtensions()
}
}
@@ -16,16 +16,19 @@
package org.jetbrains.kotlin.ir
import junit.framework.TestCase
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
import org.jetbrains.kotlin.backend.jvm.JvmStubGeneratorExtensions
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.backend.js.JsGeneratorExtensions
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
@@ -37,8 +40,6 @@ import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
@@ -114,27 +115,39 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
moduleDescriptors = emptyList(),
friendModuleDescriptors = emptyList()
),
psi2ir, ktFilesToAnalyze, JsGeneratorExtensions()
psi2ir, ktFilesToAnalyze, JsGeneratorExtensions(), StubGeneratorExtensions.EMPTY
)
fun generateIrModuleWithJvmResolve(
ktFilesToAnalyze: List<KtFile>, environment: KotlinCoreEnvironment, psi2ir: Psi2IrTranslator
): IrModuleFragment =
generateIrModule(JvmResolveUtil.analyze(ktFilesToAnalyze, environment), psi2ir, ktFilesToAnalyze, JvmGeneratorExtensions)
generateIrModule(
JvmResolveUtil.analyze(ktFilesToAnalyze, environment), psi2ir, ktFilesToAnalyze, JvmGeneratorExtensions,
IrTestStubGeneratorExtensions
)
private fun generateIrModule(
analysisResult: AnalysisResult,
psi2ir: Psi2IrTranslator,
ktFilesToAnalyze: List<KtFile>,
generatorExtensions: GeneratorExtensions
generatorExtensions: GeneratorExtensions,
stubGeneratorExtensions: StubGeneratorExtensions
): IrModuleFragment {
if (!psi2ir.configuration.ignoreErrors) {
analysisResult.throwIfError()
AnalyzingUtils.throwExceptionOnErrors(analysisResult.bindingContext)
}
return psi2ir.generateModule(
analysisResult.moduleDescriptor, ktFilesToAnalyze, analysisResult.bindingContext, generatorExtensions
analysisResult.moduleDescriptor, ktFilesToAnalyze, analysisResult.bindingContext, generatorExtensions,
stubGeneratorExtensions
)
}
}
private object IrTestStubGeneratorExtensions : StubGeneratorExtensions() {
private val jvm = JvmStubGeneratorExtensions()
override fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? =
jvm.computeExternalDeclarationOrigin(descriptor)
}
}
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
import org.jetbrains.kotlin.ir.backend.js.emptyLoggingContext
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler
import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
@@ -51,12 +51,7 @@ class JsScriptDependencyCompiler(
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it) }
ExternalDependenciesGenerator(
moduleDescriptor = moduleDescriptor,
symbolTable = symbolTable,
irBuiltIns = irBuiltIns,
deserializer = jsLinker
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns, jsLinker).generateUnboundSymbolsAsDependencies()
moduleFragment.patchDeclarationParents()
val backendContext = JsIrBackendContext(
@@ -69,12 +64,7 @@ class JsScriptDependencyCompiler(
true
)
ExternalDependenciesGenerator(
moduleDescriptor = moduleDescriptor,
symbolTable = symbolTable,
irBuiltIns = irBuiltIns,
deserializer = jsLinker
).generateUnboundSymbolsAsDependencies()
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns, jsLinker).generateUnboundSymbolsAsDependencies()
moduleFragment.patchDeclarationParents()
moduleFragment.files += irDependencies.flatMap { it.files }