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