FIR: Fix interface delegation ABI

- Unifies the name of the `$$delegate_<n>` field between K1 and K2.
- Make the `$$delegate_<n>` field private
This commit is contained in:
Steven Schäfer
2022-11-16 18:27:56 +01:00
committed by Space Team
parent 91749737f8
commit a7ba081d22
44 changed files with 232 additions and 233 deletions
@@ -17,7 +17,7 @@ FILE: delegatedSuperType.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|A| = R|<local>/b|
private final field $$delegate_0: R|A| = R|<local>/b|
public final val b: R|B| = R|<local>/b|
public get(): R|B|
@@ -13,7 +13,7 @@ FILE: anonymousObjectByDelegate.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|B| = this@R|/test_1|.R|/A.b|
private final field $$delegate_0: R|B| = this@R|/test_1|.R|/A.b|
}
@@ -24,7 +24,7 @@ FILE: anonymousObjectByDelegate.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|B| = this@R|/test_2|.R|/A.b|
private final field $$delegate_0: R|B| = this@R|/test_2|.R|/A.b|
}
@@ -6,7 +6,7 @@ FILE: delegationInInterface.kt
}
public abstract interface B : R|A| {
local final field <$$delegate_0>: R|A| = <Unresolved name: a>#
private final field $$delegate_0: R|A| = <Unresolved name: a>#
public abstract val a: R|A|
public get(): R|A|
@@ -15,6 +15,6 @@ FILE: delegationInInterface.kt
public final val test: R|A| = R|/A.A|()
public get(): R|A|
public abstract interface C : R|A| {
local final field <$$delegate_0>: R|A| = R|/test|
private final field $$delegate_0: R|A| = R|/test|
}
@@ -8,7 +8,7 @@ FILE: superCallWithDelegation.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|A| = R|<local>/a|
private final field $$delegate_0: R|A| = R|<local>/a|
private final val a: R|A| = R|<local>/a|
private get(): R|A|
@@ -103,7 +103,7 @@ FILE: inlineClassDeclaration.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|kotlin/Comparable<kotlin/Int>| = R|<local>/x|
private final field $$delegate_0: R|kotlin/Comparable<kotlin/Int>| = R|<local>/x|
public final val x: R|kotlin/Int| = R|<local>/x|
public get(): R|kotlin/Int|
@@ -121,7 +121,7 @@ digraph smartcastInByClause_kt {
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|Base| = R|/Derived.Derived|(R|<local>/a|.R|/A.index|)
private final field $$delegate_0: R|Base| = R|/Derived.Derived|(R|<local>/a|.R|/A.index|)
public final val x: R|kotlin/Int| = R|<local>/a|.R|/A.index|
public get(): R|kotlin/Int|
@@ -30,7 +30,7 @@ FILE: smartcastInByClause.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|Base| = R|/Derived.Derived|(R|<local>/a|.R|/A.index|)
private final field $$delegate_0: R|Base| = R|/Derived.Derived|(R|<local>/a|.R|/A.index|)
public final val x: R|kotlin/Int| = R|<local>/a|.R|/A.index|
public get(): R|kotlin/Int|
@@ -28,7 +28,7 @@ FILE: Platform.kt
super<R|kotlin/Any|>()
}
local final field <$$delegate_0>: R|Configurables| = R|<local>/configurables|
private final field $$delegate_0: R|Configurables| = R|<local>/configurables|
public final val configurables: R|Configurables| = R|<local>/configurables|
public get(): R|Configurables|
@@ -423,7 +423,7 @@ private val FirNamedFunctionSymbol.matchesHashCodeSignature: Boolean
private val FirNamedFunctionSymbol.matchesToStringSignature: Boolean
get() = valueParameterSymbols.isEmpty()
val Name.isDelegated: Boolean get() = asString().startsWith("<\$\$delegate_")
val Name.isDelegated: Boolean get() = asString().startsWith("\$\$delegate_")
val ConeTypeProjection.isConflictingOrNotInvariant: Boolean get() = kind != ProjectionKind.INVARIANT || this is ConeKotlinTypeConflictingProjection
@@ -169,10 +169,7 @@ object FirSupertypesChecker : FirClassChecker() {
) {
for (subDeclaration in declaration.declarations) {
if (subDeclaration is FirField) {
if (subDeclaration.visibility == Visibilities.Local &&
subDeclaration.name.isSpecial &&
subDeclaration.name.isDelegated
) {
if (subDeclaration.visibility == Visibilities.Private && subDeclaration.name.isDelegated) {
val delegatedClassSymbol = subDeclaration.returnTypeRef.toRegularClassSymbol(context.session)
if (delegatedClassSymbol != null && delegatedClassSymbol.classKind != ClassKind.INTERFACE) {
reporter.reportOn(subDeclaration.returnTypeRef.source, FirErrors.DELEGATION_NOT_TO_INTERFACE, context)
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.addIfNotNull
class Fir2IrConverter(
private val moduleDescriptor: FirModuleDescriptor,
@@ -182,8 +183,7 @@ class Fir2IrConverter(
private fun processFileAndClassMembers(file: FirFile) {
val irFile = declarationStorage.getIrFile(file)
for (declaration in file.declarations) {
val irDeclaration = processMemberDeclaration(declaration, null, irFile) ?: continue
irFile.declarations += irDeclaration
processMemberDeclaration(declaration, null, irFile)
}
}
@@ -202,8 +202,7 @@ class Fir2IrConverter(
)
}
for (declaration in syntheticPropertiesLast(anonymousObject.declarations)) {
val irDeclaration = processMemberDeclaration(declaration, anonymousObject, irClass) ?: continue
irClass.declarations += irDeclaration
processMemberDeclaration(declaration, anonymousObject, irClass)
}
// Add delegated members *before* fake override generations.
// Otherwise, fake overrides for delegated members, which are redundant, will be added.
@@ -235,8 +234,7 @@ class Fir2IrConverter(
}
// At least on enum entry creation we may need a default constructor, so ctors should be converted first
for (declaration in syntheticPropertiesLast(allDeclarations)) {
val irDeclaration = processMemberDeclaration(declaration, regularClass, irClass) ?: continue
irClass.declarations += irDeclaration
processMemberDeclaration(declaration, regularClass, irClass)
}
// Add delegated members *before* fake override generations.
// Otherwise, fake overrides for delegated members, which are redundant, will be added.
@@ -344,63 +342,60 @@ class Fir2IrConverter(
}
}
// Process `declaration` and add the results to `parent`.
private fun processMemberDeclaration(
declaration: FirDeclaration,
containingClass: FirClass?,
parent: IrDeclarationParent
): IrDeclaration? {
parent: IrDeclarationContainer
) {
val isLocal = containingClass != null &&
(containingClass !is FirRegularClass || containingClass.isLocal)
return when (declaration) {
when (declaration) {
is FirRegularClass -> {
processClassMembers(declaration)
parent.declarations += processClassMembers(declaration)
}
is FirScript -> {
assert(parent is IrFile)
declarationStorage.getOrCreateIrScript(declaration)
}
is FirSimpleFunction -> {
declarationStorage.getOrCreateIrFunction(
parent.declarations += declarationStorage.getOrCreateIrFunction(
declaration, parent, isLocal = isLocal
)
}
is FirProperty -> {
if (declaration.source?.kind == KtFakeSourceElementKind.EnumGeneratedDeclaration &&
declaration.name == StandardNames.ENUM_ENTRIES &&
!session.languageVersionSettings.supportsFeature(LanguageFeature.EnumEntries)
if (declaration.source?.kind != KtFakeSourceElementKind.EnumGeneratedDeclaration ||
declaration.name != StandardNames.ENUM_ENTRIES ||
session.languageVersionSettings.supportsFeature(LanguageFeature.EnumEntries)
) {
// Note: we have to do it, because backend without the feature
// cannot process Enum.entries properly
null
} else {
declarationStorage.getOrCreateIrProperty(
parent.declarations += declarationStorage.getOrCreateIrProperty(
declaration, parent, isLocal = isLocal
)
}
}
is FirField -> {
if (declaration.isSynthetic) {
require(declaration.isSynthetic) {
"Unexpected non-synthetic field: ${declaration::class}"
}
parent.declarations.addIfNotNull(
declarationStorage.createIrFieldAndDelegatedMembers(declaration, containingClass!!, parent as IrClass)
} else {
throw AssertionError("Unexpected non-synthetic field: ${declaration::class}")
)
}
is FirConstructor -> {
if (!declaration.isPrimary) {
parent.declarations += declarationStorage.getOrCreateIrConstructor(
declaration, parent as IrClass, isLocal = isLocal
)
}
}
is FirConstructor -> if (!declaration.isPrimary) {
declarationStorage.getOrCreateIrConstructor(
declaration, parent as IrClass, isLocal = isLocal
)
} else {
null
}
is FirEnumEntry -> {
classifierStorage.createIrEnumEntry(declaration, parent as IrClass)
parent.declarations += classifierStorage.createIrEnumEntry(declaration, parent as IrClass)
}
is FirAnonymousInitializer -> {
declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass)
parent.declarations += declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass)
}
is FirTypeAlias -> {
// DO NOTHING
null
}
else -> {
error("Unexpected member: ${declaration::class}")
@@ -897,7 +897,7 @@ class Fir2IrDeclarationStorage(
createBackingField(
property, IrDeclarationOrigin.PROPERTY_DELEGATE,
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
Name.identifier("${property.name}\$delegate"), true, delegate
SpecialNames.propertyDelegateName(property.name), true, delegate
)
} else {
val initializer = property.backingField?.initializer ?: property.initializer
@@ -1230,7 +1230,7 @@ class Fir2IrDeclarationStorage(
enterScope(this)
delegate = declareIrVariable(
startOffset, endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE,
Name.identifier("${property.name}\$delegate"), property.delegate!!.typeRef.toIrType(),
SpecialNames.propertyDelegateName(property.name), property.delegate!!.typeRef.toIrType(),
isVar = false, isConst = false, isLateinit = false
)
delegate.parent = irParent
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.util.isComposite
import org.jetbrains.kotlin.name.SpecialNames
class Fir2IrLazyProperty(
components: Fir2IrComponents,
@@ -146,7 +147,7 @@ class Fir2IrLazyProperty(
createBackingField(
fir, IrDeclarationOrigin.PROPERTY_DELEGATE,
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility),
Name.identifier("${fir.name}\$delegate"), true, fir.delegate
SpecialNames.propertyDelegateName(fir.name), true, fir.delegate
)
}
}
@@ -51,7 +51,6 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.*
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -1848,18 +1847,17 @@ class DeclarationsConverter(
explicitDelegation.toFirSourceElement(), ConeSimpleDiagnostic("Should have delegate", DiagnosticKind.Syntax)
)
val delegateName = Name.special("<\$\$delegate_${delegateFieldsMap.size}>")
delegateFieldsMap.put(
index,
buildField {
source = calculatedFirExpression.source?.fakeElement(KtFakeSourceElementKind.ClassDelegationField)
moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic
name = delegateName
name = SpecialNames.delegateFieldName(delegateFieldsMap.size)
returnTypeRef = firTypeRef
symbol = FirFieldSymbol(CallableId(name))
isVar = false
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
status = FirDeclarationStatusImpl(Visibilities.Private, Modality.FINAL)
initializer = calculatedFirExpression
}.symbol
)
@@ -2019,7 +2017,7 @@ class DeclarationsConverter(
private fun convertIntersectionType(typeRefSource: KtSourceElement, intersectionType: LighterASTNode, isNullable: Boolean): FirTypeRef {
val children = arrayListOf<FirTypeRef>()
intersectionType.forEachChildren {
if (it.tokenType != KtTokens.AND) { //skip in forEachChildren?
if (it.tokenType != AND) { //skip in forEachChildren?
children.add(convertType(it))
}
}
@@ -382,7 +382,7 @@ open class RawFirBuilder(
private fun ValueArgument?.toFirExpression(): FirExpression {
if (this == null) {
return buildErrorExpression(
(this as? KtElement)?.toFirSourceElement(),
source = null,
ConeSimpleDiagnostic("No argument given", DiagnosticKind.Syntax),
)
}
@@ -848,18 +848,17 @@ open class RawFirBuilder(
val type = superTypeListEntry.typeReference.toFirOrErrorType()
val delegateExpression = { superTypeListEntry.delegateExpression }.toFirExpression("Should have delegate")
container.superTypeRefs += type
val delegateName = Name.special("<\$\$delegate_${delegateFieldsMap.size}>")
val delegateSource =
superTypeListEntry.delegateExpression?.toFirSourceElement(KtFakeSourceElementKind.ClassDelegationField)
val delegateField = buildField {
source = delegateSource
moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic
name = delegateName
name = SpecialNames.delegateFieldName(delegateFieldsMap.size)
returnTypeRef = type
symbol = FirFieldSymbol(CallableId(name))
isVar = false
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
status = FirDeclarationStatusImpl(Visibilities.Private, Modality.FINAL)
initializer = delegateExpression
}
delegateFieldsMap[index] = delegateField.symbol