Raw FIR: generate data-class component1, component2, ... functions

This commit is contained in:
Mikhail Glukhikh
2019-04-18 18:26:40 +03:00
parent bb7dcd9945
commit f9feeac5e1
7 changed files with 128 additions and 0 deletions
@@ -22,6 +22,7 @@ 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.impl.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -551,6 +552,48 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
)
}
if (classOrObject.hasModifier(KtTokens.DATA_KEYWORD) && firPrimaryConstructor != null) {
var componentIndex = 1
val zippedParameters =
classOrObject.primaryConstructorParameters.zip(firClass.declarations.filterIsInstance<FirProperty>())
for ((ktParameter, firProperty) in zippedParameters) {
if (!ktParameter.hasValOrVar()) continue
val name = Name.identifier("component$componentIndex")
componentIndex++
val symbol = FirFunctionSymbol(callableIdForName(name))
firClass.addDeclaration(
FirMemberFunctionImpl(
session, ktParameter, symbol, name,
Visibilities.PUBLIC, Modality.FINAL,
isExpect = false, isActual = false,
isOverride = false, isOperator = false,
isInfix = false, isInline = false,
isTailRec = false, isExternal = false,
isSuspend = false, receiverTypeRef = null,
returnTypeRef = FirImplicitTypeRefImpl(session, ktParameter)
).apply {
val componentFunction = this
body = FirSingleExpressionBlock(
this@RawFirBuilder.session,
FirReturnExpressionImpl(
this@RawFirBuilder.session, ktParameter,
FirQualifiedAccessExpressionImpl(this@RawFirBuilder.session, ktParameter).apply {
val parameterName = ktParameter.nameAsSafeName
calleeReference = FirResolvedCallableReferenceImpl(
this@RawFirBuilder.session, ktParameter,
parameterName, firProperty.symbol
)
}
).apply {
target = FirFunctionTarget(null)
target.bind(componentFunction)
}
)
}
)
}
}
firClass
}
}
@@ -13,6 +13,18 @@ FILE: destructuring.kt
public? final? val third: String = R|<local>/third|
public? get(): String
public final fun component1(): <implicit> {
^component1 R|/Some.first|
}
public final fun component2(): <implicit> {
^component2 R|/Some.second|
}
public final fun component3(): <implicit> {
^component3 R|/Some.third|
}
}
public? final? fun foo(some: Some): kotlin/Unit {
lval <destruct>: <implicit> = some#
@@ -35,6 +35,14 @@ FILE: for.kt
public? final? val y: Int = R|<local>/y|
public? get(): Int
public final fun component1(): <implicit> {
^component1 R|/Some.x|
}
public final fun component2(): <implicit> {
^component2 R|/Some.y|
}
}
public? final? fun baz(set: Set<Some>): kotlin/Unit {
lval <range>: <implicit> = set#
@@ -10,6 +10,14 @@ FILE: lambda.kt
public? final? val y: Int = R|<local>/y|
public? get(): Int
public final fun component1(): <implicit> {
^component1 R|/Tuple.x|
}
public final fun component2(): <implicit> {
^component2 R|/Tuple.y|
}
}
public? final? inline fun use(f: ( (Tuple) -> Int )): <implicit> {
^use f#(Tuple#(Int(1), Int(2)))