Merge pull request #2889 from github/starcke/lang-context-queries

Apply language context to queries panel
This commit is contained in:
Anders Starcke Henriksen 2023-10-02 10:27:00 +02:00 коммит произвёл GitHub
Родитель 58249e3efe 169a425e0b
Коммит 6e06e7934b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 105 добавлений и 22 удалений

Просмотреть файл

@ -790,7 +790,7 @@ async function activateWithInstalledDistribution(
);
ctx.subscriptions.push(databaseUI);
QueriesModule.initialize(app, cliServer);
QueriesModule.initialize(app, languageContext, cliServer);
void extLogger.log("Initializing evaluator log viewer.");
const evalLogViewer = new EvalLogViewer();

Просмотреть файл

@ -6,6 +6,7 @@ import { DisposableObject } from "../common/disposable-object";
import { QueriesPanel } from "./queries-panel";
import { QueryDiscovery } from "./query-discovery";
import { QueryPackDiscovery } from "./query-pack-discovery";
import { LanguageContextStore } from "../language-context-store";
export class QueriesModule extends DisposableObject {
private queriesPanel: QueriesPanel | undefined;
@ -16,16 +17,21 @@ export class QueriesModule extends DisposableObject {
public static initialize(
app: App,
languageContext: LanguageContextStore,
cliServer: CodeQLCliServer,
): QueriesModule {
const queriesModule = new QueriesModule(app);
app.subscriptions.push(queriesModule);
queriesModule.initialize(app, cliServer);
queriesModule.initialize(app, languageContext, cliServer);
return queriesModule;
}
private initialize(app: App, cliServer: CodeQLCliServer): void {
private initialize(
app: App,
langauageContext: LanguageContextStore,
cliServer: CodeQLCliServer,
): void {
// Currently, we only want to expose the new panel when we are in canary mode
// and the user has enabled the "Show queries panel" flag.
if (!isCanary() || !showQueriesPanel()) {
@ -38,8 +44,9 @@ export class QueriesModule extends DisposableObject {
void queryPackDiscovery.initialRefresh();
const queryDiscovery = new QueryDiscovery(
app.environment,
app,
queryPackDiscovery,
langauageContext,
);
this.push(queryDiscovery);
void queryDiscovery.initialRefresh();

Просмотреть файл

@ -1,6 +1,6 @@
import { dirname, basename, normalize, relative } from "path";
import { Event } from "vscode";
import { EnvironmentContext } from "../common/app";
import { App } from "../common/app";
import {
FileTreeDirectory,
FileTreeLeaf,
@ -11,6 +11,8 @@ import { FilePathDiscovery } from "../common/vscode/file-path-discovery";
import { containsPath } from "../common/files";
import { getOnDiskWorkspaceFoldersObjects } from "../common/vscode/workspace-folders";
import { QueryLanguage } from "../common/query-language";
import { LanguageContextStore } from "../language-context-store";
import { AppEvent, AppEventEmitter } from "../common/events";
const QUERY_FILE_EXTENSION = ".ql";
@ -31,24 +33,36 @@ export class QueryDiscovery
extends FilePathDiscovery<Query>
implements QueryDiscoverer
{
public readonly onDidChangeQueries: AppEvent<void>;
private readonly onDidChangeQueriesEmitter: AppEventEmitter<void>;
constructor(
private readonly env: EnvironmentContext,
private readonly app: App,
private readonly queryPackDiscovery: QueryPackDiscoverer,
private readonly languageContext: LanguageContextStore,
) {
super("Query Discovery", `**/*${QUERY_FILE_EXTENSION}`);
// Set up event emitters
this.onDidChangeQueriesEmitter = this.push(app.createEventEmitter<void>());
this.onDidChangeQueries = this.onDidChangeQueriesEmitter.event;
// Handlers
this.push(
this.queryPackDiscovery.onDidChangeQueryPacks(
this.recomputeAllData.bind(this),
),
);
}
/**
* Event that fires when the set of queries in the workspace changes.
*/
public get onDidChangeQueries(): Event<void> {
return this.onDidChangePathData;
this.push(
this.onDidChangePathData(() => {
this.onDidChangeQueriesEmitter.fire();
}),
);
this.push(
this.languageContext.onLanguageContextChanged(() => {
this.onDidChangeQueriesEmitter.fire();
}),
);
}
/**
@ -64,8 +78,10 @@ export class QueryDiscovery
const roots = [];
for (const workspaceFolder of getOnDiskWorkspaceFoldersObjects()) {
const queriesInRoot = pathData.filter((query) =>
containsPath(workspaceFolder.uri.fsPath, query.path),
const queriesInRoot = pathData.filter(
(query) =>
containsPath(workspaceFolder.uri.fsPath, query.path) &&
this.languageContext.shouldInclude(query.language),
);
if (queriesInRoot.length === 0) {
continue;
@ -73,7 +89,7 @@ export class QueryDiscovery
const root = new FileTreeDirectory<string>(
workspaceFolder.uri.fsPath,
workspaceFolder.name,
this.env,
this.app.environment,
);
for (const query of queriesInRoot) {
const dirName = dirname(normalize(relative(root.path, query.path)));

Просмотреть файл

@ -56,7 +56,7 @@ class MockAppEventEmitter<T> implements AppEventEmitter<T> {
constructor() {
this.event = () => {
return {} as Disposable;
return new MockAppEvent();
};
}
@ -69,7 +69,17 @@ class MockAppEventEmitter<T> implements AppEventEmitter<T> {
}
}
export function createMockEnvironmentContext(): EnvironmentContext {
class MockAppEvent implements Disposable {
public fire(): void {
// no-op
}
public dispose() {
// no-op
}
}
function createMockEnvironmentContext(): EnvironmentContext {
return {
language: "en-US",
};

Просмотреть файл

@ -3,8 +3,8 @@ import {
QueryDiscovery,
QueryPackDiscoverer,
} from "../../../../src/queries-panel/query-discovery";
import { createMockEnvironmentContext } from "../../../__mocks__/appMock";
import { dirname, join } from "path";
import { createMockApp } from "../../../__mocks__/appMock";
import { basename, dirname, join } from "path";
import * as tmp from "tmp";
import {
FileTreeDirectory,
@ -13,6 +13,7 @@ import {
import { mkdirSync, writeFileSync } from "fs";
import { QueryLanguage } from "../../../../src/common/query-language";
import { sleep } from "../../../../src/common/time";
import { LanguageContextStore } from "../../../../src/language-context-store";
describe("Query pack discovery", () => {
let tmpDir: string;
@ -20,7 +21,10 @@ describe("Query pack discovery", () => {
let workspacePath: string;
const env = createMockEnvironmentContext();
const app = createMockApp({});
const env = app.environment;
const languageContext = new LanguageContextStore(app);
const onDidChangeQueryPacks = new EventEmitter<void>();
let queryPackDiscoverer: QueryPackDiscoverer;
@ -45,7 +49,7 @@ describe("Query pack discovery", () => {
getLanguageForQueryFile: () => QueryLanguage.Java,
onDidChangeQueryPacks: onDidChangeQueryPacks.event,
};
discovery = new QueryDiscovery(env, queryPackDiscoverer);
discovery = new QueryDiscovery(app, queryPackDiscoverer, languageContext);
});
afterEach(() => {
@ -160,6 +164,52 @@ describe("Query pack discovery", () => {
]),
]);
});
it("should respect the language context filter", async () => {
makeTestFile(join(workspacePath, "query1.ql"));
makeTestFile(join(workspacePath, "query2.ql"));
queryPackDiscoverer.getLanguageForQueryFile = (path) => {
if (basename(path) === "query1.ql") {
return QueryLanguage.Java;
} else {
return QueryLanguage.Python;
}
};
await discovery.initialRefresh();
// Set the language to python-only
await languageContext.setLanguageContext(QueryLanguage.Python);
expect(discovery.buildQueryTree()).toEqual([
new FileTreeDirectory(workspacePath, "workspace", env, [
new FileTreeLeaf(
join(workspacePath, "query2.ql"),
"query2.ql",
"python",
),
]),
]);
// Clear the language context filter
await languageContext.clearLanguageContext();
expect(discovery.buildQueryTree()).toEqual([
new FileTreeDirectory(workspacePath, "workspace", env, [
new FileTreeLeaf(
join(workspacePath, "query1.ql"),
"query1.ql",
"java",
),
new FileTreeLeaf(
join(workspacePath, "query2.ql"),
"query2.ql",
"python",
),
]),
]);
});
});
describe("recomputeAllQueryLanguages", () => {