Write lambda expressions and local members parsing (light tree to FIR)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
50573066fe
commit
8dd72a5cf2
@@ -46,6 +46,13 @@ class LightTree2Fir(
|
|||||||
MyKotlinParser.parseBlockExpression(builder)
|
MyKotlinParser.parseBlockExpression(builder)
|
||||||
return builder.lightTree
|
return builder.lightTree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun buildLightTreeLambdaExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
|
||||||
|
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, code)
|
||||||
|
//KotlinParser.parseLambdaExpression(builder)
|
||||||
|
MyKotlinParser.parseLambdaExpression(builder)
|
||||||
|
return builder.lightTree
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildFirFile(path: Path): FirFile {
|
fun buildFirFile(path: Path): FirFile {
|
||||||
|
|||||||
+5
@@ -26,6 +26,11 @@ open class BaseConverter(
|
|||||||
protected val implicitAnnotationType = FirImplicitAnnotationTypeRef(session, null)
|
protected val implicitAnnotationType = FirImplicitAnnotationTypeRef(session, null)
|
||||||
protected val implicitType = FirImplicitTypeRefImpl(session, null)
|
protected val implicitType = FirImplicitTypeRefImpl(session, null)
|
||||||
|
|
||||||
|
fun LighterASTNode.getParent(): LighterASTNode? {
|
||||||
|
val kidsRef = Ref<Array<LighterASTNode?>>()
|
||||||
|
return tree.getParent(this)
|
||||||
|
}
|
||||||
|
|
||||||
fun LighterASTNode?.getChildNodesByType(type: IElementType): List<LighterASTNode> {
|
fun LighterASTNode?.getChildNodesByType(type: IElementType): List<LighterASTNode> {
|
||||||
return this?.forEachChildrenReturnList { node, container ->
|
return this?.forEachChildrenReturnList { node, container ->
|
||||||
when (node.tokenType) {
|
when (node.tokenType) {
|
||||||
|
|||||||
+2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.KtNodeTypes
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirFunctionTarget
|
import org.jetbrains.kotlin.fir.FirFunctionTarget
|
||||||
|
import org.jetbrains.kotlin.fir.FirLabel
|
||||||
import org.jetbrains.kotlin.fir.FirReference
|
import org.jetbrains.kotlin.fir.FirReference
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -201,6 +202,7 @@ object ClassNameUtil {
|
|||||||
object FunctionUtil {
|
object FunctionUtil {
|
||||||
val firFunctions = mutableListOf<FirFunction>()
|
val firFunctions = mutableListOf<FirFunction>()
|
||||||
val firFunctionCalls = mutableListOf<FirFunctionCall>()
|
val firFunctionCalls = mutableListOf<FirFunctionCall>()
|
||||||
|
val firLabels = mutableListOf<FirLabel>()
|
||||||
|
|
||||||
fun <T> MutableList<T>.removeLast() {
|
fun <T> MutableList<T>.removeLast() {
|
||||||
removeAt(size - 1)
|
removeAt(size - 1)
|
||||||
|
|||||||
+98
-43
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.lightTree.converter.DataClassUtil.generateCompon
|
|||||||
import org.jetbrains.kotlin.fir.lightTree.converter.DataClassUtil.generateCopyFunction
|
import org.jetbrains.kotlin.fir.lightTree.converter.DataClassUtil.generateCopyFunction
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.FunctionUtil.removeLast
|
import org.jetbrains.kotlin.fir.lightTree.converter.FunctionUtil.removeLast
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.ClassWrapper
|
import org.jetbrains.kotlin.fir.lightTree.fir.ClassWrapper
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.fir.DestructuringDeclaration
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.TypeConstraint
|
import org.jetbrains.kotlin.fir.lightTree.fir.TypeConstraint
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
|
import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
||||||
@@ -97,12 +98,20 @@ class DeclarationsConverter(
|
|||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlockExpression
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlockExpression
|
||||||
*/
|
*/
|
||||||
private fun convertBlockExpression(block: LighterASTNode): FirBlock {
|
fun convertBlockExpression(block: LighterASTNode): FirBlock {
|
||||||
val firStatements = mutableListOf<FirStatement>()
|
val firStatements = mutableListOf<FirStatement>()
|
||||||
block.forEachChildren {
|
block.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
//TODO("not implemented")
|
//TODO("not implemented")
|
||||||
BLOCK -> ""
|
BLOCK -> ""
|
||||||
|
|
||||||
|
CLASS -> firStatements += convertClass(it) as FirStatement
|
||||||
|
FUN -> firStatements += convertFunctionDeclaration(it) as FirStatement
|
||||||
|
PROPERTY -> firStatements += convertPropertyDeclaration(it) as FirStatement
|
||||||
|
TYPEALIAS -> firStatements += convertTypeAlias(it) as FirStatement
|
||||||
|
OBJECT_DECLARATION -> firStatements += convertClass(it) as FirStatement
|
||||||
|
CLASS_INITIALIZER -> firStatements += convertAnonymousInitializer(it) as FirStatement
|
||||||
|
|
||||||
else -> if (it.isExpression()) firStatements += expressionConverter.getAsFirExpression<FirStatement>(it)
|
else -> if (it.isExpression()) firStatements += expressionConverter.getAsFirExpression<FirStatement>(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +380,7 @@ class DeclarationsConverter(
|
|||||||
null,
|
null,
|
||||||
FirClassSymbol(ClassNameUtil.currentClassId),
|
FirClassSymbol(ClassNameUtil.currentClassId),
|
||||||
className,
|
className,
|
||||||
if (FunctionUtil.firFunctions.isNotEmpty()) Visibilities.LOCAL else modifiers.getVisibility(),
|
if (classNode.getParent()?.tokenType == BLOCK) Visibilities.LOCAL else modifiers.getVisibility(),
|
||||||
modifiers.getModality(),
|
modifiers.getModality(),
|
||||||
modifiers.hasExpect(),
|
modifiers.hasExpect(),
|
||||||
modifiers.hasActual(),
|
modifiers.hasActual(),
|
||||||
@@ -569,14 +578,14 @@ class DeclarationsConverter(
|
|||||||
var modifiers = Modifier(session)
|
var modifiers = Modifier(session)
|
||||||
val firValueParameters = mutableListOf<ValueParameter>()
|
val firValueParameters = mutableListOf<ValueParameter>()
|
||||||
var constructorDelegationCall: FirDelegatedConstructorCall? = null
|
var constructorDelegationCall: FirDelegatedConstructorCall? = null
|
||||||
var firBlock: FirBlock? = null
|
var block: LighterASTNode? = null
|
||||||
|
|
||||||
secondaryConstructor.forEachChildren {
|
secondaryConstructor.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
||||||
VALUE_PARAMETER_LIST -> firValueParameters += convertValueParameters(it)
|
VALUE_PARAMETER_LIST -> firValueParameters += convertValueParameters(it)
|
||||||
CONSTRUCTOR_DELEGATION_CALL -> constructorDelegationCall = convertConstructorDelegationCall(it, classWrapper)
|
CONSTRUCTOR_DELEGATION_CALL -> constructorDelegationCall = convertConstructorDelegationCall(it, classWrapper)
|
||||||
BLOCK -> firBlock = visitBlock(it)
|
BLOCK -> block = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,7 +604,7 @@ class DeclarationsConverter(
|
|||||||
firConstructor.annotations += modifiers.annotations
|
firConstructor.annotations += modifiers.annotations
|
||||||
firConstructor.typeParameters += ConverterUtil.typeParametersFromSelfType(classWrapper.delegatedSelfTypeRef)
|
firConstructor.typeParameters += ConverterUtil.typeParametersFromSelfType(classWrapper.delegatedSelfTypeRef)
|
||||||
firConstructor.valueParameters += firValueParameters.map { it.firValueParameter }
|
firConstructor.valueParameters += firValueParameters.map { it.firValueParameter }
|
||||||
firConstructor.body = visitFunctionBody(firBlock, null)
|
firConstructor.body = visitFunctionBody(block, null)
|
||||||
FunctionUtil.firFunctions.removeLast()
|
FunctionUtil.firFunctions.removeLast()
|
||||||
return firConstructor
|
return firConstructor
|
||||||
}
|
}
|
||||||
@@ -704,7 +713,7 @@ class DeclarationsConverter(
|
|||||||
|
|
||||||
val propertyName = identifier.nameAsSafeName()
|
val propertyName = identifier.nameAsSafeName()
|
||||||
|
|
||||||
return if (FunctionUtil.firFunctions.isNotEmpty()) {
|
return if (property.getParent()?.tokenType == BLOCK) {
|
||||||
FirVariableImpl(
|
FirVariableImpl(
|
||||||
session,
|
session,
|
||||||
null,
|
null,
|
||||||
@@ -742,6 +751,44 @@ class DeclarationsConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitDestructuringDeclaration
|
||||||
|
*/
|
||||||
|
private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration {
|
||||||
|
var isVar = false
|
||||||
|
val entries = mutableListOf<FirVariable>()
|
||||||
|
destructingDeclaration.forEachChildren {
|
||||||
|
when (it.tokenType) {
|
||||||
|
VAR_KEYWORD -> isVar = true
|
||||||
|
DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DestructuringDeclaration(isVar, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseMultiDeclarationName
|
||||||
|
*/
|
||||||
|
private fun convertDestructingDeclarationEntry(entry: LighterASTNode): FirVariable {
|
||||||
|
var modifiers = Modifier(session)
|
||||||
|
lateinit var identifier: String
|
||||||
|
var firType: FirTypeRef? = null
|
||||||
|
entry.forEachChildren {
|
||||||
|
when (it.tokenType) {
|
||||||
|
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
||||||
|
IDENTIFIER -> identifier = it.getAsString()
|
||||||
|
TYPE_REFERENCE -> firType = convertType(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirVariableImpl(
|
||||||
|
session, null, identifier.nameAsSafeName(), firType ?: implicitType, false, null
|
||||||
|
).apply {
|
||||||
|
annotations += modifiers.annotations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter
|
||||||
*/
|
*/
|
||||||
@@ -750,7 +797,7 @@ class DeclarationsConverter(
|
|||||||
var isGetter = true
|
var isGetter = true
|
||||||
var returnType: FirTypeRef? = null
|
var returnType: FirTypeRef? = null
|
||||||
var firValueParameters: FirValueParameter = FirDefaultSetterValueParameter(session, null, propertyTypeRef)
|
var firValueParameters: FirValueParameter = FirDefaultSetterValueParameter(session, null, propertyTypeRef)
|
||||||
var firBlock: FirBlock? = null
|
var block: LighterASTNode? = null
|
||||||
var firExpression: FirExpression? = null
|
var firExpression: FirExpression? = null
|
||||||
getterOrSetter.forEachChildren {
|
getterOrSetter.forEachChildren {
|
||||||
if (it.getAsString() == "set") isGetter = false
|
if (it.getAsString() == "set") isGetter = false
|
||||||
@@ -759,7 +806,7 @@ class DeclarationsConverter(
|
|||||||
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
||||||
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 -> block = it
|
||||||
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -778,7 +825,7 @@ class DeclarationsConverter(
|
|||||||
firAccessor.valueParameters += firValueParameters
|
firAccessor.valueParameters += firValueParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
firAccessor.body = visitFunctionBody(firBlock, firExpression)
|
firAccessor.body = visitFunctionBody(block, firExpression)
|
||||||
FunctionUtil.firFunctions.removeLast()
|
FunctionUtil.firFunctions.removeLast()
|
||||||
return firAccessor
|
return firAccessor
|
||||||
}
|
}
|
||||||
@@ -816,16 +863,16 @@ class DeclarationsConverter(
|
|||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunction
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunction
|
||||||
*/
|
*/
|
||||||
private fun convertFunctionDeclaration(functionDeclaration: LighterASTNode): FirDeclaration {
|
fun convertFunctionDeclaration(functionDeclaration: LighterASTNode): FirDeclaration {
|
||||||
var modifiers = Modifier(session)
|
var modifiers = Modifier(session)
|
||||||
lateinit var identifier: String
|
var identifier: String? = null
|
||||||
val firTypeParameters = mutableListOf<FirTypeParameter>()
|
val firTypeParameters = mutableListOf<FirTypeParameter>()
|
||||||
val valueParametersList = mutableListOf<ValueParameter>()
|
val valueParametersList = mutableListOf<ValueParameter>()
|
||||||
var isReturnType = false
|
var isReturnType = false
|
||||||
var receiverType: FirTypeRef? = null
|
var receiverType: FirTypeRef? = null
|
||||||
var returnType: FirTypeRef? = null
|
var returnType: FirTypeRef? = null
|
||||||
val typeConstraints = mutableListOf<TypeConstraint>()
|
val typeConstraints = mutableListOf<TypeConstraint>()
|
||||||
var firBlock: FirBlock? = null
|
var block: LighterASTNode? = null
|
||||||
var firExpression: FirExpression? = null
|
var firExpression: FirExpression? = null
|
||||||
functionDeclaration.forEachChildren {
|
functionDeclaration.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
@@ -836,47 +883,53 @@ 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)
|
||||||
BLOCK -> firBlock = visitBlock(it)
|
BLOCK -> block = it
|
||||||
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnType == null) {
|
if (returnType == null) {
|
||||||
returnType =
|
returnType =
|
||||||
if (firBlock != null || (firBlock == null && firExpression == null)) implicitUnitType
|
if (block != null || (block == null && firExpression == null)) implicitUnitType
|
||||||
else implicitType
|
else implicitType
|
||||||
}
|
}
|
||||||
|
|
||||||
val functionName = identifier.nameAsSafeName()
|
val isLocal = functionDeclaration.getParent()?.tokenType == BLOCK
|
||||||
val isLocal = FunctionUtil.firFunctions.isNotEmpty()
|
val firFunction = if (identifier == null) {
|
||||||
val firFunction = FirMemberFunctionImpl(
|
FirAnonymousFunctionImpl(session, null, returnType!!, receiverType)
|
||||||
session,
|
} else {
|
||||||
null,
|
val functionName = identifier.nameAsSafeName()
|
||||||
FirFunctionSymbol(ClassNameUtil.callableIdForName(functionName, isLocal)),
|
FirMemberFunctionImpl(
|
||||||
functionName,
|
session,
|
||||||
modifiers.getVisibility(),
|
null,
|
||||||
modifiers.getModality(),
|
FirFunctionSymbol(ClassNameUtil.callableIdForName(functionName, isLocal)),
|
||||||
modifiers.hasExpect(),
|
functionName,
|
||||||
modifiers.hasActual(),
|
modifiers.getVisibility(),
|
||||||
modifiers.hasOverride(),
|
modifiers.getModality(),
|
||||||
modifiers.hasOperator(),
|
modifiers.hasExpect(),
|
||||||
modifiers.hasInfix(),
|
modifiers.hasActual(),
|
||||||
modifiers.hasInline(),
|
modifiers.hasOverride(),
|
||||||
modifiers.hasTailrec(),
|
modifiers.hasOperator(),
|
||||||
modifiers.hasExternal(),
|
modifiers.hasInfix(),
|
||||||
modifiers.hasSuspend(),
|
modifiers.hasInline(),
|
||||||
receiverType,
|
modifiers.hasTailrec(),
|
||||||
returnType!!
|
modifiers.hasExternal(),
|
||||||
)
|
modifiers.hasSuspend(),
|
||||||
|
receiverType,
|
||||||
|
returnType!!
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
FunctionUtil.firFunctions += firFunction
|
FunctionUtil.firFunctions += firFunction
|
||||||
firFunction.annotations += modifiers.annotations
|
firFunction.annotations += modifiers.annotations
|
||||||
|
|
||||||
firFunction.typeParameters += firTypeParameters
|
if (firFunction is FirMemberFunctionImpl) {
|
||||||
firFunction.joinTypeParameters(typeConstraints)
|
firFunction.typeParameters += firTypeParameters
|
||||||
|
firFunction.joinTypeParameters(typeConstraints)
|
||||||
|
}
|
||||||
|
|
||||||
firFunction.valueParameters += valueParametersList.map { it.firValueParameter }
|
firFunction.valueParameters += valueParametersList.map { it.firValueParameter }
|
||||||
firFunction.body = visitFunctionBody(firBlock, firExpression)
|
firFunction.body = visitFunctionBody(block, firExpression)
|
||||||
FunctionUtil.firFunctions.removeLast()
|
FunctionUtil.firFunctions.removeLast()
|
||||||
return firFunction
|
return firFunction
|
||||||
}
|
}
|
||||||
@@ -885,10 +938,10 @@ class DeclarationsConverter(
|
|||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunctionBody
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunctionBody
|
||||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.buildFirBody
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.buildFirBody
|
||||||
*/
|
*/
|
||||||
private fun visitFunctionBody(firBlock: FirBlock?, firExpression: FirExpression?): FirBlock? {
|
private fun visitFunctionBody(blockNode: LighterASTNode?, firExpression: FirExpression?): FirBlock? {
|
||||||
return when {
|
return when {
|
||||||
firBlock != null -> if (!stubMode) {
|
blockNode != null -> if (!stubMode) {
|
||||||
return firBlock
|
return visitBlock(blockNode)
|
||||||
} else {
|
} else {
|
||||||
FirSingleExpressionBlock(
|
FirSingleExpressionBlock(
|
||||||
session,
|
session,
|
||||||
@@ -1205,7 +1258,7 @@ class DeclarationsConverter(
|
|||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseValueParameterList
|
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseValueParameterList
|
||||||
*/
|
*/
|
||||||
private fun convertValueParameters(valueParameters: LighterASTNode): List<ValueParameter> {
|
fun convertValueParameters(valueParameters: LighterASTNode): List<ValueParameter> {
|
||||||
return valueParameters.forEachChildrenReturnList { node, container ->
|
return valueParameters.forEachChildrenReturnList { node, container ->
|
||||||
when (node.tokenType) {
|
when (node.tokenType) {
|
||||||
VALUE_PARAMETER -> container += convertValueParameter(node)
|
VALUE_PARAMETER -> container += convertValueParameter(node)
|
||||||
@@ -1223,6 +1276,7 @@ class DeclarationsConverter(
|
|||||||
var identifier: String? = null
|
var identifier: String? = null
|
||||||
var firType: FirTypeRef? = null
|
var firType: FirTypeRef? = null
|
||||||
var firExpression: FirExpression? = null
|
var firExpression: FirExpression? = null
|
||||||
|
var destructuringDeclaration: DestructuringDeclaration? = null
|
||||||
valueParameter.forEachChildren {
|
valueParameter.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
MODIFIER_LIST -> modifiers = convertModifierList(it)
|
||||||
@@ -1230,6 +1284,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)
|
||||||
|
DESTRUCTURING_DECLARATION -> destructuringDeclaration = convertDestructingDeclaration(it)
|
||||||
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
else -> if (it.isExpression()) firExpression = expressionConverter.getAsFirExpression(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1244,6 +1299,6 @@ class DeclarationsConverter(
|
|||||||
isNoinline = modifiers.hasNoinline(),
|
isNoinline = modifiers.hasNoinline(),
|
||||||
isVararg = modifiers.hasVararg()
|
isVararg = modifiers.hasVararg()
|
||||||
).apply { annotations += modifiers.annotations }
|
).apply { annotations += modifiers.annotations }
|
||||||
return ValueParameter(isVal, isVar, modifiers, firValueParameter)
|
return ValueParameter(isVal, isVar, modifiers, firValueParameter, destructuringDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+129
-30
@@ -12,15 +12,22 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.FirReference
|
import org.jetbrains.kotlin.fir.FirReference
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.builder.*
|
import org.jetbrains.kotlin.fir.builder.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousFunctionImpl
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.fir.labels.FirLabelImpl
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsString
|
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.isExpression
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.nameAsSafeName
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.nameAsSafeName
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsStringUnescapedValue
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsStringUnescapedValue
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.extractArgumentsFrom
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.extractArgumentsFrom
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.toReturn
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.FunctionUtil.removeLast
|
import org.jetbrains.kotlin.fir.lightTree.converter.FunctionUtil.removeLast
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.converter.FunctionUtil.pop
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.utils.*
|
import org.jetbrains.kotlin.fir.lightTree.converter.utils.*
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
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
|
||||||
@@ -28,8 +35,11 @@ import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.render
|
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.fir.types.impl.FirImplicitTypeRefImpl
|
||||||
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.KtLambdaExpression
|
||||||
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
|
||||||
@@ -50,9 +60,14 @@ class ExpressionsConverter(
|
|||||||
fun convertExpression(expression: LighterASTNode): FirElement {
|
fun convertExpression(expression: LighterASTNode): FirElement {
|
||||||
if (!stubMode) {
|
if (!stubMode) {
|
||||||
return when (expression.tokenType) {
|
return when (expression.tokenType) {
|
||||||
|
LAMBDA_EXPRESSION -> {
|
||||||
|
val lambdaTree = LightTree2Fir.buildLightTreeLambdaExpression(expression.getAsString())
|
||||||
|
ExpressionsConverter(session, stubMode, lambdaTree, declarationsConverter).convertLambdaExpression(lambdaTree.root)
|
||||||
|
}
|
||||||
BINARY_EXPRESSION -> convertBinaryExpression(expression)
|
BINARY_EXPRESSION -> convertBinaryExpression(expression)
|
||||||
BINARY_WITH_TYPE -> convertBinaryWithType(expression)
|
BINARY_WITH_TYPE -> convertBinaryWithType(expression)
|
||||||
IS_EXPRESSION -> convertIsExpression(expression)
|
IS_EXPRESSION -> convertIsExpression(expression)
|
||||||
|
LABELED_EXPRESSION -> convertLabeledExpression(expression)
|
||||||
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
|
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
|
||||||
ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
|
ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
|
||||||
CLASS_LITERAL_EXPRESSION -> convertClassLiteralExpression(expression)
|
CLASS_LITERAL_EXPRESSION -> convertClassLiteralExpression(expression)
|
||||||
@@ -64,9 +79,12 @@ class ExpressionsConverter(
|
|||||||
STRING_TEMPLATE -> convertStringTemplate(expression)
|
STRING_TEMPLATE -> convertStringTemplate(expression)
|
||||||
is KtConstantExpressionElementType -> convertConstantExpression(expression)
|
is KtConstantExpressionElementType -> convertConstantExpression(expression)
|
||||||
REFERENCE_EXPRESSION -> convertSimpleNameExpression(expression)
|
REFERENCE_EXPRESSION -> convertSimpleNameExpression(expression)
|
||||||
|
RETURN -> convertReturn(expression)
|
||||||
PARENTHESIZED, PROPERTY_DELEGATE, INDICES -> convertExpression(expression.getExpressionInParentheses())
|
PARENTHESIZED, PROPERTY_DELEGATE, INDICES -> convertExpression(expression.getExpressionInParentheses())
|
||||||
THIS_EXPRESSION -> convertThisExpression(expression)
|
THIS_EXPRESSION -> convertThisExpression(expression)
|
||||||
SUPER_EXPRESSION -> convertSuperExpression(expression)
|
SUPER_EXPRESSION -> convertSuperExpression(expression)
|
||||||
|
|
||||||
|
FUN -> declarationsConverter.convertFunctionDeclaration(expression)
|
||||||
else -> FirExpressionStub(session, null)
|
else -> FirExpressionStub(session, null)
|
||||||
}
|
}
|
||||||
//TODO("not fully implemented")
|
//TODO("not fully implemented")
|
||||||
@@ -75,6 +93,60 @@ class ExpressionsConverter(
|
|||||||
return FirExpressionStub(session, null)
|
return FirExpressionStub(session, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun convertLambdaExpression(lambdaExpression: LighterASTNode): FirExpression {
|
||||||
|
val valueParameterList = mutableListOf<ValueParameter>()
|
||||||
|
lateinit var block: LighterASTNode
|
||||||
|
lambdaExpression.getChildNodesByType(FUNCTION_LITERAL).first().forEachChildren {
|
||||||
|
when (it.tokenType) {
|
||||||
|
VALUE_PARAMETER_LIST -> valueParameterList += declarationsConverter.convertValueParameters(it)
|
||||||
|
BLOCK -> block = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirAnonymousFunctionImpl(session, null, implicitType, implicitType).apply {
|
||||||
|
FunctionUtil.firFunctions += this
|
||||||
|
var destructuringBlock: FirExpression? = null
|
||||||
|
for (valueParameter in valueParameterList) {
|
||||||
|
val multiDeclaration = valueParameter.destructuringDeclaration
|
||||||
|
valueParameters += if (multiDeclaration != null) {
|
||||||
|
val multiParameter = FirValueParameterImpl(
|
||||||
|
this@ExpressionsConverter.session, null, Name.special("<destruct>"),
|
||||||
|
FirImplicitTypeRefImpl(this@ExpressionsConverter.session, null),
|
||||||
|
defaultValue = null, isCrossinline = false, isNoinline = false, isVararg = false
|
||||||
|
)
|
||||||
|
destructuringBlock = generateDestructuringBlock(
|
||||||
|
this@ExpressionsConverter.session,
|
||||||
|
multiDeclaration,
|
||||||
|
multiParameter,
|
||||||
|
tmpVariable = false
|
||||||
|
)
|
||||||
|
multiParameter
|
||||||
|
} else {
|
||||||
|
valueParameter.firValueParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label = FunctionUtil.firLabels.pop() ?: FunctionUtil.firFunctionCalls.lastOrNull()?.calleeReference?.name?.let {
|
||||||
|
FirLabelImpl(this@ExpressionsConverter.session, null, it.asString())
|
||||||
|
}
|
||||||
|
val bodyExpression = declarationsConverter.convertBlockExpression(block)
|
||||||
|
body = if (bodyExpression is FirBlockImpl) {
|
||||||
|
if (bodyExpression.statements.isEmpty()) {
|
||||||
|
bodyExpression.statements.add(FirUnitExpression(this@ExpressionsConverter.session, null))
|
||||||
|
}
|
||||||
|
if (destructuringBlock is FirBlock) {
|
||||||
|
for ((index, statement) in destructuringBlock.statements.withIndex()) {
|
||||||
|
bodyExpression.statements.add(index, statement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bodyExpression
|
||||||
|
} else {
|
||||||
|
FirSingleExpressionBlock(this@ExpressionsConverter.session, bodyExpression.toReturn())
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionUtil.firFunctions.removeLast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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
|
||||||
@@ -181,6 +253,27 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseLabeledExpression
|
||||||
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitLabeledExpression
|
||||||
|
*/
|
||||||
|
private fun convertLabeledExpression(labeledExpression: LighterASTNode): FirElement {
|
||||||
|
val size = FunctionUtil.firLabels.size
|
||||||
|
var firExpression: FirElement? = null
|
||||||
|
labeledExpression.forEachChildren {
|
||||||
|
when (it.tokenType) {
|
||||||
|
LABEL_QUALIFIER -> FunctionUtil.firLabels += FirLabelImpl(session, null, it.toString().replace("@", ""))
|
||||||
|
else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != FunctionUtil.firLabels.size) {
|
||||||
|
FunctionUtil.firLabels.removeLast()
|
||||||
|
//println("Unused label: ${labeledExpression.getAsString()}")
|
||||||
|
}
|
||||||
|
return firExpression ?: FirErrorExpressionImpl(session, null, "Empty label")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePostfixExpression
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePostfixExpression
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePrefixExpression
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parsePrefixExpression
|
||||||
@@ -322,14 +415,13 @@ class ExpressionsConverter(
|
|||||||
private fun convertCallExpression(callSuffix: LighterASTNode): FirExpression {
|
private fun convertCallExpression(callSuffix: LighterASTNode): FirExpression {
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
val firTypeArguments = mutableListOf<FirTypeProjection>()
|
val firTypeArguments = mutableListOf<FirTypeProjection>()
|
||||||
val firValueArguments = mutableListOf<FirExpression>()
|
val valueArguments = mutableListOf<LighterASTNode>()
|
||||||
var additionalArgument: FirExpression? = null
|
var additionalArgument: FirExpression? = null
|
||||||
callSuffix.forEachChildren {
|
callSuffix.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
REFERENCE_EXPRESSION -> name = it.getAsString()
|
REFERENCE_EXPRESSION -> name = it.getAsString()
|
||||||
TYPE_ARGUMENT_LIST -> firTypeArguments += declarationsConverter.convertTypeArguments(it)
|
TYPE_ARGUMENT_LIST -> firTypeArguments += declarationsConverter.convertTypeArguments(it)
|
||||||
VALUE_ARGUMENT_LIST -> firValueArguments += convertValueArguments(it)
|
VALUE_ARGUMENT_LIST, LAMBDA_ARGUMENT -> valueArguments += it
|
||||||
LAMBDA_ARGUMENT -> firValueArguments += convertAnnotatedLambda(it)
|
|
||||||
else -> additionalArgument = getAsFirExpression(it)
|
else -> additionalArgument = getAsFirExpression(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,26 +437,12 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
this.calleeReference = calleeReference
|
this.calleeReference = calleeReference
|
||||||
FunctionUtil.firFunctionCalls += this
|
FunctionUtil.firFunctionCalls += this
|
||||||
this.extractArgumentsFrom(firValueArguments, stubMode)
|
this.extractArgumentsFrom(valueArguments.flatMap { convertValueArguments(it) }, stubMode)
|
||||||
typeArguments += firTypeArguments
|
typeArguments += firTypeArguments
|
||||||
FunctionUtil.firFunctionCalls.removeLast()
|
FunctionUtil.firFunctionCalls.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseAnnotatedLambda
|
|
||||||
*/
|
|
||||||
private fun convertAnnotatedLambda(annotatedLambda: LighterASTNode): FirExpression {
|
|
||||||
annotatedLambda.forEachChildren {
|
|
||||||
when (it.tokenType) {
|
|
||||||
LAMBDA_EXPRESSION -> ""
|
|
||||||
LABELED_EXPRESSION -> ""
|
|
||||||
ANNOTATED_EXPRESSION -> ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FirExpressionStub(session, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseStringTemplate
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseStringTemplate
|
||||||
* @see org.jetbrains.kotlin.fir.builder.ConversionUtilsKt.toInterpolatingCall
|
* @see org.jetbrains.kotlin.fir.builder.ConversionUtilsKt.toInterpolatingCall
|
||||||
@@ -527,6 +605,24 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseReturn
|
||||||
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitReturnExpression
|
||||||
|
*/
|
||||||
|
private fun convertReturn(returnExpression: LighterASTNode): FirExpression {
|
||||||
|
var labelName: String? = null
|
||||||
|
var firExpression: FirExpression? = null
|
||||||
|
returnExpression.forEachChildren {
|
||||||
|
when (it.tokenType) {
|
||||||
|
LABEL_QUALIFIER -> labelName = it.getAsString().replace("@", "")
|
||||||
|
else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = firExpression ?: FirUnitExpression(session, null)
|
||||||
|
return result.toReturn(labelName)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseThisExpression
|
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseThisExpression
|
||||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitThisExpression
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitThisExpression
|
||||||
@@ -568,6 +664,9 @@ class ExpressionsConverter(
|
|||||||
return valueArguments.forEachChildrenReturnList { node, container ->
|
return valueArguments.forEachChildrenReturnList { node, container ->
|
||||||
when (node.tokenType) {
|
when (node.tokenType) {
|
||||||
VALUE_ARGUMENT -> container += convertValueArgument(node)
|
VALUE_ARGUMENT -> container += convertValueArgument(node)
|
||||||
|
LAMBDA_EXPRESSION,
|
||||||
|
LABELED_EXPRESSION,
|
||||||
|
ANNOTATED_EXPRESSION -> container += FirLambdaArgumentExpressionImpl(session, null, getAsFirExpression(node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,20 +695,20 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.fir.builder.ConversionUtilsKt.initializeLValue
|
||||||
|
*/
|
||||||
fun convertLValue(leftArgNode: LighterASTNode, container: FirModifiableQualifiedAccess<*>): FirReference {
|
fun convertLValue(leftArgNode: LighterASTNode, container: FirModifiableQualifiedAccess<*>): FirReference {
|
||||||
leftArgNode.forEachChildren {
|
return when (leftArgNode.tokenType) {
|
||||||
return when (it.tokenType) {
|
THIS_EXPRESSION -> convertThisExpression(leftArgNode).calleeReference
|
||||||
THIS_EXPRESSION -> convertThisExpression(leftArgNode).calleeReference
|
REFERENCE_EXPRESSION -> FirSimpleNamedReference(session, null, leftArgNode.getAsString().nameAsSafeName())
|
||||||
REFERENCE_EXPRESSION -> FirSimpleNamedReference(session, null, it.getAsString().nameAsSafeName())
|
in qualifiedAccessTokens -> (getAsFirExpression(leftArgNode) 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
|
|
||||||
}
|
|
||||||
PARENTHESIZED -> convertLValue(it.getExpressionInParentheses(), container)
|
|
||||||
else -> FirErrorNamedReference(session, null, "Unsupported LValue: ${leftArgNode.tokenType}")
|
|
||||||
}
|
}
|
||||||
|
PARENTHESIZED -> convertLValue(leftArgNode.getExpressionInParentheses(), container)
|
||||||
|
else -> FirErrorNamedReference(session, null, "Unsupported LValue: ${leftArgNode.tokenType}")
|
||||||
}
|
}
|
||||||
return FirErrorNamedReference(session, null, "Unsupported LValue: ${leftArgNode.tokenType}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+29
@@ -11,12 +11,16 @@ import com.intellij.psi.tree.TokenSet
|
|||||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.builder.*
|
import org.jetbrains.kotlin.fir.builder.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirVariableImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsString
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.getAsString
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.nameAsSafeName
|
import org.jetbrains.kotlin.fir.lightTree.converter.ConverterUtil.nameAsSafeName
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ExpressionsConverter
|
import org.jetbrains.kotlin.fir.lightTree.converter.ExpressionsConverter
|
||||||
|
import org.jetbrains.kotlin.fir.lightTree.fir.DestructuringDeclaration
|
||||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
@@ -143,6 +147,31 @@ fun ExpressionsConverter.generateIncrementOrDecrementBlock(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateDestructuringBlock(
|
||||||
|
session: FirSession,
|
||||||
|
multiDeclaration: DestructuringDeclaration,
|
||||||
|
container: FirVariable,
|
||||||
|
tmpVariable: Boolean
|
||||||
|
): FirExpression {
|
||||||
|
return FirBlockImpl(session, null).apply {
|
||||||
|
if (tmpVariable) {
|
||||||
|
statements += container
|
||||||
|
}
|
||||||
|
val isVar = multiDeclaration.isVar
|
||||||
|
for ((index, entry) in multiDeclaration.entries.withIndex()) {
|
||||||
|
statements += FirVariableImpl(
|
||||||
|
session, null, entry.name,
|
||||||
|
entry.returnTypeRef, isVar,
|
||||||
|
FirComponentCallImpl(session, null, index + 1, generateResolvedAccessExpression(session, null, container)),
|
||||||
|
FirVariableSymbol(entry.name) // TODO?
|
||||||
|
).apply {
|
||||||
|
annotations += entry.annotations
|
||||||
|
symbol.bind(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun bangBangToWhen(session: FirSession, baseExpression: FirExpression): FirWhenExpression {
|
fun bangBangToWhen(session: FirSession, baseExpression: FirExpression): FirWhenExpression {
|
||||||
return baseExpression.generateNotNullOrOther(
|
return baseExpression.generateNotNullOrOther(
|
||||||
session,
|
session,
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.lightTree.fir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
||||||
|
|
||||||
|
data class DestructuringDeclaration(
|
||||||
|
val isVar: Boolean,
|
||||||
|
val entries: List<FirVariable>
|
||||||
|
)
|
||||||
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberPropertyImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberPropertyImpl
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.lightTree.converter.ClassNameUtil
|
import org.jetbrains.kotlin.fir.lightTree.converter.ClassNameUtil
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
||||||
@@ -20,7 +22,8 @@ class ValueParameter(
|
|||||||
private val isVal: Boolean,
|
private val isVal: Boolean,
|
||||||
private val isVar: Boolean,
|
private val isVar: Boolean,
|
||||||
private val modifiers: Modifier,
|
private val modifiers: Modifier,
|
||||||
val firValueParameter: FirValueParameter
|
val firValueParameter: FirValueParameter,
|
||||||
|
val destructuringDeclaration: DestructuringDeclaration? = null
|
||||||
) {
|
) {
|
||||||
fun hasValOrVar(): Boolean {
|
fun hasValOrVar(): Boolean {
|
||||||
return isVal || isVar
|
return isVal || isVar
|
||||||
|
|||||||
+72
@@ -186,4 +186,76 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
visitCallableReferenceAccess = true
|
visitCallableReferenceAccess = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testLocalMembers() {
|
||||||
|
compare(
|
||||||
|
stubMode = false,
|
||||||
|
visitNamedFunction = true,
|
||||||
|
visitMemberDeclaration = true,
|
||||||
|
visitAnnotation = true,
|
||||||
|
visitTypeOperatorCall = true,
|
||||||
|
visitArrayOfCall = true,
|
||||||
|
visitFunctionCall = true,
|
||||||
|
visitGetClassCall = true,
|
||||||
|
visitConstExpression = true,
|
||||||
|
visitQualifiedAccessExpression = true,
|
||||||
|
visitCallableReferenceAccess = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testReturn() {
|
||||||
|
compare(
|
||||||
|
stubMode = false,
|
||||||
|
visitNamedFunction = true,
|
||||||
|
visitMemberDeclaration = true,
|
||||||
|
visitAnnotation = true,
|
||||||
|
visitTypeOperatorCall = true,
|
||||||
|
visitArrayOfCall = true,
|
||||||
|
visitFunctionCall = true,
|
||||||
|
visitGetClassCall = true,
|
||||||
|
visitReturnExpression = true,
|
||||||
|
visitConstExpression = true,
|
||||||
|
visitQualifiedAccessExpression = true,
|
||||||
|
visitCallableReferenceAccess = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testLambdaExpression() {
|
||||||
|
compare(
|
||||||
|
stubMode = false,
|
||||||
|
visitAnonymousFunction = true,
|
||||||
|
visitLambdaExpression = true,
|
||||||
|
visitNamedFunction = true,
|
||||||
|
visitMemberDeclaration = true,
|
||||||
|
visitAnnotation = true,
|
||||||
|
visitTypeOperatorCall = true,
|
||||||
|
visitArrayOfCall = true,
|
||||||
|
visitFunctionCall = true,
|
||||||
|
visitGetClassCall = true,
|
||||||
|
visitReturnExpression = true,
|
||||||
|
visitConstExpression = true,
|
||||||
|
visitQualifiedAccessExpression = true,
|
||||||
|
visitCallableReferenceAccess = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testLambdaArgument() {
|
||||||
|
compare(
|
||||||
|
stubMode = false,
|
||||||
|
visitAnonymousFunction = true,
|
||||||
|
visitLambdaExpression = true,
|
||||||
|
visitNamedFunction = true,
|
||||||
|
visitMemberDeclaration = true,
|
||||||
|
visitAnnotation = true,
|
||||||
|
visitTypeOperatorCall = true,
|
||||||
|
visitArrayOfCall = true,
|
||||||
|
visitFunctionCall = true,
|
||||||
|
visitGetClassCall = true,
|
||||||
|
visitReturnExpression = true,
|
||||||
|
visitConstExpression = true,
|
||||||
|
visitQualifiedAccessExpression = true,
|
||||||
|
visitCallableReferenceAccess = true,
|
||||||
|
visitLambdaArgumentExpression = true
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ public class MyKotlinParser {
|
|||||||
return builder.getLightTree();
|
return builder.getLightTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FlyweightCapableTreeStructure<LighterASTNode> parseLambdaExpression(PsiBuilder psiBuilder) {
|
||||||
|
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
|
||||||
|
ktParsing.parseLambdaExpression();
|
||||||
|
return psiBuilder.getLightTree();
|
||||||
|
}
|
||||||
|
|
||||||
public static FlyweightCapableTreeStructure<LighterASTNode> parseBlockExpression(PsiBuilder builder) {
|
public static FlyweightCapableTreeStructure<LighterASTNode> parseBlockExpression(PsiBuilder builder) {
|
||||||
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(builder));
|
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(builder));
|
||||||
ktParsing.parseBlockExpression();
|
ktParsing.parseBlockExpression();
|
||||||
|
|||||||
Reference in New Issue
Block a user