提交 77817cb7 编写于 作者: S Simon Ogorodnik 提交者: Mikhail Glukhikh

Raw FIR: copy class type-parameters into constructors properly

上级 9cef9e40
...@@ -19,8 +19,7 @@ import org.jetbrains.kotlin.fir.labels.FirLabelImpl ...@@ -19,8 +19,7 @@ import org.jetbrains.kotlin.fir.labels.FirLabelImpl
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.lexer.KtTokens.*
...@@ -110,7 +109,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { ...@@ -110,7 +109,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
return when (this) { return when (this) {
is KtSecondaryConstructor -> toFirConstructor( is KtSecondaryConstructor -> toFirConstructor(
delegatedSuperType, delegatedSuperType,
delegatedSelfType!!, delegatedSelfType ?: FirErrorTypeRefImpl(this@RawFirBuilder.session, this, "Constructor in object"),
owner, owner,
hasPrimaryConstructor hasPrimaryConstructor
) )
...@@ -408,7 +407,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { ...@@ -408,7 +407,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
firDelegatedCall firDelegatedCall
) )
this?.extractAnnotationsTo(firConstructor) this?.extractAnnotationsTo(firConstructor)
owner.extractTypeParametersTo(firConstructor) firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
this?.extractValueParametersTo(firConstructor) this?.extractValueParametersTo(firConstructor)
return firConstructor return firConstructor
} }
...@@ -437,16 +436,19 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { ...@@ -437,16 +436,19 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
} }
private fun KtClassOrObject.toDelegatedSelfType(firClass: FirRegularClass): FirTypeRef { 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( return FirResolvedTypeRefImpl(
session, session,
this, this,
ConeClassTypeImpl( ConeClassTypeImpl(
firClass.symbol.toLookupTag(), firClass.symbol.toLookupTag(),
firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol, false) }.toTypedArray(), typeParameters.map { ConeTypeParameterTypeImpl(it.symbol, false) }.toTypedArray(),
false false
), )
isMarkedNullable = false,
annotations = emptyList()
) )
} }
...@@ -752,13 +754,20 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { ...@@ -752,13 +754,20 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
) )
firFunctions += firConstructor firFunctions += firConstructor
extractAnnotationsTo(firConstructor) extractAnnotationsTo(firConstructor)
owner.extractTypeParametersTo(firConstructor) firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
extractValueParametersTo(firConstructor) extractValueParametersTo(firConstructor)
firConstructor.body = buildFirBody() firConstructor.body = buildFirBody()
firFunctions.removeLast() firFunctions.removeLast()
return firConstructor return firConstructor
} }
private fun typeParametersFromSelfType(delegatedSelfTypeRef: FirTypeRef): List<FirTypeParameter> {
return delegatedSelfTypeRef.coneTypeSafe()
?.typeArguments
?.map { ((it as ConeTypeParameterType).lookupTag as FirTypeParameterSymbol).fir }
?: emptyList()
}
private fun KtConstructorDelegationCall.convert( private fun KtConstructorDelegationCall.convert(
delegatedSuperTypeRef: FirTypeRef?, delegatedSuperTypeRef: FirTypeRef?,
delegatedSelfTypeRef: FirTypeRef, delegatedSelfTypeRef: FirTypeRef,
......
FILE: complexTypes.kt FILE: complexTypes.kt
public? final? class C<T, out S> : kotlin/Any { public? final? class C<T, out S> : kotlin/Any {
public? constructor<T, out S>(): R|a/b/C<T, S>| { public? constructor<T, S>(): R|a/b/C<T, S>| {
super<kotlin/Any>() super<kotlin/Any>()
} }
public? final? inner class D<R, in P> : kotlin/Any { public? final? inner class D<R, in P> : kotlin/Any {
public? constructor<R, in P>(): R|a/b/C.D<R, P>| { public? constructor<R, P>(): R|a/b/C.D<R, P>| {
super<kotlin/Any>() super<kotlin/Any>()
} }
......
...@@ -8,7 +8,7 @@ FILE: typeParameters.kt ...@@ -8,7 +8,7 @@ FILE: typeParameters.kt
public? final typealias StringList = List<out String> public? final typealias StringList = List<out String>
public? final typealias AnyList = List<*> public? final typealias AnyList = List<*>
public? abstract class AbstractList<out T : Any> : List<T> { public? abstract class AbstractList<out T : Any> : List<T> {
public? constructor<out T : Any>(): R|AbstractList<T>| { public? constructor<T : Any>(): R|AbstractList<T>| {
super<kotlin/Any>() super<kotlin/Any>()
} }
......
open class Base<T>(val x: T) open class Base<T1>(val x: T1)
class Derived<T : Any>(x: T) : Base<T>(x) class Derived<T2 : Any>(x: T2) : Base<T2>(x)
fun <T : Any> create(x: T): Derived<T> = Derived(x) fun <T3 : Any> create(x: T3) /* Derived<T3> */ = Derived(x)
\ No newline at end of file \ No newline at end of file
FILE: derivedClass.kt FILE: derivedClass.kt
public open class Base<T> : R|kotlin/Any| { public open class Base<T1> : R|kotlin/Any| {
public constructor<T>(x: R|T|): R|Base<T>| { public constructor<T1>(x: R|T1|): R|Base<T1>| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final val x: R|T| = R|<local>/x| public final val x: R|T1| = R|<local>/x|
public get(): R|T| public get(): R|T1|
} }
public final class Derived<T : R|kotlin/Any|> : R|Base<T>| { public final class Derived<T2 : R|kotlin/Any|> : R|Base<T2>| {
public constructor<T : R|kotlin/Any|>(x: R|T|): R|Derived<T>| { public constructor<T2 : R|kotlin/Any|>(x: R|T2|): R|Derived<T2>| {
super<R|Base<T>|>(R|<local>/x|) super<R|Base<T2>|>(R|<local>/x|)
} }
} }
public final fun <T : R|kotlin/Any|> create(x: R|T|): R|Derived<T>| { public final fun <T3 : R|kotlin/Any|> create(x: R|T3|): R|Derived<T3>| {
^create R|/Derived.Derived|(R|<local>/x|) ^create R|/Derived.Derived|<R|T3|>(R|<local>/x|)
} }
...@@ -15,5 +15,5 @@ FILE: typeAliasConstructor.kt ...@@ -15,5 +15,5 @@ FILE: typeAliasConstructor.kt
public final typealias BB<U> = R|B<U>| public final typealias BB<U> = R|B<U>|
public final fun main(): R|kotlin/Unit| { public final fun main(): R|kotlin/Unit| {
lval x: R|A| = R|/A.A|(Int(1)) lval x: R|A| = R|/A.A|(Int(1))
lval y: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/B.B]> = <Inapplicable(INAPPLICABLE): [/B.B]>#<R|kotlin/String|>(String(bb)) lval y: R|B<kotlin/String>| = R|/B.B|<R|kotlin/String|>(String(bb))
} }
FILE: complexTypes.kt FILE: complexTypes.kt
public final class C<T, out S> : R|kotlin/Any| { public final class C<T, out S> : R|kotlin/Any| {
public constructor<T, out S>(): R|a/b/C<T, S>| { public constructor<T, S>(): R|a/b/C<T, S>| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final inner class D<R, in P> : R|kotlin/Any| { public final inner class D<R, in P> : R|kotlin/Any| {
public constructor<R, in P>(): R|a/b/C.D<R, P>| { public constructor<R, P>(): R|a/b/C.D<R, P>| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
......
...@@ -8,7 +8,7 @@ FILE: typeParameters.kt ...@@ -8,7 +8,7 @@ FILE: typeParameters.kt
public final typealias StringList = R|List<out kotlin/String>| public final typealias StringList = R|List<out kotlin/String>|
public final typealias AnyList = R|List<*>| public final typealias AnyList = R|List<*>|
public abstract class AbstractList<out T : R|kotlin/Any|> : R|List<T>| { public abstract class AbstractList<out T : R|kotlin/Any|> : R|List<T>| {
public constructor<out T : R|kotlin/Any|>(): R|AbstractList<T>| { public constructor<T : R|kotlin/Any|>(): R|AbstractList<T>| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
......
...@@ -6,10 +6,8 @@ ...@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.fir.declarations package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.descriptors.ClassKind 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.FirAnnotationContainer
import org.jetbrains.kotlin.fir.expressions.FirStatement 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.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
...@@ -28,8 +26,15 @@ interface FirClass : FirDeclarationContainer, FirStatement, FirAnnotationContain ...@@ -28,8 +26,15 @@ interface FirClass : FirDeclarationContainer, FirStatement, FirAnnotationContain
for (superType in superTypeRefs) { for (superType in superTypeRefs) {
superType.accept(visitor, data) superType.accept(visitor, data)
} }
var constructorFound = false
for (declaration in declarations) { for (declaration in declarations) {
declaration.accept(visitor, data) declaration.accept(visitor, data)
if (!constructorFound && declaration is FirConstructor) {
for (typeParameter in declaration.typeParameters) {
typeParameter.accept(visitor, data)
}
constructorFound = true
}
} }
} }
} }
......
...@@ -23,11 +23,13 @@ interface FirConstructor : @VisitedSupertype FirFunction, FirCallableMemberDecla ...@@ -23,11 +23,13 @@ interface FirConstructor : @VisitedSupertype FirFunction, FirCallableMemberDecla
visitor.visitConstructor(this, data) visitor.visitConstructor(this, data)
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) { override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
super<FirCallableMemberDeclaration>.acceptChildren(visitor, data) acceptAnnotations(visitor, data)
status.accept(visitor, data)
delegatedConstructor?.accept(visitor, data) delegatedConstructor?.accept(visitor, data)
for (parameter in valueParameters) { for (parameter in valueParameters) {
parameter.accept(visitor, data) parameter.accept(visitor, data)
} }
returnTypeRef.accept(visitor, data)
body?.accept(visitor, data) body?.accept(visitor, data)
} }
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind ...@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirSession 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.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
...@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.transformInplace ...@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.transformInplace
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
open class FirClassImpl( open class FirClassImpl(
session: FirSession, session: FirSession,
...@@ -69,6 +71,7 @@ open class FirClassImpl( ...@@ -69,6 +71,7 @@ open class FirClassImpl(
superTypeRefs.transformInplace(transformer, data) superTypeRefs.transformInplace(transformer, data)
val result = super<FirAbstractMemberDeclaration>.transformChildren(transformer, data) as FirRegularClass val result = super<FirAbstractMemberDeclaration>.transformChildren(transformer, data) as FirRegularClass
declarations.firstIsInstanceOrNull<FirConstructorImpl>()?.typeParameters?.transformInplace(transformer, data)
// Transform declarations in last turn // Transform declarations in last turn
declarations.transformInplace(transformer, data) declarations.transformInplace(transformer, data)
companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.isCompanion } companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.isCompanion }
......
...@@ -61,11 +61,14 @@ open class FirConstructorImpl : FirAbstractCallableMember, FirConstructor { ...@@ -61,11 +61,14 @@ open class FirConstructorImpl : FirAbstractCallableMember, FirConstructor {
override var body: FirBlock? = null override var body: FirBlock? = null
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement { override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
annotations.transformInplace(transformer, data)
valueParameters.transformInplace(transformer, data) valueParameters.transformInplace(transformer, data)
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
status = status.transformSingle(transformer, data)
delegatedConstructor?.transformSingle(transformer, data) delegatedConstructor?.transformSingle(transformer, data)
body = body?.transformSingle(transformer, data) body = body?.transformSingle(transformer, data)
return super<FirAbstractCallableMember>.transformChildren(transformer, data) return this
} }
companion object { companion object {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册