Skip to content
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

Rust/Swift: Make all public AST classes final #17444

Merged
merged 12 commits into from
Sep 16, 2024

Conversation

hvitved
Copy link
Contributor

@hvitved hvitved commented Sep 12, 2024

This PR changes the code generator used by Rust and Swift so that all public classes are final. Commit-by-commit review is strongly recommended.

Before this PR

An entry such as Expr in schema.py would give rise to two classes:

generated/Expr.qll

// generated, do not edit
module Generated {
   class Expr extends Synth::TExpr, AstNode { }
}

elements/Expr.qll

// generated, remove this comment if you wish to edit this file
class Expr extends Generated::Expr { }

Any customizations needed on Expr, such as the addition of new predicates or overriding of existing predicates, would be done in elements/Expr.qll and this would also be the public version of Expr.

After this PR

We want to avoid unintended predicate dispatch, i.e. make the public Expr class final. However, we cannot simply make the Expr class in elements/Expr.qll final, because other customization classes may want to extend it. This PR therefore adds an additional layer:

generated/Expr.qll

// generated, do not edit
module Generated {
   class Expr extends Synth::TExpr, Impl::AstNode { } // note the `Impl::` prefix
}

elements/ExprImpl.qll

// generated, remove this comment if you wish to edit this file
module Impl {
  class Expr extends Generated::Expr { }
}

elements/Expr.qll

// generated, do not edit
final class Expr = Impl::Expr;

Now the exposed Expr class is final, and all customizations are done in elements/ExprImpl.qll.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Sep 12, 2024
@hvitved hvitved force-pushed the rust/final-classes branch 3 times, most recently from 4be55f4 to 5c3eb4b Compare September 12, 2024 08:14
rust/ql/lib/codeql/rust/elements/Element.qll Fixed Show fixed Hide fixed
rust/ql/lib/codeql/rust/elements/File.qll Fixed Show fixed Hide fixed
rust/ql/lib/codeql/rust/elements/Location.qll Fixed Show fixed Hide fixed
rust/ql/lib/codeql/rust/generated/Element.qll Fixed Show fixed Hide fixed
@hvitved hvitved force-pushed the rust/final-classes branch 2 times, most recently from b3b0660 to 8a5ee7f Compare September 12, 2024 11:06
@hvitved hvitved force-pushed the rust/final-classes branch 4 times, most recently from e360f96 to 3481141 Compare September 13, 2024 12:33
@hvitved hvitved changed the title Rust: Make user-facing AST classes final Rust/Swift: Make all public AST classes final Sep 13, 2024
@github-actions github-actions bot added the Swift label Sep 13, 2024
*/

private import AvailabilityInfoImpl
import codeql.swift.elements.AstNode

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.swift.elements.AvailabilitySpec
.
private import KeyPathComponentImpl
import codeql.swift.elements.expr.Argument
import codeql.swift.elements.AstNode
import codeql.swift.elements.type.Type

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.swift.elements.decl.ValueDecl
.
result instanceof UnknownLocation
}
private import LocatableImpl
import codeql.swift.elements.Element

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.swift.elements.Location
.
}
}
private import LocationImpl
import codeql.swift.elements.Element

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.swift.elements.File
.
private import codeql.rust.generated.ElementListExpr
private import ElementListExprImpl
import codeql.rust.elements.ArrayExpr
import codeql.rust.elements.Expr

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.ArrayExpr
.
*/

private import codeql.rust.generated.MatchArm
private import MatchArmImpl
import codeql.rust.elements.AstNode

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.Expr
.
Redundant import, the module is already imported inside
codeql.rust.elements.Pat
.
*/

private import codeql.rust.generated.MatchExpr
private import MatchExprImpl
import codeql.rust.elements.Expr

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.MatchArm
.
*/

private import codeql.rust.generated.RecordExpr
private import RecordExprImpl
import codeql.rust.elements.Expr

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.RecordExprField
.
*/

