Skip to content

Commit dac4201

Browse files
committed
Attempt to autodetect language using "resolve queries"
1 parent d2d1a09 commit dac4201

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

extensions/ql-vscode/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@
245245
"command": "codeQL.runQuery",
246246
"title": "CodeQL: Run Query"
247247
},
248+
{
249+
"command": "codeQL.findLanguage",
250+
"title": "CodeQL: Find Language"
251+
},
248252
{
249253
"command": "codeQL.runQueryOnMultipleDatabases",
250254
"title": "CodeQL: Run Query on Multiple Databases"
@@ -684,6 +688,10 @@
684688
"command": "codeQL.runQuery",
685689
"when": "resourceLangId == ql && resourceExtname == .ql"
686690
},
691+
{
692+
"command": "codeQL.findLanguage",
693+
"when": "resourceLangId == ql && resourceExtname == .ql"
694+
},
687695
{
688696
"command": "codeQL.runQueryOnMultipleDatabases",
689697
"when": "resourceLangId == ql && resourceExtname == .ql"

extensions/ql-vscode/src/cli.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Readable } from 'stream';
88
import { StringDecoder } from 'string_decoder';
99
import * as tk from 'tree-kill';
1010
import { promisify } from 'util';
11-
import { CancellationToken, Disposable } from 'vscode';
11+
import { CancellationToken, Disposable, Uri, window } from 'vscode';
1212

1313
import { BQRSInfo, DecodedBqrsChunk } from './pure/bqrs-cli-types';
1414
import { CliConfig } from './config';
@@ -482,6 +482,36 @@ export class CodeQLCliServer implements Disposable {
482482
return await this.runJsonCodeQlCliCommand<QuerySetup>(['resolve', 'library-path'], subcommandArgs, 'Resolving library paths');
483483
}
484484

485+
/**
486+
* Finds the language that a query is analyzing.
487+
* @param queryUri The URI of the query
488+
*/
489+
async findLanguage(workspaces: string[], queryUri?: Uri): Promise<string> {
490+
let language = '';
491+
if (queryUri) {
492+
const subcommandArgs = [
493+
'--format', 'bylanguage',
494+
queryUri.fsPath,
495+
'--additional-packs',
496+
workspaces.join(path.delimiter)
497+
];
498+
try {
499+
const JSONResults = await this.runCodeQlCliCommand(['resolve', 'queries'], subcommandArgs, 'Finding query language');
500+
501+
// This corresponds to `codeql resolve queries <query> --format bylanguage | jq -r '.byLanguage | keys[]'`
502+
language = Object.keys(JSON.parse(JSONResults).byLanguage)[0];
503+
}
504+
catch (e) {
505+
// Add an option to manually specify the language, in case automatic language detection fails.
506+
void this.logger.log('Failed to detect language. Using manual prompt instead.');
507+
language = await window.showQuickPick(
508+
['cpp', 'csharp', 'go', 'java', 'javascript', 'python'], { placeHolder: 'Select language' }
509+
) || '';
510+
}
511+
}
512+
return language;
513+
}
514+
485515
/**
486516
* Finds all available QL tests in a given directory.
487517
* @param testPath Root of directory tree to search for tests.

extensions/ql-vscode/src/extension.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,17 @@ async function activateWithInstalledDistribution(
559559
}
560560
)
561561
);
562+
// TODO: Remove this and the package.json changes
563+
// (Temporary new command to test `cliServer.findLanguage`)
564+
ctx.subscriptions.push(
565+
commandRunner('codeQL.findLanguage', async (
566+
uri: Uri | undefined
567+
) => {
568+
const diskWorkspaceFolders = helpers.getOnDiskWorkspaceFolders();
569+
const language = await cliServer.findLanguage(diskWorkspaceFolders, uri || window.activeTextEditor?.document.uri);
570+
void helpers.showAndLogInformationMessage(language);
571+
})
572+
);
562573
interface DatabaseQuickPickItem extends QuickPickItem {
563574
databaseItem: DatabaseItem;
564575
}

0 commit comments

Comments
 (0)