RAW FIR: record annotations on destructuring declarations

This commit is contained in:
Jinseong Jeon
2021-09-24 14:02:05 -07:00
committed by TeamCityServer
parent 464eecef03
commit 8f3b06ac06
7 changed files with 91 additions and 10 deletions
@@ -1 +1,3 @@
null KtAnnotationCall:
argumentMapping = { "UNCHECKED_CAST" -> (vararg names: kotlin.String) }
targetFunction = <constructor>(vararg names: kotlin.String): kotlin.Suppress
@@ -1188,12 +1188,14 @@ class DeclarationsConverter(
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitDestructuringDeclaration * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitDestructuringDeclaration
*/ */
private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration { private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration {
var modifiers = Modifier()
var isVar = false var isVar = false
val entries = mutableListOf<FirVariable?>() val entries = mutableListOf<FirVariable?>()
val source = destructingDeclaration.toFirSourceElement() val source = destructingDeclaration.toFirSourceElement()
var firExpression: FirExpression? = null var firExpression: FirExpression? = null
destructingDeclaration.forEachChildren { destructingDeclaration.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
MODIFIER_LIST -> modifiers = convertModifierList(it)
VAR_KEYWORD -> isVar = true VAR_KEYWORD -> isVar = true
DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it) DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it)
else -> if (it.isExpression()) firExpression = else -> if (it.isExpression()) firExpression =
@@ -1208,7 +1210,8 @@ class DeclarationsConverter(
null, null,
ConeSimpleDiagnostic("Initializer required for destructuring declaration", DiagnosticKind.Syntax) ConeSimpleDiagnostic("Initializer required for destructuring declaration", DiagnosticKind.Syntax)
), ),
source source,
modifiers
) )
} }
@@ -11,15 +11,23 @@ import org.jetbrains.kotlin.fir.builder.generateTemporaryVariable
import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.lightTree.converter.generateDestructuringBlock import org.jetbrains.kotlin.fir.lightTree.converter.generateDestructuringBlock
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
data class DestructuringDeclaration( data class DestructuringDeclaration(
val isVar: Boolean, val isVar: Boolean,
val entries: List<FirVariable?>, val entries: List<FirVariable?>,
val initializer: FirExpression, val initializer: FirExpression,
val source: FirSourceElement val source: FirSourceElement,
val modifier: Modifier,
) { ) {
fun toFirDestructingDeclaration(moduleData: FirModuleData): FirExpression { fun toFirDestructingDeclaration(moduleData: FirModuleData): FirExpression {
val baseVariable = generateTemporaryVariable(moduleData, source, "destruct", initializer) val baseVariable = generateTemporaryVariable(
moduleData,
source,
"destruct",
initializer,
modifier.annotations
)
return generateDestructuringBlock(moduleData, this, baseVariable, tmpVariable = true) return generateDestructuringBlock(moduleData, this, baseVariable, tmpVariable = true)
} }
} }
@@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
internal fun KtWhenCondition.toFirWhenCondition( internal fun KtWhenCondition.toFirWhenCondition(
@@ -81,6 +83,46 @@ internal fun Array<KtWhenCondition>.toFirWhenCondition(
return firCondition!! return firCondition!!
} }
internal fun generateTemporaryVariable(
moduleData: FirModuleData,
source: FirSourceElement?,
name: Name,
initializer: FirExpression,
typeRef: FirTypeRef? = null,
extractAnnotationsTo: (KtAnnotated.(FirAnnotationContainerBuilder) -> Unit),
): FirVariable =
buildProperty {
this.source = source
this.moduleData = moduleData
origin = FirDeclarationOrigin.Source
returnTypeRef = typeRef ?: buildImplicitTypeRef {
this.source = source
}
this.name = name
this.initializer = initializer
symbol = FirPropertySymbol(name)
isVar = false
isLocal = true
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
(source.psi as? KtAnnotated)?.extractAnnotationsTo(this)
}
internal fun generateTemporaryVariable(
moduleData: FirModuleData,
source: FirSourceElement?,
specialName: String,
initializer: FirExpression,
extractAnnotationsTo: (KtAnnotated.(FirAnnotationContainerBuilder) -> Unit),
): FirVariable =
generateTemporaryVariable(
moduleData,
source,
Name.special("<$specialName>"),
initializer,
null,
extractAnnotationsTo,
)
internal fun generateDestructuringBlock( internal fun generateDestructuringBlock(
moduleData: FirModuleData, moduleData: FirModuleData,
multiDeclaration: KtDestructuringDeclaration, multiDeclaration: KtDestructuringDeclaration,
@@ -2368,8 +2368,11 @@ open class RawFirBuilder(
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Unit): FirElement { override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Unit): FirElement {
val baseVariable = generateTemporaryVariable( val baseVariable = generateTemporaryVariable(
baseModuleData, multiDeclaration.toFirSourceElement(), "destruct", baseModuleData,
multiDeclaration.toFirSourceElement(),
"destruct",
multiDeclaration.initializer.toFirExpression("Initializer required for destructuring declaration", DiagnosticKind.Syntax), multiDeclaration.initializer.toFirExpression("Initializer required for destructuring declaration", DiagnosticKind.Syntax),
extractAnnotationsTo = { extractAnnotationsTo(it) }
) )
return generateDestructuringBlock( return generateDestructuringBlock(
baseModuleData, baseModuleData,
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -279,7 +280,12 @@ fun generateResolvedAccessExpression(source: FirSourceElement?, variable: FirVar
} }
fun generateTemporaryVariable( fun generateTemporaryVariable(
moduleData: FirModuleData, source: FirSourceElement?, name: Name, initializer: FirExpression, typeRef: FirTypeRef? = null, moduleData: FirModuleData,
source: FirSourceElement?,
name: Name,
initializer: FirExpression,
typeRef: FirTypeRef? = null,
extractedAnnotations: Collection<FirAnnotation>? = null,
): FirVariable = ): FirVariable =
buildProperty { buildProperty {
this.source = source this.source = source
@@ -294,11 +300,28 @@ fun generateTemporaryVariable(
isVar = false isVar = false
isLocal = true isLocal = true
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL) status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
if (extractedAnnotations != null) {
// LT extracts annotations ahead.
// PSI extracts annotations on demand. Use a similar util in [PsiConversionUtils]
annotations.addAll(extractedAnnotations)
}
} }
fun generateTemporaryVariable( fun generateTemporaryVariable(
moduleData: FirModuleData, source: FirSourceElement?, specialName: String, initializer: FirExpression, moduleData: FirModuleData,
): FirVariable = generateTemporaryVariable(moduleData, source, Name.special("<$specialName>"), initializer) source: FirSourceElement?,
specialName: String,
initializer: FirExpression,
extractedAnnotations: Collection<FirAnnotation>? = null,
): FirVariable =
generateTemporaryVariable(
moduleData,
source,
Name.special("<$specialName>"),
initializer,
null,
extractedAnnotations,
)
val FirClassBuilder.ownerRegularOrAnonymousObjectSymbol val FirClassBuilder.ownerRegularOrAnonymousObjectSymbol
get() = when (this) { get() = when (this) {
@@ -4,6 +4,6 @@ data class Pair(val x: Int, val y: Int)
fun foo(): Int { fun foo(): Int {
@Ann val (a, b) = Pair(12, 34) @Ann val (a, b) = Pair(12, 34)
@Err val (c, d) = Pair(56, 78) @<!UNRESOLVED_REFERENCE!>Err<!> val (c, d) = Pair(56, 78)
return a + b + c + d return a + b + c + d
} }