Skip to content

Commit 579df25

Browse files
committed
Use the ast edge label when building the ast node label
The C PrintAST library now includes the edge name in the AST Viewer tree.
1 parent 1886c0c commit 579df25

File tree

4 files changed

+76
-5
lines changed

4 files changed

+76
-5
lines changed

extensions/ql-vscode/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Whenever the extension restarts, orphaned databases will be cleaned up. These are databases whose files are located inside of the extension's storage area, but are not imported into the workspace.
1111
- After renaming a database, the database list is re-sorted. [#685](https://github.com/github/vscode-codeql/pull/685)
1212
- Add a `codeQl.resultsDisplay.pageSize` setting to configure the number of results displayed in a single results view page. Increase the default page size from 100 to 200. [#686](https://github.com/github/vscode-codeql/pull/686)
13+
- Update the AST Viewer to include edge labels (if available) in addition to the target node labels. So far, only C/C++ databases take advantage of this change. [#688](https://github.com/github/vscode-codeql/pull/688)
1314

1415
## 1.3.6 - 4 November 2020
1516

extensions/ql-vscode/src/contextual/astBuilder.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,18 @@ export default class AstBuilder {
4545
const parentToChildren = new Map<BqrsId, BqrsId[]>();
4646
const childToParent = new Map<BqrsId, BqrsId>();
4747
const astOrder = new Map<BqrsId, number>();
48+
const edgeLabels = new Map<BqrsId, string>();
4849
const roots = [];
4950

5051
// Build up the parent-child relationships
5152
edgeTuples.tuples.forEach(tuple => {
52-
const [source, target, tupleType, orderValue] = tuple as [EntityValue, EntityValue, string, string];
53+
const [source, target, tupleType, value] = tuple as [EntityValue, EntityValue, string, string];
5354
const sourceId = source.id!;
5455
const targetId = target.id!;
5556

5657
switch (tupleType) {
5758
case 'semmle.order':
58-
astOrder.set(targetId, Number(orderValue));
59+
astOrder.set(targetId, Number(value));
5960
break;
6061

6162
case 'semmle.label': {
@@ -65,6 +66,11 @@ export default class AstBuilder {
6566
parentToChildren.set(sourceId, children = []);
6667
}
6768
children.push(targetId);
69+
70+
// ignore values that indicate a numeric order.
71+
if (!Number.isFinite(Number(value))) {
72+
edgeLabels.set(targetId, value);
73+
}
6874
break;
6975
}
7076

@@ -84,9 +90,13 @@ export default class AstBuilder {
8490
break;
8591

8692
case 'semmle.label': {
93+
// If an edge label exists, include it and separate from the node label using ':'
94+
const nodeLabel = value ?? entity.label;
95+
const edgeLabel = edgeLabels.get(id);
96+
const label = [edgeLabel, nodeLabel].filter(e => e).join(': ');
8797
const item = {
8898
id,
89-
label: value ?? entity.label,
99+
label,
90100
location: entity.url,
91101
fileLocation: fileRangeFromURI(entity.url, this.db),
92102
children: [] as ChildAstItem[],

extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/astBuilder.test.ts

+60
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,66 @@ describe('AstBuilder', () => {
6565
)).to.deep.eq(expectedRoots);
6666
});
6767

68+
it('should build an AST child without edge label', async () => {
69+
// just test one of the children to make sure that the structure is right
70+
// this label should only come from the node, not the edge
71+
const astBuilder = createAstBuilder();
72+
const roots = await astBuilder.getRoots();
73+
74+
expect(roots[0].children[0].parent).to.eq(roots[0]);
75+
// break the recursion
76+
(roots[0].children[0] as any).parent = undefined;
77+
(roots[0].children[0] as any).children = undefined;
78+
79+
const child = {
80+
children: undefined,
81+
fileLocation: undefined,
82+
id: 26359,
83+
label: 'params',
84+
location: {
85+
endColumn: 22,
86+
endLine: 19,
87+
startColumn: 5,
88+
startLine: 19,
89+
uri: 'file:/opt/src/arch/sandbox/lib/interrupts.c'
90+
},
91+
order: 0,
92+
parent: undefined
93+
};
94+
95+
expect(roots[0].children[0]).to.deep.eq(child);
96+
});
97+
98+
it('should build an AST child with edge label', async () => {
99+
// just test one of the children to make sure that the structure is right
100+
// this label should only come from both the node and the edge
101+
const astBuilder = createAstBuilder();
102+
const roots = await astBuilder.getRoots();
103+
104+
expect(roots[0].children[1].parent).to.eq(roots[0]);
105+
// break the recursion
106+
(roots[0].children[1] as any).parent = undefined;
107+
(roots[0].children[1] as any).children = undefined;
108+
109+
const child = {
110+
children: undefined,
111+
fileLocation: undefined,
112+
id: 26367,
113+
label: 'body: [Block] { ... }',
114+
location: {
115+
endColumn: 1,
116+
endLine: 22,
117+
startColumn: 1,
118+
startLine: 20,
119+
uri: 'file:/opt/src/arch/sandbox/lib/interrupts.c'
120+
},
121+
order: 2,
122+
parent: undefined
123+
};
124+
125+
expect(roots[0].children[1]).to.deep.eq(child);
126+
});
127+
68128
it('should fail when graphProperties are not correct', async () => {
69129
overrides.graphProperties = {
70130
tuples: [

extensions/ql-vscode/src/vscode-tests/no-workspace/data/astBuilder.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
}
2929
},
3030
"semmle.label",
31-
""
31+
"params"
3232
],
3333
[
3434
{
@@ -406,7 +406,7 @@
406406
}
407407
},
408408
"semmle.label",
409-
"params"
409+
"1234"
410410
],
411411
[
412412
{

0 commit comments

Comments
 (0)