[FIR] Save mapping from supertype to delegated field in class attribute
This is needed to let checkers know which specific interface was implemented by delegation
This commit is contained in:
committed by
teamcityserver
parent
e25fff701b
commit
b0f38bd996
+27
-10
@@ -437,6 +437,7 @@ class DeclarationsConverter(
|
||||
typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, classSymbol) }
|
||||
|
||||
withCapturedTypeParameters(status.isInner || isLocal, firTypeParameters) {
|
||||
var delegatedFieldsMap: Map<Int, FirFieldSymbol>? = null
|
||||
buildRegularClass {
|
||||
source = classNode.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
@@ -508,7 +509,8 @@ class DeclarationsConverter(
|
||||
)
|
||||
val firPrimaryConstructor = primaryConstructorWrapper?.firConstructor
|
||||
firPrimaryConstructor?.let { declarations += it }
|
||||
delegationSpecifiers?.delegateFields?.map { declarations += it }
|
||||
delegationSpecifiers?.delegateFieldsMap?.values?.mapTo(declarations) { it.fir }
|
||||
delegatedFieldsMap = delegationSpecifiers?.delegateFieldsMap?.takeIf { it.isNotEmpty() }
|
||||
|
||||
val properties = mutableListOf<FirProperty>()
|
||||
if (primaryConstructor != null && firPrimaryConstructor != null) {
|
||||
@@ -561,6 +563,8 @@ class DeclarationsConverter(
|
||||
)
|
||||
}
|
||||
initCompanionObjectSymbolAttr()
|
||||
}.also {
|
||||
it.delegateFieldsMap = delegatedFieldsMap
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
@@ -575,6 +579,7 @@ class DeclarationsConverter(
|
||||
*/
|
||||
fun convertObjectLiteral(objectLiteral: LighterASTNode): FirElement {
|
||||
return withChildClassName(SpecialNames.ANONYMOUS, isExpect = false) {
|
||||
var delegatedFieldsMap: Map<Int, FirFieldSymbol>? = null
|
||||
buildAnonymousObjectExpression {
|
||||
val objectDeclaration = objectLiteral.getChildNodesByType(OBJECT_DECLARATION).first()
|
||||
val sourceElement = objectDeclaration.toFirSourceElement()
|
||||
@@ -609,7 +614,8 @@ class DeclarationsConverter(
|
||||
superTypeRefs += specifiers.superTypesRef
|
||||
superTypeCallEntry += specifiers.delegatedConstructorArguments
|
||||
delegatedConstructorSource = specifiers.delegatedConstructorSource
|
||||
delegateFields = specifiers.delegateFields
|
||||
delegateFields = specifiers.delegateFieldsMap.values.map { it.fir }
|
||||
delegatedFieldsMap = specifiers.delegateFieldsMap.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
CLASS_BODY -> classBody = it
|
||||
}
|
||||
@@ -647,6 +653,8 @@ class DeclarationsConverter(
|
||||
classBody?.let {
|
||||
this.declarations += convertClassBody(it, classWrapper)
|
||||
}
|
||||
}.also {
|
||||
it.delegateFieldsMap = delegatedFieldsMap
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1695,7 +1703,7 @@ class DeclarationsConverter(
|
||||
val superTypesRef: List<FirTypeRef>,
|
||||
val delegatedConstructorArguments: List<FirExpression>,
|
||||
val delegatedConstructorSource: KtLightSourceElement?,
|
||||
val delegateFields: List<FirField>,
|
||||
val delegateFieldsMap: Map<Int, FirFieldSymbol>,
|
||||
)
|
||||
|
||||
private fun convertDelegationSpecifiers(delegationSpecifiers: LighterASTNode): DelegationSpecifiers {
|
||||
@@ -1703,25 +1711,29 @@ class DeclarationsConverter(
|
||||
val superTypeCallEntry = mutableListOf<FirExpression>()
|
||||
var delegatedSuperTypeRef: FirTypeRef? = null
|
||||
var delegateConstructorSource: KtLightSourceElement? = null
|
||||
val delegateFields = mutableListOf<FirField>()
|
||||
val delegateFieldsMap = mutableMapOf<Int, FirFieldSymbol>()
|
||||
var index = 0
|
||||
delegationSpecifiers.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
SUPER_TYPE_ENTRY -> {
|
||||
superTypeRefs += convertType(it)
|
||||
index++
|
||||
}
|
||||
SUPER_TYPE_CALL_ENTRY -> convertConstructorInvocation(it).apply {
|
||||
delegatedSuperTypeRef = first
|
||||
superTypeRefs += first
|
||||
superTypeCallEntry += second
|
||||
delegateConstructorSource = it.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
index++
|
||||
}
|
||||
DELEGATED_SUPER_TYPE_ENTRY -> {
|
||||
superTypeRefs += convertExplicitDelegation(it, delegateFields)
|
||||
superTypeRefs += convertExplicitDelegation(it, delegateFieldsMap, index)
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
return DelegationSpecifiers(
|
||||
delegatedSuperTypeRef, superTypeRefs, superTypeCallEntry, delegateConstructorSource, delegateFields
|
||||
delegatedSuperTypeRef, superTypeRefs, superTypeCallEntry, delegateConstructorSource, delegateFieldsMap
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1751,7 +1763,11 @@ class DeclarationsConverter(
|
||||
* : userType "by" element
|
||||
* ;
|
||||
*/
|
||||
private fun convertExplicitDelegation(explicitDelegation: LighterASTNode, delegateFields: MutableList<FirField>): FirTypeRef {
|
||||
private fun convertExplicitDelegation(
|
||||
explicitDelegation: LighterASTNode,
|
||||
delegateFieldsMap: MutableMap<Int, FirFieldSymbol>,
|
||||
index: Int
|
||||
): FirTypeRef {
|
||||
lateinit var firTypeRef: FirTypeRef
|
||||
var firExpression: FirExpression? = null
|
||||
explicitDelegation.forEachChildren {
|
||||
@@ -1765,8 +1781,9 @@ class DeclarationsConverter(
|
||||
explicitDelegation.toFirSourceElement(), ConeSimpleDiagnostic("Should have delegate", DiagnosticKind.Syntax)
|
||||
)
|
||||
|
||||
val delegateName = Name.special("<\$\$delegate_${delegateFields.size}>")
|
||||
delegateFields.add(
|
||||
val delegateName = Name.special("<\$\$delegate_${delegateFieldsMap.size}>")
|
||||
delegateFieldsMap.put(
|
||||
index,
|
||||
buildField {
|
||||
source = calculatedFirExpression.source?.fakeElement(KtFakeSourceElementKind.ClassDelegationField)
|
||||
moduleData = baseModuleData
|
||||
@@ -1777,7 +1794,7 @@ class DeclarationsConverter(
|
||||
isVar = false
|
||||
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
|
||||
initializer = calculatedFirExpression
|
||||
}
|
||||
}.symbol
|
||||
)
|
||||
return firTypeRef
|
||||
}
|
||||
|
||||
+21
-13
@@ -746,25 +746,25 @@ open class RawFirBuilder(
|
||||
classKind: ClassKind,
|
||||
containerTypeParameters: List<FirTypeParameterRef>,
|
||||
containingClassIsExpectClass: Boolean
|
||||
): FirTypeRef {
|
||||
): Pair<FirTypeRef, Map<Int, FirFieldSymbol>?> {
|
||||
var superTypeCallEntry: KtSuperTypeCallEntry? = null
|
||||
var delegatedSuperTypeRef: FirTypeRef? = null
|
||||
val delegateFields = mutableListOf<FirField>()
|
||||
for (superTypeListEntry in superTypeListEntries) {
|
||||
val delegateFieldsMap = mutableMapOf<Int, FirFieldSymbol>()
|
||||
superTypeListEntries.forEachIndexed { index, superTypeListEntry ->
|
||||
when (superTypeListEntry) {
|
||||
is KtSuperTypeEntry -> {
|
||||
container.superTypeRefs += superTypeListEntry.typeReference.toFirOrErrorType()
|
||||
}
|
||||
is KtSuperTypeCallEntry -> {
|
||||
delegatedSuperTypeRef = superTypeListEntry.calleeExpression.typeReference.toFirOrErrorType()
|
||||
container.superTypeRefs += delegatedSuperTypeRef
|
||||
container.superTypeRefs += delegatedSuperTypeRef!!
|
||||
superTypeCallEntry = superTypeListEntry
|
||||
}
|
||||
is KtDelegatedSuperTypeEntry -> {
|
||||
val type = superTypeListEntry.typeReference.toFirOrErrorType()
|
||||
val delegateExpression = { superTypeListEntry.delegateExpression }.toFirExpression("Should have delegate")
|
||||
container.superTypeRefs += type
|
||||
val delegateName = Name.special("<\$\$delegate_${delegateFields.size}>")
|
||||
val delegateName = Name.special("<\$\$delegate_${delegateFieldsMap.size}>")
|
||||
val delegateSource =
|
||||
superTypeListEntry.delegateExpression?.toFirSourceElement(KtFakeSourceElementKind.ClassDelegationField)
|
||||
val delegateField = buildField {
|
||||
@@ -778,7 +778,7 @@ open class RawFirBuilder(
|
||||
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
|
||||
initializer = delegateExpression
|
||||
}
|
||||
delegateFields.add(delegateField)
|
||||
delegateFieldsMap[index] = delegateField.symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -798,7 +798,7 @@ open class RawFirBuilder(
|
||||
isNullable = false,
|
||||
)
|
||||
}
|
||||
container.superTypeRefs += delegatedSuperTypeRef
|
||||
container.superTypeRefs += delegatedSuperTypeRef!!
|
||||
}
|
||||
this is KtClass && classKind == ClassKind.ANNOTATION_CLASS -> {
|
||||
container.superTypeRefs += implicitAnnotationType
|
||||
@@ -828,16 +828,16 @@ open class RawFirBuilder(
|
||||
if ((this !is KtClass || !this.isInterface()) && (primaryConstructor != null || !shouldNotGenerateImplicitPrimaryConstructor)) {
|
||||
val firPrimaryConstructor = primaryConstructor.toFirConstructor(
|
||||
superTypeCallEntry,
|
||||
delegatedSuperTypeRef,
|
||||
delegatedSelfTypeRef ?: delegatedSuperTypeRef,
|
||||
delegatedSuperTypeRef!!,
|
||||
delegatedSelfTypeRef ?: delegatedSuperTypeRef!!,
|
||||
owner = this,
|
||||
containerTypeParameters,
|
||||
body = null
|
||||
)
|
||||
container.declarations += firPrimaryConstructor
|
||||
}
|
||||
container.declarations += delegateFields
|
||||
return delegatedSuperTypeRef
|
||||
delegateFieldsMap.values.mapTo(container.declarations) { it.fir }
|
||||
return delegatedSuperTypeRef!! to delegateFieldsMap.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
private fun KtPrimaryConstructor?.toFirConstructor(
|
||||
@@ -1045,6 +1045,7 @@ open class RawFirBuilder(
|
||||
}
|
||||
|
||||
withCapturedTypeParameters(status.isInner || isLocal, listOf()) {
|
||||
var delegatedFieldsMap: Map<Int, FirFieldSymbol>?
|
||||
buildRegularClass {
|
||||
source = classOrObject.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
@@ -1067,7 +1068,7 @@ open class RawFirBuilder(
|
||||
val delegatedSelfType = classOrObject.toDelegatedSelfType(this)
|
||||
registerSelfType(delegatedSelfType)
|
||||
|
||||
val delegatedSuperType = classOrObject.extractSuperTypeListEntriesTo(
|
||||
val (delegatedSuperType, extractedDelegatedFieldsMap) = classOrObject.extractSuperTypeListEntriesTo(
|
||||
this,
|
||||
delegatedSelfType,
|
||||
null,
|
||||
@@ -1075,6 +1076,7 @@ open class RawFirBuilder(
|
||||
typeParameters,
|
||||
containingClassIsExpectClass = classIsExpect
|
||||
)
|
||||
delegatedFieldsMap = extractedDelegatedFieldsMap
|
||||
|
||||
val primaryConstructor = classOrObject.primaryConstructor
|
||||
val firPrimaryConstructor = declarations.firstOrNull { it is FirConstructor } as? FirConstructor
|
||||
@@ -1136,6 +1138,8 @@ open class RawFirBuilder(
|
||||
initCompanionObjectSymbolAttr()
|
||||
|
||||
context.popFirTypeParameters()
|
||||
}.also {
|
||||
it.delegateFieldsMap = delegatedFieldsMap
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
@@ -1147,6 +1151,7 @@ open class RawFirBuilder(
|
||||
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Unit): FirElement {
|
||||
val objectDeclaration = expression.objectDeclaration
|
||||
return withChildClassName(SpecialNames.ANONYMOUS, forceLocalContext = true, isExpect = false) {
|
||||
var delegatedFieldsMap: Map<Int, FirFieldSymbol>?
|
||||
buildAnonymousObjectExpression {
|
||||
val sourceElement = objectDeclaration.toFirSourceElement()
|
||||
source = sourceElement
|
||||
@@ -1162,7 +1167,7 @@ open class RawFirBuilder(
|
||||
val delegatedSelfType = objectDeclaration.toDelegatedSelfType(this)
|
||||
registerSelfType(delegatedSelfType)
|
||||
objectDeclaration.extractAnnotationsTo(this)
|
||||
val delegatedSuperType = objectDeclaration.extractSuperTypeListEntriesTo(
|
||||
val (delegatedSuperType, extractedDelegatedFieldsMap) = objectDeclaration.extractSuperTypeListEntriesTo(
|
||||
this,
|
||||
delegatedSelfType,
|
||||
null,
|
||||
@@ -1170,6 +1175,7 @@ open class RawFirBuilder(
|
||||
containerTypeParameters = emptyList(),
|
||||
containingClassIsExpectClass = false
|
||||
)
|
||||
delegatedFieldsMap = extractedDelegatedFieldsMap
|
||||
|
||||
for (declaration in objectDeclaration.declarations) {
|
||||
declarations += declaration.toFirDeclaration(
|
||||
@@ -1180,6 +1186,8 @@ open class RawFirBuilder(
|
||||
ownerTypeParameters = emptyList()
|
||||
)
|
||||
}
|
||||
}.also {
|
||||
it.delegateFieldsMap = delegatedFieldsMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
|
||||
|
||||
private object DelegateFieldsMapKey : FirDeclarationDataKey()
|
||||
|
||||
/*
|
||||
* If class implements some interfaces using delegation then this attribute contains mapping
|
||||
* from index of supertype to symbol of deelgated field
|
||||
*/
|
||||
var FirClass.delegateFieldsMap: Map<Int, FirFieldSymbol>? by FirDeclarationDataRegistry.data(DelegateFieldsMapKey)
|
||||
|
||||
Reference in New Issue
Block a user