Write annotation's conversion (light tree to FIR)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
8bcea1cf85
commit
5a24c2253a
+7
-5
@@ -11,7 +11,9 @@ import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
|
||||
open class BaseConverter(
|
||||
session: FirSession,
|
||||
@@ -39,12 +41,12 @@ open class BaseConverter(
|
||||
return kidsRef.get()
|
||||
}
|
||||
|
||||
protected inline fun LighterASTNode.forEachChildren(f: (LighterASTNode) -> Unit) {
|
||||
protected inline fun LighterASTNode.forEachChildren(vararg skipTokens: KtToken, f: (LighterASTNode) -> Unit) {
|
||||
val kidsArray = this.getChildrenAsArray()
|
||||
for (kid in kidsArray) {
|
||||
if (kid == null) continue
|
||||
if (kid == null) break
|
||||
val tokenType = kid.tokenType
|
||||
if (KtTokens.COMMENTS.contains(tokenType) || tokenType == KtTokens.WHITE_SPACE || tokenType == KtTokens.SEMICOLON) continue
|
||||
if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON || tokenType in skipTokens) continue
|
||||
f(kid)
|
||||
}
|
||||
}
|
||||
@@ -54,9 +56,9 @@ open class BaseConverter(
|
||||
|
||||
val container = mutableListOf<T>()
|
||||
for (kid in kidsArray) {
|
||||
if (kid == null) continue
|
||||
if (kid == null) break
|
||||
val tokenType = kid.tokenType
|
||||
if (KtTokens.COMMENTS.contains(tokenType) || tokenType == KtTokens.WHITE_SPACE || tokenType == KtTokens.SEMICOLON) continue
|
||||
if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON) continue
|
||||
f(kid, container)
|
||||
}
|
||||
|
||||
|
||||
+19
-10
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirFunctionTarget
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
@@ -56,6 +57,10 @@ object ConverterUtil {
|
||||
return this.toString()
|
||||
}
|
||||
|
||||
fun LighterASTNode.getAsStringUnescapedValue(): String {
|
||||
return this.toString().replaceFirst("\\", "")
|
||||
}
|
||||
|
||||
fun LighterASTNode.isExpression(): Boolean {
|
||||
return when (this.tokenType) {
|
||||
is KtNodeType,
|
||||
@@ -139,8 +144,7 @@ object ConverterUtil {
|
||||
}
|
||||
|
||||
fun <T : FirCallWithArgumentList> T.extractArgumentsFrom(container: List<FirExpression>, stubMode: Boolean): T {
|
||||
if (!stubMode) {
|
||||
//TODO("not implemented")
|
||||
if (!stubMode || this is FirAnnotationCall) {
|
||||
this.arguments += container
|
||||
}
|
||||
return this
|
||||
@@ -165,7 +169,8 @@ object ClassNameUtil {
|
||||
val currentClassId
|
||||
get() = ClassId(
|
||||
packageFqName,
|
||||
className, false)
|
||||
className, false
|
||||
)
|
||||
|
||||
fun callableIdForName(name: Name, local: Boolean = false) =
|
||||
when {
|
||||
@@ -173,14 +178,16 @@ object ClassNameUtil {
|
||||
className == FqName.ROOT -> CallableId(packageFqName, name)
|
||||
else -> CallableId(
|
||||
packageFqName,
|
||||
className, name)
|
||||
className, name
|
||||
)
|
||||
}
|
||||
|
||||
fun callableIdForClassConstructor() =
|
||||
if (className == FqName.ROOT) CallableId(packageFqName, Name.special("<anonymous-init>"))
|
||||
else CallableId(
|
||||
packageFqName,
|
||||
className, className.shortName())
|
||||
className, className.shortName()
|
||||
)
|
||||
|
||||
var className: FqName = FqName.ROOT
|
||||
}
|
||||
@@ -257,11 +264,13 @@ object DataClassUtil {
|
||||
firPrimaryConstructor: FirConstructor,
|
||||
properties: List<FirProperty>
|
||||
) {
|
||||
val symbol = FirFunctionSymbol(CallableId(
|
||||
ClassNameUtil.packageFqName,
|
||||
ClassNameUtil.className,
|
||||
copyName
|
||||
))
|
||||
val symbol = FirFunctionSymbol(
|
||||
CallableId(
|
||||
ClassNameUtil.packageFqName,
|
||||
ClassNameUtil.className,
|
||||
copyName
|
||||
)
|
||||
)
|
||||
firClass.addDeclaration(
|
||||
FirMemberFunctionImpl(
|
||||
session, null, symbol, copyName,
|
||||
|
||||
+29
-59
@@ -53,6 +53,7 @@ class DeclarationsConverter(
|
||||
private val stubMode: Boolean,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
) : BaseConverter(session, tree) {
|
||||
private val expressionConverter = ExpressionsConverter(session, stubMode, tree)
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
||||
@@ -171,7 +172,7 @@ class DeclarationsConverter(
|
||||
modifiers.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertAnnotationEntry(it, null)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertAnnotationEntry(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
@@ -186,7 +187,7 @@ class DeclarationsConverter(
|
||||
modifiers.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> typeModifierList.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> typeModifierList.annotations += convertAnnotationEntry(it, null)
|
||||
ANNOTATION_ENTRY -> typeModifierList.annotations += convertAnnotationEntry(it)
|
||||
is KtModifierKeywordToken -> typeModifierList.addModifier(it)
|
||||
}
|
||||
}
|
||||
@@ -201,7 +202,7 @@ class DeclarationsConverter(
|
||||
modifiers.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> typeArgumentModifierList.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> typeArgumentModifierList.annotations += convertAnnotationEntry(it, null)
|
||||
ANNOTATION_ENTRY -> typeArgumentModifierList.annotations += convertAnnotationEntry(it)
|
||||
is KtModifierKeywordToken -> typeArgumentModifierList.addModifier(it)
|
||||
}
|
||||
}
|
||||
@@ -216,7 +217,7 @@ class DeclarationsConverter(
|
||||
modifiers.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertAnnotationEntry(it, null)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertAnnotationEntry(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
@@ -231,7 +232,7 @@ class DeclarationsConverter(
|
||||
return fileAnnotationList.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
ANNOTATION -> container += convertAnnotation(node)
|
||||
ANNOTATION_ENTRY -> container += convertAnnotationEntry(node, AnnotationUseSiteTarget.FILE)
|
||||
ANNOTATION_ENTRY -> container += convertAnnotationEntry(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,12 +251,13 @@ class DeclarationsConverter(
|
||||
}
|
||||
|
||||
/**
|
||||
* org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationTarget
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseAnnotationTarget
|
||||
*/
|
||||
private fun convertAnnotationTarget(annotationUseSiteTarget: LighterASTNode): AnnotationUseSiteTarget {
|
||||
lateinit var annotationTarget: AnnotationUseSiteTarget
|
||||
annotationUseSiteTarget.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
FIELD_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.FIELD
|
||||
FILE_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.FILE
|
||||
PROPERTY_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY
|
||||
GET_KEYWORD -> annotationTarget = AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
@@ -276,18 +278,22 @@ class DeclarationsConverter(
|
||||
*/
|
||||
private fun convertAnnotationEntry(
|
||||
unescapedAnnotation: LighterASTNode,
|
||||
annotationUseSiteTarget: AnnotationUseSiteTarget?
|
||||
defaultAnnotationUseSiteTarget: AnnotationUseSiteTarget? = null
|
||||
): FirAnnotationCall {
|
||||
//TODO not implemented
|
||||
val pair = convertConstructorInvocation(unescapedAnnotation)
|
||||
var annotationUseSiteTarget: AnnotationUseSiteTarget? = null
|
||||
lateinit var constructorCalleePair: Pair<FirTypeRef, List<FirExpression>>
|
||||
unescapedAnnotation.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
ANNOTATION_TARGET -> annotationUseSiteTarget = convertAnnotationTarget(it)
|
||||
CONSTRUCTOR_CALLEE -> constructorCalleePair = convertConstructorInvocation(unescapedAnnotation)
|
||||
}
|
||||
}
|
||||
return FirAnnotationCallImpl(
|
||||
session,
|
||||
null,
|
||||
annotationUseSiteTarget,
|
||||
pair.first
|
||||
).apply {
|
||||
arguments += pair.second
|
||||
}
|
||||
annotationUseSiteTarget ?: defaultAnnotationUseSiteTarget,
|
||||
constructorCalleePair.first
|
||||
).extractArgumentsFrom(constructorCalleePair.second, stubMode)
|
||||
}
|
||||
|
||||
/***** DECLARATIONS *****/
|
||||
@@ -566,10 +572,11 @@ class DeclarationsConverter(
|
||||
classWrapper: ClassWrapper
|
||||
): FirDelegatedConstructorCallImpl {
|
||||
var thisKeywordPresent = false
|
||||
val firValueArguments = mutableListOf<FirExpression>()
|
||||
constructorDelegationCall.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
CONSTRUCTOR_DELEGATION_REFERENCE -> if (it.getAsString() == "this") thisKeywordPresent = true
|
||||
VALUE_ARGUMENT_LIST -> "" //TODO implement
|
||||
VALUE_ARGUMENT_LIST -> firValueArguments += expressionConverter.convertValueArguments(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +592,7 @@ class DeclarationsConverter(
|
||||
null,
|
||||
delegatedType,
|
||||
isThis
|
||||
).extractArgumentsFrom(listOf(), stubMode) //TODO implement
|
||||
).extractArgumentsFrom(firValueArguments, stubMode)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -654,7 +661,7 @@ class DeclarationsConverter(
|
||||
val propertyAccessor = convertGetterOrSetter(it, returnType)
|
||||
if (propertyAccessor.isGetter) getter = propertyAccessor else setter = propertyAccessor
|
||||
}
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,7 +731,7 @@ class DeclarationsConverter(
|
||||
TYPE_REFERENCE -> returnType = convertType(it)
|
||||
VALUE_PARAMETER_LIST -> firValueParameters = convertSetterParameter(it, propertyTypeRef)
|
||||
BLOCK -> firBlock = visitBlock(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,7 +808,7 @@ class DeclarationsConverter(
|
||||
TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it)
|
||||
TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it)
|
||||
BLOCK -> firBlock = visitBlock(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +930,7 @@ class DeclarationsConverter(
|
||||
constructorInvocation.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
CONSTRUCTOR_CALLEE -> firTypeRef = convertType(it)
|
||||
VALUE_ARGUMENT_LIST -> firValueArguments += convertValueArguments(it)
|
||||
VALUE_ARGUMENT_LIST -> firValueArguments += expressionConverter.convertValueArguments(it)
|
||||
}
|
||||
}
|
||||
return Pair(firTypeRef, firValueArguments)
|
||||
@@ -942,7 +949,7 @@ class DeclarationsConverter(
|
||||
explicitDelegation.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
TYPE_REFERENCE -> firTypeRef = convertType(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1193,7 +1200,7 @@ class DeclarationsConverter(
|
||||
VAR_KEYWORD -> isVar = true
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = expressionConverter.visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,41 +1216,4 @@ class DeclarationsConverter(
|
||||
).apply { annotations += modifiers.annotations }
|
||||
return ValueParameter(isVal, isVar, modifiers, firValueParameter)
|
||||
}
|
||||
|
||||
/***** EXPRESSIONS *****/
|
||||
//TODO move to parsing class?
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseValueArgumentList
|
||||
*/
|
||||
private fun convertValueArguments(valueArguments: LighterASTNode): List<FirExpression> {
|
||||
return valueArguments.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
VALUE_ARGUMENT -> container += convertValueArgument(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertValueArgument(valueArgument: LighterASTNode): FirExpression {
|
||||
return FirErrorExpressionImpl(session, null, "Not implemented")
|
||||
//TODO implement
|
||||
|
||||
/*
|
||||
this ?: return FirErrorExpressionImpl(session, this as? KtElement, "No argument given")
|
||||
val expression = this.getArgumentExpression()
|
||||
return when (expression) {
|
||||
is KtConstantExpression, is KtStringTemplateExpression -> {
|
||||
expression.accept(this@Visitor, Unit) as FirExpression
|
||||
}
|
||||
|
||||
else -> {
|
||||
{ expression }.toFirExpression("Argument is absent")
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private fun visitExpression(expression: LighterASTNode): FirExpression {
|
||||
return if (stubMode) FirExpressionStub(session, null)
|
||||
else TODO("not implemented")
|
||||
}
|
||||
}
|
||||
+162
@@ -7,7 +7,19 @@ package org.jetbrains.kotlin.fir.lightTree.converter
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.parseCharacter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsString
|
||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.isExpression
|
||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.nameAsSafeName
|
||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsStringUnescapedValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.*
|
||||
|
||||
class ExpressionsConverter(
|
||||
private val session: FirSession,
|
||||
@@ -15,4 +27,154 @@ class ExpressionsConverter(
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
) : BaseConverter(session, tree) {
|
||||
|
||||
/***** EXPRESSIONS *****/
|
||||
fun visitExpression(expression: LighterASTNode): FirExpression {
|
||||
if (!stubMode) {
|
||||
when (expression.tokenType) {
|
||||
STRING_TEMPLATE -> return convertStringTemplate(expression)
|
||||
is KtConstantExpressionElementType -> return convertConstantExpression(expression)
|
||||
}
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
return FirExpressionStub(session, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.fir.builder.ConversionUtilsKt.toInterpolatingCall
|
||||
*/
|
||||
private fun convertStringTemplate(stringTemplate: LighterASTNode): FirExpression {
|
||||
val sb = StringBuilder()
|
||||
var hasExpressions = false
|
||||
var result: FirExpression? = null
|
||||
var callCreated = false
|
||||
stringTemplate.forEachChildren(OPEN_QUOTE, CLOSING_QUOTE) {
|
||||
val nextArgument = when (it.tokenType) {
|
||||
LITERAL_STRING_TEMPLATE_ENTRY -> {
|
||||
sb.append(it.getAsString())
|
||||
FirConstExpressionImpl(session, null, IrConstKind.String, it.getAsString())
|
||||
}
|
||||
ESCAPE_STRING_TEMPLATE_ENTRY -> {
|
||||
sb.append(it.getAsStringUnescapedValue())
|
||||
FirConstExpressionImpl(session, null, IrConstKind.String, it.getAsStringUnescapedValue())
|
||||
}
|
||||
SHORT_STRING_TEMPLATE_ENTRY, LONG_STRING_TEMPLATE_ENTRY -> {
|
||||
hasExpressions = true
|
||||
convertShortOrLongStringTemplate(it)
|
||||
}
|
||||
else -> {
|
||||
hasExpressions = true
|
||||
FirErrorExpressionImpl(session, null, "Incorrect template entry: ${it.getAsString()}")
|
||||
}
|
||||
}
|
||||
result = when {
|
||||
result == null -> nextArgument
|
||||
callCreated && result is FirStringConcatenationCallImpl -> (result as FirStringConcatenationCallImpl).apply {
|
||||
//TODO smart cast to FirStringConcatenationCallImpl isn't working
|
||||
arguments += nextArgument
|
||||
}
|
||||
else -> {
|
||||
callCreated = true
|
||||
FirStringConcatenationCallImpl(session, null).apply {
|
||||
arguments += result!!
|
||||
arguments += nextArgument
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (hasExpressions) result!! else FirConstExpressionImpl(session, null, IrConstKind.String, sb.toString())
|
||||
}
|
||||
|
||||
private fun convertShortOrLongStringTemplate(shortOrLongString: LighterASTNode): FirExpression {
|
||||
lateinit var firExpression: FirExpression
|
||||
shortOrLongString.forEachChildren {
|
||||
firExpression = visitExpression(it)
|
||||
}
|
||||
return firExpression
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.fir.builder.ConversionUtilsKt.generateConstantExpressionByLiteral
|
||||
*/
|
||||
private fun convertConstantExpression(constantExpression: LighterASTNode): FirExpression {
|
||||
val type = constantExpression.tokenType
|
||||
val text: String = constantExpression.getAsString()
|
||||
val convertedText: Any? = when (type) {
|
||||
INTEGER_CONSTANT, FLOAT_CONSTANT -> parseNumericLiteral(text, type)
|
||||
BOOLEAN_CONSTANT -> parseBoolean(text)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return when (type) {
|
||||
INTEGER_CONSTANT ->
|
||||
if (convertedText is Long &&
|
||||
(hasLongSuffix(text) || hasUnsignedLongSuffix(text) || hasUnsignedSuffix(text) ||
|
||||
convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE)
|
||||
) {
|
||||
FirConstExpressionImpl(
|
||||
session, null, IrConstKind.Long, convertedText, "Incorrect long: $text"
|
||||
)
|
||||
} else if (convertedText is Number) {
|
||||
// TODO: support byte / short
|
||||
FirConstExpressionImpl(session, null, IrConstKind.Int, convertedText.toInt(), "Incorrect int: $text")
|
||||
} else {
|
||||
FirErrorExpressionImpl(session, null, reason = "Incorrect constant expression: $text")
|
||||
}
|
||||
FLOAT_CONSTANT ->
|
||||
if (convertedText is Float) {
|
||||
FirConstExpressionImpl(
|
||||
session, null, IrConstKind.Float, convertedText, "Incorrect float: $text"
|
||||
)
|
||||
} else {
|
||||
FirConstExpressionImpl(
|
||||
session, null, IrConstKind.Double, convertedText as Double, "Incorrect double: $text"
|
||||
)
|
||||
}
|
||||
CHARACTER_CONSTANT ->
|
||||
FirConstExpressionImpl(
|
||||
session, null, IrConstKind.Char, text.parseCharacter(), "Incorrect character: $text"
|
||||
)
|
||||
BOOLEAN_CONSTANT ->
|
||||
FirConstExpressionImpl(session, null, IrConstKind.Boolean, convertedText as Boolean)
|
||||
NULL ->
|
||||
FirConstExpressionImpl(session, null, IrConstKind.Null, null)
|
||||
else ->
|
||||
throw AssertionError("Unknown literal type: $type, $text")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseValueArgumentList
|
||||
*/
|
||||
fun convertValueArguments(valueArguments: LighterASTNode): List<FirExpression> {
|
||||
return valueArguments.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
VALUE_ARGUMENT -> container += convertValueArgument(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseValueArgument
|
||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.toFirExpression(org.jetbrains.kotlin.psi.ValueArgument)
|
||||
*/
|
||||
private fun convertValueArgument(valueArgument: LighterASTNode): FirExpression {
|
||||
var identifier: String? = null
|
||||
var isSpread = false
|
||||
lateinit var firExpression: FirExpression
|
||||
valueArgument.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
VALUE_ARGUMENT_NAME -> identifier = it.getAsString()
|
||||
MUL -> isSpread = true
|
||||
STRING_TEMPLATE -> firExpression = convertStringTemplate(it)
|
||||
is KtConstantExpressionElementType -> firExpression = convertConstantExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
return when {
|
||||
identifier != null -> FirNamedArgumentExpressionImpl(session, null, identifier.nameAsSafeName(), isSpread, firExpression)
|
||||
isSpread -> FirSpreadArgumentExpressionImpl(session, null, firExpression)
|
||||
else -> firExpression
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -64,6 +64,10 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
||||
compare(stubMode = true)
|
||||
}
|
||||
|
||||
fun testCompareAll() {
|
||||
compare(stubMode = false)
|
||||
}
|
||||
|
||||
fun testStubCompareWithoutAnnotations() {
|
||||
compare(stubMode = true, visitAnnotation = false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user