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
Ruby: Model editor improvements #15048
base: main
Are you sure you want to change the base?
Conversation
This allows us to render type relations between modules/classes, not just methods.
c255d95
to
ec24b25
Compare
We don't actually generate type models for `extend` relationships yet, because they are more complex than `include`.
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.
Looks good to me overall.
|
|
||
| File getFile() { result = this.getLocation().getFile() } | ||
| abstract class Endpoint instanceof AstNode { | ||
| string getNamespace() { result = getNamespace(this.(AstNode).getLocation().getFile()) } |
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 think this should work:
| string getNamespace() { result = getNamespace(this.(AstNode).getLocation().getFile()) } | |
| string getNamespace() { result = getNamespace(super.getLocation().getFile()) } |
|
|
||
| string getName() { result = this.getMethodName() } | ||
| string getFileName() { result = this.(AstNode).getLocation().getFile().getBaseName() } |
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.
| string getFileName() { result = this.(AstNode).getLocation().getFile().getBaseName() } | |
| string getFileName() { result = super.getLocation().getFile().getBaseName() } |
| string toString() { result = this.(AstNode).toString() } | ||
|
|
||
| Location getLocation() { result = this.(AstNode).getLocation() } |
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.
| string toString() { result = this.(AstNode).toString() } | |
| Location getLocation() { result = this.(AstNode).getLocation() } | |
| string toString() { result = super.toString() } | |
| Location getLocation() { result = super.getLocation() } |
|
|
||
| File getFile() { result = this.getLocation().getFile() } | ||
| abstract class Endpoint instanceof AstNode { |
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.
Why not
| abstract class Endpoint instanceof AstNode { | |
| abstract class Endpoint instanceof DataFlow::Node { |
An AstNode may have multiple associated DataFlow Nodes, so I think we best avoid switching between AST and Dataflow layers.
This PR does a few things:
examplesin it. This removes a lot of example code that otherwise gets picked up when modeling libraries.FrameworkModeEndpointsquery to produce not only methods, but also classes. These are not technically endpoints, but it allows the model editor to learn about them and thus handle the new results fromGenerateModel(see below). This involves some refactoring of theEndpointclass, because we want to include bothDataFlow::MethodNodes andDataFlow::ModuleNodes, which don't have a common ancestor.GenerateModelquery to producetypeModelrows for subclass relationships. For example:If we mark
A#fooas a sink, we also want to recognise calls toB#fooas a sink as well. Instead of duplicating the models for every subclass, we instead emit a type row:which states that
Bcan be considered to have typeA. This means any models that targetAwill targetBas well.The same applies for
include:but not for
extend, because its behaviour is a bit odd (instance methods on the included module become class methods on the including class). I haven't worked out how to deal with them yet.