diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index f0cbf46e23f..787adae5c72 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -19,8 +19,7 @@ import org.jetbrains.kotlin.fir.labels.FirLabelImpl import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeProjection +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.* @@ -110,7 +109,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { return when (this) { is KtSecondaryConstructor -> toFirConstructor( delegatedSuperType, - delegatedSelfType!!, + delegatedSelfType ?: FirErrorTypeRefImpl(this@RawFirBuilder.session, this, "Constructor in object"), owner, hasPrimaryConstructor ) @@ -408,7 +407,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { firDelegatedCall ) this?.extractAnnotationsTo(firConstructor) - owner.extractTypeParametersTo(firConstructor) + firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) this?.extractValueParametersTo(firConstructor) return firConstructor } @@ -437,16 +436,19 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { } private fun KtClassOrObject.toDelegatedSelfType(firClass: FirRegularClass): FirTypeRef { + val typeParameters = firClass.typeParameters.map { + FirTypeParameterImpl(session, it.psi, FirTypeParameterSymbol(), it.name, Variance.INVARIANT, false).apply { + this.bounds += it.bounds + } + } return FirResolvedTypeRefImpl( session, this, ConeClassTypeImpl( firClass.symbol.toLookupTag(), - firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol, false) }.toTypedArray(), + typeParameters.map { ConeTypeParameterTypeImpl(it.symbol, false) }.toTypedArray(), false - ), - isMarkedNullable = false, - annotations = emptyList() + ) ) } @@ -752,13 +754,20 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { ) firFunctions += firConstructor extractAnnotationsTo(firConstructor) - owner.extractTypeParametersTo(firConstructor) + firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) extractValueParametersTo(firConstructor) firConstructor.body = buildFirBody() firFunctions.removeLast() return firConstructor } + private fun typeParametersFromSelfType(delegatedSelfTypeRef: FirTypeRef): List { + return delegatedSelfTypeRef.coneTypeSafe() + ?.typeArguments + ?.map { ((it as ConeTypeParameterType).lookupTag as FirTypeParameterSymbol).fir } + ?: emptyList() + } + private fun KtConstructorDelegationCall.convert( delegatedSuperTypeRef: FirTypeRef?, delegatedSelfTypeRef: FirTypeRef, diff --git a/compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.txt b/compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.txt index a08bbb7ab42..909197e2332 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.txt @@ -1,11 +1,11 @@ FILE: complexTypes.kt public? final? class C : kotlin/Any { - public? constructor(): R|a/b/C| { + public? constructor(): R|a/b/C| { super() } public? final? inner class D : kotlin/Any { - public? constructor(): R|a/b/C.D| { + public? constructor(): R|a/b/C.D| { super() } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt b/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt index 442d29b5efd..d10cbd0509f 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt @@ -8,7 +8,7 @@ FILE: typeParameters.kt public? final typealias StringList = List public? final typealias AnyList = List<*> public? abstract class AbstractList : List { - public? constructor(): R|AbstractList| { + public? constructor(): R|AbstractList| { super() } diff --git a/compiler/fir/resolve/testData/resolve/derivedClass.kt b/compiler/fir/resolve/testData/resolve/derivedClass.kt index 90379bd28e7..0ef313b2750 100644 --- a/compiler/fir/resolve/testData/resolve/derivedClass.kt +++ b/compiler/fir/resolve/testData/resolve/derivedClass.kt @@ -1,5 +1,5 @@ -open class Base(val x: T) +open class Base(val x: T1) -class Derived(x: T) : Base(x) +class Derived(x: T2) : Base(x) -fun create(x: T): Derived = Derived(x) \ No newline at end of file +fun create(x: T3) /* Derived */ = Derived(x) \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/derivedClass.txt b/compiler/fir/resolve/testData/resolve/derivedClass.txt index ab87d9eb982..e9e4092bbd7 100644 --- a/compiler/fir/resolve/testData/resolve/derivedClass.txt +++ b/compiler/fir/resolve/testData/resolve/derivedClass.txt @@ -1,19 +1,19 @@ FILE: derivedClass.kt - public open class Base : R|kotlin/Any| { - public constructor(x: R|T|): R|Base| { + public open class Base : R|kotlin/Any| { + public constructor(x: R|T1|): R|Base| { super() } - public final val x: R|T| = R|/x| - public get(): R|T| + public final val x: R|T1| = R|/x| + public get(): R|T1| } - public final class Derived : R|Base| { - public constructor(x: R|T|): R|Derived| { - super|>(R|/x|) + public final class Derived : R|Base| { + public constructor(x: R|T2|): R|Derived| { + super|>(R|/x|) } } - public final fun create(x: R|T|): R|Derived| { - ^create R|/Derived.Derived|(R|/x|) + public final fun create(x: R|T3|): R|Derived| { + ^create R|/Derived.Derived|(R|/x|) } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/typeAliasConstructor.txt b/compiler/fir/resolve/testData/resolve/expresssions/typeAliasConstructor.txt index b21677b1824..2447605b6ff 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/typeAliasConstructor.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/typeAliasConstructor.txt @@ -15,5 +15,5 @@ FILE: typeAliasConstructor.kt public final typealias BB = R|B| public final fun main(): R|kotlin/Unit| { lval x: R|A| = R|/A.A|(Int(1)) - lval y: = #(String(bb)) + lval y: R|B| = R|/B.B|(String(bb)) } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/complexTypes.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/complexTypes.txt index 971702c1ca1..3282459322b 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/complexTypes.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/complexTypes.txt @@ -1,11 +1,11 @@ FILE: complexTypes.kt public final class C : R|kotlin/Any| { - public constructor(): R|a/b/C| { + public constructor(): R|a/b/C| { super() } public final inner class D : R|kotlin/Any| { - public constructor(): R|a/b/C.D| { + public constructor(): R|a/b/C.D| { super() } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt index fb1fd298c06..ff0c71974fb 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/typeParameters.txt @@ -8,7 +8,7 @@ FILE: typeParameters.kt public final typealias StringList = R|List| public final typealias AnyList = R|List<*>| public abstract class AbstractList : R|List| { - public constructor(): R|AbstractList| { + public constructor(): R|AbstractList| { super() } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirClass.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirClass.kt index b3cc2334755..14f4429f339 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirClass.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirClass.kt @@ -6,10 +6,8 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.coneTypeSafe @@ -28,8 +26,15 @@ interface FirClass : FirDeclarationContainer, FirStatement, FirAnnotationContain for (superType in superTypeRefs) { superType.accept(visitor, data) } + var constructorFound = false for (declaration in declarations) { declaration.accept(visitor, data) + if (!constructorFound && declaration is FirConstructor) { + for (typeParameter in declaration.typeParameters) { + typeParameter.accept(visitor, data) + } + constructorFound = true + } } } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt index e66f4e19998..087bdaae495 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt @@ -23,11 +23,13 @@ interface FirConstructor : @VisitedSupertype FirFunction, FirCallableMemberDecla visitor.visitConstructor(this, data) override fun acceptChildren(visitor: FirVisitor, data: D) { - super.acceptChildren(visitor, data) + acceptAnnotations(visitor, data) + status.accept(visitor, data) delegatedConstructor?.accept(visitor, data) for (parameter in valueParameters) { parameter.accept(visitor, data) } + returnTypeRef.accept(visitor, data) body?.accept(visitor, data) } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirClassImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirClassImpl.kt index 7ba1e31ae7b..ecc26b2c9c9 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirClassImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirClassImpl.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol @@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.transformInplace import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull open class FirClassImpl( session: FirSession, @@ -69,6 +71,7 @@ open class FirClassImpl( superTypeRefs.transformInplace(transformer, data) val result = super.transformChildren(transformer, data) as FirRegularClass + declarations.firstIsInstanceOrNull()?.typeParameters?.transformInplace(transformer, data) // Transform declarations in last turn declarations.transformInplace(transformer, data) companionObject = declarations.asSequence().filterIsInstance().firstOrNull { it.isCompanion } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt index 9194fd73325..1d2cb9d93ea 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt @@ -61,11 +61,14 @@ open class FirConstructorImpl : FirAbstractCallableMember, FirConstructor { override var body: FirBlock? = null override fun transformChildren(transformer: FirTransformer, data: D): FirElement { + annotations.transformInplace(transformer, data) valueParameters.transformInplace(transformer, data) + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + status = status.transformSingle(transformer, data) delegatedConstructor?.transformSingle(transformer, data) body = body?.transformSingle(transformer, data) - return super.transformChildren(transformer, data) + return this } companion object {