KE2: Extract when expressions

This commit is contained in:
Tamas Vajk
2024-11-21 15:46:57 +01:00
parent 74ee483fa1
commit a2d90ed0c6
3 changed files with 177 additions and 29 deletions

View File

@@ -918,6 +918,7 @@ case @stmt.kind of
| 23 = @yieldstmt
| 24 = @errorstmt
| 25 = @whenbranch
| 26 = @whenbranchcondition
;
#keyset[parent,idx]
@@ -1047,6 +1048,25 @@ when_if(unique int id: @whenexpr ref);
/** Holds if this `when` branch was written as an `else` branch. */
when_branch_else(unique int id: @whenbranch ref);
/** Holds if this `when` branch condition has an expression. */
when_branch_condition_with_expr(
unique int id: @whenbranchcondition ref
);
/** Holds if this `when` branch condition has a range. */
when_branch_condition_with_range(
unique int id: @whenbranchcondition ref,
boolean isNegated: boolean ref
);
/** Holds if this `when` branch condition has a type pattern. */
when_branch_condition_with_pattern(
unique int id: @whenbranchcondition ref,
boolean isNegated: boolean ref,
int typeid: @type ref,
int kttypeid: @kt_type ref
);
@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref
@annotation = @declannotation | @typeannotation

View File

@@ -2566,16 +2566,37 @@ class WhenExpr extends Expr, StmtParent, @whenexpr {
override string getAPrimaryQlClass() { result = "WhenExpr" }
/** Gets the `i`th branch. */
WhenBranch getBranch(int i) { result.isNthChildOf(this, i) }
WhenBranch getBranch(int i) { result.isNthChildOf(this, i) and i >= 0 }
/** Holds if this was written as an `if` expression. */
predicate isIf() { when_if(this) }
/** Gets the expression of this `when` expression, if any. */
Expr getExpr() { result.isNthChildOf(this, -1) }
/** Gets the local variable declaration of this `when` expression, if any. */
LocalVariableDeclExpr getAVariableDeclExpr() { result.isNthChildOf(this, -1) }
}
/** A Kotlin `when` branch. */
class WhenBranch extends Stmt, @whenbranch {
/** Gets the condition of this branch. */
Expr getCondition() { result.isNthChildOf(this, 0) }
/**
* DEPRECATED: Use `getACondition` or `getCondition/1` instead.
*
* Gets the condition of this branch.
*/
deprecated Expr getCondition() {
result = this.getCondition(0).(WhenBranchConditionWithExpression).getExpression()
}
/** Gets the `i`th condition of this branch. */
WhenBranchCondition getCondition(int i) { i <= 0 and result.isNthChildOf(this, i) }
/** Gets a condition of this branch. */
WhenBranchCondition getACondition() { result = this.getCondition(_) }
/** Gets the guard applicable to this branch, if any. */
Expr getGuard() { result.isNthChildOf(this, 2) }
/** Gets the result of this branch. */
Stmt getRhs() { result.isNthChildOf(this, 1) }
@@ -2594,6 +2615,42 @@ class WhenBranch extends Stmt, @whenbranch {
override string getAPrimaryQlClass() { result = "WhenBranch" }
}
/** A Kotlin `when` branch condition. */
abstract class WhenBranchCondition extends Stmt, @whenbranchcondition { }
/** A Kotlin `when` branch condition with an expression. */
class WhenBranchConditionWithExpression extends WhenBranchCondition {
WhenBranchConditionWithExpression() { when_branch_condition_with_expr(this) }
/** Gets the expression of this branch condition. */
Expr getExpression() { result.isNthChildOf(this, 0) }
}
/** A Kotlin `when` branch condition with a range. */
class WhenBranchConditionWithRange extends WhenBranchCondition {
WhenBranchConditionWithRange() { when_branch_condition_with_range(this, _) }
/** Holds if this is a negated range condition. */
predicate isNegated() { when_branch_condition_with_range(this, true) }
/**
* Gets the range of this branch condition.
* Ranges are represented by calls to `operator fun <T : Comparable<T>> T.rangeTo(that: T): ClosedRange<T>`.
*/
MethodCall getRange() { result.isNthChildOf(this, 0) }
}
/** A Kotlin `when` branch condition with a pattern. */
class WhenBranchConditionWithPattern extends WhenBranchCondition {
WhenBranchConditionWithPattern() { when_branch_condition_with_pattern(this, _, _, _) }
/** Holds if this is a negated pattern condition. */
predicate isNegated() { when_branch_condition_with_pattern(this, true, _, _) }
/** Gets the type pattern of this branch condition. */
Type getType() { when_branch_condition_with_pattern(this, _, result, _) }
}
// TODO: This might need more cases. It might be better as a predicate
// on Stmt, overridden in each subclass.
private Expr getAResult(Stmt s) {