private import codeql.rust.generated.RecordExprField
private import RecordExprFieldImpl
import codeql.rust.elements.AstNode

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.Expr
.
*/

private import codeql.rust.generated.RecordPat
private import RecordPatImpl
import codeql.rust.elements.Pat

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.RecordPatField
.
*/

private import codeql.rust.generated.RecordPatField
private import RecordPatFieldImpl
import codeql.rust.elements.AstNode

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.Pat
.
private import codeql.rust.generated.RepeatExpr
private import RepeatExprImpl
import codeql.rust.elements.ArrayExpr
import codeql.rust.elements.Expr

Check warning

Code scanning / CodeQL

Redundant import Warning

Redundant import, the module is already imported inside
codeql.rust.elements.ArrayExpr
.
@hvitved hvitved force-pushed the rust/final-classes branch 3 times, most recently from 6b91a2e to ec9377f Compare September 16, 2024 09:35
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Sep 16, 2024
@hvitved hvitved marked this pull request as ready for review September 16, 2024 12:06
@hvitved hvitved requested a review from a team as a code owner September 16, 2024 12:06
@redsun82
Copy link
Contributor

// generated, remove this comment if you wish to edit this file
module {
  class Expr extends Generated::Expr { }
}

meta-review comment: a module Generated is missing in the PR description there 😆

misc/codegen/lib/ql.py Outdated Show resolved Hide resolved
@hvitved
Copy link
Contributor Author

hvitved commented Sep 16, 2024

meta-review comment: a module Generated is missing in the PR description there 😆

Thanks; actually it should be module Impl.

redsun82
redsun82 previously approved these changes Sep 16, 2024
Copy link
Contributor

@redsun82 redsun82 left a comment

Choose a reason for hiding this comment

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

I really like this, thanks for the hard work!

I think we should move all stubs to a separate directory (impl or internal), but I saw on slack you agree with this for a follow-up PR, so I'm perfectly happy with that.

@@ -1,4 +1,4 @@
# configuration file for Swift code generation default options
# configuration file for Rust code generation default options
Copy link
Contributor

Choose a reason for hiding this comment

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

well spotted! 😅

@redsun82
Copy link
Contributor

ah, that pesky autopep again 😅

Ah, forgot to mention, the Doc coverage failure is pretty normal, because the baseline situation (with uncovered defs) gets lost in the renames. I'm ok with ignoring it.

@redsun82 redsun82 self-assigned this Sep 16, 2024
Co-authored-by: Paolo Tranquilli <[email protected]>
@hvitved
Copy link
Contributor Author

hvitved commented Sep 16, 2024

Ah, forgot to mention, the Doc coverage failure is pretty normal, because the baseline situation (with uncovered defs) gets lost in the renames. I'm ok with ignoring it.

Yes, it was also my impression that this was because of the renamed files.

@redsun82 redsun82 merged commit d1704cf into github:main Sep 16, 2024
26 of 27 checks passed
@geoffw0
Copy link
Contributor

geoffw0 commented Sep 16, 2024

You've checked in a merge artifact CommandInjection.expected.orig. Could you do a follow-up to remove it please (I appreciate it's easy to miss stuff like this with so many other files touched by this PR).

Also why is no change note required for Swift - are we confident users can't or have been told they shouldn't be overriding these classes?

@hvitved
Copy link
Contributor Author

hvitved commented Sep 16, 2024

You've checked in a merge artifact CommandInjection.expected.orig. Could you do a follow-up to remove it please (I appreciate it's easy to miss stuff like this with so many other files touched by this PR).

Yes, sorry, thanks for noticing.

Also why is no change note required for Swift - are we confident users can't or have been told they shouldn't be overriding these classes?

I'll add a change note.

@hvitved hvitved deleted the rust/final-classes branch September 16, 2024 17:27
@hvitved hvitved mentioned this pull request Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code Swift
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants