Write local variable parsing (light tree to FIR)

This commit is contained in:
Ivan Cilcic
2019-07-18 16:20:29 +03:00
committed by Mikhail Glukhikh
parent c0fdbec358
commit e0a92c5ed5
5 changed files with 65 additions and 39 deletions
@@ -105,6 +105,7 @@ class DeclarationsConverter(
CLASS -> firStatements += convertClass(it) as FirStatement
FUN -> firStatements += convertFunctionDeclaration(it) as FirStatement
PROPERTY -> firStatements += convertPropertyDeclaration(it) as FirStatement
DESTRUCTURING_DECLARATION -> firStatements += convertDestructingDeclaration(it).toFirDestructingDeclaration(session)
TYPEALIAS -> firStatements += convertTypeAlias(it) as FirStatement
OBJECT_DECLARATION -> firStatements += convertClass(it) as FirStatement
CLASS_INITIALIZER -> firStatements += convertAnonymousInitializer(it) as FirStatement
@@ -676,7 +677,6 @@ class DeclarationsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseProperty
*/
private fun convertPropertyDeclaration(property: LighterASTNode): FirDeclaration {
//TODO DESTRUCTURING_DECLARATION
var modifiers = Modifier(session)
lateinit var identifier: String
val firTypeParameters = mutableListOf<FirTypeParameter>()
@@ -718,7 +718,9 @@ class DeclarationsConverter(
isVar,
firExpression,
delegate = firDelegateExpression
)
).apply {
annotations += modifiers.annotations
}
} else {
FirMemberPropertyImpl(
session,
@@ -753,14 +755,16 @@ class DeclarationsConverter(
private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration {
var isVar = false
val entries = mutableListOf<FirVariable>()
var firExpression: FirExpression? = null
destructingDeclaration.forEachChildren {
when (it.tokenType) {
VAR_KEYWORD -> isVar = true
DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it)
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
}
}
return DestructuringDeclaration(isVar, entries)
return DestructuringDeclaration(isVar, entries, firExpression)
}
/**
@@ -5,9 +5,29 @@
package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.generateTemporaryVariable
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirVariable
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
import org.jetbrains.kotlin.fir.lightTree.converter.utils.generateDestructuringBlock
data class DestructuringDeclaration(
val isVar: Boolean,
val entries: List<FirVariable>
)
val entries: List<FirVariable>,
val initializer: FirExpression?
) {
fun toFirDestructingDeclaration(session: FirSession): FirExpression {
val baseVariable = generateTemporaryVariable(
session, null, "destruct",
initializer ?: FirErrorExpressionImpl(session, null, "Destructuring declaration without initializer")
)
return generateDestructuringBlock(
session,
this,
baseVariable,
tmpVariable = true
)
}
}
@@ -19,16 +19,14 @@ import org.jetbrains.kotlin.psi.KtLambdaExpression
class FirPartialTransformer(
private val visitAnonymousFunction: Boolean = false,
private val visitLambdaExpression: Boolean = false,
private val visitNamedFunction: Boolean = false,
private val visitMemberDeclaration: Boolean = false,
private val visitLocalMembers: Boolean = false,
private val visitVariable: Boolean = false,
private val visitAnnotation: Boolean = false,
private val visitTypeOperatorCall: Boolean = false,
private val visitArrayOfCall: Boolean = false,
private val visitFunctionCall: Boolean = false,
private val visitGetClassCall: Boolean = false,
private val visitBreakExpression: Boolean = false,
private val visitContinueExpression: Boolean = false,
private val visitLoopJump: Boolean = false,
private val visitReturnExpression: Boolean = false,
private val visitThrowExpression: Boolean = false,
private val visitLoops: Boolean = false,
@@ -38,8 +36,7 @@ class FirPartialTransformer(
private val visitTryExpression: Boolean = false,
private val visitWhenExpression: Boolean = false,
private val visitLambdaArgumentExpression: Boolean = false,
private val visitAnonymousObject: Boolean = false,
private val visitAssignment: Boolean = false
private val visitAnonymousObject: Boolean = false
) : FirAbstractTreeTransformer() {
override fun transformAnonymousFunction(
anonymousFunction: FirAnonymousFunction,
@@ -55,7 +52,7 @@ class FirPartialTransformer(
}
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Nothing?): CompositeTransformResult<FirDeclaration> {
return if (!visitNamedFunction && namedFunction is FirAbstractCallableMember && namedFunction.visibility == Visibilities.LOCAL) {
return if (!visitLocalMembers && namedFunction is FirAbstractCallableMember && namedFunction.visibility == Visibilities.LOCAL) {
DummyFirDeclaration().compose()
} else {
(namedFunction.transformChildren(this, data) as FirNamedFunction).compose()
@@ -66,7 +63,7 @@ class FirPartialTransformer(
memberDeclaration: FirMemberDeclaration,
data: Nothing?
): CompositeTransformResult<FirDeclaration> {
return if (!visitMemberDeclaration && memberDeclaration.visibility == Visibilities.LOCAL) {
return if (!visitLocalMembers && memberDeclaration.visibility == Visibilities.LOCAL) {
DummyFirDeclaration().compose()
} else {
(memberDeclaration.transformChildren(this, data) as FirMemberDeclaration).compose()
@@ -130,7 +127,7 @@ class FirPartialTransformer(
}
override fun transformBreakExpression(breakExpression: FirBreakExpression, data: Nothing?): CompositeTransformResult<FirStatement> {
return if (visitBreakExpression) {
return if (visitLoopJump) {
(breakExpression.transformChildren(this, data) as FirBreakExpression).compose()
} else {
DummyFirStatement().compose()
@@ -141,7 +138,7 @@ class FirPartialTransformer(
continueExpression: FirContinueExpression,
data: Nothing?
): CompositeTransformResult<FirStatement> {
return if (visitContinueExpression) {
return if (visitLoopJump) {
(continueExpression.transformChildren(this, data) as FirContinueExpression).compose()
} else {
DummyFirStatement().compose()
@@ -257,7 +254,7 @@ class FirPartialTransformer(
}
override fun transformAssignment(assignment: FirAssignment, data: Nothing?): CompositeTransformResult<FirStatement> {
return if (visitAssignment) {
return if (visitVariable) {
(assignment.transformChildren(this, data) as FirAssignment).compose()
} else {
DummyFirStatement().compose()
@@ -59,16 +59,14 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
stubMode: Boolean,
visitAnonymousFunction: Boolean = false,
visitLambdaExpression: Boolean = false,
visitNamedFunction: Boolean = false,
visitMemberDeclaration: Boolean = false,
visitLocalMembers: Boolean = false,
visitVariable: Boolean = false,
visitAnnotation: Boolean = false,
visitTypeOperatorCall: Boolean = false,
visitArrayOfCall: Boolean = false,
visitFunctionCall: Boolean = false,
visitGetClassCall: Boolean = false,
visitBreakExpression: Boolean = false,
visitContinueExpression: Boolean = false,
visitLoopJump: Boolean = false,
visitReturnExpression: Boolean = false,
visitThrowExpression: Boolean = false,
visitLoops: Boolean = false,
@@ -78,22 +76,19 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
visitTryExpression: Boolean = false,
visitWhenExpression: Boolean = false,
visitLambdaArgumentExpression: Boolean = false,
visitAnonymousObject: Boolean = false,
visitAssignment: Boolean = false
visitAnonymousObject: Boolean = false
) {
val firVisitor = FirPartialTransformer(
visitAnonymousFunction = visitAnonymousFunction,
visitLambdaExpression = visitLambdaExpression,
visitNamedFunction = visitNamedFunction,
visitMemberDeclaration = visitMemberDeclaration,
visitLocalMembers = visitLocalMembers,
visitVariable = visitVariable,
visitAnnotation = visitAnnotation,
visitTypeOperatorCall = visitTypeOperatorCall,
visitArrayOfCall = visitArrayOfCall,
visitFunctionCall = visitFunctionCall,
visitGetClassCall = visitGetClassCall,
visitBreakExpression = visitBreakExpression,
visitContinueExpression = visitContinueExpression,
visitLoopJump = visitLoopJump,
visitReturnExpression = visitReturnExpression,
visitThrowExpression = visitThrowExpression,
visitLoops = visitLoops,
@@ -103,8 +98,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
visitTryExpression = visitTryExpression,
visitWhenExpression = visitWhenExpression,
visitLambdaArgumentExpression = visitLambdaArgumentExpression,
visitAnonymousObject = visitAnonymousObject,
visitAssignment = visitAssignment
visitAnonymousObject = visitAnonymousObject
)
val lightTreeConverter = LightTree2Fir(stubMode, myProject)
compareBase { file ->
@@ -186,8 +180,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testLocalMembers() {
compare(
stubMode = false,
visitNamedFunction = true,
visitMemberDeclaration = true,
visitLocalMembers = true,
visitAnnotation = true,
visitTypeOperatorCall = true,
visitArrayOfCall = true,
@@ -202,8 +195,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testReturn() {
compare(
stubMode = false,
visitNamedFunction = true,
visitMemberDeclaration = true,
visitLocalMembers = true,
visitAnnotation = true,
visitTypeOperatorCall = true,
visitArrayOfCall = true,
@@ -221,8 +213,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
stubMode = false,
visitAnonymousFunction = true,
visitLambdaExpression = true,
visitNamedFunction = true,
visitMemberDeclaration = true,
visitLocalMembers = true,
visitAnnotation = true,
visitTypeOperatorCall = true,
visitArrayOfCall = true,
@@ -240,8 +231,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
stubMode = false,
visitAnonymousFunction = true,
visitLambdaExpression = true,
visitNamedFunction = true,
visitMemberDeclaration = true,
visitLocalMembers = true,
visitAnnotation = true,
visitTypeOperatorCall = true,
visitArrayOfCall = true,
@@ -260,8 +250,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
stubMode = false,
visitAnonymousFunction = true,
visitLambdaExpression = true,
visitNamedFunction = true,
visitMemberDeclaration = true,
visitLocalMembers = true,
visitAnnotation = true,
visitTypeOperatorCall = true,
visitArrayOfCall = true,
@@ -288,4 +277,20 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
visitQualifiedAccessExpression = true
)
}
fun testVariables() {
compare(
stubMode = false,
visitAnonymousFunction = true,
visitLambdaExpression = true,
visitLocalMembers = true,
visitVariable = true,
visitAnnotation = true,
visitFunctionCall = true,
visitLoops = true,
visitConstExpression = true,
visitQualifiedAccessExpression = true,
visitAnonymousObject = true
)
}
}
@@ -469,7 +469,7 @@ fun generateTemporaryVariable(
symbol.bind(this)
}
internal fun generateTemporaryVariable(
fun generateTemporaryVariable(
session: FirSession, psi: PsiElement?, specialName: String, initializer: FirExpression
): FirVariable<*> = generateTemporaryVariable(session, psi, Name.special("<$specialName>"), initializer)