Skip to content

Commit 11016e1

Browse files
committed
Rust: PrintAst improvements
1 parent 1f1b1b7 commit 11016e1

File tree

3 files changed

+101
-129
lines changed

3 files changed

+101
-129
lines changed

rust/ql/lib/codeql/rust/printast/PrintAst.qll

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,51 @@
22
* Provides queries to pretty-print a Rust AST as a graph.
33
*/
44

5-
import PrintAstNode
5+
import codeql.rust.printast.PrintAstNode
66

7-
cached
8-
private int getOrder(PrintAstNode node) {
9-
node =
10-
rank[result](PrintAstNode n, Location loc |
11-
loc = n.getLocation()
12-
|
13-
n
14-
order by
15-
loc.getFile().getAbsolutePath(), loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(),
16-
loc.getEndColumn()
17-
)
18-
}
7+
module PrintAst<shouldPrintSig/1 shouldPrint> {
8+
import PrintAstNode<shouldPrint/1>
9+
10+
pragma[nomagic]
11+
private predicate orderBy(
12+
PrintAstNode n, string filepath, int startline, int startcolumn, int endline, int endcolumn
13+
) {
14+
n.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
15+
}
1916

20-
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
21-
query predicate nodes(PrintAstNode node, string key, string value) {
22-
node.shouldBePrinted() and
23-
(
17+
private int getOrder(PrintAstNode node) {
18+
node =
19+
rank[result](PrintAstNode n, string filepath, int startline, int startcolumn, int endline,
20+
int endcolumn |
21+
orderBy(n, filepath, startline, startcolumn, endline, endcolumn)
22+
|
23+
n order by filepath, startline, startcolumn, endline, endcolumn
24+
)
25+
}
26+
27+
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
28+
query predicate nodes(PrintAstNode node, string key, string value) {
2429
key = "semmle.label" and value = node.toString()
2530
or
2631
key = "semmle.order" and value = getOrder(node).toString()
2732
or
2833
value = node.getProperty(key)
29-
)
30-
}
34+
}
3135

32-
/**
33-
* Holds if `target` is a child of `source` in the AST, and property `key` of the edge has the
34-
* given `value`.
35-
*/
36-
query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) {
37-
source.shouldBePrinted() and
38-
target.shouldBePrinted() and
39-
exists(int index, string accessor | source.hasChild(target, index, accessor) |
40-
key = "semmle.label" and value = accessor
41-
or
42-
key = "semmle.order" and value = index.toString()
43-
)
44-
}
36+
/**
37+
* Holds if `target` is a child of `source` in the AST, and property `key` of the edge has the
38+
* given `value`.
39+
*/
40+
query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) {
41+
exists(int index, string accessor | source.hasChild(target, index, accessor) |
42+
key = "semmle.label" and value = accessor
43+
or
44+
key = "semmle.order" and value = index.toString()
45+
)
46+
}
4547

46-
/** Holds if property `key` of the graph has the given `value`. */
47-
query predicate graphProperties(string key, string value) {
48-
key = "semmle.graphKind" and value = "tree"
48+
/** Holds if property `key` of the graph has the given `value`. */
49+
query predicate graphProperties(string key, string value) {
50+
key = "semmle.graphKind" and value = "tree"
51+
}
4952
}

rust/ql/lib/codeql/rust/printast/PrintAstNode.qll

Lines changed: 57 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -6,105 +6,81 @@
66
import rust
77
import codeql.rust.elements.internal.generated.ParentChild
88

9-
private newtype TPrintAstConfiguration = TMakePrintAstConfiguration()
9+
signature predicate shouldPrintSig(Locatable e);
1010

