FIR: support delegated types in secondary constructors
So #KT-24088 Fixed
This commit is contained in:
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirBody
|
import org.jetbrains.kotlin.fir.expressions.FirBody
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
@@ -206,7 +207,7 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtClassOrObject.extractSuperTypeListEntriesTo(container: FirClassImpl) {
|
private fun KtClassOrObject.extractSuperTypeListEntriesTo(container: FirClassImpl): FirType? {
|
||||||
var superTypeCallEntry: KtSuperTypeCallEntry? = null
|
var superTypeCallEntry: KtSuperTypeCallEntry? = null
|
||||||
var delegatedSuperType: FirType? = null
|
var delegatedSuperType: FirType? = null
|
||||||
for (superTypeListEntry in superTypeListEntries) {
|
for (superTypeListEntry in superTypeListEntries) {
|
||||||
@@ -228,15 +229,21 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this is KtClass && this.isInterface()) return delegatedSuperType
|
||||||
|
|
||||||
fun isEnum() = this is KtClass && this.isEnum()
|
fun isEnum() = this is KtClass && this.isEnum()
|
||||||
if (this is KtClass && this.isInterface()) return
|
// TODO: in case we have no primary constructor,
|
||||||
if (!this.hasPrimaryConstructor()) return
|
// it may be not possible to determine delegated super type right here
|
||||||
|
delegatedSuperType = delegatedSuperType ?: (if (isEnum()) implicitEnumType else implicitAnyType)
|
||||||
|
if (!this.hasPrimaryConstructor()) return delegatedSuperType
|
||||||
|
|
||||||
val firPrimaryConstructor = primaryConstructor.toFirConstructor(
|
val firPrimaryConstructor = primaryConstructor.toFirConstructor(
|
||||||
superTypeCallEntry,
|
superTypeCallEntry,
|
||||||
delegatedSuperType = delegatedSuperType ?: (if (isEnum()) implicitEnumType else implicitAnyType),
|
delegatedSuperType,
|
||||||
owner = this
|
owner = this
|
||||||
)
|
)
|
||||||
container.declarations += firPrimaryConstructor
|
container.declarations += firPrimaryConstructor
|
||||||
|
return delegatedSuperType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtPrimaryConstructor?.toFirConstructor(
|
private fun KtPrimaryConstructor?.toFirConstructor(
|
||||||
@@ -288,6 +295,11 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
return firFile
|
return firFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtClassOrObject.toDelegatedSelfType(): FirType =
|
||||||
|
FirUserTypeImpl(session, this, isNullable = false).apply {
|
||||||
|
qualifier.add(FirQualifierPartImpl(nameAsSafeName))
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitEnumEntry(enumEntry: KtEnumEntry, data: Unit): FirElement {
|
override fun visitEnumEntry(enumEntry: KtEnumEntry, data: Unit): FirElement {
|
||||||
return withChildClassName(enumEntry.nameAsSafeName) {
|
return withChildClassName(enumEntry.nameAsSafeName) {
|
||||||
val firEnumEntry = FirEnumEntryImpl(
|
val firEnumEntry = FirEnumEntryImpl(
|
||||||
@@ -297,9 +309,17 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
enumEntry.nameAsSafeName
|
enumEntry.nameAsSafeName
|
||||||
)
|
)
|
||||||
enumEntry.extractAnnotationsTo(firEnumEntry)
|
enumEntry.extractAnnotationsTo(firEnumEntry)
|
||||||
enumEntry.extractSuperTypeListEntriesTo(firEnumEntry)
|
val delegatedSuperType = enumEntry.extractSuperTypeListEntriesTo(firEnumEntry)
|
||||||
|
val delegatedSelfType = enumEntry.toDelegatedSelfType()
|
||||||
for (declaration in enumEntry.declarations) {
|
for (declaration in enumEntry.declarations) {
|
||||||
firEnumEntry.declarations += declaration.convert<FirDeclaration>()
|
firEnumEntry.declarations += when (declaration) {
|
||||||
|
is KtSecondaryConstructor -> declaration.toFirConstructor(
|
||||||
|
delegatedSuperType,
|
||||||
|
delegatedSelfType,
|
||||||
|
hasPrimaryConstructor = true
|
||||||
|
)
|
||||||
|
else -> declaration.convert<FirDeclaration>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
firEnumEntry
|
firEnumEntry
|
||||||
}
|
}
|
||||||
@@ -345,15 +365,23 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
)
|
)
|
||||||
classOrObject.extractAnnotationsTo(firClass)
|
classOrObject.extractAnnotationsTo(firClass)
|
||||||
classOrObject.extractTypeParametersTo(firClass)
|
classOrObject.extractTypeParametersTo(firClass)
|
||||||
classOrObject.extractSuperTypeListEntriesTo(firClass)
|
val delegatedSuperType = classOrObject.extractSuperTypeListEntriesTo(firClass)
|
||||||
classOrObject.primaryConstructor?.valueParameters?.forEach {
|
classOrObject.primaryConstructor?.valueParameters?.forEach {
|
||||||
if (it.hasValOrVar()) {
|
if (it.hasValOrVar()) {
|
||||||
firClass.declarations += it.toFirProperty()
|
firClass.declarations += it.toFirProperty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val delegatedSelfType = classOrObject.toDelegatedSelfType()
|
||||||
for (declaration in classOrObject.declarations) {
|
for (declaration in classOrObject.declarations) {
|
||||||
firClass.declarations += declaration.convert<FirDeclaration>()
|
firClass.declarations += when (declaration) {
|
||||||
|
is KtSecondaryConstructor -> declaration.toFirConstructor(
|
||||||
|
delegatedSuperType,
|
||||||
|
delegatedSelfType,
|
||||||
|
classOrObject.primaryConstructor != null
|
||||||
|
)
|
||||||
|
else -> declaration.convert<FirDeclaration>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firClass
|
firClass
|
||||||
@@ -413,25 +441,38 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
return firFunction
|
return firFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit): FirElement {
|
private fun KtSecondaryConstructor.toFirConstructor(
|
||||||
|
delegatedSuperType: FirType?,
|
||||||
|
delegatedSelfType: FirType,
|
||||||
|
hasPrimaryConstructor: Boolean
|
||||||
|
): FirConstructor {
|
||||||
val firConstructor = FirConstructorImpl(
|
val firConstructor = FirConstructorImpl(
|
||||||
session,
|
session,
|
||||||
constructor,
|
this,
|
||||||
constructor.visibility,
|
visibility,
|
||||||
constructor.getDelegationCall().convert(),
|
getDelegationCall().convert(delegatedSuperType, delegatedSelfType, hasPrimaryConstructor),
|
||||||
constructor.buildFirBody()
|
buildFirBody()
|
||||||
)
|
)
|
||||||
constructor.extractAnnotationsTo(firConstructor)
|
extractAnnotationsTo(firConstructor)
|
||||||
constructor.extractValueParametersTo(firConstructor)
|
extractValueParametersTo(firConstructor)
|
||||||
return firConstructor
|
return firConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructorDelegationCall(call: KtConstructorDelegationCall, data: Unit): FirElement {
|
private fun KtConstructorDelegationCall.convert(
|
||||||
|
delegatedSuperType: FirType?,
|
||||||
|
delegatedSelfType: FirType,
|
||||||
|
hasPrimaryConstructor: Boolean
|
||||||
|
): FirDelegatedConstructorCall {
|
||||||
|
val isThis = isCallToThis || (isImplicit && hasPrimaryConstructor)
|
||||||
|
val delegatedType = when {
|
||||||
|
isThis -> delegatedSelfType
|
||||||
|
else -> delegatedSuperType ?: FirErrorTypeImpl(session, this, "No super type")
|
||||||
|
}
|
||||||
val firConstructorCall = FirDelegatedConstructorCallImpl(
|
val firConstructorCall = FirDelegatedConstructorCallImpl(
|
||||||
session,
|
session,
|
||||||
call,
|
this,
|
||||||
FirErrorTypeImpl(session, call, "Not implemented yet"),
|
delegatedType,
|
||||||
call.isCallToThis || call.isImplicit
|
isThis
|
||||||
)
|
)
|
||||||
// TODO: arguments are not needed for light classes, but will be needed later
|
// TODO: arguments are not needed for light classes, but will be needed later
|
||||||
// call.extractArgumentsTo(firConstructorCall)
|
// call.extractArgumentsTo(firConstructorCall)
|
||||||
@@ -512,6 +553,7 @@ class RawFirBuilder(val session: FirSession) {
|
|||||||
typeReference,
|
typeReference,
|
||||||
isNullable,
|
isNullable,
|
||||||
unwrappedElement.receiverTypeReference.convertSafe(),
|
unwrappedElement.receiverTypeReference.convertSafe(),
|
||||||
|
// TODO: probably implicit type should not be here
|
||||||
unwrappedElement.returnTypeReference.toFirOrImplicitType()
|
unwrappedElement.returnTypeReference.toFirOrImplicitType()
|
||||||
)
|
)
|
||||||
for (valueParameter in unwrappedElement.parameters) {
|
for (valueParameter in unwrappedElement.parameters) {
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ FILE: noPrimaryConstructor.kt
|
|||||||
public? final? property x(val): String
|
public? final? property x(val): String
|
||||||
public? get(): String
|
public? get(): String
|
||||||
|
|
||||||
public? constructor(x: String): this<<ERROR TYPE: Not implemented yet>>() {
|
public? constructor(x: String): super<kotlin.Any>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public? constructor(): this<<ERROR TYPE: Not implemented yet>>()
|
public? constructor(): this<NoPrimary>()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ FILE: Annotations.kt
|
|||||||
STUB
|
STUB
|
||||||
}
|
}
|
||||||
|
|
||||||
@R|annotations/WithString|(STUB) public? constructor(): this<R|error: Not implemented yet|>()
|
@R|annotations/WithString|(STUB) public? constructor(): this<R|test/Second|>()
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|annotations/WithInt|(STUB) @R|annotations/WithInt|(STUB) public? final typealias Third = @R|annotations/Simple|() R|test/Second|
|
@R|annotations/WithInt|(STUB) @R|annotations/WithInt|(STUB) public? final typealias Third = @R|annotations/Simple|() R|test/Second|
|
||||||
|
|||||||
Reference in New Issue
Block a user