[FIR2IR] Make ExternalPackageParentPatcher a lowering
This is needed for two reasons: 1. Consistency 2. It should run after compiler plugins, which are now runs after fir2ir is finished for all modules ^KT-56173
This commit is contained in:
committed by
Space Team
parent
8e73d5a54a
commit
fd87d722c1
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
// TODO: should be a lowering
|
||||
internal class ExternalPackageParentPatcher(
|
||||
private val components: Fir2IrComponents,
|
||||
private val fir2IrExtensions: Fir2IrExtensions
|
||||
) : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>) {
|
||||
super.visitMemberAccess(expression)
|
||||
val callee = expression.symbol.owner as? IrMemberWithContainerSource ?: return
|
||||
if (callee.parent is IrExternalPackageFragment) {
|
||||
val parentClass = fir2IrExtensions.generateOrGetFacadeClass(callee, components) ?: return
|
||||
parentClass.parent = callee.parent
|
||||
callee.parent = parentClass
|
||||
when (callee) {
|
||||
is IrProperty -> handleProperty(callee, parentClass)
|
||||
is IrSimpleFunction -> callee.correspondingPropertySymbol?.owner?.let { handleProperty(it, parentClass) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleProperty(property: IrProperty, newParent: IrClass) {
|
||||
property.parent = newParent
|
||||
property.getter?.parent = newParent
|
||||
property.setter?.parent = newParent
|
||||
property.backingField?.parent = newParent
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.KtPsiSourceFileLinesMapping
|
||||
import org.jetbrains.kotlin.KtSourceFileLinesMappingFromLineStartOffsets
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
@@ -32,12 +31,9 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
|
||||
import org.jetbrains.kotlin.ir.interpreter.transformer.preprocessForConstTransformer
|
||||
import org.jetbrains.kotlin.ir.interpreter.transformer.transformConst
|
||||
import org.jetbrains.kotlin.ir.util.KotlinMangler
|
||||
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.platform.isJs
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Fir2IrConverter(
|
||||
@@ -54,7 +50,6 @@ class Fir2IrConverter(
|
||||
allFirFiles: List<FirFile>,
|
||||
irModuleFragment: IrModuleFragmentImpl,
|
||||
fir2irVisitor: Fir2IrVisitor,
|
||||
fir2IrExtensions: Fir2IrExtensions,
|
||||
runPreCacheBuiltinClasses: Boolean
|
||||
) {
|
||||
session.lazyDeclarationResolver.disableLazyResolveContractChecks()
|
||||
@@ -98,8 +93,6 @@ class Fir2IrConverter(
|
||||
}
|
||||
|
||||
evaluateConstants(irModuleFragment, configuration)
|
||||
|
||||
irModuleFragment.acceptVoid(ExternalPackageParentPatcher(components, fir2IrExtensions))
|
||||
}
|
||||
|
||||
fun bindFakeOverridesOrPostpone(declarations: List<IrDeclaration>) {
|
||||
@@ -499,8 +492,7 @@ class Fir2IrConverter(
|
||||
}
|
||||
|
||||
converter.runSourcesConversion(
|
||||
allFirFiles, irModuleFragment, fir2irVisitor, fir2IrExtensions,
|
||||
runPreCacheBuiltinClasses = initializedIrBuiltIns == null
|
||||
allFirFiles, irModuleFragment, fir2irVisitor, runPreCacheBuiltinClasses = initializedIrBuiltIns == null
|
||||
)
|
||||
|
||||
return Fir2IrResult(irModuleFragment, components, moduleDescriptor)
|
||||
|
||||
+2
-1
@@ -331,7 +331,8 @@ open class JvmIrCodegenFactory(
|
||||
val phases = if (evaluatorFragmentInfoForPsi2Ir != null) jvmFragmentLoweringPhases else jvmLoweringPhases
|
||||
val phaseConfig = customPhaseConfig ?: PhaseConfig(phases)
|
||||
val context = JvmBackendContext(
|
||||
state, irModuleFragment.irBuiltins, symbolTable, phaseConfig, extensions, backendExtension, irSerializer, irPluginContext
|
||||
state, irModuleFragment.irBuiltins, symbolTable, phaseConfig, extensions,
|
||||
backendExtension, irSerializer, JvmIrDeserializerImpl(), irProviders, irPluginContext
|
||||
)
|
||||
if (evaluatorFragmentInfoForPsi2Ir != null) {
|
||||
context.localDeclarationsLoweringData = mutableMapOf()
|
||||
|
||||
@@ -473,7 +473,8 @@ private fun buildJvmLoweringPhases(
|
||||
nlevels = 1,
|
||||
actions = setOf(defaultDumper, validationAction),
|
||||
lower =
|
||||
fragmentSharedVariablesLowering then
|
||||
externalPackageParentPatcherPhase then
|
||||
fragmentSharedVariablesLowering then
|
||||
validateIrBeforeLowering then
|
||||
processOptionalAnnotationsPhase then
|
||||
expectDeclarationsRemovingPhase then
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmFileFacadeClass
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
|
||||
|
||||
internal val externalPackageParentPatcherPhase = makeIrModulePhase(
|
||||
::createLowering,
|
||||
name = "ExternalPackageParentPatcherLowering",
|
||||
description = "Replace parent from package fragment to FileKt class for top-level callables (K2 only)"
|
||||
)
|
||||
|
||||
private fun createLowering(context: CommonBackendContext): FileLoweringPass {
|
||||
require(context is JvmBackendContext)
|
||||
return when (context.configuration[CommonConfigurationKeys.USE_FIR]) {
|
||||
true -> ExternalPackageParentPatcherLowering(context)
|
||||
false, null -> FileLoweringPass.Empty
|
||||
}
|
||||
}
|
||||
|
||||
class ExternalPackageParentPatcherLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.acceptVoid(Visitor())
|
||||
}
|
||||
|
||||
private inner class Visitor : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>) {
|
||||
visitElement(expression)
|
||||
val callee = expression.symbol.owner as? IrMemberWithContainerSource ?: return
|
||||
if (callee.parent is IrExternalPackageFragment) {
|
||||
val parentClass = generateOrGetFacadeClass(callee) ?: return
|
||||
parentClass.parent = callee.parent
|
||||
callee.parent = parentClass
|
||||
when (callee) {
|
||||
is IrProperty -> handleProperty(callee, parentClass)
|
||||
is IrSimpleFunction -> callee.correspondingPropertySymbol?.owner?.let { handleProperty(it, parentClass) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource): IrClass? {
|
||||
val deserializedSource = declaration.containerSource ?: return null
|
||||
if (deserializedSource !is FacadeClassSource) return null
|
||||
val facadeName = deserializedSource.facadeClassName ?: deserializedSource.className
|
||||
return JvmFileFacadeClass(
|
||||
if (deserializedSource.facadeClassName != null) IrDeclarationOrigin.JVM_MULTIFILE_CLASS else IrDeclarationOrigin.FILE_CLASS,
|
||||
facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName(),
|
||||
deserializedSource,
|
||||
deserializeIr = { irClass -> deserializeTopLevelClass(irClass) }
|
||||
).also {
|
||||
it.createParameterDeclarations()
|
||||
context.classNameOverride[it] = facadeName
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeTopLevelClass(irClass: IrClass): Boolean {
|
||||
return context.irDeserializer.deserializeTopLevelClass(
|
||||
irClass, context.irBuiltIns, context.symbolTable, context.irProviders, context.generatorExtensions
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleProperty(property: IrProperty, newParent: IrClass) {
|
||||
property.parent = newParent
|
||||
property.getter?.parent = newParent
|
||||
property.setter?.parent = newParent
|
||||
property.backingField?.parent = newParent
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
|
||||
internal val typeAliasAnnotationMethodsPhase = makeIrFilePhase(
|
||||
::TypeAliasAnnotationMethodsLowering,
|
||||
name = "TypeAliasAnnotationMethodsLowering",
|
||||
|
||||
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -49,6 +49,8 @@ class JvmBackendContext(
|
||||
val generatorExtensions: JvmGeneratorExtensions,
|
||||
val backendExtension: JvmBackendExtension,
|
||||
val irSerializer: JvmIrSerializer?,
|
||||
val irDeserializer: JvmIrDeserializer,
|
||||
val irProviders: List<IrProvider>,
|
||||
val irPluginContext: IrPluginContext?,
|
||||
) : CommonBackendContext {
|
||||
|
||||
@@ -63,12 +65,17 @@ class JvmBackendContext(
|
||||
generatorExtensions: JvmGeneratorExtensions,
|
||||
backendExtension: JvmBackendExtension,
|
||||
irSerializer: JvmIrSerializer?,
|
||||
) : this(state, irBuiltIns, symbolTable, phaseConfig, generatorExtensions, backendExtension, irSerializer, null)
|
||||
irProviders: List<IrProvider>,
|
||||
irDeserializer: JvmIrDeserializer,
|
||||
) : this(
|
||||
state, irBuiltIns, symbolTable, phaseConfig, generatorExtensions,
|
||||
backendExtension, irSerializer, irDeserializer, irProviders, irPluginContext = null
|
||||
)
|
||||
|
||||
data class LocalFunctionData(
|
||||
val localContext: LocalDeclarationsLowering.LocalFunctionContext,
|
||||
val newParameterToOld: Map<IrValueParameter, IrValueParameter>,
|
||||
val newParameterToCaptured: Map<IrValueParameter, IrValueSymbol>
|
||||
val newParameterToCaptured: Map<IrValueParameter, IrValueSymbol>,
|
||||
)
|
||||
|
||||
// If not-null, this is populated by LocalDeclarationsLowering with the intermediate data
|
||||
@@ -219,7 +226,7 @@ class JvmBackendContext(
|
||||
override fun handleDeepCopy(
|
||||
fileSymbolMap: MutableMap<IrFileSymbol, IrFileSymbol>,
|
||||
classSymbolMap: MutableMap<IrClassSymbol, IrClassSymbol>,
|
||||
functionSymbolMap: MutableMap<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>
|
||||
functionSymbolMap: MutableMap<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>,
|
||||
) {
|
||||
val oldClassesWithNameOverride = classNameOverride.keys.toList()
|
||||
for (klass in oldClassesWithNameOverride) {
|
||||
@@ -290,7 +297,7 @@ class JvmBackendContext(
|
||||
get() = false
|
||||
|
||||
inner class JvmIr(
|
||||
symbolTable: SymbolTable
|
||||
symbolTable: SymbolTable,
|
||||
) : Ir<JvmBackendContext>(this) {
|
||||
override val symbols = JvmSymbols(this@JvmBackendContext, symbolTable)
|
||||
|
||||
@@ -300,7 +307,7 @@ class JvmBackendContext(
|
||||
override fun remapMultiFieldValueClassStructure(
|
||||
oldFunction: IrFunction,
|
||||
newFunction: IrFunction,
|
||||
parametersMappingOrNull: Map<IrValueParameter, IrValueParameter>?
|
||||
parametersMappingOrNull: Map<IrValueParameter, IrValueParameter>?,
|
||||
) {
|
||||
val parametersMapping = parametersMappingOrNull ?: run {
|
||||
require(oldFunction.explicitParametersCount == newFunction.explicitParametersCount) {
|
||||
|
||||
+12
-3
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.test.backend.handlers
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.AbstractIrLazyFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
@@ -25,7 +27,7 @@ class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(test
|
||||
override fun processModule(module: TestModule, info: IrBackendInput) {
|
||||
info.processAllIrModuleFragments(module) { irModule, _ ->
|
||||
irModule.acceptChildrenVoid(InlineFunctionsCollector())
|
||||
irModule.acceptChildrenVoid(InlineCallBodiesCheck())
|
||||
irModule.acceptChildrenVoid(InlineCallBodiesCheck(firEnabled = module.frontendKind == FrontendKinds.FIR))
|
||||
}
|
||||
|
||||
assertions.assertTrue((info as IrBackendInput.JvmIrBackendInput).backendInput.symbolTable.allUnbound.isEmpty())
|
||||
@@ -46,7 +48,7 @@ class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(test
|
||||
}
|
||||
}
|
||||
|
||||
inner class InlineCallBodiesCheck : IrElementVisitorVoid {
|
||||
inner class InlineCallBodiesCheck(val firEnabled: Boolean) : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -68,7 +70,14 @@ class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(test
|
||||
if (this !is AbstractIrLazyFunction) return body != null
|
||||
if (!isDeserializationEnabled) return false
|
||||
if (!isInline || isFakeOverride) return false
|
||||
return getTopLevelDeclaration() is DeserializableClass
|
||||
val topLevelDeclaration = getTopLevelDeclaration()
|
||||
if (topLevelDeclaration is DeserializableClass) return true
|
||||
return when (firEnabled) {
|
||||
// In compilation with FIR parents of external top-levels functions are replaced
|
||||
// in lowerings, not in fir2ir converter
|
||||
true -> topLevelDeclaration.parent is IrExternalPackageFragment
|
||||
false -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user