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