Conversation
121f8ea to
d0053e7
Compare
|
Note: Now rebaased on #494. Let's get that one in first. |
d0053e7 to
c7c27fe
Compare
This commit adds the AST Viewer for viewing the QL AST of a file in a database. The different components are as follows: 1. There is a new view `codeQLAstViewer`, which displays the AST 2. This view is backed by the `AstViewerDataProvider` and `AstViewer` classes in astView.ts 3. To generate an AST, we use contextual queries, similar to how Find references/declarations are implemented. In particular, in `definitions.ts` there is `TemplatePrintAstProvider` which provides an AST for a given source buffer. - Similar to the other queries, we first determine which database the buffer belongs to. - Based on that, we generate a synthetic qlpack and run the templatized `printAst.ql` query - We plug in the archive-relative path name of the source file. - After the query is run, we wrap the results in an `AstBuilder` instance. - When requested, the `AstBuilder` will generate the full AST of the file from the BQRS results. - The AST roots (all top-level elements, functions, variable declarations, etc, are roots) are passed to the `AstViewer` instance, which handles the display lifecycle and other VS Code-specific functions. There are a few unrelated pieces here, which can be pulled out to another PR if required: - The `codeQLQueryHistory` view now has a _welcome_ message to make it more obvious to users how to start. - `definitions.ts` is moved to the `contextual` subfolder. - `fileRangeFromURI` is extracted from `definitions.ts` to its own file so it can be reused. Also, note that this relies on github/codeql#3931 for the C/C++ query to be available in the QL sources. Other languages will need similar queries.
* Fix command-linting tests. * Fix failing windows test and Use Uri.parse(_, true) * Use Uri.parse(_, true). That is the preferred API. * Reformat comments.
c7c27fe to
3639dcb
Compare
This commit adds the AST Viewer for viewing the QL AST of a file in a database. The different components are as follows: 1. There is a new view `codeQLAstViewer`, which displays the AST 2. This view is backed by the `AstViewerDataProvider` and `AstViewer` classes in astView.ts 3. To generate an AST, we use contextual queries, similar to how Find references/declarations are implemented. In particular, in `definitions.ts` there is `TemplatePrintAstProvider` which provides an AST for a given source buffer. - Similar to the other queries, we first determine which database the buffer belongs to. - Based on that, we generate a synthetic qlpack and run the templatized `printAst.ql` query - We plug in the archive-relative path name of the source file. - After the query is run, we wrap the results in an `AstBuilder` instance. - When requested, the `AstBuilder` will generate the full AST of the file from the BQRS results. - The AST roots (all top-level elements, functions, variable declarations, etc, are roots) are passed to the `AstViewer` instance, which handles the display lifecycle and other VS Code-specific functions. There are a few unrelated pieces here, which can be pulled out to another PR if required: - The `codeQLQueryHistory` view now has a _welcome_ message to make it more obvious to users how to start. - `definitions.ts` is moved to the `contextual` subfolder. - `fileRangeFromURI` is extracted from `definitions.ts` to its own file so it can be reused. Also, note that this relies on github/codeql#3931 for the C/C++ query to be available in the QL sources. Other languages will need similar queries.
* Fix command-linting tests. * Fix failing windows test and Use Uri.parse(_, true) * Use Uri.parse(_, true). That is the preferred API. * Reformat comments.
Set `codeQL.experimentalAstViewer` to true in settings in order for component to be enabled.
…codeql into aeisenberg/ast-viewer
extensions/ql-vscode/src/cli.ts
Outdated
| async bqrsDecode(bqrsPath: string, resultSet: string, pageSize?: number, offset?: number): Promise<DecodedBqrsChunk> { | ||
| const subcommandArgs = [ | ||
| '--entities=url,string', | ||
| '--entities=id,url,string', |
There was a problem hiding this comment.
I don't suppose there's any performance penalty for including more things than we need for any particular query here, is there? Just idle speculation as to whether we might want to parameterize over the set of entities, since the other bqrs decoding code paths didn't need id until now.
There was a problem hiding this comment.
I originally implemented this as optionally including the id field. I could add it back.
There was a problem hiding this comment.
Do whatever you think is reasonable; I can see the side of the argument for it being awkward to make it optional too, since that makes the type vary.
| const destFile = dest.url && fileRangeFromURI(dest.url, db); | ||
| if (srcFile && destFile && filter(srcFile.file.toString(), destFile.file.toString())) { | ||
| localLinks.push({ targetRange: destFile.range, targetUri: destFile.file, originSelectionRange: srcFile.range, originUri: srcFile.file }); | ||
| if (srcFile && destFile && filter(srcFile.uri.toString(), destFile.uri.toString())) { |
There was a problem hiding this comment.
This file -> uri replacement is slightly scary to me since I don't have this fully paged into my brain. I would have thought those would have different behavior. Did this not work before? Does it definitely continue working after this change?
There was a problem hiding this comment.
Ahhh...I had forgotten that I did this. We are comparing 2 strings to see if they are a match and if so, then we mark the tuple as a match. Earlier on, we call getDefinitions and getReferences with document.uri.toString(). So, I am not sure how this worked in the past. I'll go try this out now and see.
There was a problem hiding this comment.
Right. I extracted fileRangeFromURI to its own file and I made it return a vscode.Location object. It's the same as before, except it is returning a vscode api type. file and uri are both vscode.Uri instances.
extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/astBuilder.test.ts
Outdated
Show resolved
Hide resolved
|
|
||
| // Build up the parent-child relationships | ||
| edgeTuples.tuples.forEach(tuple => { | ||
| const from = tuple[0] as EntityValue; |
There was a problem hiding this comment.
Not a huge deal, but I'd have a slight preference for establishing what type we expect tuple to have right away, like
// Build up the parent-child relationships
edgeTuples.tuples.forEach(tuple => {
const [src, tgt, tupleType, orderValue] = tuple as [EntityValue, EntityValue, string, number];
const toId = src.id!;
const fromId = tgt.id!;
switch (tupleType) {
case 'semmle.order':
astOrder.set(toId, Number(orderValue));
break;
case 'semmle.label': {
childToParent.set(toId, fromId);
let children = parentToChildren.get(fromId);
if (!children) {
parentToChildren.set(fromId, children = []);
}
children.push(toId);
break;
}
default:
throw new Error(`unexpected tuple type ${tupleType}`);
}
});
I don't know if the names I provided are the most appropriate for the fields of the tuples but that's sort of my point --- I'm a little uncertain reading this code what the expected schema/interpretation is.
There was a problem hiding this comment.
(and if the interpretation of some columns depends on the values of others, which looks like it might be the case here with respect to tuple[3] depending on tuple[2], it would be similarly nice to clarify that)
There was a problem hiding this comment.
Fair point. I will clarify.
|
|
||
| // populate parents and children | ||
| nodeTuples.tuples.forEach(tuple => { | ||
| const entity = tuple[0] as EntityValue; |
There was a problem hiding this comment.
Same comment as above about deconstructing tuple here
| }); | ||
|
|
||
| // find the roots and add the order | ||
| for(const [, item] of idToItem) { |
There was a problem hiding this comment.
I didn't know you didn't have to write an explicit undefined to avoid binding a tuple deconstructor field! Nice.
| switch (keyType) { | ||
| case KeyType.DefinitionQuery: return 'ide-contextual-queries/local-definitions'; | ||
| case KeyType.ReferenceQuery: return 'ide-contextual-queries/local-references'; | ||
| case KeyType.DefinitionQuery: |
There was a problem hiding this comment.
It seems like a bunch of these definitions should be hoisted out of definitions.ts into some more general file in contextual/ but that needn't happen in this PR.
There was a problem hiding this comment.
Sure. I agree that it's getting a bit messy. I'll work on that next.
572e38c to
0045891
Compare
| children.push(toId); | ||
|
|
||
| default: | ||
| // ignore other tupleTypes since they are not needed by the ast viewer |
There was a problem hiding this comment.
Ah, ok, great --- I didn't know that other values of tupleType existed, and it's great to clarify here that we're explicitly ignoring them.
There was a problem hiding this comment.
Thanks for suggesting that change. I think it makes the code clearer.
This commit adds the AST Viewer for viewing the QL AST of a file in a
database.
The different components are as follows:
codeQLAstViewer, which displays the ASTAstViewerDataProviderandAstViewerclasses in astView.tsdefinitions.tsthere isTemplatePrintAstProviderwhich provides an AST for a given source buffer.printAst.qlqueryAstBuilderinstance.AstBuilderwill generate the full AST of the file from the BQRS results.AstViewerinstance, which handles the display lifecycle and other VS Code-specific functions.There are a few unrelated pieces here, which can be pulled out to another PR if required:
codeQLQueryHistoryview now has a welcome message to make it more obvious to users how to start.definitions.tsis moved to thecontextualsubfolder.fileRangeFromURIis extracted fromdefinitions.tsto its own file so it can be reused.Also, note that this relies on github/codeql#3931 for the C/C++ query to be available in the QL sources. Other languages will need similar queries.
Replace this with a description of the changes your pull request makes.
Checklist
@github/product-docs-dsphas been cc'd in all issues for UI or other user-facing changes made by this pull request.