Skip to content

Commit 4ef520d

Browse files
authored
Merge pull request #2407 from github/koesie10/query-language
Use `QueryLanguage` type for representing query languages
2 parents cae7239 + 9884476 commit 4ef520d

File tree

5 files changed

+55
-12
lines changed

5 files changed

+55
-12
lines changed

extensions/ql-vscode/src/data-extensions-editor/external-api-usage-query.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { writeFile } from "fs-extra";
44
import { dump as dumpYaml } from "js-yaml";
55
import {
66
getOnDiskWorkspaceFolders,
7+
isQueryLanguage,
78
showAndLogExceptionWithTelemetry,
89
} from "../helpers";
910
import { TeeLogger } from "../common";
@@ -15,7 +16,6 @@ import { fetchExternalApiQueries } from "./queries";
1516
import { QueryResultType } from "../pure/new-messages";
1617
import { join } from "path";
1718
import { redactableError } from "../pure/errors";
18-
import { QueryLanguage } from "../common/query-language";
1919

2020
export type RunQueryOptions = {
2121
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
@@ -41,7 +41,14 @@ export async function runQuery({
4141
// For a reference of what this should do in the future, see the previous implementation in
4242
// https://github.com/github/vscode-codeql/blob/089d3566ef0bc67d9b7cc66e8fd6740b31c1c0b0/extensions/ql-vscode/src/data-extensions-editor/external-api-usage-query.ts#L33-L72
4343

44-
const query = fetchExternalApiQueries[databaseItem.language as QueryLanguage];
44+
if (!isQueryLanguage(databaseItem.language)) {
45+
void showAndLogExceptionWithTelemetry(
46+
redactableError`Unsupported database language ${databaseItem.language}`,
47+
);
48+
return;
49+
}
50+
51+
const query = fetchExternalApiQueries[databaseItem.language];
4552
if (!query) {
4653
void showAndLogExceptionWithTelemetry(
4754
redactableError`No external API usage query found for language ${databaseItem.language}`,

extensions/ql-vscode/src/databases/local-databases/database-manager.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import { DatabaseItemImpl } from "./database-item-impl";
1616
import {
1717
getFirstWorkspaceFolder,
1818
isFolderAlreadyInWorkspace,
19+
isQueryLanguage,
1920
showAndLogExceptionWithTelemetry,
2021
showNeverAskAgainDialog,
2122
} from "../../helpers";
2223
import { existsSync } from "fs";
2324
import { QlPackGenerator } from "../../qlpack-generator";
24-
import { QueryLanguage } from "../../common/query-language";
2525
import { asError, getErrorMessage } from "../../pure/helpers-pure";
2626
import { DatabaseItem, PersistedDatabaseItem } from "./database-item";
2727
import { redactableError } from "../../pure/errors";
@@ -213,6 +213,13 @@ export class DatabaseManager extends DisposableObject {
213213
return;
214214
}
215215

216+
if (!isQueryLanguage(databaseItem.language)) {
217+
void this.logger.log(
218+
"Could not create skeleton QL pack because the selected database's language is not supported.",
219+
);
220+
return;
221+
}
222+
216223
const firstWorkspaceFolder = getFirstWorkspaceFolder();
217224
const folderName = `codeql-custom-queries-${databaseItem.language}`;
218225

@@ -243,7 +250,7 @@ export class DatabaseManager extends DisposableObject {
243250
try {
244251
const qlPackGenerator = new QlPackGenerator(
245252
folderName,
246-
databaseItem.language as QueryLanguage,
253+
databaseItem.language,
247254
this.cli,
248255
firstWorkspaceFolder,
249256
);

extensions/ql-vscode/src/helpers.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { QueryMetadata } from "./pure/interface-types";
1818
import { telemetryListener } from "./telemetry";
1919
import { RedactableError } from "./pure/errors";
2020
import { getQlPackPath } from "./pure/ql";
21-
import { dbSchemeToLanguage } from "./common/query-language";
21+
import { dbSchemeToLanguage, QueryLanguage } from "./common/query-language";
2222
import { isCodespacesTemplate } from "./config";
2323
import { AppCommandManager } from "./common/commands";
2424

@@ -548,14 +548,18 @@ export async function isLikelyDbLanguageFolder(dbPath: string) {
548548
);
549549
}
550550

551+
export function isQueryLanguage(language: string): language is QueryLanguage {
552+
return Object.values(QueryLanguage).includes(language as QueryLanguage);
553+
}
554+
551555
/**
552556
* Finds the language that a query targets.
553557
* If it can't be autodetected, prompt the user to specify the language manually.
554558
*/
555559
export async function findLanguage(
556560
cliServer: CodeQLCliServer,
557561
queryUri: Uri | undefined,
558-
): Promise<string | undefined> {
562+
): Promise<QueryLanguage | undefined> {
559563
const uri = queryUri || Window.activeTextEditor?.document.uri;
560564
if (uri !== undefined) {
561565
try {
@@ -565,7 +569,14 @@ export async function findLanguage(
565569
);
566570
const language = Object.keys(queryInfo.byLanguage)[0];
567571
void extLogger.log(`Detected query language: ${language}`);
568-
return language;
572+
573+
if (isQueryLanguage(language)) {
574+
return language;
575+
}
576+
577+
void extLogger.log(
578+
"Query language is unsupported. Select language manually.",
579+
);
569580
} catch (e) {
570581
void extLogger.log(
571582
"Could not autodetect query language. Select language manually.",
@@ -580,7 +591,7 @@ export async function findLanguage(
580591
export async function askForLanguage(
581592
cliServer: CodeQLCliServer,
582593
throwOnEmpty = true,
583-
): Promise<string | undefined> {
594+
): Promise<QueryLanguage | undefined> {
584595
const language = await Window.showQuickPick(
585596
await cliServer.getSupportedLanguages(),
586597
{
@@ -597,7 +608,18 @@ export async function askForLanguage(
597608
"Language not found. Language must be specified manually.",
598609
);
599610
}
611+
return undefined;
600612
}
613+
614+
if (!isQueryLanguage(language)) {
615+
void showAndLogErrorMessage(
616+
`Language '${language}' is not supported. Only languages ${Object.values(
617+
QueryLanguage,
618+
).join(", ")} are supported.`,
619+
);
620+
return undefined;
621+
}
622+
601623
return language;
602624
}
603625

extensions/ql-vscode/src/skeleton-query-wizard.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const QUERY_LANGUAGE_TO_DATABASE_REPO: QueryLanguagesToDatabaseMap = {
4141
};
4242

4343
export class SkeletonQueryWizard {
44-
private language: string | undefined;
44+
private language: QueryLanguage | undefined;
4545
private fileName = "example.ql";
4646
private qlPackStoragePath: string | undefined;
4747

@@ -154,6 +154,9 @@ export class SkeletonQueryWizard {
154154
if (this.folderName === undefined) {
155155
throw new Error("Folder name is undefined");
156156
}
157+
if (this.language === undefined) {
158+
throw new Error("Language is undefined");
159+
}
157160

158161
this.progress({
159162
message: "Creating skeleton QL pack around query",
@@ -164,7 +167,7 @@ export class SkeletonQueryWizard {
164167
try {
165168
const qlPackGenerator = new QlPackGenerator(
166169
this.folderName,
167-
this.language as QueryLanguage,
170+
this.language,
168171
this.cliServer,
169172
this.qlPackStoragePath,
170173
);
@@ -181,6 +184,9 @@ export class SkeletonQueryWizard {
181184
if (this.folderName === undefined) {
182185
throw new Error("Folder name is undefined");
183186
}
187+
if (this.language === undefined) {
188+
throw new Error("Language is undefined");
189+
}
184190

185191
this.progress({
186192
message:
@@ -192,7 +198,7 @@ export class SkeletonQueryWizard {
192198
try {
193199
const qlPackGenerator = new QlPackGenerator(
194200
this.folderName,
195-
this.language as QueryLanguage,
201+
this.language,
196202
this.cliServer,
197203
this.qlPackStoragePath,
198204
);

extensions/ql-vscode/src/variant-analysis/run-remote-query.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
QLPACK_FILENAMES,
4040
QLPACK_LOCK_FILENAMES,
4141
} from "../pure/ql";
42+
import { QueryLanguage } from "../common/query-language";
4243

4344
export interface QlPack {
4445
name: string;
@@ -76,7 +77,7 @@ async function generateQueryPack(
7677
const targetQueryFileName = join(queryPackDir, packRelativePath);
7778
const workspaceFolders = getOnDiskWorkspaceFolders();
7879

79-
let language: string | undefined;
80+
let language: QueryLanguage | undefined;
8081

8182
// Check if the query is already in a query pack.
8283
// If so, copy the entire query pack to the temporary directory.

0 commit comments

Comments
 (0)