Skip to content

Commit e033578

Browse files
Edoardo Pirovanoaeisenberg
authored andcommitted
Add feature to jump to the .ql file referenced by a .qlref
1 parent c082a38 commit e033578

File tree

4 files changed

+75
-4
lines changed

4 files changed

+75
-4
lines changed

extensions/ql-vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
- Avoid showing an error popup when user runs a query without `@kind` metadata. [#801](https://github.com/github/vscode-codeql/pull/801)
1010
- Fix running of tests when the `ms-python` extension is installed. [#803](https://github.com/github/vscode-codeql/pull/803)
11+
- Add an option to jump from a .qlref file to the .ql file it references.
1112

1213
## 1.4.4 - 19 March 2021
1314

extensions/ql-vscode/package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"onCommand:codeQLDatabases.chooseDatabaseLgtm",
3535
"onCommand:codeQL.setCurrentDatabase",
3636
"onCommand:codeQL.viewAst",
37+
"onCommand:codeQL.openReferencedFile",
3738
"onCommand:codeQL.chooseDatabaseFolder",
3839
"onCommand:codeQL.chooseDatabaseArchive",
3940
"onCommand:codeQL.chooseDatabaseInternet",
@@ -229,6 +230,10 @@
229230
"command": "codeQL.quickEval",
230231
"title": "CodeQL: Quick Evaluation"
231232
},
233+
{
234+
"command": "codeQL.openReferencedFile",
235+
"title": "CodeQL: Open Referenced File"
236+
},
232237
{
233238
"command": "codeQL.quickQuery",
234239
"title": "CodeQL: Quick Query"
@@ -619,6 +624,11 @@
619624
"command": "codeQL.runQueries",
620625
"group": "9_qlCommands",
621626
"when": "resourceScheme != codeql-zip-archive"
627+
},
628+
{
629+
"command": "codeQL.openReferencedFile",
630+
"group": "9_qlCommands",
631+
"when": "resourceExtname == .qlref"
622632
}
623633
],
624634
"commandPalette": [
@@ -634,6 +644,10 @@
634644
"command": "codeQL.quickEval",
635645
"when": "editorLangId == ql"
636646
},
647+
{
648+
"command": "codeQL.openReferencedFile",
649+
"when": "resourceExtname == .qlref"
650+
},
637651
{
638652
"command": "codeQL.setCurrentDatabase",
639653
"when": "false"
@@ -771,6 +785,10 @@
771785
{
772786
"command": "codeQL.quickEval",
773787
"when": "editorLangId == ql"
788+
},
789+
{
790+
"command": "codeQL.openReferencedFile",
791+
"when": "resourceExtname == .qlref"
774792
}
775793
]
776794
},

