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
*/
private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration {
var modifiers = Modifier()
var isVar = false
val entries = mutableListOf<FirVariable?>()
val source = destructingDeclaration.toFirSourceElement()
var firExpression: FirExpression? = null
destructingDeclaration.forEachChildren {
when (it.tokenType) {
MODIFIER_LIST -> modifiers = convertModifierList(it)
VAR_KEYWORD -> isVar = true
DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it)
else -> if (it.isExpression()) firExpression =
@@ -1208,7 +1210,8 @@ class DeclarationsConverter(
null,
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.expressions.FirExpression
import org.jetbrains.kotlin.fir.lightTree.converter.generateDestructuringBlock
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
data class DestructuringDeclaration(
val isVar: Boolean,
val entries: List<FirVariable?>,
val initializer: FirExpression,
val source: FirSourceElement
val source: FirSourceElement,
val modifier: Modifier,
) {
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)
}
}
@@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
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.*
internal fun KtWhenCondition.toFirWhenCondition(
@@ -81,6 +83,46 @@ internal fun Array<KtWhenCondition>.toFirWhenCondition(
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(
moduleData: FirModuleData,
multiDeclaration: KtDestructuringDeclaration,
@@ -2368,8 +2368,11 @@ open class RawFirBuilder(
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Unit): FirElement {
val baseVariable = generateTemporaryVariable(
baseModuleData, multiDeclaration.toFirSourceElement(), "destruct",
baseModuleData,
multiDeclaration.toFirSourceElement(),
"destruct",
multiDeclaration.initializer.toFirExpression("Initializer required for destructuring declaration", DiagnosticKind.Syntax),
extractAnnotationsTo = { extractAnnotationsTo(it) }
)
return generateDestructuringBlock(
baseModuleData,
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -279,7 +280,12 @@ fun generateResolvedAccessExpression(source: FirSourceElement?, variable: FirVar
}
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 =
buildProperty {
this.source = source
@@ -294,11 +300,28 @@ fun generateTemporaryVariable(
isVar = false
isLocal = true
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(
moduleData: FirModuleData, source: FirSourceElement?, specialName: String, initializer: FirExpression,
): FirVariable = generateTemporaryVariable(moduleData, source, Name.special("<$specialName>"), initializer)
moduleData: FirModuleData,
source: FirSourceElement?,
specialName: String,
initializer: FirExpression,
extractedAnnotations: Collection<FirAnnotation>? = null,
): FirVariable =
generateTemporaryVariable(
moduleData,
source,
Name.special("<$specialName>"),
initializer,
null,
extractedAnnotations,
)
val FirClassBuilder.ownerRegularOrAnonymousObjectSymbol
get() = when (this) {
@@ -4,6 +4,6 @@ data class Pair(val x: Int, val y: Int)
fun foo(): Int {
@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
}
}