Skip to content

Commit 6e06e79

Browse files
authored
Merge pull request #2889 from github/starcke/lang-context-queries
Apply language context to queries panel
2 parents 58249e3 + 169a425 commit 6e06e79

File tree

5 files changed

+105
-22
lines changed

5 files changed

+105
-22
lines changed

extensions/ql-vscode/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ async function activateWithInstalledDistribution(
790790
);
791791
ctx.subscriptions.push(databaseUI);
792792

793-
QueriesModule.initialize(app, cliServer);
793+
QueriesModule.initialize(app, languageContext, cliServer);
794794

795795
void extLogger.log("Initializing evaluator log viewer.");
796796
const evalLogViewer = new EvalLogViewer();

extensions/ql-vscode/src/queries-panel/queries-module.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { DisposableObject } from "../common/disposable-object";
66
import { QueriesPanel } from "./queries-panel";
77
import { QueryDiscovery } from "./query-discovery";
88
import { QueryPackDiscovery } from "./query-pack-discovery";
9+
import { LanguageContextStore } from "../language-context-store";
910

1011
export class QueriesModule extends DisposableObject {
1112
private queriesPanel: QueriesPanel | undefined;
@@ -16,16 +17,21 @@ export class QueriesModule extends DisposableObject {
1617

1718
public static initialize(
1819
app: App,
20+
languageContext: LanguageContextStore,
1921
cliServer: CodeQLCliServer,
2022
): QueriesModule {
2123
const queriesModule = new QueriesModule(app);
2224
app.subscriptions.push(queriesModule);
2325

24-
queriesModule.initialize(app, cliServer);
26+
queriesModule.initialize(app, languageContext, cliServer);
2527
return queriesModule;
2628
}
2729

28-
private initialize(app: App, cliServer: CodeQLCliServer): void {
30+
private initialize(
31+
app: App,
32+
langauageContext: LanguageContextStore,
33+
cliServer: CodeQLCliServer,
34+
): void {
2935
// Currently, we only want to expose the new panel when we are in canary mode
3036
// and the user has enabled the "Show queries panel" flag.
3137
if (!isCanary() || !showQueriesPanel()) {
@@ -38,8 +44,9 @@ export class QueriesModule extends DisposableObject {
3844
void queryPackDiscovery.initialRefresh();
3945

4046
const queryDiscovery = new QueryDiscovery(
41-
app.environment,
47+
app,
4248
queryPackDiscovery,
49+
langauageContext,
4350
);
4451
this.push(queryDiscovery);
4552
void queryDiscovery.initialRefresh();

extensions/ql-vscode/src/queries-panel/query-discovery.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { dirname, basename, normalize, relative } from "path";
22
import { Event } from "vscode";
3-
import { EnvironmentContext } from "../common/app";
3+
import { App } from "../common/app";
44
import {
55
FileTreeDirectory,
66
FileTreeLeaf,
@@ -11,6 +11,8 @@ import { FilePathDiscovery } from "../common/vscode/file-path-discovery";
1111
import { containsPath } from "../common/files";
1212
import { getOnDiskWorkspaceFoldersObjects } from "../common/vscode/workspace-folders";
1313
import { QueryLanguage } from "../common/query-language";
14+
import { LanguageContextStore } from "../language-context-store";
15+
import { AppEvent, AppEventEmitter } from "../common/events";
1416

1517
const QUERY_FILE_EXTENSION = ".ql";
1618

@@ -31,24 +33,36 @@ export class QueryDiscovery
3133
extends FilePathDiscovery<Query>
3234
implements QueryDiscoverer
3335
{
36+
public readonly onDidChangeQueries: AppEvent<void>;
37+
private readonly onDidChangeQueriesEmitter: AppEventEmitter<void>;
38+
3439
constructor(
35-
private readonly env: EnvironmentContext,
40+
private readonly app: App,
3641
private readonly queryPackDiscovery: QueryPackDiscoverer,
42+
private readonly languageContext: LanguageContextStore,
3743
) {
3844
super("Query Discovery", `**/*${QUERY_FILE_EXTENSION}`);
3945

46+
// Set up event emitters
47+
this.onDidChangeQueriesEmitter = this.push(app.createEventEmitter<void>());
48+
this.onDidChangeQueries = this.onDidChangeQueriesEmitter.event;
49+
50+
// Handlers
4051
this.push(
4152
this.queryPackDiscovery.onDidChangeQueryPacks(
4253
this.recomputeAllData.bind(this),
4354
),
4455
);
45-
}
46-
47-
/**
48-
* Event that fires when the set of queries in the workspace changes.
49-
*/
50-
public get onDidChangeQueries(): Event<void> {
51-
return this.onDidChangePathData;
56+
this.push(
57+
this.onDidChangePathData(() => {
58+
this.onDidChangeQueriesEmitter.fire();
59+
}),
60+
);
61+
this.push(
62+
this.languageContext.onLanguageContextChanged(() => {
63+
this.onDidChangeQueriesEmitter.fire();
64+
}),
65+
);
5266
}
5367

5468
/**
@@ -64,16 +78,18 @@ export class QueryDiscovery
6478

6579
const roots = [];
6680
for (const workspaceFolder of getOnDiskWorkspaceFoldersObjects()) {
67-
const queriesInRoot = pathData.filter((query) =>
68-
containsPath(workspaceFolder.uri.fsPath, query.path),
81+
const queriesInRoot = pathData.filter(
82+
(query) =>
83+
containsPath(workspaceFolder.uri.fsPath, query.path) &&
84+
this.languageContext.shouldInclude(query.language),
6985
);
7086
if (queriesInRoot.length === 0) {
7187
continue;
7288
}
7389
const root = new FileTreeDirectory<string>(
7490
workspaceFolder.uri.fsPath,
7591
workspaceFolder.name,
76-
this.env,
92+
this.app.environment,
7793
);
7894
for (const query of queriesInRoot) {
7995
const dirName = dirname(normalize(relative(root.path, query.path)));

extensions/ql-vscode/test/__mocks__/appMock.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class MockAppEventEmitter<T> implements AppEventEmitter<T> {
5656

5757
constructor() {
5858
this.event = () => {
59-
return {} as Disposable;
59+
return new MockAppEvent();
6060
};
6161
}
6262

@@ -69,7 +69,17 @@ class MockAppEventEmitter<T> implements AppEventEmitter<T> {
6969
}
7070
}
7171

72-
export function createMockEnvironmentContext(): EnvironmentContext {
72+
class MockAppEvent implements Disposable {
73+
public fire(): void {
74+
// no-op
75+
}
76+
77+
public dispose() {
78+
// no-op
79+
}
80+
}
81+
82+
function createMockEnvironmentContext(): EnvironmentContext {
7383
return {
7484
language: "en-US",
7585
};

extensions/ql-vscode/test/vscode-tests/minimal-workspace/queries-panel/query-discovery.test.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import {
33
QueryDiscovery,
44
QueryPackDiscoverer,
55
} from "../../../../src/queries-panel/query-discovery";
6-
import { createMockEnvironmentContext } from "../../../__mocks__/appMock";
7-
import { dirname, join } from "path";
6+
import { createMockApp } from "../../../__mocks__/appMock";
7+
import { basename, dirname, join } from "path";
88
import * as tmp from "tmp";
99
import {
1010
FileTreeDirectory,
@@ -13,14 +13,18 @@ import {
1313
import { mkdirSync, writeFileSync } from "fs";
1414
import { QueryLanguage } from "../../../../src/common/query-language";
1515
import { sleep } from "../../../../src/common/time";
16+
import { LanguageContextStore } from "../../../../src/language-context-store";
1617

1718
describe("Query pack discovery", () => {
1819
let tmpDir: string;
1920
let tmpDirRemoveCallback: (() => void) | undefined;
2021

2122
let workspacePath: string;
2223

23-
const env = createMockEnvironmentContext();
24+
const app = createMockApp({});
25+
const env = app.environment;
26+
27+
const languageContext = new LanguageContextStore(app);
2428

2529
const onDidChangeQueryPacks = new EventEmitter<void>();
2630
let queryPackDiscoverer: QueryPackDiscoverer;
@@ -45,7 +49,7 @@ describe("Query pack discovery", () => {
4549
getLanguageForQueryFile: () => QueryLanguage.Java,
4650
onDidChangeQueryPacks: onDidChangeQueryPacks.event,
4751
};
48-
discovery = new QueryDiscovery(env, queryPackDiscoverer);
52+
discovery = new QueryDiscovery(app, queryPackDiscoverer, languageContext);
4953
});
5054

5155
afterEach(() => {
@@ -160,6 +164,52 @@ describe("Query pack discovery", () => {
160164
]),
161165
]);
162166
});
167+
168+
it("should respect the language context filter", async () => {
169+
makeTestFile(join(workspacePath, "query1.ql"));
170+
makeTestFile(join(workspacePath, "query2.ql"));
171+
172+
queryPackDiscoverer.getLanguageForQueryFile = (path) => {
173+
if (basename(path) === "query1.ql") {
174+
return QueryLanguage.Java;
175+
} else {
176+
return QueryLanguage.Python;
177+
}
178+
};
179+
180+
await discovery.initialRefresh();
181+
182+
// Set the language to python-only
183+
await languageContext.setLanguageContext(QueryLanguage.Python);
184+
185+
expect(discovery.buildQueryTree()).toEqual([
186+
new FileTreeDirectory(workspacePath, "workspace", env, [
187+
new FileTreeLeaf(
188+
join(workspacePath, "query2.ql"),
189+
"query2.ql",
190+
"python",
191+
),
192+
]),
193+
]);
194+
195+
// Clear the language context filter
196+
await languageContext.clearLanguageContext();
197+
198+
expect(discovery.buildQueryTree()).toEqual([
199+
new FileTreeDirectory(workspacePath, "workspace", env, [
200+
new FileTreeLeaf(
201+
join(workspacePath, "query1.ql"),
202+
"query1.ql",
203+
"java",
204+
),
205+
new FileTreeLeaf(
206+
join(workspacePath, "query2.ql"),
207+
"query2.ql",
208+
"python",
209+
),
210+
]),
211+
]);
212+
});
163213
});
164214

165215
describe("recomputeAllQueryLanguages", () => {

0 commit comments

Comments
 (0)