FIR: add implicit primary constructors, add delegated types to them

So #KT-24088 In Progress
This commit is contained in:
Mikhail Glukhikh
2018-04-13 11:15:34 +03:00
parent 1c6490a1be
commit c06b0efdfa
50 changed files with 308 additions and 66 deletions
@@ -37,6 +37,10 @@ class RawFirBuilder(val session: FirSession) {
private val implicitUnitType = FirImplicitUnitType(session, null)
private val implicitAnyType = FirImplicitAnyType(session, null)
private val implicitEnumType = FirImplicitEnumType(session, null)
fun buildFirFile(file: KtFile): FirFile {
return file.accept(Visitor(), Unit) as FirFile
}
@@ -204,13 +208,15 @@ class RawFirBuilder(val session: FirSession) {
private fun KtClassOrObject.extractSuperTypeListEntriesTo(container: FirClassImpl) {
var superTypeCallEntry: KtSuperTypeCallEntry? = null
var delegatedSuperType: FirType? = null
for (superTypeListEntry in superTypeListEntries) {
when (superTypeListEntry) {
is KtSuperTypeEntry -> {
container.superTypes += superTypeListEntry.typeReference.toFirOrErrorType()
}
is KtSuperTypeCallEntry -> {
container.superTypes += superTypeListEntry.calleeExpression.typeReference.toFirOrErrorType()
delegatedSuperType = superTypeListEntry.calleeExpression.typeReference.toFirOrErrorType()
container.superTypes += delegatedSuperType
superTypeCallEntry = superTypeListEntry
}
is KtDelegatedSuperTypeEntry -> {
@@ -222,31 +228,40 @@ class RawFirBuilder(val session: FirSession) {
}
}
}
val firPrimaryConstructor = primaryConstructor?.toFirConstructor(superTypeCallEntry) ?: return
fun isEnum() = this is KtClass && this.isEnum()
if (this is KtClass && this.isInterface()) return
if (!this.hasPrimaryConstructor()) return
val firPrimaryConstructor = primaryConstructor.toFirConstructor(
superTypeCallEntry,
delegatedSuperType = delegatedSuperType ?: (if (isEnum()) implicitEnumType else implicitAnyType),
owner = this
)
container.declarations += firPrimaryConstructor
}
private fun KtPrimaryConstructor.toFirConstructor(superTypeCallEntry: KtSuperTypeCallEntry?): FirConstructor {
private fun KtPrimaryConstructor?.toFirConstructor(
superTypeCallEntry: KtSuperTypeCallEntry?,
delegatedSuperType: FirType,
owner: KtClassOrObject
): FirConstructor {
val constructorCallee = superTypeCallEntry?.calleeExpression
val firDelegatedCall = constructorCallee?.let {
FirDelegatedConstructorCallImpl(
session,
constructorCallee,
FirErrorTypeImpl(session, constructorCallee, "Not implemented yet"),
isThis = false
).apply {
// TODO: arguments are not needed for light classes, but will be needed later
//superTypeCallEntry.extractArgumentsTo(this)
}
val firDelegatedCall = FirDelegatedConstructorCallImpl(
session,
constructorCallee ?: (this ?: owner),
delegatedSuperType,
isThis = false
).apply {
// TODO: arguments are not needed for light classes, but will be needed later
//superTypeCallEntry.extractArgumentsTo(this)
}
val firConstructor = FirPrimaryConstructorImpl(
session,
this,
visibility,
this ?: owner,
this?.visibility ?: Visibilities.UNKNOWN,
firDelegatedCall
)
extractAnnotationsTo(firConstructor)
extractValueParametersTo(firConstructor)
this?.extractAnnotationsTo(firConstructor)
this?.extractValueParametersTo(firConstructor)
return firConstructor
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
class FirTypeResolverImpl : FirTypeResolver {
@@ -56,7 +57,9 @@ class FirTypeResolverImpl : FirTypeResolver {
}
}
private val implicitUnitTypeSymbols = mutableMapOf<FirSession, ConeSymbol>()
private data class NameInSession(val session: FirSession, val name: Name)
private val implicitBuiltinTypeSymbols = mutableMapOf<NameInSession, ConeSymbol>()
override fun resolveToSymbol(
type: FirType,
@@ -91,14 +94,17 @@ class FirTypeResolverImpl : FirTypeResolver {
// TODO: Imports
resolvedSymbol ?: qualifierResolver.resolveSymbol(type.qualifier)
}
is FirImplicitUnitType -> implicitUnitTypeSymbols[type.session] ?: run {
var resolvedSymbol: ConeSymbol? = null
scope.processClassifiersByName(KotlinBuiltIns.FQ_NAMES.unit.shortName(), position) {
resolvedSymbol = (it as ConeClassLikeSymbol)
resolvedSymbol == null
is FirImplicitBuiltinType -> {
val nameInSession = NameInSession(type.session, type.name)
implicitBuiltinTypeSymbols[nameInSession] ?: run {
var resolvedSymbol: ConeSymbol? = null
scope.processClassifiersByName(type.name, position) {
resolvedSymbol = (it as ConeClassLikeSymbol)
resolvedSymbol == null
}
implicitBuiltinTypeSymbols[nameInSession] = resolvedSymbol!!
resolvedSymbol
}
implicitUnitTypeSymbols[type.session] = resolvedSymbol!!
resolvedSymbol
}
else -> null
}
@@ -129,7 +135,7 @@ class FirTypeResolverImpl : FirTypeResolver {
type.returnType.coneTypeUnsafe()
)
}
is FirImplicitUnitType -> {
is FirImplicitBuiltinType -> {
resolveToSymbol(type, scope, position)!!.toConeKotlinType(emptyList())!!
}
is FirDynamicType, is FirImplicitType, is FirDelegatedType -> {
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitType
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinType
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.Variance
@@ -387,10 +387,12 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
override fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall) {
if (delegatedConstructorCall.isSuper) {
print(": super")
print(": super<")
} else if (delegatedConstructorCall.isThis) {
print(": this")
print(": this<")
}
delegatedConstructorCall.constructedType.accept(this)
print(">")
visitCall(delegatedConstructorCall)
}
@@ -411,7 +413,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
}
override fun visitImplicitType(implicitType: FirImplicitType) {
print(if (implicitType is FirImplicitUnitType) "kotlin.Unit" else "<implicit>")
print(if (implicitType is FirImplicitBuiltinType) "kotlin.${implicitType.name}" else "<implicit>")
}
override fun visitTypeWithNullability(typeWithNullability: FirTypeWithNullability) {
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.types.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.types.FirImplicitType
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
sealed class FirImplicitBuiltinType(
override val session: FirSession,
override val psi: PsiElement?,
val name: Name
) : FirImplicitType {
override val annotations: List<FirAnnotationCall>
get() = emptyList()
constructor(session: FirSession, psi: PsiElement?, name: FqNameUnsafe) : this(session, psi, name.shortName())
}
class FirImplicitUnitType(
session: FirSession,
psi: PsiElement?
) : FirImplicitBuiltinType(session, psi, KotlinBuiltIns.FQ_NAMES.unit)
class FirImplicitAnyType(
session: FirSession,
psi: PsiElement?
) : FirImplicitBuiltinType(session, psi, KotlinBuiltIns.FQ_NAMES.any)
class FirImplicitEnumType(
session: FirSession,
psi: PsiElement?
) : FirImplicitBuiltinType(session, psi, KotlinBuiltIns.FQ_NAMES._enum)
@@ -1,19 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.types.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.types.FirImplicitType
class FirImplicitUnitType(
override val session: FirSession,
override val psi: PsiElement?
) : FirImplicitType {
override val annotations: List<FirAnnotationCall>
get() = emptyList()
}