diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index fcf16c051e8..6630dd845b1 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java index 7318a5b1496..c358d46096f 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index 352104ad5d2..64abd5cb554 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index 26aec167b03..1506e39356c 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt b/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt new file mode 100644 index 00000000000..4b45a30e797 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.kt @@ -0,0 +1,3 @@ +open class A() +open class B(): A() +class C(): A(), B() diff --git a/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.txt b/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.txt new file mode 100644 index 00000000000..9c4691675b4 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/withErrors/ClassWithMultipleSuperTypeCalls.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in A) constructor() diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt index ec48a44054a..18f16f6d462 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt @@ -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 diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index 5a7b50763fc..c2e9d2f46f7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -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() - return ConstructorConversionParams(superTypeCallEntry, selfType, typeParameters) + val allSuperTypeCallEntries = classOrObject.superTypeListEntries.filterIsInstance() + 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, + val allSuperTypeCallEntries: List, ) } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 21a4cea3ef3..958657ee28b 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -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 diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index b64520abd6e..db2943df7ac 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -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 diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.fir.txt index 0462d1203c6..b284dc6bcf4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.fir.txt @@ -9,6 +9,7 @@ FILE: classInSupertypeForEnum.kt } public final enum class B : R|C|, R|A|, R|kotlin/Any| { private constructor(): R|B| { + super() super() } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 40566e8e366..937406051ef 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -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 diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index bb11cadfe0f..9894dc66248 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -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 diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 38701c635f4..2ab6f648fc5 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -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() 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() - val superTypeCallEntry = mutableListOf() var delegatedSuperTypeRef: FirTypeRef? = null var classBody: LighterASTNode? = null var delegatedConstructorSource: KtLightSourceElement? = null + var delegatedSuperCalls: List? = null var delegateFields: List? = 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, + ): 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, val superTypesRef: List, - val delegatedConstructorArguments: List, - val delegatedConstructorSource: KtLightSourceElement?, val delegateFieldsMap: Map, ) private fun convertDelegationSpecifiers(delegationSpecifiers: LighterASTNode): DelegationSpecifiers { val superTypeRefs = mutableListOf() - val superTypeCallEntry = mutableListOf() - var delegatedSuperTypeRef: FirTypeRef? = null - var delegateConstructorSource: KtLightSourceElement? = null + val superTypeCalls = mutableListOf() val delegateFieldsMap = mutableMapOf() 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) } /** diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ClassWrapper.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ClassWrapper.kt index c4263f86709..b0c5c8da812 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ClassWrapper.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ClassWrapper.kt @@ -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, + val delegatedSuperCalls: List, ) { 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, + val source: KtLightSourceElement?, +) diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index af3563db51d..b7e38e720df 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -878,6 +878,7 @@ open class RawFirBuilder( containingClassIsExpectClass: Boolean ): Pair?> { var superTypeCallEntry: KtSuperTypeCallEntry? = null + val allSuperTypeCallEntries = mutableListOf>() var delegatedSuperTypeRef: FirTypeRef? = null val delegateFieldsMap = mutableMapOf() 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, + allSuperTypeCallEntries: List>, 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, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 04216296872..445af430466 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -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 diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirMultiDelegatedConstructorCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirMultiDelegatedConstructorCall.kt new file mode 100644 index 00000000000..8170893c256 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirMultiDelegatedConstructorCall.kt @@ -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 + abstract override val argumentList: FirArgumentList + abstract override val contextReceiverArguments: List + 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 + + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitMultiDelegatedConstructorCall(this, data) + + @Suppress("UNCHECKED_CAST") + override fun transform(transformer: FirTransformer, data: D): E = + transformer.transformMultiDelegatedConstructorCall(this, data) as E + + abstract override fun replaceAnnotations(newAnnotations: List) + + abstract override fun replaceArgumentList(newArgumentList: FirArgumentList) + + abstract override fun replaceContextReceiverArguments(newContextReceiverArguments: List) + + abstract override fun replaceConstructedTypeRef(newConstructedTypeRef: FirTypeRef) + + abstract override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression) + + abstract override fun replaceCalleeReference(newCalleeReference: FirReference) + + abstract fun replaceDelegatedConstructorCalls(newDelegatedConstructorCalls: List) + + abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCall + + abstract override fun transformDispatchReceiver(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCall + + abstract override fun transformCalleeReference(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCall + + abstract fun transformDelegatedConstructorCalls(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCall +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirMultiDelegatedConstructorCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirMultiDelegatedConstructorCallBuilder.kt new file mode 100644 index 00000000000..34b281b87b2 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirMultiDelegatedConstructorCallBuilder.kt @@ -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 = 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 = mutableListOf() +} + +@OptIn(ExperimentalContracts::class) +inline fun buildMultiDelegatedConstructorCall(init: FirMultiDelegatedConstructorCallBuilder.() -> Unit = {}): FirMultiDelegatedConstructorCall { + contract { + callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) + } + return FirMultiDelegatedConstructorCallBuilder().apply(init).build() +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirMultiDelegatedConstructorCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirMultiDelegatedConstructorCallImpl.kt new file mode 100644 index 00000000000..d5172ec96f1 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirMultiDelegatedConstructorCallImpl.kt @@ -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, +) : FirMultiDelegatedConstructorCall() { + override val source: KtSourceElement? get() = delegatedConstructorCalls.last().source + override val annotations: List get() = delegatedConstructorCalls.last().annotations + override val argumentList: FirArgumentList get() = delegatedConstructorCalls.last().argumentList + override val contextReceiverArguments: List 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 acceptChildren(visitor: FirVisitor, data: D) { + delegatedConstructorCalls.forEach { it.accept(visitor, data) } + } + + override fun transformChildren(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCallImpl { + transformDelegatedConstructorCalls(transformer, data) + return this + } + + override fun transformAnnotations(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCallImpl { + return this + } + + override fun transformDispatchReceiver(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCallImpl { + return this + } + + override fun transformCalleeReference(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCallImpl { + return this + } + + override fun transformDelegatedConstructorCalls(transformer: FirTransformer, data: D): FirMultiDelegatedConstructorCallImpl { + delegatedConstructorCalls.transformInplace(transformer, data) + return this + } + + override fun replaceAnnotations(newAnnotations: List) {} + + override fun replaceArgumentList(newArgumentList: FirArgumentList) {} + + override fun replaceContextReceiverArguments(newContextReceiverArguments: List) {} + + override fun replaceConstructedTypeRef(newConstructedTypeRef: FirTypeRef) {} + + override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression) {} + + override fun replaceCalleeReference(newCalleeReference: FirReference) {} + + override fun replaceDelegatedConstructorCalls(newDelegatedConstructorCalls: List) { + delegatedConstructorCalls.clear() + delegatedConstructorCalls.addAll(newDelegatedConstructorCalls) + } +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt index c77e4bc6b7b..bd0f21bc38c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt @@ -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 : FirVisitor() { 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) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt index 27661ddb2de..ce98df0d081 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt @@ -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) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt index afa10b3225d..f63d9f0d19b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt @@ -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 : FirVisitor() { 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 : FirVisitor() { 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) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt index 694f11b6ce4..2cdce485a46 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt @@ -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 { 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) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt index dfb5f6a5530..b69ba2da979 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt @@ -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() { visitElement(delegatedConstructorCall) } + open fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall) { + visitElement(multiDelegatedConstructorCall) + } + open fun visitComponentCall(componentCall: FirComponentCall) { visitElement(componentCall) } @@ -1160,6 +1165,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitDelegatedConstructorCall(delegatedConstructorCall) } + final override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: Nothing?) { + visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall) + } + final override fun visitComponentCall(componentCall: FirComponentCall, data: Nothing?) { visitComponentCall(componentCall) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index 648fbdfe3e9..54e74fec34a 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -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) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt index d6c9e328a5e..371190a4c4c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt @@ -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) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 6756f81e3dd..a825bc78335 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -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") { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 56217a74501..21f9a255d03 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -418,6 +418,10 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild generateBooleanFields("this", "super") } + multiDelegatedConstructorCall.configure { + +fieldList("delegatedConstructorCalls", delegatedConstructorCall, withReplace = true).withTransform() + } + valueParameter.configure { +symbol("FirValueParameterSymbol") +field("defaultValue", expression, nullable = true, withReplace = true) diff --git a/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.fir.kt b/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.fir.kt new file mode 100644 index 00000000000..194a912f744 --- /dev/null +++ b/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.fir.kt @@ -0,0 +1,3 @@ +open class A(s: String) +open class B(): A("1") +class C(): A(100), B() diff --git a/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt b/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt new file mode 100644 index 00000000000..a83f9b6af47 --- /dev/null +++ b/compiler/testData/diagnostics/tests/constructorConsistency/twoSuperTypeCalls.kt @@ -0,0 +1,3 @@ +open class A(s: String) +open class B(): A("1") +class C(): A(100), B() diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index aa83bc238d9..b2f769b5c84 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -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