Extract some information to separate Context class
This commit is contained in:
committed by
Mikhail Glukhikh
parent
cad0dbf087
commit
c5547a2229
+4
-2
@@ -12,6 +12,7 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure
|
|||||||
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.BaseFirBuilder
|
import org.jetbrains.kotlin.fir.builder.BaseFirBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.builder.Context
|
||||||
import org.jetbrains.kotlin.fir.builder.escapedStringToCharacter
|
import org.jetbrains.kotlin.fir.builder.escapedStringToCharacter
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
import org.jetbrains.kotlin.fir.types.impl.*
|
||||||
import org.jetbrains.kotlin.lexer.KtToken
|
import org.jetbrains.kotlin.lexer.KtToken
|
||||||
@@ -23,8 +24,9 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
open class BaseConverter(
|
open class BaseConverter(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val tree: FlyweightCapableTreeStructure<LighterASTNode>
|
private val tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
) : BaseFirBuilder<LighterASTNode>(session) {
|
context: Context = Context()
|
||||||
|
) : BaseFirBuilder<LighterASTNode>(session, context) {
|
||||||
protected val implicitType = FirImplicitTypeRefImpl(session, null)
|
protected val implicitType = FirImplicitTypeRefImpl(session, null)
|
||||||
|
|
||||||
override val LighterASTNode.elementType: IElementType
|
override val LighterASTNode.elementType: IElementType
|
||||||
|
|||||||
+20
-18
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.builder.Context
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
@@ -49,9 +50,10 @@ import org.jetbrains.kotlin.fir.builder.generateComponentFunctions
|
|||||||
class DeclarationsConverter(
|
class DeclarationsConverter(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val stubMode: Boolean,
|
private val stubMode: Boolean,
|
||||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
) : BaseConverter(session, tree) {
|
context: Context = Context()
|
||||||
private val expressionConverter = ExpressionsConverter(session, stubMode, tree, this)
|
) : BaseConverter(session, tree, context) {
|
||||||
|
private val expressionConverter = ExpressionsConverter(session, stubMode, tree, this, context)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
||||||
@@ -66,11 +68,11 @@ class DeclarationsConverter(
|
|||||||
val fileAnnotationList = mutableListOf<FirAnnotationCall>()
|
val fileAnnotationList = mutableListOf<FirAnnotationCall>()
|
||||||
val importList = mutableListOf<FirImport>()
|
val importList = mutableListOf<FirImport>()
|
||||||
val firDeclarationList = mutableListOf<FirDeclaration>()
|
val firDeclarationList = mutableListOf<FirDeclaration>()
|
||||||
packageFqName = FqName.ROOT
|
context.packageFqName = FqName.ROOT
|
||||||
file.forEachChildren {
|
file.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
FILE_ANNOTATION_LIST -> fileAnnotationList += convertFileAnnotationList(it)
|
FILE_ANNOTATION_LIST -> fileAnnotationList += convertFileAnnotationList(it)
|
||||||
PACKAGE_DIRECTIVE -> packageFqName = convertPackageName(it)
|
PACKAGE_DIRECTIVE -> context.packageFqName = convertPackageName(it)
|
||||||
IMPORT_LIST -> importList += convertImportDirectives(it)
|
IMPORT_LIST -> importList += convertImportDirectives(it)
|
||||||
CLASS -> firDeclarationList += convertClass(it)
|
CLASS -> firDeclarationList += convertClass(it)
|
||||||
FUN -> firDeclarationList += convertFunctionDeclaration(it)
|
FUN -> firDeclarationList += convertFunctionDeclaration(it)
|
||||||
@@ -84,7 +86,7 @@ class DeclarationsConverter(
|
|||||||
session,
|
session,
|
||||||
null,
|
null,
|
||||||
fileName,
|
fileName,
|
||||||
packageFqName
|
context.packageFqName
|
||||||
)
|
)
|
||||||
firFile.annotations += fileAnnotationList
|
firFile.annotations += fileAnnotationList
|
||||||
firFile.imports += importList
|
firFile.imports += importList
|
||||||
@@ -368,7 +370,7 @@ class DeclarationsConverter(
|
|||||||
val firClass = FirClassImpl(
|
val firClass = FirClassImpl(
|
||||||
session,
|
session,
|
||||||
null,
|
null,
|
||||||
FirClassSymbol(currentClassId),
|
FirClassSymbol(context.currentClassId),
|
||||||
className,
|
className,
|
||||||
if (isLocal) Visibilities.LOCAL else modifiers.getVisibility(),
|
if (isLocal) Visibilities.LOCAL else modifiers.getVisibility(),
|
||||||
modifiers.getModality(),
|
modifiers.getModality(),
|
||||||
@@ -413,8 +415,8 @@ class DeclarationsConverter(
|
|||||||
//parse data class
|
//parse data class
|
||||||
if (modifiers.isDataClass() && firPrimaryConstructor != null) {
|
if (modifiers.isDataClass() && firPrimaryConstructor != null) {
|
||||||
val zippedParameters = MutableList(properties.size) { null }.zip(properties)
|
val zippedParameters = MutableList(properties.size) { null }.zip(properties)
|
||||||
zippedParameters.generateComponentFunctions(session, firClass, packageFqName, Companion.className)
|
zippedParameters.generateComponentFunctions(session, firClass, context.packageFqName, context.className)
|
||||||
zippedParameters.generateCopyFunction(session, null, firClass, packageFqName, Companion.className, firPrimaryConstructor)
|
zippedParameters.generateCopyFunction(session, null, firClass, context.packageFqName, context.className, firPrimaryConstructor)
|
||||||
// TODO: equals, hashCode, toString
|
// TODO: equals, hashCode, toString
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +501,7 @@ class DeclarationsConverter(
|
|||||||
val firEnumEntry = FirEnumEntryImpl(
|
val firEnumEntry = FirEnumEntryImpl(
|
||||||
session,
|
session,
|
||||||
null,
|
null,
|
||||||
FirClassSymbol(currentClassId),
|
FirClassSymbol(context.currentClassId),
|
||||||
enumEntryName
|
enumEntryName
|
||||||
)
|
)
|
||||||
firEnumEntry.annotations += modifiers.annotations
|
firEnumEntry.annotations += modifiers.annotations
|
||||||
@@ -657,12 +659,12 @@ class DeclarationsConverter(
|
|||||||
constructorDelegationCall
|
constructorDelegationCall
|
||||||
)
|
)
|
||||||
|
|
||||||
firFunctions += firConstructor
|
context.firFunctions += firConstructor
|
||||||
firConstructor.annotations += modifiers.annotations
|
firConstructor.annotations += modifiers.annotations
|
||||||
firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||||
firConstructor.valueParameters += firValueParameters.map { it.firValueParameter }
|
firConstructor.valueParameters += firValueParameters.map { it.firValueParameter }
|
||||||
firConstructor.body = convertFunctionBody(block, null)
|
firConstructor.body = convertFunctionBody(block, null)
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
return firConstructor
|
return firConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +727,7 @@ class DeclarationsConverter(
|
|||||||
return@withChildClassName FirTypeAliasImpl(
|
return@withChildClassName FirTypeAliasImpl(
|
||||||
session,
|
session,
|
||||||
null,
|
null,
|
||||||
FirTypeAliasSymbol(currentClassId),
|
FirTypeAliasSymbol(context.currentClassId),
|
||||||
typeAliasName,
|
typeAliasName,
|
||||||
modifiers.getVisibility(),
|
modifiers.getVisibility(),
|
||||||
modifiers.hasExpect(),
|
modifiers.hasExpect(),
|
||||||
@@ -886,7 +888,7 @@ class DeclarationsConverter(
|
|||||||
modifiers.getVisibility(),
|
modifiers.getVisibility(),
|
||||||
returnType ?: if (isGetter) propertyTypeRef else implicitUnitType
|
returnType ?: if (isGetter) propertyTypeRef else implicitUnitType
|
||||||
)
|
)
|
||||||
firFunctions += firAccessor
|
context.firFunctions += firAccessor
|
||||||
firAccessor.annotations += modifiers.annotations
|
firAccessor.annotations += modifiers.annotations
|
||||||
|
|
||||||
if (!isGetter) {
|
if (!isGetter) {
|
||||||
@@ -894,7 +896,7 @@ class DeclarationsConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
firAccessor.body = convertFunctionBody(block, expression)
|
firAccessor.body = convertFunctionBody(block, expression)
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
return firAccessor
|
return firAccessor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,7 +993,7 @@ class DeclarationsConverter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
firFunctions += firFunction
|
context.firFunctions += firFunction
|
||||||
firFunction.annotations += modifiers.annotations
|
firFunction.annotations += modifiers.annotations
|
||||||
|
|
||||||
if (firFunction is FirMemberFunctionImpl) {
|
if (firFunction is FirMemberFunctionImpl) {
|
||||||
@@ -1001,7 +1003,7 @@ class DeclarationsConverter(
|
|||||||
|
|
||||||
valueParametersList?.let { firFunction.valueParameters += convertValueParameters(it).map { it.firValueParameter } }
|
valueParametersList?.let { firFunction.valueParameters += convertValueParameters(it).map { it.firValueParameter } }
|
||||||
firFunction.body = convertFunctionBody(block, expression)
|
firFunction.body = convertFunctionBody(block, expression)
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
return firFunction
|
return firFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1033,7 +1035,7 @@ class DeclarationsConverter(
|
|||||||
}
|
}
|
||||||
return if (!stubMode) {
|
return if (!stubMode) {
|
||||||
val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText)
|
val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText)
|
||||||
return DeclarationsConverter(session, stubMode, blockTree).convertBlockExpression(blockTree.root)
|
return DeclarationsConverter(session, stubMode, blockTree, context).convertBlockExpression(blockTree.root)
|
||||||
} else {
|
} else {
|
||||||
FirSingleExpressionBlock(
|
FirSingleExpressionBlock(
|
||||||
session,
|
session,
|
||||||
|
|||||||
+15
-14
@@ -49,8 +49,9 @@ class ExpressionsConverter(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val stubMode: Boolean,
|
private val stubMode: Boolean,
|
||||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
private val declarationsConverter: DeclarationsConverter
|
private val declarationsConverter: DeclarationsConverter,
|
||||||
) : BaseConverter(session, tree) {
|
context: Context = Context()
|
||||||
|
) : BaseConverter(session, tree, context) {
|
||||||
|
|
||||||
inline fun <reified R : FirElement> LighterASTNode?.toFirExpression(errorReason: String = ""): R {
|
inline fun <reified R : FirElement> LighterASTNode?.toFirExpression(errorReason: String = ""): R {
|
||||||
return this?.let { convertExpression(it, errorReason) } as? R ?: (FirErrorExpressionImpl(session, null, errorReason) as R)
|
return this?.let { convertExpression(it, errorReason) } as? R ?: (FirErrorExpressionImpl(session, null, errorReason) as R)
|
||||||
@@ -66,7 +67,7 @@ class ExpressionsConverter(
|
|||||||
return when (expression.tokenType) {
|
return when (expression.tokenType) {
|
||||||
LAMBDA_EXPRESSION -> {
|
LAMBDA_EXPRESSION -> {
|
||||||
val lambdaTree = LightTree2Fir.buildLightTreeLambdaExpression(expression.asText)
|
val lambdaTree = LightTree2Fir.buildLightTreeLambdaExpression(expression.asText)
|
||||||
ExpressionsConverter(session, stubMode, lambdaTree, declarationsConverter).convertLambdaExpression(lambdaTree.root)
|
ExpressionsConverter(session, stubMode, lambdaTree, declarationsConverter, context).convertLambdaExpression(lambdaTree.root)
|
||||||
}
|
}
|
||||||
BINARY_EXPRESSION -> convertBinaryExpression(expression)
|
BINARY_EXPRESSION -> convertBinaryExpression(expression)
|
||||||
BINARY_WITH_TYPE -> convertBinaryWithType(expression)
|
BINARY_WITH_TYPE -> convertBinaryWithType(expression)
|
||||||
@@ -122,7 +123,7 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return FirAnonymousFunctionImpl(session, null, implicitType, implicitType).apply {
|
return FirAnonymousFunctionImpl(session, null, implicitType, implicitType).apply {
|
||||||
firFunctions += this
|
context.firFunctions += this
|
||||||
var destructuringBlock: FirExpression? = null
|
var destructuringBlock: FirExpression? = null
|
||||||
for (valueParameter in valueParameterList) {
|
for (valueParameter in valueParameterList) {
|
||||||
val multiDeclaration = valueParameter.destructuringDeclaration
|
val multiDeclaration = valueParameter.destructuringDeclaration
|
||||||
@@ -143,7 +144,7 @@ class ExpressionsConverter(
|
|||||||
valueParameter.firValueParameter
|
valueParameter.firValueParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label = firLabels.pop() ?: firFunctionCalls.lastOrNull()?.calleeReference?.name?.let {
|
label = context.firLabels.pop() ?: context.firFunctionCalls.lastOrNull()?.calleeReference?.name?.let {
|
||||||
FirLabelImpl(this@ExpressionsConverter.session, null, it.asString())
|
FirLabelImpl(this@ExpressionsConverter.session, null, it.asString())
|
||||||
}
|
}
|
||||||
val bodyExpression = block?.let { declarationsConverter.convertBlockExpression(it) }
|
val bodyExpression = block?.let { declarationsConverter.convertBlockExpression(it) }
|
||||||
@@ -162,7 +163,7 @@ class ExpressionsConverter(
|
|||||||
FirSingleExpressionBlock(this@ExpressionsConverter.session, bodyExpression.toReturn())
|
FirSingleExpressionBlock(this@ExpressionsConverter.session, bodyExpression.toReturn())
|
||||||
}
|
}
|
||||||
|
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,19 +278,19 @@ class ExpressionsConverter(
|
|||||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitLabeledExpression
|
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitLabeledExpression
|
||||||
*/
|
*/
|
||||||
private fun convertLabeledExpression(labeledExpression: LighterASTNode): FirElement {
|
private fun convertLabeledExpression(labeledExpression: LighterASTNode): FirElement {
|
||||||
val size = firLabels.size
|
val size = context.firLabels.size
|
||||||
var firExpression: FirElement? = null
|
var firExpression: FirElement? = null
|
||||||
labeledExpression.forEachChildren {
|
labeledExpression.forEachChildren {
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
LABEL_QUALIFIER -> firLabels += FirLabelImpl(session, null, it.toString().replace("@", ""))
|
LABEL_QUALIFIER -> context.firLabels += FirLabelImpl(session, null, it.toString().replace("@", ""))
|
||||||
BLOCK -> firExpression = declarationsConverter.convertBlock(it)
|
BLOCK -> firExpression = declarationsConverter.convertBlock(it)
|
||||||
PROPERTY -> firExpression = declarationsConverter.convertPropertyDeclaration(it)
|
PROPERTY -> firExpression = declarationsConverter.convertPropertyDeclaration(it)
|
||||||
else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
|
else -> if (it.isExpression()) firExpression = getAsFirExpression(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != firLabels.size) {
|
if (size != context.firLabels.size) {
|
||||||
firLabels.removeLast()
|
context.firLabels.removeLast()
|
||||||
//println("Unused label: ${labeledExpression.getAsString()}")
|
//println("Unused label: ${labeledExpression.getAsString()}")
|
||||||
}
|
}
|
||||||
return firExpression ?: FirErrorExpressionImpl(session, null, "Empty label")
|
return firExpression ?: FirErrorExpressionImpl(session, null, "Empty label")
|
||||||
@@ -460,10 +461,10 @@ class ExpressionsConverter(
|
|||||||
else -> FirErrorNamedReference(this@ExpressionsConverter.session, null, "Call has no callee")
|
else -> FirErrorNamedReference(this@ExpressionsConverter.session, null, "Call has no callee")
|
||||||
}
|
}
|
||||||
|
|
||||||
firFunctionCalls += this
|
context.firFunctionCalls += this
|
||||||
this.extractArgumentsFrom(valueArguments.flatMap { convertValueArguments(it) }, stubMode)
|
this.extractArgumentsFrom(valueArguments.flatMap { convertValueArguments(it) }, stubMode)
|
||||||
typeArguments += firTypeArguments
|
typeArguments += firTypeArguments
|
||||||
firFunctionCalls.removeLast()
|
context.firFunctionCalls.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,7 +886,7 @@ class ExpressionsConverter(
|
|||||||
|
|
||||||
return (if (isBreak) FirBreakExpressionImpl(session, null) else FirContinueExpressionImpl(session, null)).apply {
|
return (if (isBreak) FirBreakExpressionImpl(session, null) else FirContinueExpressionImpl(session, null)).apply {
|
||||||
target = FirLoopTarget(labelName)
|
target = FirLoopTarget(labelName)
|
||||||
val lastLoop = firLoops.lastOrNull()
|
val lastLoop = context.firLoops.lastOrNull()
|
||||||
if (labelName == null) {
|
if (labelName == null) {
|
||||||
if (lastLoop != null) {
|
if (lastLoop != null) {
|
||||||
target.bind(lastLoop)
|
target.bind(lastLoop)
|
||||||
@@ -893,7 +894,7 @@ class ExpressionsConverter(
|
|||||||
target.bind(FirErrorLoop(this@ExpressionsConverter.session, null, "Cannot bind unlabeled jump to a loop"))
|
target.bind(FirErrorLoop(this@ExpressionsConverter.session, null, "Cannot bind unlabeled jump to a loop"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (firLoop in firLoops.asReversed()) {
|
for (firLoop in context.firLoops.asReversed()) {
|
||||||
if (firLoop.label?.name == labelName) {
|
if (firLoop.label?.name == labelName) {
|
||||||
target.bind(firLoop)
|
target.bind(firLoop)
|
||||||
return this
|
return this
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
//T can be either PsiElement, or LighterASTNode
|
//T can be either PsiElement, or LighterASTNode
|
||||||
abstract class BaseFirBuilder<T>(val session: FirSession) {
|
abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context = Context()) {
|
||||||
|
|
||||||
protected val implicitUnitType = FirImplicitUnitTypeRef(session, null)
|
protected val implicitUnitType = FirImplicitUnitTypeRef(session, null)
|
||||||
protected val implicitAnyType = FirImplicitAnyTypeRef(session, null)
|
protected val implicitAnyType = FirImplicitAnyTypeRef(session, null)
|
||||||
@@ -56,41 +56,26 @@ abstract class BaseFirBuilder<T>(val session: FirSession) {
|
|||||||
abstract val T?.selectorExpression: T?
|
abstract val T?.selectorExpression: T?
|
||||||
|
|
||||||
/**** Class name utils ****/
|
/**** Class name utils ****/
|
||||||
// var packageFqName: FqName = FqName.ROOT
|
|
||||||
// var className: FqName = FqName.ROOT
|
|
||||||
// val currentClassId get() = ClassId(packageFqName, className, false)
|
|
||||||
|
|
||||||
inline fun <T> withChildClassName(name: Name, l: () -> T): T {
|
inline fun <T> withChildClassName(name: Name, l: () -> T): T {
|
||||||
className = className.child(name)
|
context.className = context.className.child(name)
|
||||||
val t = l()
|
val t = l()
|
||||||
className = className.parent()
|
context.className = context.className.parent()
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
fun callableIdForName(name: Name, local: Boolean = false) =
|
fun callableIdForName(name: Name, local: Boolean = false) =
|
||||||
when {
|
when {
|
||||||
local -> CallableId(name)
|
local -> CallableId(name)
|
||||||
className == FqName.ROOT -> CallableId(packageFqName, name)
|
context.className == FqName.ROOT -> CallableId(context.packageFqName, name)
|
||||||
else -> CallableId(packageFqName, className, name)
|
else -> CallableId(context.packageFqName, context.className, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun callableIdForClassConstructor() =
|
fun callableIdForClassConstructor() =
|
||||||
if (className == FqName.ROOT) CallableId(packageFqName, Name.special("<anonymous-init>"))
|
if (context.className == FqName.ROOT) CallableId(context.packageFqName, Name.special("<anonymous-init>"))
|
||||||
else CallableId(packageFqName, className, className.shortName())
|
else CallableId(context.packageFqName, context.className, context.className.shortName())
|
||||||
|
|
||||||
|
|
||||||
/**** Function utils ****/
|
/**** Function utils ****/
|
||||||
companion object {
|
|
||||||
val firFunctions = mutableListOf<FirFunction>()
|
|
||||||
val firFunctionCalls = mutableListOf<FirFunctionCall>()
|
|
||||||
val firLabels = mutableListOf<FirLabel>()
|
|
||||||
val firLoops = mutableListOf<FirLoop>()
|
|
||||||
|
|
||||||
lateinit var packageFqName: FqName
|
|
||||||
var className: FqName = FqName.ROOT
|
|
||||||
val currentClassId get() = ClassId(packageFqName, className, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> MutableList<T>.removeLast() {
|
fun <T> MutableList<T>.removeLast() {
|
||||||
removeAt(size - 1)
|
removeAt(size - 1)
|
||||||
}
|
}
|
||||||
@@ -111,7 +96,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession) {
|
|||||||
this
|
this
|
||||||
).apply {
|
).apply {
|
||||||
target = FirFunctionTarget(labelName)
|
target = FirFunctionTarget(labelName)
|
||||||
val lastFunction = firFunctions.lastOrNull()
|
val lastFunction = context.firFunctions.lastOrNull()
|
||||||
if (labelName == null) {
|
if (labelName == null) {
|
||||||
if (lastFunction != null) {
|
if (lastFunction != null) {
|
||||||
target.bind(lastFunction)
|
target.bind(lastFunction)
|
||||||
@@ -119,7 +104,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession) {
|
|||||||
target.bind(FirErrorFunction(this@BaseFirBuilder.session, psi, "Cannot bind unlabeled return to a function"))
|
target.bind(FirErrorFunction(this@BaseFirBuilder.session, psi, "Cannot bind unlabeled return to a function"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (firFunction in firFunctions.asReversed()) {
|
for (firFunction in context.firFunctions.asReversed()) {
|
||||||
when (firFunction) {
|
when (firFunction) {
|
||||||
is FirAnonymousFunction -> {
|
is FirAnonymousFunction -> {
|
||||||
if (firFunction.label?.name == labelName) {
|
if (firFunction.label?.name == labelName) {
|
||||||
@@ -165,10 +150,10 @@ abstract class BaseFirBuilder<T>(val session: FirSession) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirAbstractLoop.configure(generateBlock: () -> FirBlock): FirAbstractLoop {
|
fun FirAbstractLoop.configure(generateBlock: () -> FirBlock): FirAbstractLoop {
|
||||||
label = firLabels.pop()
|
label = context.firLabels.pop()
|
||||||
firLoops += this
|
context.firLoops += this
|
||||||
block = generateBlock()
|
block = generateBlock()
|
||||||
firLoops.removeLast()
|
context.firLoops.removeLast()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +334,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirModifiableQualifiedAccess<*>.initializeLValue(
|
private fun FirModifiableQualifiedAccess<*>.initializeLValue(
|
||||||
left: T?,
|
left: T?,
|
||||||
convertQualified: T.() -> FirQualifiedAccess?
|
convertQualified: T.() -> FirQualifiedAccess?
|
||||||
): FirReference {
|
): FirReference {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.builder
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirLabel
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
lateinit var packageFqName: FqName
|
||||||
|
var className: FqName = FqName.ROOT
|
||||||
|
val currentClassId get() = ClassId(packageFqName, className, false)
|
||||||
|
|
||||||
|
val firFunctions = mutableListOf<FirFunction>()
|
||||||
|
val firFunctionCalls = mutableListOf<FirFunctionCall>()
|
||||||
|
val firLabels = mutableListOf<FirLabel>()
|
||||||
|
val firLoops = mutableListOf<FirLoop>()
|
||||||
|
}
|
||||||
@@ -207,14 +207,14 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
returnTypeReference.toFirOrUnitType()
|
returnTypeReference.toFirOrUnitType()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
firFunctions += firAccessor
|
this@RawFirBuilder.context.firFunctions += firAccessor
|
||||||
extractAnnotationsTo(firAccessor)
|
extractAnnotationsTo(firAccessor)
|
||||||
extractValueParametersTo(firAccessor, propertyTypeRef)
|
extractValueParametersTo(firAccessor, propertyTypeRef)
|
||||||
if (!isGetter && firAccessor.valueParameters.isEmpty()) {
|
if (!isGetter && firAccessor.valueParameters.isEmpty()) {
|
||||||
firAccessor.valueParameters += FirDefaultSetterValueParameter(session, this, propertyTypeRef)
|
firAccessor.valueParameters += FirDefaultSetterValueParameter(session, this, propertyTypeRef)
|
||||||
}
|
}
|
||||||
firAccessor.body = this.buildFirBody()
|
firAccessor.body = this.buildFirBody()
|
||||||
firFunctions.removeLast()
|
this@RawFirBuilder.context.firFunctions.removeLast()
|
||||||
return firAccessor
|
return firAccessor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,8 +394,8 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitKtFile(file: KtFile, data: Unit): FirElement {
|
override fun visitKtFile(file: KtFile, data: Unit): FirElement {
|
||||||
packageFqName = file.packageFqName
|
context.packageFqName = file.packageFqName
|
||||||
val firFile = FirFileImpl(session, file, file.name, packageFqName)
|
val firFile = FirFileImpl(session, file, file.name, context.packageFqName)
|
||||||
for (annotationEntry in file.annotationEntries) {
|
for (annotationEntry in file.annotationEntries) {
|
||||||
firFile.annotations += annotationEntry.convert<FirAnnotationCall>()
|
firFile.annotations += annotationEntry.convert<FirAnnotationCall>()
|
||||||
}
|
}
|
||||||
@@ -418,7 +418,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
val firEnumEntry = FirEnumEntryImpl(
|
val firEnumEntry = FirEnumEntryImpl(
|
||||||
session,
|
session,
|
||||||
enumEntry,
|
enumEntry,
|
||||||
FirClassSymbol(currentClassId),
|
FirClassSymbol(context.currentClassId),
|
||||||
enumEntry.nameAsSafeName
|
enumEntry.nameAsSafeName
|
||||||
)
|
)
|
||||||
enumEntry.extractAnnotationsTo(firEnumEntry)
|
enumEntry.extractAnnotationsTo(firEnumEntry)
|
||||||
@@ -451,7 +451,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
val firClass = FirClassImpl(
|
val firClass = FirClassImpl(
|
||||||
session,
|
session,
|
||||||
classOrObject,
|
classOrObject,
|
||||||
FirClassSymbol(currentClassId),
|
FirClassSymbol(context.currentClassId),
|
||||||
classOrObject.nameAsSafeName,
|
classOrObject.nameAsSafeName,
|
||||||
if (classOrObject.isLocal) Visibilities.LOCAL else classOrObject.visibility,
|
if (classOrObject.isLocal) Visibilities.LOCAL else classOrObject.visibility,
|
||||||
classOrObject.modality,
|
classOrObject.modality,
|
||||||
@@ -489,8 +489,10 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
||||||
firClass.declarations.filterIsInstance<FirProperty>()
|
firClass.declarations.filterIsInstance<FirProperty>()
|
||||||
)
|
)
|
||||||
zippedParameters.generateComponentFunctions(session, firClass, packageFqName, className)
|
zippedParameters.generateComponentFunctions(session, firClass, context.packageFqName, context.className)
|
||||||
zippedParameters.generateCopyFunction(session, classOrObject, firClass, packageFqName, className, firPrimaryConstructor)
|
zippedParameters.generateCopyFunction(
|
||||||
|
session, classOrObject, firClass, context.packageFqName, context.className, firPrimaryConstructor
|
||||||
|
)
|
||||||
// TODO: equals, hashCode, toString
|
// TODO: equals, hashCode, toString
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,7 +521,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
val firTypeAlias = FirTypeAliasImpl(
|
val firTypeAlias = FirTypeAliasImpl(
|
||||||
session,
|
session,
|
||||||
typeAlias,
|
typeAlias,
|
||||||
FirTypeAliasSymbol(currentClassId),
|
FirTypeAliasSymbol(context.currentClassId),
|
||||||
typeAlias.nameAsSafeName,
|
typeAlias.nameAsSafeName,
|
||||||
typeAlias.visibility,
|
typeAlias.visibility,
|
||||||
typeAlias.hasExpectModifier(),
|
typeAlias.hasExpectModifier(),
|
||||||
@@ -564,7 +566,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
returnType
|
returnType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
firFunctions += firFunction
|
context.firFunctions += firFunction
|
||||||
function.extractAnnotationsTo(firFunction)
|
function.extractAnnotationsTo(firFunction)
|
||||||
if (firFunction is FirMemberFunctionImpl) {
|
if (firFunction is FirMemberFunctionImpl) {
|
||||||
function.extractTypeParametersTo(firFunction)
|
function.extractTypeParametersTo(firFunction)
|
||||||
@@ -573,7 +575,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
firFunction.valueParameters += valueParameter.convert<FirValueParameter>()
|
firFunction.valueParameters += valueParameter.convert<FirValueParameter>()
|
||||||
}
|
}
|
||||||
firFunction.body = function.buildFirBody()
|
firFunction.body = function.buildFirBody()
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
return firFunction
|
return firFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +584,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
val returnType = FirImplicitTypeRefImpl(literal)
|
val returnType = FirImplicitTypeRefImpl(literal)
|
||||||
val receiverType = FirImplicitTypeRefImpl(literal)
|
val receiverType = FirImplicitTypeRefImpl(literal)
|
||||||
return FirAnonymousFunctionImpl(session, literal, returnType, receiverType).apply {
|
return FirAnonymousFunctionImpl(session, literal, returnType, receiverType).apply {
|
||||||
firFunctions += this
|
context.firFunctions += this
|
||||||
var destructuringBlock: FirExpression? = null
|
var destructuringBlock: FirExpression? = null
|
||||||
for (valueParameter in literal.valueParameters) {
|
for (valueParameter in literal.valueParameters) {
|
||||||
val multiDeclaration = valueParameter.destructuringDeclaration
|
val multiDeclaration = valueParameter.destructuringDeclaration
|
||||||
@@ -604,7 +606,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
valueParameter.toFirValueParameter(FirImplicitTypeRefImpl(psi))
|
valueParameter.toFirValueParameter(FirImplicitTypeRefImpl(psi))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label = firLabels.pop() ?: firFunctionCalls.lastOrNull()?.calleeReference?.name?.let {
|
label = context.firLabels.pop() ?: context.firFunctionCalls.lastOrNull()?.calleeReference?.name?.let {
|
||||||
FirLabelImpl(expression, it.asString())
|
FirLabelImpl(expression, it.asString())
|
||||||
}
|
}
|
||||||
val bodyExpression = literal.bodyExpression.toFirExpression("Lambda has no body")
|
val bodyExpression = literal.bodyExpression.toFirExpression("Lambda has no body")
|
||||||
@@ -622,7 +624,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
FirSingleExpressionBlock(bodyExpression.toReturn())
|
FirSingleExpressionBlock(bodyExpression.toReturn())
|
||||||
}
|
}
|
||||||
|
|
||||||
firFunctions.removeLast()
|
context.firFunctions.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,12 +644,12 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
delegatedSelfTypeRef,
|
delegatedSelfTypeRef,
|
||||||
getDelegationCall().convert(delegatedSuperTypeRef, delegatedSelfTypeRef, hasPrimaryConstructor)
|
getDelegationCall().convert(delegatedSuperTypeRef, delegatedSelfTypeRef, hasPrimaryConstructor)
|
||||||
)
|
)
|
||||||
firFunctions += firConstructor
|
this@RawFirBuilder.context.firFunctions += firConstructor
|
||||||
extractAnnotationsTo(firConstructor)
|
extractAnnotationsTo(firConstructor)
|
||||||
firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
firConstructor.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||||
extractValueParametersTo(firConstructor)
|
extractValueParametersTo(firConstructor)
|
||||||
firConstructor.body = buildFirBody()
|
firConstructor.body = buildFirBody()
|
||||||
firFunctions.removeLast()
|
this@RawFirBuilder.context.firFunctions.removeLast()
|
||||||
return firConstructor
|
return firConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,7 +1038,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
private fun FirLoopJump.bindLabel(expression: KtExpressionWithLabel): FirLoopJump {
|
private fun FirLoopJump.bindLabel(expression: KtExpressionWithLabel): FirLoopJump {
|
||||||
val labelName = expression.getLabelName()
|
val labelName = expression.getLabelName()
|
||||||
target = FirLoopTarget(labelName)
|
target = FirLoopTarget(labelName)
|
||||||
val lastLoop = firLoops.lastOrNull()
|
val lastLoop = context.firLoops.lastOrNull()
|
||||||
if (labelName == null) {
|
if (labelName == null) {
|
||||||
if (lastLoop != null) {
|
if (lastLoop != null) {
|
||||||
target.bind(lastLoop)
|
target.bind(lastLoop)
|
||||||
@@ -1044,7 +1046,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
target.bind(FirErrorLoop(psi, "Cannot bind unlabeled jump to a loop"))
|
target.bind(FirErrorLoop(psi, "Cannot bind unlabeled jump to a loop"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (firLoop in firLoops.asReversed()) {
|
for (firLoop in context.firLoops.asReversed()) {
|
||||||
if (firLoop.label?.name == labelName) {
|
if (firLoop.label?.name == labelName) {
|
||||||
target.bind(firLoop)
|
target.bind(firLoop)
|
||||||
return this
|
return this
|
||||||
@@ -1178,12 +1180,12 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.calleeReference = calleeReference
|
this.calleeReference = calleeReference
|
||||||
firFunctionCalls += this
|
context.firFunctionCalls += this
|
||||||
expression.extractArgumentsTo(this)
|
expression.extractArgumentsTo(this)
|
||||||
for (typeArgument in expression.typeArguments) {
|
for (typeArgument in expression.typeArguments) {
|
||||||
typeArguments += typeArgument.convert<FirTypeProjection>()
|
typeArguments += typeArgument.convert<FirTypeProjection>()
|
||||||
}
|
}
|
||||||
firFunctionCalls.removeLast()
|
context.firFunctionCalls.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1229,13 +1231,13 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
|
|||||||
|
|
||||||
override fun visitLabeledExpression(expression: KtLabeledExpression, data: Unit): FirElement {
|
override fun visitLabeledExpression(expression: KtLabeledExpression, data: Unit): FirElement {
|
||||||
val labelName = expression.getLabelName()
|
val labelName = expression.getLabelName()
|
||||||
val size = firLabels.size
|
val size = context.firLabels.size
|
||||||
if (labelName != null) {
|
if (labelName != null) {
|
||||||
firLabels += FirLabelImpl(expression, labelName)
|
context.firLabels += FirLabelImpl(expression, labelName)
|
||||||
}
|
}
|
||||||
val result = expression.baseExpression?.accept(this, data) ?: FirErrorExpressionImpl(expression, "Empty label")
|
val result = expression.baseExpression?.accept(this, data) ?: FirErrorExpressionImpl(expression, "Empty label")
|
||||||
if (size != firLabels.size) {
|
if (size != context.firLabels.size) {
|
||||||
firLabels.removeLast()
|
context.firLabels.removeLast()
|
||||||
println("Unused label: ${expression.text}")
|
println("Unused label: ${expression.text}")
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user