Fix some light tree to FIR converter bugs after testing

This commit is contained in:
Ivan Cilcic
2019-07-17 12:31:13 +03:00
committed by Mikhail Glukhikh
parent 08ab530ef0
commit e0bebba42e
4 changed files with 123 additions and 68 deletions
@@ -103,9 +103,7 @@ class DeclarationsConverter(
when (it.tokenType) { when (it.tokenType) {
//TODO("not implemented") //TODO("not implemented")
BLOCK -> "" BLOCK -> ""
BINARY_EXPRESSION -> firStatements += expressionConverter.convertBinaryExpression(it) else -> if (it.isExpression()) firStatements += expressionConverter.getAsFirExpression<FirStatement>(it)
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> firStatements += expressionConverter.convertUnaryExpression(it)
else -> if (it.isExpression()) firStatements += expressionConverter.visitExpression(it)
} }
} }
return FirBlockImpl(session, null).apply { return FirBlockImpl(session, null).apply {
@@ -263,7 +261,7 @@ class DeclarationsConverter(
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationOrList * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationOrList
*/ */
private fun convertAnnotation(annotationNode: LighterASTNode): List<FirAnnotationCall> { fun convertAnnotation(annotationNode: LighterASTNode): List<FirAnnotationCall> {
var annotationTarget: AnnotationUseSiteTarget? = null var annotationTarget: AnnotationUseSiteTarget? = null
return annotationNode.forEachChildrenReturnList { node, container -> return annotationNode.forEachChildrenReturnList { node, container ->
when (node.tokenType) { when (node.tokenType) {
@@ -299,7 +297,7 @@ class DeclarationsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotation * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotation
* can be treated as unescapedAnnotation * can be treated as unescapedAnnotation
*/ */
private fun convertAnnotationEntry( fun convertAnnotationEntry(
unescapedAnnotation: LighterASTNode, unescapedAnnotation: LighterASTNode,
defaultAnnotationUseSiteTarget: AnnotationUseSiteTarget? = null defaultAnnotationUseSiteTarget: AnnotationUseSiteTarget? = null
): FirAnnotationCall { ): FirAnnotationCall {
@@ -429,16 +427,16 @@ class DeclarationsConverter(
var modifiers = Modifier(session) var modifiers = Modifier(session)
lateinit var identifier: String lateinit var identifier: String
var hasInitializerList = false var hasInitializerList = false
val enumSuperTypeCallEntry = mutableListOf<FirExpression>() //TODO get from INITIALIZER_LIST val enumSuperTypeCallEntry = mutableListOf<FirExpression>()
val firDeclarations = mutableListOf<FirDeclaration>() val firDeclarations = mutableListOf<FirDeclaration>()
enumEntry.forEachChildren { enumEntry.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
MODIFIER_LIST -> modifiers = convertModifierList(it) MODIFIER_LIST -> modifiers = convertModifierList(it)
IDENTIFIER -> identifier = it.getAsString() IDENTIFIER -> identifier = it.getAsString()
INITIALIZER_LIST -> hasInitializerList = true //TODO implement INITIALIZER_LIST -> {
/*enumSuperTypeCallEntry += initializerList.valueParameters.map { firValueParameter -> hasInitializerList = true
firValueParameter.toFirExpression(stubMode) enumSuperTypeCallEntry += convertInitializerList(it)
}*/ }
CLASS_BODY -> firDeclarations += convertClassBody(it, classWrapper) CLASS_BODY -> firDeclarations += convertClassBody(it, classWrapper)
} }
} }
@@ -469,6 +467,22 @@ class DeclarationsConverter(
} }
} }
/**
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumEntry
*/
private fun convertInitializerList(initializerList: LighterASTNode): List<FirExpression> {
val firValueArguments = mutableListOf<FirExpression>()
initializerList.forEachChildren {
when (it.tokenType) {
SUPER_TYPE_CALL_ENTRY -> convertConstructorInvocation(it).apply {
firValueArguments += second
}
}
}
return firValueArguments
}
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseClassBody * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseClassBody
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody
@@ -678,13 +692,13 @@ class DeclarationsConverter(
COLON -> isReturnType = true COLON -> isReturnType = true
TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it) TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it)
TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it) TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it)
PROPERTY_DELEGATE -> firDelegateExpression = expressionConverter.visitExpression(it) PROPERTY_DELEGATE -> firDelegateExpression = expressionConverter.getAsFirExpression(it)
VAR_KEYWORD -> isVar = true VAR_KEYWORD -> isVar = true
PROPERTY_ACCESSOR -> { PROPERTY_ACCESSOR -> {
val propertyAccessor = convertGetterOrSetter(it, returnType) val propertyAccessor = convertGetterOrSetter(it, returnType)
if (propertyAccessor.isGetter) getter = propertyAccessor else setter = propertyAccessor if (propertyAccessor.isGetter) getter = propertyAccessor else setter = propertyAccessor
} }
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it) else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
} }
} }
@@ -746,7 +760,7 @@ class DeclarationsConverter(
TYPE_REFERENCE -> returnType = convertType(it) TYPE_REFERENCE -> returnType = convertType(it)
VALUE_PARAMETER_LIST -> firValueParameters = convertSetterParameter(it, propertyTypeRef) VALUE_PARAMETER_LIST -> firValueParameters = convertSetterParameter(it, propertyTypeRef)
BLOCK -> firBlock = visitBlock(it) BLOCK -> firBlock = visitBlock(it)
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it) else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
} }
} }
@@ -823,7 +837,7 @@ class DeclarationsConverter(
TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it) TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it)
TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it) TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it)
BLOCK -> firBlock = visitBlock(it) BLOCK -> firBlock = visitBlock(it)
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it) else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
} }
} }
@@ -941,11 +955,11 @@ class DeclarationsConverter(
* ; * ;
*/ */
private fun convertConstructorInvocation(constructorInvocation: LighterASTNode): Pair<FirTypeRef, List<FirExpression>> { private fun convertConstructorInvocation(constructorInvocation: LighterASTNode): Pair<FirTypeRef, List<FirExpression>> {
lateinit var firTypeRef: FirTypeRef var firTypeRef: FirTypeRef = implicitType
val firValueArguments = mutableListOf<FirExpression>() val firValueArguments = mutableListOf<FirExpression>()
constructorInvocation.forEachChildren { constructorInvocation.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
CONSTRUCTOR_CALLEE -> firTypeRef = convertType(it) CONSTRUCTOR_CALLEE -> if (it.getAsString().isNotEmpty()) firTypeRef = convertType(it) //is empty in enum entry constructor
VALUE_ARGUMENT_LIST -> firValueArguments += expressionConverter.convertValueArguments(it) VALUE_ARGUMENT_LIST -> firValueArguments += expressionConverter.convertValueArguments(it)
} }
} }
@@ -965,7 +979,7 @@ class DeclarationsConverter(
explicitDelegation.forEachChildren { explicitDelegation.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
TYPE_REFERENCE -> firTypeRef = convertType(it) TYPE_REFERENCE -> firTypeRef = convertType(it)
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it) else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
} }
} }
@@ -1216,7 +1230,7 @@ class DeclarationsConverter(
VAR_KEYWORD -> isVar = true VAR_KEYWORD -> isVar = true
IDENTIFIER -> identifier = it.getAsString() IDENTIFIER -> identifier = it.getAsString()
TYPE_REFERENCE -> firType = convertType(it) TYPE_REFERENCE -> firType = convertType(it)
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it) else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
} }
} }
@@ -25,13 +25,11 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirExplicitSuperReference import org.jetbrains.kotlin.fir.references.FirExplicitSuperReference
import org.jetbrains.kotlin.fir.references.FirExplicitThisReference import org.jetbrains.kotlin.fir.references.FirExplicitThisReference
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.psi.KtThisExpression
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
import org.jetbrains.kotlin.resolve.constants.evaluate.* import org.jetbrains.kotlin.resolve.constants.evaluate.*
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
@@ -44,23 +42,28 @@ class ExpressionsConverter(
private val declarationsConverter: DeclarationsConverter private val declarationsConverter: DeclarationsConverter
) : BaseConverter(session, tree) { ) : BaseConverter(session, tree) {
inline fun <reified R : FirElement> getAsFirExpression(expression: LighterASTNode): R {
return convertExpression(expression) as R
}
/***** EXPRESSIONS *****/ /***** EXPRESSIONS *****/
fun visitExpression(expression: LighterASTNode): FirExpression { fun convertExpression(expression: LighterASTNode): FirElement {
if (!stubMode) { if (!stubMode) {
when (expression.tokenType) { return when (expression.tokenType) {
BINARY_EXPRESSION -> return convertBinaryExpression(expression) as FirExpression BINARY_EXPRESSION -> convertBinaryExpression(expression)
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> return convertUnaryExpression(expression) as FirExpression PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
in qualifiedAccessTokens -> return convertQualifiedExpression(expression) ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
CALL_EXPRESSION -> return convertCallExpression(expression) in qualifiedAccessTokens -> convertQualifiedExpression(expression)
ARRAY_ACCESS_EXPRESSION -> return convertArrayAccessExpression(expression) CALL_EXPRESSION -> convertCallExpression(expression)
STRING_TEMPLATE -> return convertStringTemplate(expression) ARRAY_ACCESS_EXPRESSION -> convertArrayAccessExpression(expression)
is KtConstantExpressionElementType -> return convertConstantExpression(expression) STRING_TEMPLATE -> convertStringTemplate(expression)
REFERENCE_EXPRESSION -> return convertSimpleNameExpression(expression) is KtConstantExpressionElementType -> convertConstantExpression(expression)
PARENTHESIZED, PROPERTY_DELEGATE, INDICES -> return visitExpression(expression.getExpressionInParentheses()) REFERENCE_EXPRESSION -> convertSimpleNameExpression(expression)
THIS_EXPRESSION -> return convertThisExpression(expression) PARENTHESIZED, PROPERTY_DELEGATE, INDICES -> convertExpression(expression.getExpressionInParentheses())
SUPER_EXPRESSION -> return convertSuperExpression(expression) THIS_EXPRESSION -> convertThisExpression(expression)
SUPER_EXPRESSION -> convertSuperExpression(expression)
else -> FirExpressionStub(session, null)
} }
return FirExpressionStub(session, null)
//TODO("not fully implemented") //TODO("not fully implemented")
} }
@@ -71,7 +74,7 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseBinaryExpression * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseBinaryExpression
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitBinaryExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitBinaryExpression
*/ */
fun convertBinaryExpression(binaryExpression: LighterASTNode): FirStatement { private fun convertBinaryExpression(binaryExpression: LighterASTNode): FirStatement {
var isLeftArgument = true var isLeftArgument = true
lateinit var operationTokenName: String lateinit var operationTokenName: String
lateinit var leftArgNode: LighterASTNode lateinit var leftArgNode: LighterASTNode
@@ -86,7 +89,7 @@ class ExpressionsConverter(
if (isLeftArgument) { if (isLeftArgument) {
leftArgNode = it leftArgNode = it
} else { } else {
rightArgAsFir = visitExpression(it) rightArgAsFir = getAsFirExpression(it)
} }
} }
} }
@@ -95,11 +98,17 @@ class ExpressionsConverter(
val operationToken = operationTokenName.getOperationSymbol() val operationToken = operationTokenName.getOperationSymbol()
when (operationToken) { when (operationToken) {
ELVIS -> ELVIS ->
return visitExpression(leftArgNode).generateNotNullOrOther(session, rightArgAsFir, "elvis", null) return getAsFirExpression<FirExpression>(leftArgNode).generateNotNullOrOther(
session, rightArgAsFir, "elvis", null
)
ANDAND, OROR -> ANDAND, OROR ->
return visitExpression(leftArgNode).generateLazyLogicalOperation(session, rightArgAsFir, operationToken == ANDAND, null) return getAsFirExpression<FirExpression>(leftArgNode).generateLazyLogicalOperation(
session, rightArgAsFir, operationToken == ANDAND, null
)
in OperatorConventions.IN_OPERATIONS -> in OperatorConventions.IN_OPERATIONS ->
return rightArgAsFir.generateContainsOperation(session, visitExpression(leftArgNode), operationToken == NOT_IN, null, null) return rightArgAsFir.generateContainsOperation(
session, getAsFirExpression(leftArgNode), operationToken == NOT_IN, null, null
)
} }
val conventionCallName = operationToken.toBinaryName() val conventionCallName = operationToken.toBinaryName()
return if (conventionCallName != null || operationToken == IDENTIFIER) { return if (conventionCallName != null || operationToken == IDENTIFIER) {
@@ -108,7 +117,7 @@ class ExpressionsConverter(
this@ExpressionsConverter.session, null, this@ExpressionsConverter.session, null,
conventionCallName ?: operationTokenName.nameAsSafeName() conventionCallName ?: operationTokenName.nameAsSafeName()
) )
explicitReceiver = visitExpression(leftArgNode) explicitReceiver = getAsFirExpression(leftArgNode)
arguments += rightArgAsFir arguments += rightArgAsFir
} }
} else { } else {
@@ -117,7 +126,7 @@ class ExpressionsConverter(
return convertAssignment(leftArgNode, rightArgAsFir, firOperation) return convertAssignment(leftArgNode, rightArgAsFir, firOperation)
} else { } else {
FirOperatorCallImpl(session, null, firOperation).apply { FirOperatorCallImpl(session, null, firOperation).apply {
arguments += visitExpression(leftArgNode) arguments += getAsFirExpression<FirExpression>(leftArgNode)
arguments += rightArgAsFir arguments += rightArgAsFir
} }
} }
@@ -129,7 +138,7 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePrefixExpression * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePrefixExpression
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitUnaryExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitUnaryExpression
*/ */
fun convertUnaryExpression(unaryExpression: LighterASTNode): FirStatement { private fun convertUnaryExpression(unaryExpression: LighterASTNode): FirExpression {
lateinit var operationTokenName: String lateinit var operationTokenName: String
lateinit var argument: LighterASTNode lateinit var argument: LighterASTNode
unaryExpression.forEachChildren { unaryExpression.forEachChildren {
@@ -141,7 +150,7 @@ class ExpressionsConverter(
val operationToken = operationTokenName.getOperationSymbol() val operationToken = operationTokenName.getOperationSymbol()
if (operationToken == EXCLEXCL) { if (operationToken == EXCLEXCL) {
return bangBangToWhen(session, visitExpression(argument)) return bangBangToWhen(session, getAsFirExpression(argument))
} }
val conventionCallName = operationToken.toUnaryName() val conventionCallName = operationToken.toUnaryName()
@@ -155,16 +164,32 @@ class ExpressionsConverter(
} }
FirFunctionCallImpl(session, null).apply { FirFunctionCallImpl(session, null).apply {
calleeReference = FirSimpleNamedReference(this@ExpressionsConverter.session, null, conventionCallName) calleeReference = FirSimpleNamedReference(this@ExpressionsConverter.session, null, conventionCallName)
explicitReceiver = visitExpression(argument) explicitReceiver = getAsFirExpression(argument)
} }
} else { } else {
val firOperation = operationToken.toFirOperation() val firOperation = operationToken.toFirOperation()
FirOperatorCallImpl(session, null, firOperation).apply { FirOperatorCallImpl(session, null, firOperation).apply {
arguments += visitExpression(argument) arguments += getAsFirExpression<FirExpression>(argument)
} }
} }
} }
private fun convertAnnotatedExpression(annotatedExpression: LighterASTNode): FirElement {
var firExpression: FirElement? = null
val firAnnotationList = mutableListOf<FirAnnotationCall>()
annotatedExpression.forEachChildren {
when (it.tokenType) {
ANNOTATION -> firAnnotationList += declarationsConverter.convertAnnotation(it)
ANNOTATION_ENTRY -> firAnnotationList += declarationsConverter.convertAnnotationEntry(it)
else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
}
}
return (firExpression as? FirAbstractAnnotatedElement)?.apply {
annotations += firAnnotationList
} ?: FirErrorExpressionImpl(session, null, "Strange annotated expression: ${firExpression?.render()}")
}
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePostfixExpression * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePostfixExpression
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitQualifiedExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitQualifiedExpression
@@ -181,7 +206,7 @@ class ExpressionsConverter(
isSafe = true isSafe = true
isSelector = true isSelector = true
} }
else -> if (isSelector) firSelector = visitExpression(it) else firReceiver = visitExpression(it) else -> if (isSelector) firSelector = getAsFirExpression(it) else firReceiver = getAsFirExpression(it)
} }
} }
@@ -211,7 +236,7 @@ class ExpressionsConverter(
TYPE_ARGUMENT_LIST -> firTypeArguments += declarationsConverter.convertTypeArguments(it) TYPE_ARGUMENT_LIST -> firTypeArguments += declarationsConverter.convertTypeArguments(it)
VALUE_ARGUMENT_LIST -> firValueArguments += convertValueArguments(it) VALUE_ARGUMENT_LIST -> firValueArguments += convertValueArguments(it)
LAMBDA_ARGUMENT -> firValueArguments += convertAnnotatedLambda(it) LAMBDA_ARGUMENT -> firValueArguments += convertAnnotatedLambda(it)
else -> additionalArgument = visitExpression(it) else -> additionalArgument = getAsFirExpression(it)
} }
} }
@@ -294,8 +319,8 @@ class ExpressionsConverter(
private fun convertShortOrLongStringTemplate(shortOrLongString: LighterASTNode): FirExpression { private fun convertShortOrLongStringTemplate(shortOrLongString: LighterASTNode): FirExpression {
lateinit var firExpression: FirExpression lateinit var firExpression: FirExpression
shortOrLongString.forEachChildren { shortOrLongString.forEachChildren(LONG_TEMPLATE_ENTRY_START, LONG_TEMPLATE_ENTRY_END) {
firExpression = visitExpression(it) firExpression = getAsFirExpression(it)
} }
return firExpression return firExpression
} }
@@ -355,24 +380,34 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseArrayAccess * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseArrayAccess
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitArrayAccessExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitArrayAccessExpression
*/ */
private fun convertArrayAccessExpression(arrayAccess: LighterASTNode): FirFunctionCall {//Pair<LighterASTNode, List<FirExpression>> { private fun convertArrayAccessExpression(arrayAccess: LighterASTNode): FirFunctionCall {
lateinit var expression: FirExpression lateinit var firExpression: FirExpression
val indexes: MutableList<FirExpression> = mutableListOf() val indices: MutableList<FirExpression> = mutableListOf()
arrayAccess.forEachChildren { arrayAccess.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
INDICES -> indexes += visitExpression(it) INDICES -> indices += convertIndices(it)
else -> if (it.isExpression()) expression = visitExpression(it) else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
} }
} }
return FirFunctionCallImpl(session, null).apply { return FirFunctionCallImpl(session, null).apply {
calleeReference = FirSimpleNamedReference(this@ExpressionsConverter.session, null, OperatorNameConventions.GET) calleeReference = FirSimpleNamedReference(this@ExpressionsConverter.session, null, OperatorNameConventions.GET)
explicitReceiver = expression explicitReceiver = firExpression
for (indexExpression in indexes) { arguments += indices
arguments += indexExpression
}
} }
} }
/**
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseAsCollectionLiteralExpression
*/
private fun convertIndices(indices: LighterASTNode): List<FirExpression> {
val firExpressionList: MutableList<FirExpression> = mutableListOf()
indices.forEachChildren {
if (it.isExpression()) firExpressionList += getAsFirExpression<FirExpression>(it)
}
return firExpressionList
}
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseSimpleNameExpression * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseSimpleNameExpression
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitSimpleNameExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitSimpleNameExpression
@@ -443,7 +478,7 @@ class ExpressionsConverter(
MUL -> isSpread = true MUL -> isSpread = true
STRING_TEMPLATE -> firExpression = convertStringTemplate(it) STRING_TEMPLATE -> firExpression = convertStringTemplate(it)
is KtConstantExpressionElementType -> firExpression = convertConstantExpression(it) is KtConstantExpressionElementType -> firExpression = convertConstantExpression(it)
else -> if (it.isExpression()) firExpression = visitExpression(it) else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
} }
} }
return when { return when {
@@ -458,7 +493,7 @@ class ExpressionsConverter(
return when (it.tokenType) { return when (it.tokenType) {
THIS_EXPRESSION -> convertThisExpression(leftArgNode).calleeReference THIS_EXPRESSION -> convertThisExpression(leftArgNode).calleeReference
REFERENCE_EXPRESSION -> FirSimpleNamedReference(session, null, it.getAsString().nameAsSafeName()) REFERENCE_EXPRESSION -> FirSimpleNamedReference(session, null, it.getAsString().nameAsSafeName())
in qualifiedAccessTokens -> (visitExpression(it) as FirQualifiedAccess).let { firQualifiedAccess -> in qualifiedAccessTokens -> (getAsFirExpression(it) as FirQualifiedAccess).let { firQualifiedAccess ->
container.explicitReceiver = firQualifiedAccess.explicitReceiver container.explicitReceiver = firQualifiedAccess.explicitReceiver
container.safe = firQualifiedAccess.safe container.safe = firQualifiedAccess.safe
return@let firQualifiedAccess.calleeReference return@let firQualifiedAccess.calleeReference
@@ -43,7 +43,7 @@ fun ExpressionsConverter.convertAssignment(
return convertAssignment(leftArgNode.getExpressionInParentheses(), rightArgAsFir, operation) return convertAssignment(leftArgNode.getExpressionInParentheses(), rightArgAsFir, operation)
} }
if (leftArgNode.tokenType == ARRAY_ACCESS_EXPRESSION) { if (leftArgNode.tokenType == ARRAY_ACCESS_EXPRESSION) {
val arrayAccessFunctionCall = visitExpression(leftArgNode) as FirFunctionCall val arrayAccessFunctionCall = getAsFirExpression(leftArgNode) as FirFunctionCall
val firArrayExpression = arrayAccessFunctionCall.explicitReceiver!! val firArrayExpression = arrayAccessFunctionCall.explicitReceiver!!
val arraySet = if (operation != FirOperation.ASSIGN) { val arraySet = if (operation != FirOperation.ASSIGN) {
FirArraySetCallImpl(session, null, rightArgAsFir, operation).apply { FirArraySetCallImpl(session, null, rightArgAsFir, operation).apply {
@@ -74,7 +74,7 @@ fun ExpressionsConverter.convertAssignment(
) { ) {
return FirBlockImpl(session, null).apply { return FirBlockImpl(session, null).apply {
val name = Name.special("<complex-set>") val name = Name.special("<complex-set>")
statements += generateTemporaryVariable(this@convertAssignment.session, null, name, visitExpression(leftArgNode)) statements += generateTemporaryVariable(this@convertAssignment.session, null, name, getAsFirExpression(leftArgNode))
statements += FirVariableAssignmentImpl(this@convertAssignment.session, null, rightArgAsFir, operation).apply { statements += FirVariableAssignmentImpl(this@convertAssignment.session, null, rightArgAsFir, operation).apply {
lValue = FirSimpleNamedReference(this@convertAssignment.session, null, name) lValue = FirSimpleNamedReference(this@convertAssignment.session, null, name)
} }
@@ -96,12 +96,16 @@ fun ExpressionsConverter.generateIncrementOrDecrementBlock(
} }
return FirBlockImpl(session, null).apply { return FirBlockImpl(session, null).apply {
val tempName = Name.special("<unary>") val tempName = Name.special("<unary>")
val temporaryVariable = generateTemporaryVariable(this@generateIncrementOrDecrementBlock.session, null, tempName, visitExpression(argument)) val temporaryVariable = generateTemporaryVariable(
this@generateIncrementOrDecrementBlock.session, null, tempName, getAsFirExpression(argument)
)
statements += temporaryVariable statements += temporaryVariable
val resultName = Name.special("<unary-result>") val resultName = Name.special("<unary-result>")
val resultInitializer = FirFunctionCallImpl(this@generateIncrementOrDecrementBlock.session, null).apply { val resultInitializer = FirFunctionCallImpl(this@generateIncrementOrDecrementBlock.session, null).apply {
this.calleeReference = FirSimpleNamedReference(this@generateIncrementOrDecrementBlock.session, null, callName) this.calleeReference = FirSimpleNamedReference(this@generateIncrementOrDecrementBlock.session, null, callName)
this.explicitReceiver = generateResolvedAccessExpression(this@generateIncrementOrDecrementBlock.session, null, temporaryVariable) this.explicitReceiver = generateResolvedAccessExpression(
this@generateIncrementOrDecrementBlock.session, null, temporaryVariable
)
} }
val resultVar = generateTemporaryVariable(this@generateIncrementOrDecrementBlock.session, null, resultName, resultInitializer) val resultVar = generateTemporaryVariable(this@generateIncrementOrDecrementBlock.session, null, resultName, resultInitializer)
val assignment = convertAssignment( val assignment = convertAssignment(
@@ -128,7 +132,9 @@ fun ExpressionsConverter.generateIncrementOrDecrementBlock(
statements += generateResolvedAccessExpression(this@generateIncrementOrDecrementBlock.session, null, resultVar) statements += generateResolvedAccessExpression(this@generateIncrementOrDecrementBlock.session, null, resultVar)
} else { } else {
appendAssignment() appendAssignment()
statements += generateAccessExpression(this@generateIncrementOrDecrementBlock.session, null, argument.getAsString().nameAsSafeName()) statements += generateAccessExpression(
this@generateIncrementOrDecrementBlock.session, null, argument.getAsString().nameAsSafeName()
)
} }
} else { } else {
appendAssignment() appendAssignment()
@@ -62,7 +62,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 (!visitNamedFunction && 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()
@@ -73,7 +73,7 @@ class FirPartialTransformer(
memberDeclaration: FirMemberDeclaration, memberDeclaration: FirMemberDeclaration,
data: Nothing? data: Nothing?
): CompositeTransformResult<FirDeclaration> { ): CompositeTransformResult<FirDeclaration> {
return if (!visitMemberDeclaration || memberDeclaration.visibility == Visibilities.LOCAL) { return if (!visitMemberDeclaration && memberDeclaration.visibility == Visibilities.LOCAL) {
DummyFirDeclaration().compose() DummyFirDeclaration().compose()
} else { } else {
(memberDeclaration.transformChildren(this, data) as FirMemberDeclaration).compose() (memberDeclaration.transformChildren(this, data) as FirMemberDeclaration).compose()