Skip to content

Commit db9105d

Browse files
vlad20012yopox
authored andcommitted
GRAM: pin if let and while let conditions
1 parent 266e103 commit db9105d

File tree

13 files changed

+60
-23
lines changed

13 files changed

+60
-23
lines changed

src/main/grammars/RustParser.bnf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,8 @@ WhileExpr ::= OuterAttr* LabelDecl? while Condition SimpleBlock {
11911191
"org.rust.lang.core.psi.ext.RsLooplikeExpr" ]
11921192
elementTypeFactory = "org.rust.lang.core.stubs.StubImplementationsKt.factory"
11931193
}
1194-
Condition ::= [ let TopPat '=' ] NoStructLitExpr
1194+
Condition ::= IfLetCondition | NoStructLitExpr
1195+
private IfLetCondition ::= let TopPat '=' NoStructLitExpr { pin = 1 }
11951196

11961197
LoopExpr ::= OuterAttr* LabelDecl? loop SimpleBlock {
11971198
pin = 'loop'

src/main/kotlin/org/rust/ide/inspections/RsMissingElseInspection.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ class RsMissingElseInspection : RsLocalInspectionTool() {
3232
.dropWhile { (it is PsiWhiteSpace || it is PsiComment) && '\n' !in it.text }
3333
.firstOrNull()
3434
.extractIf() ?: return
35-
val condition = nextIf.condition ?: return
35+
val conditionExpr = nextIf.condition?.expr ?: return
3636
val rangeStart = expr.startOffsetInParent + firstIf.textLength
37-
val rangeLen = condition.expr.startOffset - firstIf.startOffset - firstIf.textLength
37+
val rangeLen = conditionExpr.startOffset - firstIf.startOffset - firstIf.textLength
3838
holder.registerProblem(
3939
expr.parent,
4040
TextRange(rangeStart, rangeStart + rangeLen),

src/main/kotlin/org/rust/ide/inspections/RsRedundantElseInspection.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,13 @@ class RsRedundantElseInspection : RsLocalInspectionTool() {
5959
}
6060
private val RsCondition.isRedundant: Boolean
6161
get() {
62-
return patList?.all { pat -> pat.isIrrefutable } ?: (this.expr.evaluate().asBool() ?: false)
62+
val patList = patList
63+
return if (patList != null) {
64+
patList.all { pat -> pat.isIrrefutable }
65+
} else {
66+
val expr = expr ?: return false
67+
expr.evaluate().asBool() == true
68+
}
6369
}
6470
}
6571
}

src/main/kotlin/org/rust/ide/intentions/IfLetToMatchIntention.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class IfLetToMatchIntention : RsElementBaseIntentionAction<IfLetToMatchIntention
103103
val pat = condition.pat ?: return null
104104

105105
//3) Extract the target
106-
val target = condition.expr
106+
val target = condition.expr ?: return null
107107

108108
//4) Extract the if body
109109
val ifBody = iflet.block ?: return null

src/main/kotlin/org/rust/ide/intentions/InvertIfIntention.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import org.rust.lang.utils.negate
1515
class InvertIfIntention : RsElementBaseIntentionAction<InvertIfIntention.Context>() {
1616
data class Context(
1717
val ifExpr: RsIfExpr,
18-
val condition: RsCondition,
18+
val conditionExpr: RsExpr,
1919
val thenBlock: RsBlock,
2020
val elseBlock: RsBlock
2121
)
@@ -25,14 +25,15 @@ class InvertIfIntention : RsElementBaseIntentionAction<InvertIfIntention.Context
2525
val ifExpr = element.ancestorStrict<RsIfExpr>() ?: return null
2626
if (element != ifExpr.`if`) return null
2727
val condition = getSuitableCondition(ifExpr) ?: return null
28+
val conditionExpr = condition.expr ?: return null
2829
val thenBlock = ifExpr.block ?: return null
2930
val elseBlock = ifExpr.elseBranch?.block ?: return null
3031

31-
return Context(ifExpr, condition, thenBlock, elseBlock)
32+
return Context(ifExpr, conditionExpr, thenBlock, elseBlock)
3233
}
3334

3435
override fun invoke(project: Project, editor: Editor, ctx: Context) {
35-
val negatedCondition = ctx.condition.expr.negate() as? RsExpr ?: return
36+
val negatedCondition = ctx.conditionExpr.negate() as? RsExpr ?: return
3637

3738
val newIfExpr = RsPsiFactory(project).createIfElseExpression(negatedCondition, ctx.elseBlock, ctx.thenBlock)
3839
val replacedIfExpr = ctx.ifExpr.replace(newIfExpr) as RsIfExpr

src/main/kotlin/org/rust/ide/intentions/SplitIfIntention.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,34 @@ class SplitIfIntention : RsElementBaseIntentionAction<SplitIfIntention.Context>(
2323

2424
data class Context(
2525
val binaryOp: RsBinaryOp,
26-
val condition: RsCondition
26+
val operatorType: LogicOp,
27+
val conditionExpr: RsExpr,
28+
val ifExpr: RsIfExpr
2729
)
2830

2931
override fun findApplicableContext(project: Project, editor: Editor, element: PsiElement): Context? {
3032
val binExpr = element.ancestorStrict<RsBinaryExpr>() ?: return null
3133
if (binExpr.operatorType !is LogicOp) return null
32-
if (element.parent != binExpr.binaryOp) return null
34+
val binaryOp = binExpr.binaryOp
35+
val operatorType = binaryOp.operatorType as? LogicOp ?: return null
36+
if (element.parent != binaryOp) return null
3337
val condition = binExpr.findCondition() ?: return null
34-
return Context(binExpr.binaryOp, condition)
38+
if (condition.let != null) return null
39+
val conditionExpr = condition.skipParenExprDown() ?: return null
40+
val ifStatement = condition.ancestorOrSelf<RsIfExpr>() ?: return null
41+
return Context(binaryOp, operatorType, conditionExpr, ifStatement)
3542
}
3643

3744
override fun invoke(project: Project, editor: Editor, ctx: Context) {
38-
val (binaryOp, condition) = ctx
39-
val ifStatement = condition.ancestorOrSelf<RsIfExpr>() ?: return
45+
val (binaryOp, operatorType, conditionExpr, ifStatement) = ctx
4046
val thenBranch = ifStatement.block?.text ?: "{ }"
4147
val elseBranch = ifStatement.elseBranch?.text ?: ""
4248

43-
val conditionExpr = condition.skipParenExprDown()
4449
val leftCondition = leftPart(conditionExpr, binaryOp)
4550
val rightCondition = rightPart(conditionExpr, binaryOp)
46-
val generatedCode = when (binaryOp.operatorType) {
51+
val generatedCode = when (operatorType) {
4752
LogicOp.AND -> createAndAnd(leftCondition, rightCondition, thenBranch, elseBranch)
4853
LogicOp.OR -> createOrOr(leftCondition, rightCondition, thenBranch, elseBranch)
49-
else -> return
5054
}
5155

5256
val newIfStatement = RsPsiFactory(project).createExpression(generatedCode) as RsIfExpr

src/main/kotlin/org/rust/ide/surroundWith/expression/RsWithIfExpSurrounder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class RsWithIfExpSurrounder : RsExpressionSurrounderBase<RsIfExpr>() {
2525
RsPsiFactory(project).createExpression("if a {stmt;}") as RsIfExpr
2626

2727
override fun getWrappedExpression(expression: RsIfExpr): RsExpr =
28-
expression.condition!!.expr
28+
expression.condition!!.expr!!
2929

3030
override fun isApplicable(expression: RsExpr): Boolean =
3131
expression.type is TyBool

src/main/kotlin/org/rust/ide/surroundWith/expression/RsWithWhileExpSurrounder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class RsWithWhileExpSurrounder : RsExpressionSurrounderBase<RsWhileExpr>() {
2525
RsPsiFactory(project).createExpression("while a {stmt;}") as RsWhileExpr
2626

2727
override fun getWrappedExpression(expression: RsWhileExpr): RsExpr =
28-
expression.condition!!.expr
28+
expression.condition!!.expr!!
2929

3030
override fun isApplicable(expression: RsExpr): Boolean =
3131
expression.type is TyBool

src/main/kotlin/org/rust/ide/utils/ExprUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,5 @@ fun RsExpr.skipParenExprUp(): RsExpr {
9595
*
9696
* @return a child expression without parentheses.
9797
*/
98-
fun RsCondition.skipParenExprDown(): RsExpr =
99-
unwrapParenExprs(expr)
98+
fun RsCondition.skipParenExprDown(): RsExpr? =
99+
expr?.let { unwrapParenExprs(it) }

src/main/kotlin/org/rust/lang/core/dfa/ExprUseWalker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ class ExprUseWalker(private val delegate: Delegate, private val mc: MemoryCatego
375375
}
376376

377377
private fun walkCondition(condition: RsCondition) {
378-
val init = condition.expr
378+
val init = condition.expr ?: return
379379
walkExpr(init)
380380
val initCmt = mc.processExpr(init)
381381
for (pat in condition.patList.orEmpty()) {

0 commit comments

Comments
 (0)