-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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: add some toString
implementations
#18035
Conversation
Also make `--learn` work with the nested qltest tests.
import codeql.rust.elements.Item | ||
import codeql.rust.elements.ItemList | ||
import codeql.rust.elements.Label | ||
import codeql.rust.elements.LabelableExpr |
Check warning
Code scanning / CodeQL
Redundant import Warning
codeql.rust.elements.BlockExpr
Redundant import, the module is already imported inside
codeql.rust.elements.LoopingExpr
@@ -74,6 +75,7 @@ | |||
import codeql.rust.elements.LiteralPat | |||
import codeql.rust.elements.Locatable | |||
import codeql.rust.elements.LoopExpr | |||
import codeql.rust.elements.LoopingExpr |
Check warning
Code scanning / CodeQL
Redundant import Warning
codeql.rust.elements.ForExpr
Redundant import, the module is already imported inside
codeql.rust.elements.LoopExpr
Redundant import, the module is already imported inside
codeql.rust.elements.WhileExpr
|
||
private import internal.LoopingExprImpl | ||
import codeql.rust.elements.BlockExpr | ||
import codeql.rust.elements.LabelableExpr |
Check warning
Code scanning / CodeQL
Redundant import Warning
codeql.rust.elements.BlockExpr
@@ -27,5 +27,7 @@ module Impl { | |||
*/ | |||
class LiteralExpr extends Generated::LiteralExpr { | |||
override string toString() { result = this.getTextValue() } | |||
|
|||
override string toAbbreviatedString() { result = this.getTextValue() } |
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.
I now thought we might want to trim long literals here
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.
Yes
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
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.
@@ -102,5 +103,15 @@ module Impl { | |||
isLabelled(result, label) | |||
) | |||
} | |||
|
|||
override string toString() { result = concat(int i | | this.toStringPart(i), " " order by i) } |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, better if we can avoid recursion.
/** | ||
* A Enum. For example: | ||
* ```rust | ||
* todo!() | ||
* ``` | ||
*/ | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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() |
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.
Recursion.
@@ -21,5 +21,7 @@ module Impl { | |||
* Foo { .. } = second; | |||
* ``` | |||
*/ | |||
class RecordExpr extends Generated::RecordExpr { } | |||
class RecordExpr extends Generated::RecordExpr { | |||
override string toString() { result = this.getPath().toString() + " {...}" } |
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.
Recursion.
@@ -21,5 +21,7 @@ module Impl { | |||
* } | |||
* ``` | |||
*/ | |||
class RecordPat extends Generated::RecordPat { } | |||
class RecordPat extends Generated::RecordPat { | |||
override string toString() { result = this.getPath().toString() + " {...}" } |
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.
Recursion.
@@ -24,5 +24,7 @@ module Impl { | |||
* pub trait Foo<T: Frobinizable> where T::Frobinator: Eq {} | |||
* ``` | |||
*/ | |||
class Trait extends Generated::Trait { } | |||
class Trait extends Generated::Trait { | |||
override string toString() { result = "trait " + this.getName() } |
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.
Recursion.
/** | ||
* A Union. For example: | ||
* ```rust | ||
* todo!() | ||
* ``` | ||
*/ | ||
class Union extends Generated::Union { } | ||
class Union extends Generated::Union { | ||
override string toString() { result = "union " + this.getName().toString() } |
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.
Recursion.
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.
Great work on making toString
non-recursive, thanks!
This sets up better
toString
implementations 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
Expr
s, but it should get us started.The strategy is to make
toString
as 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 {...}
)