Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3870503

Browse files
committed
Java 12: add QL for switch expressions, etc
1 parent 6ac1ee5 commit 3870503

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

java/ql/src/semmle/code/java/Expr.qll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,33 @@ class ConditionalExpr extends Expr, @conditionalexpr {
10931093
override string toString() { result = "...?...:..." }
10941094
}
10951095

1096+
/** A `switch` expression. */
1097+
class SwitchExpr extends Expr, @switchexpr {
1098+
/** Gets an immediate child statement of this `switch` expression. */
1099+
Stmt getAStmt() { result.getParent() = this }
1100+
1101+
/**
1102+
* Gets the immediate child statement of this `switch` expression
1103+
* that occurs at the specified (zero-based) position.
1104+
*/
1105+
Stmt getStmt(int index) { result = this.getAStmt() and result.getIndex() = index }
1106+
1107+
/**
1108+
* Gets a case of this `switch` expression,
1109+
* which may be either a normal `case` or a `default`.
1110+
*/
1111+
SwitchCase getACase() { result = getAConstCase() or result = getDefaultCase() }
1112+
1113+
/** Gets a (non-default) `case` of this `switch` expression. */
1114+
ConstCase getAConstCase() { result.getParent() = this }
1115+
1116+
/** Gets the `default` case of this switch expression, if any. */
1117+
DefaultCase getDefaultCase() { result.getParent() = this }
1118+
1119+
/** Gets the expression of this `switch` expression. */
1120+
Expr getExpr() { result.getParent() = this }
1121+
}
1122+
10961123
/** A parenthesised expression. */
10971124
class ParExpr extends Expr, @parexpr {
10981125
/** Gets the expression inside the parentheses. */

java/ql/src/semmle/code/java/Statement.qll

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,23 +400,43 @@ class SwitchStmt extends Stmt, @switchstmt {
400400
}
401401

402402
/**
403-
* A case of a `switch` statement.
403+
* A case of a `switch` statement or expression.
404404
*
405405
* This includes both normal `case`s and the `default` case.
406406
*/
407407
class SwitchCase extends Stmt, @case {
408+
/** Gets the switch statement to which this case belongs, if any. */
408409
SwitchStmt getSwitch() { result.getACase() = this }
410+
411+
/** Gets the switch expression to which this case belongs, if any. */
412+
SwitchExpr getSwitchExpr() { result.getACase() = this }
413+
414+
/** Holds if this `case` is a switch labeled rule of the form `... -> ...`. */
415+
predicate isRule() {
416+
exists(Expr e | e.getParent() = this | e.getIndex() = -1)
417+
or
418+
exists(Stmt s | s.getParent() = this | s.getIndex() = -1)
419+
}
409420
}
410421

411422
/** A constant `case` of a switch statement. */
412423
class ConstCase extends SwitchCase {
413424
ConstCase() { exists(Expr e | e.getParent() = this | e.getIndex() >= 0) }
414425

415-
/** Gets the expression of this `case`. */
426+
/** Gets the `case` constant at index 0. */
416427
Expr getValue() { result.getParent() = this and result.getIndex() = 0 }
417428

429+
/** Gets the `case` constant at the specified index. */
430+
Expr getValue(int i) { result.getParent() = this and result.getIndex() = i and i >= 0 }
431+
432+
/** Gets the expression on the right-hand side of the arrow, if any. */
433+
Expr getRuleExpression() { result.getParent() = this and result.getIndex() = -1 }
434+
435+
/** Gets the statement on the right-hand side of the arrow, if any. */
436+
Stmt getRuleStatement() { result.getParent() = this and result.getIndex() = -1 }
437+
418438
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
419-
override string pp() { result = "case ...:" }
439+
override string pp() { result = "case ..." }
420440

421441
/** This statement's Halstead ID (used to compute Halstead metrics). */
422442
override string getHalsteadID() { result = "ConstCase" }
@@ -552,9 +572,17 @@ class BreakStmt extends Stmt, @breakstmt {
552572
/** Holds if this `break` statement has an explicit label. */
553573
predicate hasLabel() { exists(string s | s = this.getLabel()) }
554574

575+
/** Gets the value of this `break` statement, if any. */
576+
Expr getValue() { result.getParent() = this }
577+
578+
/** Holds if this `break` statement has a value. */
579+
predicate hasValue() { exists(Expr e | e.getParent() = this) }
580+
555581
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
556582
override string pp() {
557-
if this.hasLabel() then result = "break " + this.getLabel() else result = "break"
583+
if this.hasLabel()
584+
then result = "break " + this.getLabel()
585+
else (if this.hasValue() then result = "break ..." else result = "break")
558586
}
559587

560588
/** This statement's Halstead ID (used to compute Halstead metrics). */

0 commit comments

Comments
 (0)