11-
/**
12-
* The hook to customize the files and functions printed by this module.
13-
*/
14-
class PrintAstConfiguration extends TPrintAstConfiguration {
11+
module PrintAstNode<shouldPrintSig/1 shouldPrint> {
1512
/**
16-
* Gets the string representation of this singleton
13+
* An AST node that should be printed.
1714
*/
18-
string toString() { result = "PrintAstConfiguration" }
15+
private newtype TPrintAstNode = TPrintLocatable(Locatable ast) { shouldPrint(ast) }
1916

2017
/**
21-
* Holds if the AST for `e` should be printed. By default, holds for all.
18+
* A node in the output tree.
2219
*/
23-
predicate shouldPrint(Locatable e) { any() }
24-
}
25-
26-
private predicate shouldPrint(Locatable e) { any(PrintAstConfiguration config).shouldPrint(e) }
27-
28-
/**
29-
* An AST node that should be printed.
30-
*/
31-
private newtype TPrintAstNode = TPrintLocatable(Locatable ast)
32-
33-
/**
34-
* A node in the output tree.
35-
*/
36-
class PrintAstNode extends TPrintAstNode {
37-
/**
38-
* Gets a textual representation of this node.
39-
*/
40-
abstract string toString();
41-
42-
/**
43-
* Gets the child node at index `index`. Child indices must be unique,
44-
* but need not be contiguous.
45-
*/
46-
abstract predicate hasChild(PrintAstNode child, int index, string label);
47-
48-
/**
49-
* Holds if this node should be printed in the output.
50-
*/
51-
abstract predicate shouldBePrinted();
20+
class PrintAstNode extends TPrintAstNode {
21+
/**
22+
* Gets a textual representation of this node.
23+
*/
24+
abstract string toString();
25+
26+
/**
27+
* Gets the child node at index `index`. Child indices must be unique,
28+
* but need not be contiguous.
29+
*/
30+
abstract predicate hasChild(PrintAstNode child, int index, string label);
31+
32+
/**
33+
* Gets the location of this node in the source code.
34+
*/
35+
abstract Location getLocation();
36+
37+
/**
38+
* Gets the value of an additional property of this node, where the name of
39+
* the property is `key`.
40+
*/
41+
string getProperty(string key) { none() }
42+
43+
/**
44+
* Gets the underlying AST node, if any.
45+
*/
46+
abstract Locatable getAstNode();
47+
}
5248

53-
/**
54-
* Gets the location of this node in the source code.
55-
*/
56-
abstract Location getLocation();
49+
private string prettyPrint(Locatable e) { result = "[" + e.getPrimaryQlClasses() + "] " + e }
5750

58-
/**
59-
* Gets the value of an additional property of this node, where the name of
60-
* the property is `key`.
61-
*/
62-
string getProperty(string key) { none() }
51+
private class Unresolved extends Locatable {
52+
Unresolved() { this != this.resolve() }
53+
}
6354

6455
/**
65-
* Gets the underlying AST node, if any.
56+
* A graph node representing a real Locatable node.
6657
*/
67-
abstract Locatable getAstNode();
68-
}
58+
class PrintLocatable extends PrintAstNode, TPrintLocatable {
59+
Locatable ast;
6960

70-
private string prettyPrint(Locatable e) {
71-
result = "[" + concat(e.getPrimaryQlClasses(), ", ") + "] " + e
72-
}
61+
PrintLocatable() { this = TPrintLocatable(ast) }
7362

74-
private class Unresolved extends Locatable {
75-
Unresolved() { this != this.resolve() }
76-
}
63+
override string toString() { result = prettyPrint(ast) }
7764

78-
/**
79-
* A graph node representing a real Locatable node.
80-
*/
81-
class PrintLocatable extends PrintAstNode, TPrintLocatable {
82-
Locatable ast;
65+
override predicate hasChild(PrintAstNode child, int index, string label) {
66+
child = TPrintLocatable(any(Locatable c | c = getChildAndAccessor(ast, index, label)))
67+
}
8368

84-
PrintLocatable() { this = TPrintLocatable(ast) }
69+
final override Locatable getAstNode() { result = ast }
8570

86-
override string toString() { result = prettyPrint(ast) }
87-
88-
final override predicate shouldBePrinted() { shouldPrint(ast) }
89-
90-
override predicate hasChild(PrintAstNode child, int index, string label) {
91-
child = TPrintLocatable(any(Locatable c | c = getChildAndAccessor(ast, index, label)))
71+
final override Location getLocation() { result = ast.getLocation() }
9272
}
9373

94-
final override Locatable getAstNode() { result = ast }
95-
96-
final override Location getLocation() { result = ast.getLocation() }
97-
}
98-
99-
/**
100-
* A specialization of graph node for "unresolved" children, that is nodes in
101-
* the parallel conversion AST.
102-
*/
103-
class PrintUnresolved extends PrintLocatable {
104-
override Unresolved ast;
74+
/**
75+
* A specialization of graph node for "unresolved" children, that is nodes in
76+
* the parallel conversion AST.
77+
*/
78+
class PrintUnresolved extends PrintLocatable {
79+
override Unresolved ast;
10580

106-
override predicate hasChild(PrintAstNode child, int index, string label) {
107-
// only print immediate unresolved children from the "parallel" AST
108-
child = TPrintLocatable(getImmediateChildAndAccessor(ast, index, label).(Unresolved))
81+
override predicate hasChild(PrintAstNode child, int index, string label) {
82+
// only print immediate unresolved children from the "parallel" AST
83+
child = TPrintLocatable(getImmediateChildAndAccessor(ast, index, label).(Unresolved))
84+
}
10985
}
11086
}

rust/ql/src/queries/ide-contextual-queries/printAst.ql

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,10 @@ import codeql.rust.elements.internal.generated.ParentChild
1717
*/
1818
external string selectedSourceFile();
1919

20-
class PrintAstConfigurationOverride extends PrintAstConfiguration {
21-
/**
22-
* Holds if the location matches the selected file in the VS Code extension and
23-
* the element is `e`.
24-
*/
25-
override predicate shouldPrint(Locatable e) {
26-
super.shouldPrint(e) and
27-
(
28-
e.getFile() = getFileBySourceArchiveName(selectedSourceFile())
29-
or
30-
exists(Locatable parent | this.shouldPrint(parent) and parent = getImmediateParent(e))
31-
)
32-
}
20+
predicate shouldPrint(Locatable e) {
21+
e.getFile() = getFileBySourceArchiveName(selectedSourceFile())
22+
or
23+
exists(Locatable parent | shouldPrint(parent) and parent = getImmediateParent(e))
3324
}
25+
26+
import PrintAst<shouldPrint/1>

0 commit comments

Comments
 (0)