[Analysis API FIR] fix KtSymbol creation for _ destructuring parameter

We need to have a corresponding declaration in the FIR tree,
so we can create a symbol for it

^KT-60904 fixed
^KT-60904 fixed
This commit is contained in:
Ilya Kirillov
2023-08-15 18:52:46 +02:00
committed by Space Team
parent 04b9faf9e6
commit c963eadb44
36 changed files with 431 additions and 11 deletions
@@ -26,11 +26,13 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.AbstractTypeChecker
object FirDestructuringDeclarationChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val source = declaration.source ?: return
if (declaration.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return
// val (...) = `destructuring_declaration`
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) {
checkInitializer(source, declaration.initializer, reporter, context)
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.isCatchParameter
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.name.SpecialNames
object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -55,7 +56,10 @@ object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
isSingleUnderscoreAllowed: Boolean = false
) {
val declarationSource = declaration.source
if (declarationSource != null && declarationSource.kind !is KtFakeSourceElementKind) {
if (declarationSource != null &&
declarationSource.kind !is KtFakeSourceElementKind &&
(declaration as? FirProperty)?.name != SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
) {
with(SourceNavigator.forElement(declaration)) {
val rawName = declaration.getRawName()
if (rawName?.isUnderscore == true && !(isSingleUnderscoreAllowed && rawName == "_")) {
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isBasicFunctionType
import org.jetbrains.kotlin.name.SpecialNames
object UnusedChecker : AbstractFirPropertyInitializationChecker() {
override fun analyze(data: PropertyInitializationInfoData, reporter: DiagnosticReporter, context: CheckerContext) {
@@ -62,6 +63,7 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
val variableSymbol = node.fir.symbol
if (node.fir.source == null) return
if (variableSymbol.isLoopIterator) return
if (variableSymbol.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return
val dataPerNode = data[node] ?: return
val data = dataPerNode.values.mapNotNull { it[variableSymbol] }.reduceOrNull { acc, it -> acc.merge(it) }
@@ -251,6 +251,9 @@ class Fir2IrVisitor(
for (statement in script.statements) {
val irStatement = if (statement is FirDeclaration) {
when {
statement is FirProperty && statement.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR -> {
continue
}
statement is FirProperty && statement.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> {
// Generating the result property only for expressions with a meaningful result type
// otherwise skip the property and convert the expression into the statement
@@ -820,6 +823,7 @@ class Fir2IrVisitor(
}
if (this is FirContractCallBlock) return null
if (this is FirBlock) return convertToIrExpression(this)
if (this is FirProperty && name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return null
return accept(this@Fir2IrVisitor, null) as IrStatement
}
@@ -1390,8 +1390,11 @@ class LightTreeRawFirDeclarationBuilder(
}
}
if (identifier == "_") return null
val name = identifier.nameAsSafeName()
val name = if (identifier == "_") {
SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
} else {
identifier.nameAsSafeName()
}
return buildProperty {
source = entry.toFirSourceElement()
moduleData = baseModuleData
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.*
internal fun KtWhenCondition.toFirWhenCondition(
@@ -135,9 +136,12 @@ internal fun generateDestructuringBlock(
}
val isVar = multiDeclaration.isVar
for ((index, entry) in multiDeclaration.entries.withIndex()) {
if (entry.nameIdentifier?.text == "_") continue
val name = if (entry.nameIdentifier?.text == "_") {
SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
} else {
entry.nameAsSafeName
}
val entrySource = entry.toKtPsiSourceElement()
val name = entry.nameAsSafeName
statements += buildProperty {
source = entrySource
this.moduleData = moduleData
@@ -34,5 +34,6 @@ FILE: destructuring.kt
public? final? fun bar(some: Some): R|kotlin/Unit| {
lval <destruct>: <implicit> = some#
lval a: <implicit> = R|<local>/<destruct>|.component1#()
lval <unused var>: <implicit> = R|<local>/<destruct>|.component2#()
lval _: <implicit> = R|<local>/<destruct>|.component3#()
}
@@ -48,4 +48,5 @@ FILE: RedeclaredValsAndVars.fir.kt
lval <destruct>: R|A| = R|/A.A|()
lval _: R|kotlin/Int| = R|<local>/<destruct>|.R|/A.component1|()
lval <unused var>: R|kotlin/String| = R|<local>/<destruct>|.R|/A.component2|()
}