[FIR] Generate an error primary constructor when super call is invalid

Merge-request: KT-MR-11026
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
This commit is contained in:
Egor Kulikov
2023-07-13 17:37:48 +00:00
committed by Space Team
parent a588e75c11
commit 70d49999ac
30 changed files with 523 additions and 75 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.SingleNonLoca
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirErrorConstructor
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
@@ -148,7 +149,10 @@ internal class NonReanalyzableClassDeclarationStructureElement(
}
override fun visitConstructor(constructor: FirConstructor, data: MutableMap<KtElement, FirElement>) {
if (constructor is FirPrimaryConstructor && constructor.source?.kind == KtFakeSourceElementKind.ImplicitConstructor) {
if (
(constructor is FirPrimaryConstructor || constructor is FirErrorConstructor) &&
constructor.source?.kind == KtFakeSourceElementKind.ImplicitConstructor
) {
NonReanalyzableNonClassDeclarationStructureElement.Recorder.visitConstructor(constructor, data)
}
}
@@ -1,14 +1,9 @@
KT element: KtNameReferenceExpression
FIR element: FirRegularClassImpl
FIR element: FirResolvedNamedReferenceImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] object C : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
super<R|A|>()
}
}
R|/A.prop|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall3.kt
@@ -18,17 +13,27 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall3.kt
LAZY_super<R|kotlin/Any|>
}
public final [ResolvedTo(STATUS)] val prop: R|kotlin/String| = LAZY_EXPRESSION
public [ResolvedTo(STATUS)] [ContainingClassKey=A] get(): R|kotlin/String|
public final [ResolvedTo(CONTRACTS)] val prop: R|kotlin/String| = String()
public [ResolvedTo(CONTRACTS)] [ContainingClassKey=A] get(): R|kotlin/String|
}
public? final? [ResolvedTo(RAW_FIR)] object B : A {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<A>
public final [ResolvedTo(STATUS)] object B : R|A| {
private [ResolvedTo(STATUS)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<R|A|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] object C : R|A| {
private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] error_constructor(): R|C| {
super<R|A|>([ResolvedTo(RAW_FIR)] fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=Unknown> {
local final [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/String| {
^foo Q|B|.R|/A.prop|.R|kotlin/String.toString|()
}
}
)
}
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
super<R|A|>()
}
@@ -1,20 +1,9 @@
KT element: KtNameReferenceExpression
FIR element: FirRegularClassImpl
FIR element: FirResolvedNamedReferenceImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] class G : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=G] constructor(): R|G| {
super<R|A|>([ResolvedTo(RAW_FIR)] fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=Unknown> {
local final [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/String| {
^foo Q|C|.R|/A.prop|.R|kotlin/String.toString|()
}
}
)
}
}
R|/A.prop|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall4.kt
@@ -28,9 +17,9 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall4.kt
public [ResolvedTo(CONTRACTS)] [ContainingClassKey=A] get(): R|kotlin/String|
}
public? final? [ResolvedTo(RAW_FIR)] object B : A {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<A>
public final [ResolvedTo(STATUS)] object B : R|A| {
private [ResolvedTo(STATUS)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<R|A|>
}
}
@@ -41,6 +30,16 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall4.kt
}
public final [ResolvedTo(BODY_RESOLVE)] class G : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=G] error_constructor(): R|G| {
super<R|A|>([ResolvedTo(RAW_FIR)] fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=Unknown> {
local final [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/String| {
^foo Q|B|.R|/A.prop|.R|kotlin/String.toString|()
}
}
)
}
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=G] constructor(): R|G| {
super<R|A|>([ResolvedTo(RAW_FIR)] fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=Unknown> {
local final [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/String| {
@@ -51,4 +50,4 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall4.kt
)
}
}
}
@@ -30,6 +30,10 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedCallInsideSuperCall5.kt
}
public final [ResolvedTo(STATUS)] class G : R|A| {
public [ResolvedTo(STATUS)] [ContainingClassKey=G] error_constructor(): R|G| {
LAZY_super<R|A|>
}
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=G] constructor(): R|G| {
super<R|A|>([ResolvedTo(RAW_FIR)] fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=Unknown> {
local final [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/String| {
@@ -5990,6 +5990,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/constructorConsistency/derivedProperty.kt");
}
@Test
@TestMetadata("errorInsideDelegationCallNoPrimary.kt")
public void testErrorInsideDelegationCallNoPrimary() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/errorInsideDelegationCallNoPrimary.kt");
}
@Test
@TestMetadata("getset.kt")
public void testGetset() throws Exception {
@@ -5990,6 +5990,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/constructorConsistency/derivedProperty.kt");
}
@Test
@TestMetadata("errorInsideDelegationCallNoPrimary.kt")
public void testErrorInsideDelegationCallNoPrimary() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/errorInsideDelegationCallNoPrimary.kt");
}
@Test
@TestMetadata("getset.kt")
public void testGetset() throws Exception {
@@ -20,6 +20,10 @@ FILE: explicitDelegationCallRequired.kt
}
public final class C : R|A| {
public error_constructor(): R|C| {
super<R|A|>(Int(20))
}
public constructor(): R|C| {
super<R|A|>()
}
@@ -9,7 +9,7 @@ class B : A {
<!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>class C : A(20) {
<!EXPLICIT_DELEGATION_CALL_REQUIRED!>constructor()<!>
constructor(z: String) : this()
constructor(z: String) : <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>()
}<!>
class D() : A(20) {
@@ -6,6 +6,10 @@ FILE: interfaceWithSuperclass.kt
}
public abstract interface B : R|A| {
public error_constructor(): R|B| {
super<R|A|>()
}
}
public abstract interface C : R|kotlin/Any| {
}
@@ -16,4 +20,9 @@ FILE: interfaceWithSuperclass.kt
}
public abstract interface E : R|A|, R|C|, R|D| {
public error_constructor(): R|E| {
super<R|A|>()
super<R|D|>()
}
}
@@ -2,6 +2,10 @@ FILE: supertypeInitializedInInterface.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|A| {
public error_constructor(): R|B| {
super<R|A|>()
}
}
public open class C : R|kotlin/Any| {
public constructor(): R|C| {
@@ -10,8 +14,22 @@ FILE: supertypeInitializedInInterface.kt
}
public abstract interface D : R|C| {
public error_constructor(): R|D| {
super<R|C|>()
}
}
public abstract interface E : R|kotlin/Any| {
public error_constructor(): R|E| {
super<R|kotlin/Any|>()
}
}
public abstract interface F : R|A|, R|B|, R|C|, R|D|, R|kotlin/Any| {
public error_constructor(): R|F| {
super<R|B|>()
super<R|D|>()
super<R|kotlin/Any|>()
}
}
@@ -1,6 +1,6 @@
interface A
interface B : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>()
interface B : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!><!NO_CONSTRUCTOR!>()<!>
open class C
@@ -36,6 +36,10 @@ FILE: supertypeInitializedWithoutPrimaryConstructor.kt
}
public final class G : R|C| {
public error_constructor(): R|G| {
super<R|C|>(Int(10))
}
public constructor(): R|G| {
super<R|C|>(Int(1))
}
@@ -20,6 +20,10 @@ FILE: withSuppression.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|@R|kotlin/Suppress|(names = vararg(String(SUPERTYPE_INITIALIZED_IN_INTERFACE))) A| {
public error_constructor(): R|B| {
super<R|@R|kotlin/Suppress|(names = vararg(String(SUPERTYPE_INITIALIZED_IN_INTERFACE))) A|>()
}
}
public final data class D : R|kotlin/Any| {
@R|kotlin/Suppress|(names = vararg(String(DATA_CLASS_VARARG_PARAMETER))) public constructor(vararg x: R|kotlin/Array<out kotlin/String>|): R|D| {
@@ -15,6 +15,6 @@ typealias Alias<T> = @Suppress("TYPEALIAS_SHOULD_EXPAND_TO_CLASS") T
interface A
interface B : @Suppress("SUPERTYPE_INITIALIZED_IN_INTERFACE") A()
interface B : @Suppress("SUPERTYPE_INITIALIZED_IN_INTERFACE") A<!NO_CONSTRUCTOR!>()<!>
data class D @Suppress("DATA_CLASS_VARARG_PARAMETER") constructor(vararg val x: String)
@@ -5990,6 +5990,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/constructorConsistency/derivedProperty.kt");
}
@Test
@TestMetadata("errorInsideDelegationCallNoPrimary.kt")
public void testErrorInsideDelegationCallNoPrimary() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/errorInsideDelegationCallNoPrimary.kt");
}
@Test
@TestMetadata("getset.kt")
public void testGetset() throws Exception {
@@ -5996,6 +5996,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/constructorConsistency/derivedProperty.kt");
}
@Test
@TestMetadata("errorInsideDelegationCallNoPrimary.kt")
public void testErrorInsideDelegationCallNoPrimary() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/errorInsideDelegationCallNoPrimary.kt");
}
@Test
@TestMetadata("getset.kt")
public void testGetset() throws Exception {
@@ -891,12 +891,15 @@ class LightTreeRawFirDeclarationBuilder(
isEnumEntry: Boolean = false,
containingClassIsExpectClass: Boolean
): PrimaryConstructor? {
if (primaryConstructor == null && !classWrapper.isEnumEntry() && classWrapper.hasSecondaryConstructor) return null
val classKind = classWrapper.classBuilder.classKind
if (primaryConstructor == null &&
(containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS && classKind != ClassKind.ENUM_ENTRY)
) return null
if (primaryConstructor == null && classWrapper.isInterface()) return null
fun ClassKind.isEnumRelated(): Boolean = this == ClassKind.ENUM_CLASS || this == ClassKind.ENUM_ENTRY
val shouldGenerateImplicitConstructor =
(classWrapper.isEnumEntry() || !classWrapper.hasSecondaryConstructor) &&
!classWrapper.isInterface() &&
(!containingClassIsExpectClass || classWrapper.classBuilder.classKind.isEnumRelated())
val isErrorConstructor = primaryConstructor == null && !shouldGenerateImplicitConstructor
if (isErrorConstructor && classWrapper.delegatedSuperCalls.isEmpty()) {
return null
}
val constructorSymbol = FirConstructorSymbol(callableIdForClassConstructor())
var modifiers = Modifier()
@@ -963,25 +966,29 @@ class LightTreeRawFirDeclarationBuilder(
isFromEnumClass = classWrapper.isEnum()
}
val builder = if (isErrorConstructor) FirErrorConstructorBuilder() else FirPrimaryConstructorBuilder()
builder.apply {
source = primaryConstructor?.toFirSourceElement()
?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.ImplicitConstructor)
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
returnTypeRef = classWrapper.delegatedSelfTypeRef
dispatchReceiverType = classWrapper.obtainDispatchReceiverForConstructor()
this.status = status
symbol = constructorSymbol
annotations += modifiers.annotations
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
this.valueParameters += valueParameters.map { it.firValueParameter }
delegatedConstructor = firDelegatedCall
this.body = null
this.contextReceivers.addAll(convertContextReceivers(classNode))
}
return PrimaryConstructor(
buildPrimaryConstructor {
source = primaryConstructor?.toFirSourceElement()
?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.ImplicitConstructor)
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
returnTypeRef = classWrapper.delegatedSelfTypeRef
dispatchReceiverType = classWrapper.obtainDispatchReceiverForConstructor()
this.status = status
symbol = constructorSymbol
annotations += modifiers.annotations
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
this.valueParameters += valueParameters.map { it.firValueParameter }
delegatedConstructor = firDelegatedCall
this.body = null
this.contextReceivers.addAll(convertContextReceivers(classNode))
}.apply {
builder.build().apply {
containingClassForStaticMemberAttr = currentDispatchReceiverType()!!.lookupTag
}, valueParameters
},
valueParameters,
)
}
@@ -956,10 +956,17 @@ open class PsiRawFirBuilder(
// TODO: in case we have no primary constructor,
// it may be not possible to determine delegated super type right here
delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef
val shouldGenerateImplicitPrimaryConstructor =
!hasExplicitPrimaryConstructor() && !hasSecondaryConstructors() && !(containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS)
if (primaryConstructor != null || (this !is KtClass || !this.isInterface()) && shouldGenerateImplicitPrimaryConstructor) {
// We are never here as part of enum entry
val shouldGenerateImplicitPrimaryConstructor =
!hasSecondaryConstructors() &&
!(containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS) &&
(this !is KtClass || !this.isInterface())
val hasPrimaryConstructor = primaryConstructor != null || shouldGenerateImplicitPrimaryConstructor
if (hasPrimaryConstructor || superTypeCallEntry != null) {
val firPrimaryConstructor = primaryConstructor.toFirConstructor(
superTypeCallEntry,
delegatedSuperTypeRef,
@@ -969,6 +976,7 @@ open class PsiRawFirBuilder(
allSuperTypeCallEntries,
containingClassIsExpectClass,
copyConstructedTypeRefWithImplicitSource = true,
isErrorConstructor = !hasPrimaryConstructor,
)
container.declarations += firPrimaryConstructor
}
@@ -988,6 +996,7 @@ open class PsiRawFirBuilder(
allSuperTypeCallEntries: List<Pair<KtSuperTypeCallEntry, FirTypeRef>>,
containingClassIsExpectClass: Boolean,
copyConstructedTypeRefWithImplicitSource: Boolean,
isErrorConstructor: Boolean = false,
): FirConstructor {
val constructorSource = this?.toFirSourceElement()
?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor)
@@ -1040,7 +1049,8 @@ open class PsiRawFirBuilder(
isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.Private
isFromEnumClass = owner.hasModifier(ENUM_KEYWORD)
}
return buildPrimaryConstructor {
val builder = if (isErrorConstructor) FirErrorConstructorBuilder() else FirPrimaryConstructorBuilder()
builder.apply {
source = constructorSource
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
@@ -1054,9 +1064,8 @@ open class PsiRawFirBuilder(
this@toFirConstructor?.extractAnnotationsTo(this)
this@toFirConstructor?.extractValueParametersTo(this, symbol, ValueParameterDeclaration.PRIMARY_CONSTRUCTOR)
this.body = null
}.apply {
containingClassForStaticMemberAttr = currentDispatchReceiverType()!!.lookupTag
}
return builder.build().apply { containingClassForStaticMemberAttr = currentDispatchReceiverType()!!.lookupTag }
}
private fun KtClassOrObject.obtainDispatchReceiverForConstructor(): ConeClassLikeType? =
@@ -33,12 +33,20 @@ FILE: classWithWrongSuperCall.kt
}
public? final? class F : A {
public? error_constructor(): R|F| {
LAZY_super<A>
}
public? constructor(): R|F| {
LAZY_super<A>
}
}
public? final? class G : A {
public? error_constructor(): R|G| {
LAZY_super<A>
}
public? constructor(): R|G| {
LAZY_super<A>
}
@@ -54,12 +54,32 @@ FILE: classWithWrongSuperCall.kt
}
public? final? class F : A {
public? [ContainingClassKey=F] error_constructor(): R|F| {
super<A>(fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
local final? fun foo(): <implicit> {
^foo B#.prop#.toString#()
}
}
)
}
public? [ContainingClassKey=F] constructor(): R|F| {
super<A>()
}
}
public? final? class G : A {
public? [ContainingClassKey=G] error_constructor(): R|G| {
super<A>(fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
local final? fun foo(): <implicit> {
^foo B#.prop#.toString#()
}
}
)
}
public? [ContainingClassKey=G] constructor(): R|G| {
super<A>(fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
local final? fun foo(): <implicit> {
@@ -0,0 +1,112 @@
/*
* 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", "unused")
package org.jetbrains.kotlin.fir.declarations.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData
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.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirResolveState
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess
import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider
import org.jetbrains.kotlin.fir.declarations.asResolveState
import org.jetbrains.kotlin.fir.declarations.builder.FirAbstractConstructorBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirErrorConstructor
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
class FirErrorConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotationContainerBuilder {
override var source: KtSourceElement? = null
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
override lateinit var moduleData: FirModuleData
override lateinit var origin: FirDeclarationOrigin
override var attributes: FirDeclarationAttributes = FirDeclarationAttributes()
override val typeParameters: MutableList<FirTypeParameterRef> = mutableListOf()
override lateinit var status: FirDeclarationStatus
override lateinit var returnTypeRef: FirTypeRef
override var receiverParameter: FirReceiverParameter? = null
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
override var containerSource: DeserializedContainerSource? = null
override var dispatchReceiverType: ConeSimpleKotlinType? = null
override val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
override var contractDescription: FirContractDescription = FirEmptyContractDescription
override val annotations: MutableList<FirAnnotation> = mutableListOf()
override lateinit var symbol: FirConstructorSymbol
override var delegatedConstructor: FirDelegatedConstructorCall? = null
override var body: FirBlock? = null
@OptIn(FirImplementationDetail::class)
override fun build(): FirConstructor {
return FirErrorConstructor(
source,
resolvePhase,
moduleData,
origin,
attributes,
typeParameters,
status,
returnTypeRef,
receiverParameter,
deprecationsProvider,
containerSource,
dispatchReceiverType,
contextReceivers.toMutableOrEmpty(),
valueParameters,
contractDescription,
annotations.toMutableOrEmpty(),
symbol,
delegatedConstructor,
body,
)
}
@Deprecated("Modification of 'controlFlowGraphReference' has no impact for FirErrorConstructorBuilder", level = DeprecationLevel.HIDDEN)
override var controlFlowGraphReference: FirControlFlowGraphReference?
get() = throw IllegalStateException()
set(_) {
throw IllegalStateException()
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildErrorConstructor(init: FirErrorConstructorBuilder.() -> Unit): FirConstructor {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirErrorConstructorBuilder().apply(init).build()
}
@@ -0,0 +1,192 @@
/*
* 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", "unused")
package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirResolveState
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.asResolveState
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.fir.MutableOrEmptyList
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
class FirErrorConstructor @FirImplementationDetail constructor(
override val source: KtSourceElement?,
resolvePhase: FirResolvePhase,
override val moduleData: FirModuleData,
override val origin: FirDeclarationOrigin,
override val attributes: FirDeclarationAttributes,
override val typeParameters: MutableList<FirTypeParameterRef>,
override var status: FirDeclarationStatus,
override var returnTypeRef: FirTypeRef,
override var receiverParameter: FirReceiverParameter?,
override var deprecationsProvider: DeprecationsProvider,
override val containerSource: DeserializedContainerSource?,
override val dispatchReceiverType: ConeSimpleKotlinType?,
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
override val valueParameters: MutableList<FirValueParameter>,
override var contractDescription: FirContractDescription,
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val symbol: FirConstructorSymbol,
override var delegatedConstructor: FirDelegatedConstructorCall?,
override var body: FirBlock?,
) : FirConstructor() {
override var controlFlowGraphReference: FirControlFlowGraphReference? = null
override val isPrimary: Boolean get() = false
init {
symbol.bind(this)
@OptIn(ResolveStateAccess::class)
resolveState = resolvePhase.asResolveState()
}
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeParameters.forEach { it.accept(visitor, data) }
status.accept(visitor, data)
returnTypeRef.accept(visitor, data)
receiverParameter?.accept(visitor, data)
contextReceivers.forEach { it.accept(visitor, data) }
controlFlowGraphReference?.accept(visitor, data)
valueParameters.forEach { it.accept(visitor, data) }
contractDescription.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) }
delegatedConstructor?.accept(visitor, data)
body?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
transformTypeParameters(transformer, data)
transformStatus(transformer, data)
transformReturnTypeRef(transformer, data)
transformReceiverParameter(transformer, data)
contextReceivers.transformInplace(transformer, data)
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
transformValueParameters(transformer, data)
transformContractDescription(transformer, data)
transformAnnotations(transformer, data)
transformDelegatedConstructor(transformer, data)
transformBody(transformer, data)
return this
}
override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
typeParameters.transformInplace(transformer, data)
return this
}
override fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
status = status.transform(transformer, data)
return this
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
returnTypeRef = returnTypeRef.transform(transformer, data)
return this
}
override fun <D> transformReceiverParameter(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
receiverParameter = receiverParameter?.transform(transformer, data)
return this
}
override fun <D> transformValueParameters(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
valueParameters.transformInplace(transformer, data)
return this
}
override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
contractDescription = contractDescription.transform(transformer, data)
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
annotations.transformInplace(transformer, data)
return this
}
override fun <D> transformDelegatedConstructor(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
delegatedConstructor = delegatedConstructor?.transform(transformer, data)
return this
}
override fun <D> transformBody(transformer: FirTransformer<D>, data: D): FirErrorConstructor {
body = body?.transform(transformer, data)
return this
}
override fun replaceStatus(newStatus: FirDeclarationStatus) {
status = newStatus
}
override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) {
returnTypeRef = newReturnTypeRef
}
override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) {
receiverParameter = newReceiverParameter
}
override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) {
deprecationsProvider = newDeprecationsProvider
}
override fun replaceContextReceivers(newContextReceivers: List<FirContextReceiver>) {
contextReceivers = newContextReceivers.toMutableOrEmpty()
}
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {
controlFlowGraphReference = newControlFlowGraphReference
}
override fun replaceValueParameters(newValueParameters: List<FirValueParameter>) {
valueParameters.clear()
valueParameters.addAll(newValueParameters)
}
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
contractDescription = newContractDescription
}
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
annotations = newAnnotations.toMutableOrEmpty()
}
override fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?) {
delegatedConstructor = newDelegatedConstructor
}
override fun replaceBody(newBody: FirBlock?) {
body = newBody
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirErrorConstructor
import org.jetbrains.kotlin.fir.isCatchParameter
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -23,6 +24,9 @@ open class FirDeclarationRenderer {
typeRenderer.render(it)
printer.print(".")
}
if (declaration is FirErrorConstructor) {
printer.print("error_")
}
printer.print("constructor")
return
}
@@ -89,7 +89,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
fields from functionCall
}
for (constructorType in listOf("FirPrimaryConstructor", "FirConstructorImpl")) {
for (constructorType in listOf("FirPrimaryConstructor", "FirConstructorImpl", "FirErrorConstructor")) {
builder(constructor, constructorType) {
parents += abstractConstructorBuilder
defaultNull("delegatedConstructor")
@@ -26,6 +26,11 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
defaultTrue("isPrimary", withGetter = true)
}
impl(constructor, "FirErrorConstructor") {
publicImplementation()
defaultFalse("isPrimary", withGetter = true)
}
impl(typeParameterRef, "FirOuterClassTypeParameterRef") {
publicImplementation()
}
@@ -9,9 +9,9 @@ abstract class D : suspend () -> Int<!NO_CONSTRUCTOR!>()<!>
abstract class E : (suspend () -> Int)<!NO_CONSTRUCTOR!>()<!>
abstract class F : kotlin.coroutines.SuspendFunction0<Int><!NO_CONSTRUCTOR!>()<!>
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!>()
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!>()
interface IC : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>Function0<Int><!>()
interface ID : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>suspend () -> Int<!>()
interface IE : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(suspend () -> Int)<!>()
interface IF : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>kotlin.coroutines.SuspendFunction0<Int><!>()
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!><!NO_CONSTRUCTOR!>()<!>
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!><!NO_CONSTRUCTOR!>()<!>
interface IC : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>Function0<Int><!><!NO_CONSTRUCTOR!>()<!>
interface ID : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>suspend () -> Int<!><!NO_CONSTRUCTOR!>()<!>
interface IE : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(suspend () -> Int)<!><!NO_CONSTRUCTOR!>()<!>
interface IF : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>kotlin.coroutines.SuspendFunction0<Int><!><!NO_CONSTRUCTOR!>()<!>
@@ -9,9 +9,9 @@ abstract class D : suspend () -> Int<!NO_CONSTRUCTOR!>()<!>
abstract class E : (suspend () -> Int)<!NO_CONSTRUCTOR!>()<!>
abstract class F : kotlin.coroutines.SuspendFunction0<Int><!NO_CONSTRUCTOR!>()<!>
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!>()
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!>()
interface IC : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>Function0<Int><!>()
interface ID : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>suspend () -> Int<!>()
interface IE : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(suspend () -> Int)<!>()
interface IF : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>kotlin.coroutines.SuspendFunction0<Int><!>()
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!><!NO_CONSTRUCTOR!>()<!>
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!><!NO_CONSTRUCTOR!>()<!>
interface IC : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>Function0<Int><!><!NO_CONSTRUCTOR!>()<!>
interface ID : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>suspend () -> Int<!><!NO_CONSTRUCTOR!>()<!>
interface IE : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(suspend () -> Int)<!><!NO_CONSTRUCTOR!>()<!>
interface IF : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>kotlin.coroutines.SuspendFunction0<Int><!><!NO_CONSTRUCTOR!>()<!>
@@ -0,0 +1,5 @@
open class A(i: Int)
<!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>class B : A(<!UNRESOLVED_REFERENCE!>x<!>) {
constructor(i: Int) : super(i)
}<!>
@@ -0,0 +1,5 @@
open class A(i: Int)
class B : <!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>A(<!DEBUG_INFO_MISSING_UNRESOLVED!>x<!>)<!> {
constructor(i: Int) : super(i)
}
@@ -5996,6 +5996,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/derivedProperty.kt");
}
@Test
@TestMetadata("errorInsideDelegationCallNoPrimary.kt")
public void testErrorInsideDelegationCallNoPrimary() throws Exception {
runTest("compiler/testData/diagnostics/tests/constructorConsistency/errorInsideDelegationCallNoPrimary.kt");
}
@Test
@TestMetadata("getset.kt")
public void testGetset() throws Exception {