-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: Make JumpStmt
a proper superclass
#8582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
category: fix | ||
--- | ||
* The QL class `JumpStmt` has been made the superclass of `BreakStmt`, `ContinueStmt` and `YieldStmt`. This allows directly using its inherited predicates without having to explicitly cast to `JumpStmt` first. |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -556,14 +556,10 @@ class ThrowStmt extends Stmt, @throwstmt { | |||||||||
override string getAPrimaryQlClass() { result = "ThrowStmt" } | ||||||||||
} | ||||||||||
|
||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We generally try to avoid exposing public
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, thanks! I have implemented your suggestion manually, and added a small comment explaining the rationale; hopefully that is alright. A bit unrelated, but I have created a #8713 to discuss making implementing abstract classes less error-prone. |
||||||||||
/** A `break`, `yield` or `continue` statement. */ | ||||||||||
class JumpStmt extends Stmt { | ||||||||||
JumpStmt() { | ||||||||||
this instanceof BreakStmt or | ||||||||||
this instanceof YieldStmt or | ||||||||||
this instanceof ContinueStmt | ||||||||||
} | ||||||||||
private class JumpStmt_ = @breakstmt or @yieldstmt or @continuestmt; | ||||||||||
|
||||||||||
/** A `break`, `yield` or `continue` statement. */ | ||||||||||
class JumpStmt extends Stmt, JumpStmt_ { | ||||||||||
/** | ||||||||||
* Gets the labeled statement that this `break` or | ||||||||||
* `continue` statement refers to, if any. | ||||||||||
|
@@ -584,12 +580,7 @@ class JumpStmt extends Stmt { | |||||||||
) | ||||||||||
} | ||||||||||
|
||||||||||
private SwitchExpr getSwitchExprTarget() { result = this.(YieldStmt).getParent+() } | ||||||||||
|
||||||||||
private StmtParent getEnclosingTarget() { | ||||||||||
result = this.getSwitchExprTarget() | ||||||||||
or | ||||||||||
not exists(this.getSwitchExprTarget()) and | ||||||||||
result = this.getAPotentialTarget() and | ||||||||||
not exists(Stmt other | other = this.getAPotentialTarget() | other.getEnclosingStmt+() = result) | ||||||||||
} | ||||||||||
|
@@ -598,14 +589,15 @@ class JumpStmt extends Stmt { | |||||||||
* Gets the statement or `switch` expression that this `break`, `yield` or `continue` jumps to. | ||||||||||
*/ | ||||||||||
StmtParent getTarget() { | ||||||||||
// Note: This implementation only considers `break` and `continue`; YieldStmt overrides this predicate | ||||||||||
result = this.getLabelTarget() | ||||||||||
or | ||||||||||
not exists(this.getLabelTarget()) and result = this.getEnclosingTarget() | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
/** A `break` statement. */ | ||||||||||
class BreakStmt extends Stmt, @breakstmt { | ||||||||||
class BreakStmt extends JumpStmt, @breakstmt { | ||||||||||
/** Gets the label targeted by this `break` statement, if any. */ | ||||||||||
string getLabel() { namestrings(result, _, this) } | ||||||||||
|
||||||||||
|
@@ -626,12 +618,21 @@ class BreakStmt extends Stmt, @breakstmt { | |||||||||
/** | ||||||||||
* A `yield` statement. | ||||||||||
*/ | ||||||||||
class YieldStmt extends Stmt, @yieldstmt { | ||||||||||
class YieldStmt extends JumpStmt, @yieldstmt { | ||||||||||
/** | ||||||||||
* Gets the value of this `yield` statement. | ||||||||||
*/ | ||||||||||
Expr getValue() { result.getParent() = this } | ||||||||||
|
||||||||||
/** | ||||||||||
* Gets the `switch` expression target of this `yield` statement. | ||||||||||
*/ | ||||||||||
override SwitchExpr getTarget() { | ||||||||||
// Get the innermost enclosing SwitchExpr; this works because getParent() is defined for Stmt and | ||||||||||
// therefore won't proceed after the innermost SwitchExpr (due to it being an Expr) | ||||||||||
result = this.getParent+() | ||||||||||
} | ||||||||||
|
||||||||||
override string pp() { result = "yield ..." } | ||||||||||
|
||||||||||
override string toString() { result = "yield ..." } | ||||||||||
|
@@ -642,7 +643,7 @@ class YieldStmt extends Stmt, @yieldstmt { | |||||||||
} | ||||||||||
|
||||||||||
/** A `continue` statement. */ | ||||||||||
class ContinueStmt extends Stmt, @continuestmt { | ||||||||||
class ContinueStmt extends JumpStmt, @continuestmt { | ||||||||||
/** Gets the label targeted by this `continue` statement, if any. */ | ||||||||||
string getLabel() { namestrings(result, _, this) } | ||||||||||
|
||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,14 @@ | ||
| stmts/A.java:6:3:6:10 | case ... | | ||
| stmts/A.java:8:3:8:10 | case ... | | ||
| stmts/A.java:10:3:10:10 | default | | ||
| stmts/A.java:17:4:17:12 | case ... | | ||
| stmts/A.java:20:4:20:12 | case ... | | ||
| stmts/A.java:21:5:21:13 | case ... | | ||
| stmts/A.java:24:5:24:14 | default | | ||
| stmts/A.java:28:4:28:12 | case ... | | ||
| stmts/A.java:29:4:29:13 | default | | ||
| stmts/A.java:32:6:32:14 | case ... | | ||
| stmts/A.java:33:6:33:14 | case ... | | ||
| stmts/B.java:21:5:21:12 | case ... | | ||
| stmts/B.java:23:5:23:12 | case ... | | ||
| stmts/B.java:25:5:25:12 | case ... | |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
//semmle-extractor-options: --javac-args -source 14 -target 14 |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really a "fix", but the other categories do not seem to fit much better either. Maybe it should be "feature"?