extensions/ql-vscode/src/cli.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ export interface UpgradesInfo {
7373
*/
7474
export type QlpacksInfo = { [name: string]: string[] };
7575

76+
/**
77+
* The expected output of `codeql resolve qlref`.
78+
*/
79+
export type QlrefInfo = { resolvedPath: string };
80+
7681
// `codeql bqrs interpret` requires both of these to be present or
7782
// both absent.
7883
export interface SourceInfo {
@@ -143,6 +148,11 @@ export class CodeQLCliServer implements Disposable {
143148
*/
144149
private static CLI_VERSION_WITH_DOWNGRADES = new SemVer('2.4.4');
145150

151+
/**
152+
* CLI version where the `codeql resolve qlref` command is available.
153+
*/
154+
private static CLI_VERSION_WITH_RESOLVE_QLREF = new SemVer('2.5.1');
155+
146156
/** The process for the cli server, or undefined if one doesn't exist yet */
147157
process?: child_process.ChildProcessWithoutNullStreams;
148158
/** Queue of future commands*/
@@ -461,12 +471,15 @@ export class CodeQLCliServer implements Disposable {
461471
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
462472
* @param commandArgs The arguments to pass to the `codeql` command.
463473
* @param description Description of the action being run, to be shown in log and error messages.
474+
* @param addFormat Whether or not to add commandline arguments to specify the format as JSON.
464475
* @param progressReporter Used to output progress messages, e.g. to the status bar.
465476
* @returns The contents of the command's stdout, if the command succeeded.
466477
*/
467-
async runJsonCodeQlCliCommand<OutputType>(command: string[], commandArgs: string[], description: string, progressReporter?: ProgressReporter): Promise<OutputType> {
468-
// Add format argument first, in case commandArgs contains positional parameters.
469-
const args = ['--format', 'json'].concat(commandArgs);
478+
async runJsonCodeQlCliCommand<OutputType>(command: string[], commandArgs: string[], description: string, addFormat = true, progressReporter?: ProgressReporter): Promise<OutputType> {
479+
let args: string[] = [];
480+
if (addFormat) // Add format argument first, in case commandArgs contains positional parameters.
481+
args = args.concat(['--format', 'json']);
482+
args = args.concat(commandArgs);
470483
const result = await this.runCodeQlCliCommand(command, args, description, progressReporter);
471484
try {
472485
return JSON.parse(result) as OutputType;
@@ -505,6 +518,18 @@ export class CodeQLCliServer implements Disposable {
505518
);
506519
}
507520

521+
public async resolveQlref(qlref: string): Promise<QlrefInfo> {
522+
const subcommandArgs = [
523+
qlref
524+
];
525+
return await this.runJsonCodeQlCliCommand<QlrefInfo>(
526+
['resolve', 'qlref'],
527+
subcommandArgs,
528+
'Resolving qlref',
529+
false
530+
);
531+
}
532+
508533
/**
509534
* Runs QL tests.
510535
* @param testPaths Full paths of the tests to run.
@@ -549,7 +574,7 @@ export class CodeQLCliServer implements Disposable {
549574
if (queryMemoryMb !== undefined) {
550575
args.push('--ram', queryMemoryMb.toString());
551576
}
552-
return await this.runJsonCodeQlCliCommand<string[]>(['resolve', 'ram'], args, 'Resolving RAM settings', progressReporter);
577+
return await this.runJsonCodeQlCliCommand<string[]>(['resolve', 'ram'], args, 'Resolving RAM settings', true, progressReporter);
553578
}
554579
/**
555580
* Gets the headers (and optionally pagination info) of a bqrs.
@@ -773,6 +798,10 @@ export class CodeQLCliServer implements Disposable {
773798
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_DOWNGRADES) >= 0;
774799
}
775800

801+
public async supportsResolveQlref() {
802+
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_RESOLVE_QLREF) >= 0;
803+
}
804+
776805
private async refreshVersion() {
777806
const distribution = await this.distributionProvider.getDistribution();
778807
switch (distribution.kind) {

extensions/ql-vscode/src/extension.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,23 @@ async function activateWithInstalledDistribution(
480480
}
481481
}
482482

483+
async function openReferencedFile(
484+
selectedQuery: Uri
485+
): Promise<void> {
486+
if (qs !== undefined) {
487+
if (await cliServer.supportsResolveQlref()) {
488+
const resolved = await cliServer.resolveQlref(selectedQuery.path);
489+
const uri = Uri.file(resolved.resolvedPath);
490+
await window.showTextDocument(uri, { preview: false });
491+
} else {
492+
helpers.showAndLogErrorMessage(
493+
'Jumping from a .qlref file to the .ql file it references is not '
494+
+ 'supported with the CLI version you are running.\n'
495+
+ 'Please upgrade your CLI to use this feature.');
496+
}
497+
}
498+
}
499+
483500
ctx.subscriptions.push(tmpDirDisposal);
484501

485502
logger.log('Initializing CodeQL language server.');
@@ -616,6 +633,12 @@ async function activateWithInstalledDistribution(
616633
}
617634
)
618635
);
636+
ctx.subscriptions.push(
637+
commandRunner(
638+
'codeQL.openReferencedFile',
639+
openReferencedFile
640+
)
641+
);
619642

620643
ctx.subscriptions.push(
621644
commandRunnerWithProgress('codeQL.restartQueryServer', async (

0 commit comments

Comments
 (0)