Rust: add some toString implementations#18035
Conversation
Also make `--learn` work with the nested qltest tests.
rust/ql/lib/codeql/rust/elements.qll
Outdated
Check warning
Code scanning / CodeQL
Redundant import
rust/ql/lib/codeql/rust/elements.qll
Outdated
Check warning
Code scanning / CodeQL
Redundant import
|
|
||
| private import internal.LoopingExprImpl | ||
| import codeql.rust.elements.BlockExpr | ||
| import codeql.rust.elements.LabelableExpr |
Check warning
Code scanning / CodeQL
Redundant import
| class LiteralExpr extends Generated::LiteralExpr { | ||
| override string toString() { result = this.getTextValue() } | ||
|
|
||
| override string toAbbreviatedString() { result = this.getTextValue() } |
There was a problem hiding this comment.
I now thought we might want to trim long literals here
| | variables.rs:332:9:332:9 | v | variables.rs:332:13:332:41 | RefExpr | | ||
| | variables.rs:155:9:155:10 | p2 | variables.rs:155:14:155:37 | Point {...} | | ||
| | variables.rs:169:9:169:11 | msg | variables.rs:169:15:169:38 | Message::Hello {...} | | ||
| | variables.rs:189:9:189:14 | either | variables.rs:189:18:189:33 | Either::Left(...) | |
There was a problem hiding this comment.
I'm probably not the right person to review the extractor changes right now but I will say this: these look good, much better than before.
hvitved
left a comment
There was a problem hiding this comment.
Thanks a lot for taking on this task! My main concern is that ideally toString should not be recursive, since (a) it takes longer to evaluate, (b) the DIL becomes more complex, and (c) it prevents magic sets optimizations.
| ) | ||
| } | ||
|
|
||
| override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } |
There was a problem hiding this comment.
May as well use strictconcat.
| class CastExpr extends Generated::CastExpr { } | ||
| class CastExpr extends Generated::CastExpr { | ||
| override string toString() { | ||
| result = this.getExpr().toAbbreviatedString() + " as " + this.getTy().toString() |
There was a problem hiding this comment.
We should avoid, if possible, to make toString recursive. Could we instead have a predicate, getName, on TypeRef?
| private string toStringPart(int index) { | ||
| index = 0 and result = "continue" | ||
| or | ||
| index = 1 and result = this.getLifetime().toString() |
There was a problem hiding this comment.
Again, better if we can avoid recursion.
| */ | ||
| class Enum extends Generated::Enum { } | ||
| class Enum extends Generated::Enum { | ||
| override string toString() { result = "enum " + this.getName().toString() } |
There was a problem hiding this comment.
getText instead of toString.
| override string toString() { | ||
| exists(string abbr, string name | | ||
| abbr = this.getExpr().toAbbreviatedString() and | ||
| name = this.getNameRef().toString() and |
There was a problem hiding this comment.
Again, better if we can avoid recursion.
| override string toString() { result = concat(int i | | this.toStringPart(i) order by i) } | ||
|
|
||
| private string toStringPart(int index) { | ||
| index = 0 and result = this.getNameRef().toString() |
| */ | ||
| class RecordExpr extends Generated::RecordExpr { } | ||
| class RecordExpr extends Generated::RecordExpr { | ||
| override string toString() { result = this.getPath().toString() + " {...}" } |
| */ | ||
| class RecordPat extends Generated::RecordPat { } | ||
| class RecordPat extends Generated::RecordPat { | ||
| override string toString() { result = this.getPath().toString() + " {...}" } |
| */ | ||
| class Trait extends Generated::Trait { } | ||
| class Trait extends Generated::Trait { | ||
| override string toString() { result = "trait " + this.getName() } |
| */ | ||
| class Union extends Generated::Union { } | ||
| class Union extends Generated::Union { | ||
| override string toString() { result = "union " + this.getName().toString() } |
hvitved
left a comment
There was a problem hiding this comment.
Great work on making toString non-recursive, thanks!
This sets up better
toStringimplementations to give more meaningful test expectations and AST printing results.This is by no means systematic and complete. Most notably almost all type representations are still missing, and some less frequent
Exprs, but it should get us started.The strategy is to make
toStringas close as possible to the rust syntax, but...What is considered a "simple" subnode (causing it to be part of the parent
toString) can be tweaked by implementingtoAbbreviatedString(), which returns...by default. Currently simple subnodes are:_expressions and patternsThis means for example that
toString(i.e.source(...))x + ....) or statements (if cond {...})