[FIR]: fix library methods in packages

Library methods such as 'listOf' are resolved
to have the package fragments as their parents,
but JVM expects their containing file classes as parents.
This fix generates those file classes and
uses them as parent replacements for such library methods.
This commit is contained in:
Juan Chen
2020-02-19 14:54:18 -08:00
committed by Mikhail Glukhikh
parent 81b30b7399
commit 9dd8eda1c9
201 changed files with 19 additions and 199 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.PackageCodegenImpl
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
@@ -45,6 +46,13 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
irModuleFragment.descriptor, irModuleFragment.irBuiltins, symbolTable, extensions = extensions
)
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
val stubGenerator = irProviders.filterIsInstance<DeclarationStubGenerator>().first()
for (descriptor in symbolTable.functionDescriptorsWithNonClassParent()) {
val parentClass = stubGenerator.generateOrGetFacadeClass(descriptor)
descriptor.owner.parent = parentClass ?: throw AssertionError("Facade class for ${descriptor.name} not found")
}
JvmBackendFacade.doGenerateFilesInternal(
state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions
)
@@ -830,6 +830,17 @@ open class SymbolTable(private val signaturer: IdSignatureComposer) : ReferenceS
else ->
throw IllegalArgumentException("Unexpected value descriptor: $value")
}
fun functionDescriptorsWithNonClassParent(): Set<WrappedFunctionDescriptorWithContainerSource> {
val result = mutableSetOf<WrappedFunctionDescriptorWithContainerSource>()
for (descriptor in simpleFunctionSymbolTable.descriptorToSymbol.keys) {
if (descriptor is WrappedFunctionDescriptorWithContainerSource
&& descriptor.owner.parent !is IrClass) {
result.add(descriptor)
}
}
return result
}
}
inline fun <T, D : DeclarationDescriptor> SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T {