FIR: Make LHS of FirVariableAssignment a FirExpression
This way references can even be resolved for erroneous assignments (e.g. function call, if expression, ... on LHS) ^KT-54648 Fixed
This commit is contained in:
committed by
Space Team
parent
e9b8d6db80
commit
ace47c06a5
+5
-4
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.expressions.explicitReceiver
|
||||
|
||||
@OptIn(DfaInternals::class)
|
||||
class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||
@@ -92,7 +93,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||
}
|
||||
|
||||
private fun getIdentifierBySymbol(flow: Flow, symbol: FirBasedSymbol<*>, fir: FirElement): Identifier {
|
||||
val expression = fir as? FirQualifiedAccess
|
||||
val expression = fir as? FirQualifiedAccessExpression ?: (fir as? FirVariableAssignment)?.lValue as? FirQualifiedAccessExpression
|
||||
// TODO: don't create receiver variables if not going to create the composed variable either?
|
||||
return Identifier(
|
||||
symbol,
|
||||
@@ -104,10 +105,10 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||
private fun createReal(flow: Flow, identifier: Identifier, originalFir: FirElement, stability: PropertyStability): RealVariable {
|
||||
val receiver: FirExpression?
|
||||
val isThisReference: Boolean
|
||||
val expression: FirQualifiedAccess? = when (originalFir) {
|
||||
val expression: FirQualifiedAccessExpression? = when (originalFir) {
|
||||
is FirQualifiedAccessExpression -> originalFir
|
||||
is FirWhenSubjectExpression -> originalFir.whenRef.value.subject as? FirQualifiedAccessExpression
|
||||
is FirVariableAssignment -> originalFir
|
||||
is FirVariableAssignment -> originalFir.unwrapLValue()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -162,7 +163,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||
property.receiverParameter != null -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.modality != Modality.FINAL -> {
|
||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return null
|
||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccessExpression)?.dispatchReceiver ?: return null
|
||||
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
||||
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
||||
when (val receiverFir = receiverSymbol.fir) {
|
||||
|
||||
+2
-4
@@ -5,9 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDoWhileLoop
|
||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.renderer.FirCallNoArgumentsRenderer
|
||||
@@ -55,7 +53,7 @@ fun CFGNode<*>.render(): String =
|
||||
CfgRenderer.renderAsCallableDeclarationString(fir)
|
||||
}"
|
||||
|
||||
is VariableAssignmentNode -> "Assignment: ${CfgRenderer.renderElementAsString(fir.lValue)}"
|
||||
is VariableAssignmentNode -> "Assignment: ${fir.calleeReference?.let(CfgRenderer::renderElementAsString)}"
|
||||
is FunctionCallNode -> "Function call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||
is DelegatedConstructorCallNode -> "Delegated constructor call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||
is StringConcatenationCallNode -> "String concatenation call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||
|
||||
@@ -40,10 +40,12 @@ val FirExpression.coneType: ConeKotlinType
|
||||
val FirElement.symbol: FirBasedSymbol<*>?
|
||||
get() = when (this) {
|
||||
is FirResolvable -> symbol
|
||||
is FirVariableAssignment -> unwrapLValue()?.symbol
|
||||
is FirDeclaration -> symbol
|
||||
is FirWhenSubjectExpression -> whenRef.value.subject?.symbol
|
||||
is FirSafeCallExpression -> selector.symbol
|
||||
is FirSmartCastExpression -> originalExpression.symbol
|
||||
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.symbol
|
||||
else -> null
|
||||
}?.takeIf {
|
||||
(this as? FirExpression)?.unwrapSmartcastExpression() is FirThisReceiverExpression ||
|
||||
|
||||
-4
@@ -138,10 +138,6 @@ object ConeVariableExpectedError : ConeDiagnostic {
|
||||
override val reason: String get() = "Variable expected"
|
||||
}
|
||||
|
||||
class ConeValReassignmentError(val variable: FirVariableSymbol<*>) : ConeDiagnostic {
|
||||
override val reason: String get() = "Re-assigning a val variable"
|
||||
}
|
||||
|
||||
class ConeContractDescriptionError(override val reason: String) : ConeDiagnostic
|
||||
|
||||
class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic {
|
||||
|
||||
Reference in New Issue
Block a user