[FIR] Add excessive delegated constructors to FIR tree

^KTIJ-25453 fixed

Merge-request: KT-MR-10379
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
This commit is contained in:
Egor Kulikov
2023-06-05 14:27:53 +00:00
committed by Space Team
parent 7fbdd8e0bc
commit 347c748182
32 changed files with 494 additions and 67 deletions
@@ -1991,6 +1991,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassNameBeforeDot.kt");
}
@Test
@TestMetadata("ClassWithMultipleSuperTypeCalls.kt")
public void testClassWithMultipleSuperTypeCalls() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt");
}
@Test
@TestMetadata("CollectionLiteralLeft.kt")
public void testCollectionLiteralLeft() throws Exception {
@@ -1991,6 +1991,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassNameBeforeDot.kt");
}
@Test
@TestMetadata("ClassWithMultipleSuperTypeCalls.kt")
public void testClassWithMultipleSuperTypeCalls() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt");
}
@Test
@TestMetadata("CollectionLiteralLeft.kt")
public void testCollectionLiteralLeft() throws Exception {
@@ -1991,6 +1991,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassNameBeforeDot.kt");
}
@Test
@TestMetadata("ClassWithMultipleSuperTypeCalls.kt")
public void testClassWithMultipleSuperTypeCalls() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt");
}
@Test
@TestMetadata("CollectionLiteralLeft.kt")
public void testCollectionLiteralLeft() throws Exception {
@@ -1991,6 +1991,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassNameBeforeDot.kt");
}
@Test
@TestMetadata("ClassWithMultipleSuperTypeCalls.kt")
public void testClassWithMultipleSuperTypeCalls() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt");
}
@Test
@TestMetadata("CollectionLiteralLeft.kt")
public void testCollectionLiteralLeft() throws Exception {
@@ -0,0 +1,3 @@
open class A()
open class B(): A()
class C(): <caret>A(), B()
@@ -0,0 +1,2 @@
Resolved to:
0: (in A) constructor()
@@ -189,8 +189,20 @@ private fun calculateLazyBodyForAnonymousInitializer(designation: FirDesignation
}
}
private fun needCalculatingLazyBodyForConstructor(firConstructor: FirConstructor): Boolean =
needCalculatingLazyBodyForFunction(firConstructor) || firConstructor.delegatedConstructor is FirLazyDelegatedConstructorCall
private fun needCalculatingLazyBodyForConstructor(firConstructor: FirConstructor): Boolean {
if (needCalculatingLazyBodyForFunction(firConstructor) || firConstructor.delegatedConstructor is FirLazyDelegatedConstructorCall) {
return true
}
val deleatedConstructor = firConstructor.delegatedConstructor
if (deleatedConstructor is FirMultiDelegatedConstructorCall) {
for (delegated in deleatedConstructor.delegatedConstructorCalls) {
if (delegated is FirLazyDelegatedConstructorCall) {
return true
}
}
}
return false
}
private fun calculateLazyBodiesForField(designation: FirDesignation) {
val field = designation.target as FirField
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyAccessorBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyBuilder
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
internal class RawFirNonLocalDeclarationBuilder private constructor(
session: FirSession,
@@ -222,8 +222,9 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
withPsiEntry("constructor", constructor, baseSession.llFirModuleData.ktModule)
}
val selfType = classOrObject.toDelegatedSelfType(typeParameters, containingClass.symbol)
val superTypeCallEntry = classOrObject.superTypeListEntries.lastIsInstanceOrNull<KtSuperTypeCallEntry>()
return ConstructorConversionParams(superTypeCallEntry, selfType, typeParameters)
val allSuperTypeCallEntries = classOrObject.superTypeListEntries.filterIsInstance<KtSuperTypeCallEntry>()
val superTypeCallEntry = allSuperTypeCallEntries.lastOrNull()
return ConstructorConversionParams(superTypeCallEntry, selfType, typeParameters, allSuperTypeCallEntries)
}
override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: FirElement?): FirElement {
@@ -244,18 +245,36 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
fun processPrimaryConstructor(classOrObject: KtClassOrObject, constructor: KtPrimaryConstructor?): FirElement {
val params = extractContructorConversionParams(classOrObject, constructor)
val firConstructor = originalDeclaration as FirConstructor
val calleeReference = firConstructor.delegatedConstructor?.calleeReference as FirSuperReference?
val allSuperTypeCallEntries = if (params.allSuperTypeCallEntries.size <= 1) {
params.allSuperTypeCallEntries.map { it to firConstructor.delegatedConstructor!!.constructedTypeRef }
} else {
params.allSuperTypeCallEntries.zip((firConstructor.delegatedConstructor as FirMultiDelegatedConstructorCall).delegatedConstructorCalls.map { it.constructedTypeRef })
}
val newConstructor = constructor.toFirConstructor(
params.superTypeCallEntry,
firConstructor.delegatedConstructor?.constructedTypeRef,
params.selfType,
classOrObject,
params.typeParameters,
allSuperTypeCallEntries,
firConstructor.delegatedConstructor == null,
copyConstructedTypeRefWithImplicitSource = false,
)
if (calleeReference != null) {
(newConstructor.delegatedConstructor?.calleeReference as? FirSuperReference)?.replaceSuperTypeRef(calleeReference.superTypeRef)
val delegatedConstructor = firConstructor.delegatedConstructor
if (delegatedConstructor is FirMultiDelegatedConstructorCall) {
for ((oldExcessiveDelegate, newExcessiveDelegate) in delegatedConstructor.delegatedConstructorCalls
.zip((newConstructor.delegatedConstructor as FirMultiDelegatedConstructorCall).delegatedConstructorCalls)) {
val calleeReferenceForExessiveDelegate = oldExcessiveDelegate.calleeReference
if (calleeReferenceForExessiveDelegate is FirSuperReference) {
(newExcessiveDelegate.calleeReference as? FirSuperReference)
?.replaceSuperTypeRef(calleeReferenceForExessiveDelegate.superTypeRef)
}
}
} else {
val calleeReference = delegatedConstructor?.calleeReference
if (calleeReference is FirSuperReference) {
(newConstructor.delegatedConstructor?.calleeReference as? FirSuperReference)?.replaceSuperTypeRef(calleeReference.superTypeRef)
}
}
return newConstructor
}
@@ -351,6 +370,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
val superTypeCallEntry: KtSuperTypeCallEntry?,
val selfType: FirTypeRef,
val typeParameters: List<FirTypeParameterRef>,
val allSuperTypeCallEntries: List<KtSuperTypeCallEntry>,
)
}
@@ -6037,6 +6037,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
public void testTwoSecondaryConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSecondaryConstructors.kt");
}
@Test
@TestMetadata("twoSuperTypeCalls.kt")
public void testTwoSuperTypeCalls() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt");
}
}
@Nested
@@ -6037,6 +6037,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
public void testTwoSecondaryConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSecondaryConstructors.kt");
}
@Test
@TestMetadata("twoSuperTypeCalls.kt")
public void testTwoSuperTypeCalls() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt");
}
}
@Nested
@@ -9,6 +9,7 @@ FILE: classInSupertypeForEnum.kt
}
public final enum class B : R|C|, R|A|, R|kotlin/Any| {
private constructor(): R|B| {
super<R|A|>()
super<R|kotlin/Any|>()
}
@@ -6037,6 +6037,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
public void testTwoSecondaryConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSecondaryConstructors.kt");
}
@Test
@TestMetadata("twoSuperTypeCalls.kt")
public void testTwoSuperTypeCalls() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt");
}
}
@Nested
@@ -6043,6 +6043,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
public void testTwoSecondaryConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSecondaryConstructors.kt");
}
@Test
@TestMetadata("twoSuperTypeCalls.kt")
public void testTwoSuperTypeCalls() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt");
}
}
@Nested
@@ -509,10 +509,9 @@ class DeclarationsConverter(
registerSelfType(selfType)
val delegationSpecifiers = superTypeList?.let { convertDelegationSpecifiers(it) }
var delegatedSuperTypeRef: FirTypeRef? = delegationSpecifiers?.delegatedSuperTypeRef
val delegatedConstructorSource: KtLightSourceElement? = delegationSpecifiers?.delegatedConstructorSource
var delegatedSuperTypeRef: FirTypeRef? = delegationSpecifiers?.superTypeCalls?.lastOrNull()?.delegatedSuperTypeRef
val delegatedConstructorSource: KtLightSourceElement? = delegationSpecifiers?.superTypeCalls?.lastOrNull()?.source
val superTypeCallEntry = delegationSpecifiers?.delegatedConstructorArguments.orEmpty()
val superTypeRefs = mutableListOf<FirTypeRef>()
delegationSpecifiers?.let { superTypeRefs += it.superTypesRef }
@@ -550,7 +549,7 @@ class DeclarationsConverter(
else secondaryConstructors.isEmpty() || secondaryConstructors.any { !it.hasValueParameters() },
delegatedSelfTypeRef = selfType,
delegatedSuperTypeRef = delegatedSuperTypeRef ?: FirImplicitTypeRefImplWithoutSource,
superTypeCallEntry = superTypeCallEntry
delegatedSuperCalls = delegationSpecifiers?.superTypeCalls ?: emptyList()
)
//parse primary constructor
val primaryConstructorWrapper = convertPrimaryConstructor(
@@ -669,10 +668,10 @@ class DeclarationsConverter(
var modifiers = Modifier()
var primaryConstructor: LighterASTNode? = null
val superTypeRefs = mutableListOf<FirTypeRef>()
val superTypeCallEntry = mutableListOf<FirExpression>()
var delegatedSuperTypeRef: FirTypeRef? = null
var classBody: LighterASTNode? = null
var delegatedConstructorSource: KtLightSourceElement? = null
var delegatedSuperCalls: List<DelegatedConstructorWrapper>? = null
var delegateFields: List<FirField>? = null
objectDeclaration.forEachChildren {
@@ -680,12 +679,12 @@ class DeclarationsConverter(
MODIFIER_LIST -> modifiers = convertModifierList(it)
PRIMARY_CONSTRUCTOR -> primaryConstructor = it
SUPER_TYPE_LIST -> convertDelegationSpecifiers(it).let { specifiers ->
delegatedSuperTypeRef = specifiers.delegatedSuperTypeRef
delegatedSuperTypeRef = specifiers.superTypeCalls.lastOrNull()?.delegatedSuperTypeRef
superTypeRefs += specifiers.superTypesRef
superTypeCallEntry += specifiers.delegatedConstructorArguments
delegatedConstructorSource = specifiers.delegatedConstructorSource
delegatedConstructorSource = specifiers.superTypeCalls.lastOrNull()?.source
delegateFields = specifiers.delegateFieldsMap.values.map { it.fir }
delegatedFieldsMap = specifiers.delegateFieldsMap.takeIf { it.isNotEmpty() }
delegatedSuperCalls = specifiers.superTypeCalls
}
CLASS_BODY -> classBody = it
}
@@ -707,7 +706,7 @@ class DeclarationsConverter(
hasDefaultConstructor = false,
delegatedSelfTypeRef = delegatedSelfType,
delegatedSuperTypeRef = delegatedSuperType,
superTypeCallEntry = superTypeCallEntry
delegatedSuperCalls = delegatedSuperCalls ?: emptyList(),
)
//parse primary constructor
convertPrimaryConstructor(
@@ -798,7 +797,11 @@ class DeclarationsConverter(
)
}.also { registerSelfType(it) },
delegatedSuperTypeRef = classWrapper.delegatedSelfTypeRef,
superTypeCallEntry = enumSuperTypeCallEntry
delegatedSuperCalls = listOf(DelegatedConstructorWrapper(
classWrapper.delegatedSelfTypeRef,
enumSuperTypeCallEntry,
superTypeCallEntry?.toFirSourceElement(),
))
)
superTypeRefs += enumClassWrapper.delegatedSuperTypeRef
convertPrimaryConstructor(
@@ -908,26 +911,45 @@ class DeclarationsConverter(
val defaultVisibility = classWrapper.defaultConstructorVisibility()
val firDelegatedCall = runUnless(containingClassIsExpectClass) {
buildDelegatedConstructorCall {
source = delegatedConstructorSource ?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
constructedTypeRef = classWrapper.delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
isThis = false
calleeReference = buildExplicitSuperReference {
//[dirty] in case of enum classWrapper.delegatedSuperTypeRef.source is whole enum source
source = if (!isEnumEntry) {
classWrapper.delegatedSuperTypeRef.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
} else {
delegatedConstructorSource
?.lighterASTNode
?.getChildNodeByType(CONSTRUCTOR_CALLEE)
?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source
}
fun createDelegatedConstructorCall(
delegatedConstructorSource: KtLightSourceElement?,
delegatedSuperTypeRef: FirTypeRef,
arguments: List<FirExpression>,
): FirDelegatedConstructorCall {
return buildDelegatedConstructorCall {
source = delegatedConstructorSource ?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
constructedTypeRef = delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
isThis = false
calleeReference = buildExplicitSuperReference {
//[dirty] in case of enum classWrapper.delegatedSuperTypeRef.source is whole enum source
source = if (!isEnumEntry) {
classWrapper.delegatedSuperTypeRef.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
} else {
delegatedConstructorSource
?.lighterASTNode
?.getChildNodeByType(CONSTRUCTOR_CALLEE)
?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source
}
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
}
extractArgumentsFrom(arguments)
}
}
if (classWrapper.delegatedSuperCalls.size <= 1) {
createDelegatedConstructorCall(
delegatedConstructorSource,
classWrapper.delegatedSuperTypeRef,
classWrapper.delegatedSuperCalls.lastOrNull()?.arguments ?: emptyList(),
)
} else {
buildMultiDelegatedConstructorCall {
classWrapper.delegatedSuperCalls.mapTo(delegatedConstructorCalls) { (delegatedSuperTypeRef, arguments, source) ->
createDelegatedConstructorCall(source, delegatedSuperTypeRef, arguments)
}
}
extractArgumentsFrom(classWrapper.superTypeCallEntry)
}
}
@@ -1813,18 +1835,14 @@ class DeclarationsConverter(
*/
//TODO make wrapper for result?
private data class DelegationSpecifiers(
val delegatedSuperTypeRef: FirTypeRef?,
val superTypeCalls: List<DelegatedConstructorWrapper>,
val superTypesRef: List<FirTypeRef>,
val delegatedConstructorArguments: List<FirExpression>,
val delegatedConstructorSource: KtLightSourceElement?,
val delegateFieldsMap: Map<Int, FirFieldSymbol>,
)
private fun convertDelegationSpecifiers(delegationSpecifiers: LighterASTNode): DelegationSpecifiers {
val superTypeRefs = mutableListOf<FirTypeRef>()
val superTypeCallEntry = mutableListOf<FirExpression>()
var delegatedSuperTypeRef: FirTypeRef? = null
var delegateConstructorSource: KtLightSourceElement? = null
val superTypeCalls = mutableListOf<DelegatedConstructorWrapper>()
val delegateFieldsMap = mutableMapOf<Int, FirFieldSymbol>()
var index = 0
delegationSpecifiers.forEachChildren {
@@ -1834,10 +1852,8 @@ class DeclarationsConverter(
index++
}
SUPER_TYPE_CALL_ENTRY -> convertConstructorInvocation(it).apply {
delegatedSuperTypeRef = first
superTypeCalls += DelegatedConstructorWrapper(first, second, it.toFirSourceElement())
superTypeRefs += first
superTypeCallEntry += second
delegateConstructorSource = it.toFirSourceElement()
index++
}
DELEGATED_SUPER_TYPE_ENTRY -> {
@@ -1846,9 +1862,7 @@ class DeclarationsConverter(
}
}
}
return DelegationSpecifiers(
delegatedSuperTypeRef, superTypeRefs, superTypeCallEntry, delegateConstructorSource, delegateFieldsMap
)
return DelegationSpecifiers(superTypeCalls, superTypeRefs, delegateFieldsMap)
}
/**
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -26,7 +27,7 @@ class ClassWrapper(
val hasDefaultConstructor: Boolean,
val delegatedSelfTypeRef: FirTypeRef,
val delegatedSuperTypeRef: FirTypeRef,
val superTypeCallEntry: List<FirExpression>,
val delegatedSuperCalls: List<DelegatedConstructorWrapper>,
) {
fun isObjectLiteral(): Boolean {
return className == SpecialNames.NO_NAME_PROVIDED && isObject()
@@ -69,3 +70,9 @@ class ClassWrapper(
}
}
}
data class DelegatedConstructorWrapper(
val delegatedSuperTypeRef: FirTypeRef,
val arguments: List<FirExpression>,
val source: KtLightSourceElement?,
)
@@ -878,6 +878,7 @@ open class RawFirBuilder(
containingClassIsExpectClass: Boolean
): Pair<FirTypeRef, Map<Int, FirFieldSymbol>?> {
var superTypeCallEntry: KtSuperTypeCallEntry? = null
val allSuperTypeCallEntries = mutableListOf<Pair<KtSuperTypeCallEntry, FirTypeRef>>()
var delegatedSuperTypeRef: FirTypeRef? = null
val delegateFieldsMap = mutableMapOf<Int, FirFieldSymbol>()
superTypeListEntries.forEachIndexed { index, superTypeListEntry ->
@@ -889,6 +890,7 @@ open class RawFirBuilder(
delegatedSuperTypeRef = superTypeListEntry.calleeExpression.typeReference.toFirOrErrorType()
container.superTypeRefs += delegatedSuperTypeRef!!
superTypeCallEntry = superTypeListEntry
allSuperTypeCallEntries.add(superTypeListEntry to delegatedSuperTypeRef!!)
}
is KtDelegatedSuperTypeEntry -> {
val type = superTypeListEntry.typeReference.toFirOrErrorType()
@@ -948,6 +950,7 @@ open class RawFirBuilder(
delegatedSelfTypeRef ?: delegatedSuperTypeRef!!,
owner = this,
containerTypeParameters,
allSuperTypeCallEntries,
containingClassIsExpectClass,
copyConstructedTypeRefWithImplicitSource = true,
)
@@ -966,30 +969,42 @@ open class RawFirBuilder(
delegatedSelfTypeRef: FirTypeRef,
owner: KtClassOrObject,
ownerTypeParameters: List<FirTypeParameterRef>,
allSuperTypeCallEntries: List<Pair<KtSuperTypeCallEntry, FirTypeRef>>,
containingClassIsExpectClass: Boolean,
copyConstructedTypeRefWithImplicitSource: Boolean,
): FirConstructor {
val constructorCall = superTypeCallEntry?.toFirSourceElement()
val constructorSource = this?.toFirSourceElement()
?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor)
val firDelegatedCall = if (containingClassIsExpectClass) null else {
val constructedTypeRef = if (copyConstructedTypeRefWithImplicitSource) {
delegatedSuperTypeRef!!.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
} else {
delegatedSuperTypeRef!!
}
buildOrLazyDelegatedConstructorCall(isThis = false, constructedTypeRef) {
buildDelegatedConstructorCall {
source = constructorCall ?: constructorSource.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
this.constructedTypeRef = constructedTypeRef
isThis = false
calleeReference = buildExplicitSuperReference {
source =
superTypeCallEntry?.calleeExpression?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
fun buildDelegatedCall(superTypeCallEntry: KtSuperTypeCallEntry?, delegatedTypeRef: FirTypeRef): FirDelegatedConstructorCall? {
val constructorCall = superTypeCallEntry?.toFirSourceElement()
return if (containingClassIsExpectClass) null else {
val constructedTypeRef = if (copyConstructedTypeRefWithImplicitSource) {
delegatedTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
} else {
delegatedTypeRef
}
buildOrLazyDelegatedConstructorCall(isThis = false, constructedTypeRef) {
buildDelegatedConstructorCall {
source = constructorCall ?: constructorSource.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
this.constructedTypeRef = constructedTypeRef
isThis = false
calleeReference = buildExplicitSuperReference {
source =
superTypeCallEntry?.calleeExpression?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
}
superTypeCallEntry?.extractArgumentsTo(this)
}
superTypeCallEntry?.extractArgumentsTo(this)
}
}
}
val firDelegatedCall = if (allSuperTypeCallEntries.size <= 1 ) {
buildDelegatedCall(superTypeCallEntry, delegatedSuperTypeRef!!)
} else {
buildMultiDelegatedConstructorCall {
allSuperTypeCallEntries.mapTo(delegatedConstructorCalls) { (superTypeCallEntry, delegatedTypeRef) ->
buildDelegatedCall(superTypeCallEntry, delegatedTypeRef)!!
}
}
}
@@ -1183,6 +1198,7 @@ open class RawFirBuilder(
delegatedEntrySelfType,
owner = ktEnumEntry,
typeParameters,
allSuperTypeCallEntries = emptyList(),
containingClassIsExpectClass,
copyConstructedTypeRefWithImplicitSource = true,
)
@@ -700,6 +700,14 @@ open class FirDeclarationsResolveTransformer(
return constructor
}
override fun transformMultiDelegatedConstructorCall(
multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall,
data: ResolutionMode,
): FirStatement {
multiDelegatedConstructorCall.transformChildren(this, data)
return super.transformMultiDelegatedConstructorCall(multiDelegatedConstructorCall, data)
}
override fun transformAnonymousInitializer(
anonymousInitializer: FirAnonymousInitializer,
data: ResolutionMode
@@ -0,0 +1,58 @@
/*
* 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.fir.expressions
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirMultiDelegatedConstructorCall : FirDelegatedConstructorCall() {
abstract override val source: KtSourceElement?
abstract override val annotations: List<FirAnnotation>
abstract override val argumentList: FirArgumentList
abstract override val contextReceiverArguments: List<FirExpression>
abstract override val constructedTypeRef: FirTypeRef
abstract override val dispatchReceiver: FirExpression
abstract override val calleeReference: FirReference
abstract override val isThis: Boolean
abstract override val isSuper: Boolean
abstract val delegatedConstructorCalls: List<FirDelegatedConstructorCall>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitMultiDelegatedConstructorCall(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
transformer.transformMultiDelegatedConstructorCall(this, data) as E
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
abstract override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>)
abstract override fun replaceConstructedTypeRef(newConstructedTypeRef: FirTypeRef)
abstract override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression)
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
abstract fun replaceDelegatedConstructorCalls(newDelegatedConstructorCalls: List<FirDelegatedConstructorCall>)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCall
abstract override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCall
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCall
abstract fun <D> transformDelegatedConstructorCalls(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCall
}
@@ -0,0 +1,59 @@
/*
* 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.
*/
@file:Suppress("DuplicatedCode")
package org.jetbrains.kotlin.fir.expressions.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.impl.FirMultiDelegatedConstructorCallImpl
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
class FirMultiDelegatedConstructorCallBuilder : FirAnnotationContainerBuilder {
val delegatedConstructorCalls: MutableList<FirDelegatedConstructorCall> = mutableListOf()
@OptIn(FirImplementationDetail::class)
override fun build(): FirMultiDelegatedConstructorCall {
return FirMultiDelegatedConstructorCallImpl(
delegatedConstructorCalls,
)
}
@Deprecated("Modification of 'source' has no impact for FirMultiDelegatedConstructorCallBuilder", level = DeprecationLevel.HIDDEN)
override var source: KtSourceElement?
get() = throw IllegalStateException()
set(_) {
throw IllegalStateException()
}
@Deprecated("Modification of 'annotations' has no impact for FirMultiDelegatedConstructorCallBuilder", level = DeprecationLevel.HIDDEN)
override val annotations: MutableList<FirAnnotation> = mutableListOf()
}
@OptIn(ExperimentalContracts::class)
inline fun buildMultiDelegatedConstructorCall(init: FirMultiDelegatedConstructorCallBuilder.() -> Unit = {}): FirMultiDelegatedConstructorCall {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirMultiDelegatedConstructorCallBuilder().apply(init).build()
}
@@ -0,0 +1,83 @@
/*
* 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.
*/
@file:Suppress("DuplicatedCode")
package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.fir.MutableOrEmptyList
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
class FirMultiDelegatedConstructorCallImpl @FirImplementationDetail constructor(
override val delegatedConstructorCalls: MutableList<FirDelegatedConstructorCall>,
) : FirMultiDelegatedConstructorCall() {
override val source: KtSourceElement? get() = delegatedConstructorCalls.last().source
override val annotations: List<FirAnnotation> get() = delegatedConstructorCalls.last().annotations
override val argumentList: FirArgumentList get() = delegatedConstructorCalls.last().argumentList
override val contextReceiverArguments: List<FirExpression> get() = delegatedConstructorCalls.last().contextReceiverArguments
override val constructedTypeRef: FirTypeRef get() = delegatedConstructorCalls.last().constructedTypeRef
override val dispatchReceiver: FirExpression get() = delegatedConstructorCalls.last().dispatchReceiver
override val calleeReference: FirReference get() = delegatedConstructorCalls.last().calleeReference
override val isThis: Boolean get() = delegatedConstructorCalls.last().isThis
override val isSuper: Boolean get() = !isThis
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
delegatedConstructorCalls.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCallImpl {
transformDelegatedConstructorCalls(transformer, data)
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCallImpl {
return this
}
override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCallImpl {
return this
}
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCallImpl {
return this
}
override fun <D> transformDelegatedConstructorCalls(transformer: FirTransformer<D>, data: D): FirMultiDelegatedConstructorCallImpl {
delegatedConstructorCalls.transformInplace(transformer, data)
return this
}
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
override fun replaceArgumentList(newArgumentList: FirArgumentList) {}
override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>) {}
override fun replaceConstructedTypeRef(newConstructedTypeRef: FirTypeRef) {}
override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression) {}
override fun replaceCalleeReference(newCalleeReference: FirReference) {}
override fun replaceDelegatedConstructorCalls(newDelegatedConstructorCalls: List<FirDelegatedConstructorCall>) {
delegatedConstructorCalls.clear()
delegatedConstructorCalls.addAll(newDelegatedConstructorCalls)
}
}
@@ -105,6 +105,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
@@ -240,6 +241,8 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitFunctionCall(implicitInvokeCall, data)
override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: D): R = visitDelegatedConstructorCall(multiDelegatedConstructorCall, data)
override fun visitComponentCall(componentCall: FirComponentCall, data: D): R = visitFunctionCall(componentCall, data)
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: D): R = visitQualifiedAccessExpression(callableReferenceAccess, data)
@@ -105,6 +105,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
@@ -240,6 +241,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) = visitFunctionCall(implicitInvokeCall)
override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall) = visitDelegatedConstructorCall(multiDelegatedConstructorCall)
override fun visitComponentCall(componentCall: FirComponentCall) = visitFunctionCall(componentCall)
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) = visitQualifiedAccessExpression(callableReferenceAccess)
@@ -105,6 +105,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
@@ -561,6 +562,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformElement(delegatedConstructorCall, data)
}
open fun transformMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: D): FirStatement {
return transformElement(multiDelegatedConstructorCall, data)
}
open fun transformComponentCall(componentCall: FirComponentCall, data: D): FirStatement {
return transformElement(componentCall, data)
}
@@ -1161,6 +1166,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformDelegatedConstructorCall(delegatedConstructorCall, data)
}
final override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: D): FirStatement {
return transformMultiDelegatedConstructorCall(multiDelegatedConstructorCall, data)
}
final override fun visitComponentCall(componentCall: FirComponentCall, data: D): FirStatement {
return transformComponentCall(componentCall, data)
}
@@ -105,6 +105,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
@@ -362,6 +363,8 @@ abstract class FirVisitor<out R, in D> {
open fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: D): R = visitElement(delegatedConstructorCall, data)
open fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: D): R = visitElement(multiDelegatedConstructorCall, data)
open fun visitComponentCall(componentCall: FirComponentCall, data: D): R = visitElement(componentCall, data)
open fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: D): R = visitElement(callableReferenceAccess, data)
@@ -105,6 +105,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirMultiDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
@@ -560,6 +561,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(delegatedConstructorCall)
}
open fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall) {
visitElement(multiDelegatedConstructorCall)
}
open fun visitComponentCall(componentCall: FirComponentCall) {
visitElement(componentCall)
}
@@ -1160,6 +1165,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitDelegatedConstructorCall(delegatedConstructorCall)
}
final override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: Nothing?) {
visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall)
}
final override fun visitComponentCall(componentCall: FirComponentCall, data: Nothing?) {
visitComponentCall(componentCall)
}
@@ -726,6 +726,18 @@ class FirRenderer(
}
}
override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall) {
var first = true
for (delegatedConstructorCall in multiDelegatedConstructorCall.delegatedConstructorCalls) {
if (first) {
first = false
} else {
printer.println()
}
visitDelegatedConstructorCall(delegatedConstructorCall)
}
}
override fun visitTypeRef(typeRef: FirTypeRef) {
annotationRenderer?.render(typeRef)
visitElement(typeRef)
@@ -129,6 +129,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val integerLiteralOperatorCall by element(Expression, functionCall)
val implicitInvokeCall by element(Expression, functionCall)
val delegatedConstructorCall by element(Expression, resolvable, call, contextReceiverArgumentListOwner)
val multiDelegatedConstructorCall by element(Expression, delegatedConstructorCall)
val componentCall by element(Expression, functionCall)
val callableReferenceAccess by element(Expression, qualifiedAccessExpression)
val thisReceiverExpression by element(Expression, qualifiedAccessExpression)
@@ -129,6 +129,46 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
useTypes(explicitThisReferenceType, explicitSuperReferenceType)
}
impl(multiDelegatedConstructorCall) {
default("source") {
value = "delegatedConstructorCalls.last().source"
withGetter = true
}
default("annotations") {
value = "delegatedConstructorCalls.last().annotations"
withGetter = true
}
default("argumentList") {
value = "delegatedConstructorCalls.last().argumentList"
withGetter = true
}
default("contextReceiverArguments") {
value = "delegatedConstructorCalls.last().contextReceiverArguments"
withGetter = true
}
default("constructedTypeRef") {
value = "delegatedConstructorCalls.last().constructedTypeRef"
withGetter = true
}
default("dispatchReceiver") {
value = "delegatedConstructorCalls.last().dispatchReceiver"
withGetter = true
}
default("calleeReference") {
value = "delegatedConstructorCalls.last().calleeReference"
withGetter = true
}
default("isThis") {
value = "delegatedConstructorCalls.last().isThis"
withGetter = true
}
default("isSuper") {
value = "!isThis"
withGetter = true
}
publicImplementation()
}
impl(delegatedConstructorCall, "FirLazyDelegatedConstructorCall") {
val error = """error("FirLazyDelegatedConstructorCall should be calculated before accessing")"""
default("source") {
@@ -418,6 +418,10 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
generateBooleanFields("this", "super")
}
multiDelegatedConstructorCall.configure {
+fieldList("delegatedConstructorCalls", delegatedConstructorCall, withReplace = true).withTransform()
}
valueParameter.configure {
+symbol("FirValueParameterSymbol")
+field("defaultValue", expression, nullable = true, withReplace = true)
@@ -0,0 +1,3 @@
open class A(s: String)
open class B(): A("1")
class C(): A(<!ARGUMENT_TYPE_MISMATCH!>100<!>), <!MANY_CLASSES_IN_SUPERTYPE_LIST!>B<!>()
@@ -0,0 +1,3 @@
open class A(s: String)
open class B(): A("1")
class C(): A(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>100<!>), <!MANY_CLASSES_IN_SUPERTYPE_LIST!>B<!>()
@@ -6043,6 +6043,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
public void testTwoSecondaryConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSecondaryConstructors.kt");
}
@Test
@TestMetadata("twoSuperTypeCalls.kt")
public void testTwoSuperTypeCalls() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt");
}
}
@Nested