Skip to content

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

Merged
merged 3 commits into from
Apr 25, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Java: Make JumpStmt a concrete class again
Public abstract classes can be error-prone, when users unintentionally
implement a new subclass instead of refining the set of existing subclasses.
  • Loading branch information
Marcono1234 committed Apr 10, 2022
commit 348a186df89b0ffc0c9997a9e8a9af613bf1ab33
5 changes: 4 additions & 1 deletion java/ql/lib/semmle/code/java/Statement.qll
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,11 @@ class ThrowStmt extends Stmt, @throwstmt {
override string getAPrimaryQlClass() { result = "ThrowStmt" }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally try to avoid exposing public abstract classes like this, since subclassing using extends can lead to surprising results. It is better to define the union type explicitly:

Suggested change
private class JumpStmt_ = @breakstmt or @yieldstmt or @continuestmt;

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

// Workaround to avoid having to make JumpStmt abstract
private class JumpStmt_ = @breakstmt or @yieldstmt or @continuestmt;

/** A `break`, `yield` or `continue` statement. */
abstract class JumpStmt extends Stmt {
class JumpStmt extends Stmt, JumpStmt_ {
/**
* Gets the labeled statement that this `break` or
* `continue` statement refers to, if any.
Expand Down