Skip to content

Commit a9edb36

Browse files
authored
Merge branch 'main' into aeisenberg/avoid-double-restart
2 parents 2b17979 + 3489c26 commit a9edb36

12 files changed

Lines changed: 158 additions & 46 deletions

File tree

docs/test-plan.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ Note that this test requires the feature flag: `codeQL.model.llmGeneration`
173173

174174
#### Test Case 4: Model as dependency
175175

176+
Note that this test requires the feature flag: `codeQL.model.flowGeneration`
177+
176178
1. Click "Model as dependency"
177179
- Check that grouping are now per package (e.g. `com.alipay.sofa.rraft.option` or `com.google.protobuf`)
178180
2. Click "Generate".

extensions/ql-vscode/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
- Fix a bug where the query server was restarted twice after configuration changes. [#2884](https://github.com/github/vscode-codeql/pull/2884).
66

7+
## 1.9.1 - 29 September 2023
8+
9+
- Add warning when using a VS Code version older than 1.82.0. [#2854](https://github.com/github/vscode-codeql/pull/2854)
10+
- Fix a bug when parsing large evaluation log summaries. [#2858](https://github.com/github/vscode-codeql/pull/2858)
11+
- Right-align and format numbers in raw result tables. [#2864](https://github.com/github/vscode-codeql/pull/2864)
12+
- Remove rate limit warning notifications when using Code Search to add repositories to a variant analysis list. [#2812](https://github.com/github/vscode-codeql/pull/2812)
13+
714
## 1.9.0 - 19 September 2023
815

916
- Release the [CodeQL model editor](https://codeql.github.com/docs/codeql/codeql-for-visual-studio-code/using-the-codeql-model-editor) to create CodeQL model packs for Java frameworks. Open the editor using the "CodeQL: Open CodeQL Model Editor (Beta)" command. [#2823](https://github.com/github/vscode-codeql/pull/2823)

extensions/ql-vscode/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/ql-vscode/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "CodeQL for Visual Studio Code",
55
"author": "GitHub",
66
"private": true,
7-
"version": "1.9.1",
7+
"version": "1.9.2",
88
"publisher": "GitHub",
99
"license": "MIT",
1010
"icon": "media/VS-marketplace-CodeQL-icon.png",
@@ -1870,11 +1870,11 @@
18701870
"codeQLDatabases.languages": [
18711871
{
18721872
"command": "codeQLDatabases.displayAllLanguages",
1873-
"when": "codeQLDatabases.languageFilter != All"
1873+
"when": "codeQLDatabases.languageFilter"
18741874
},
18751875
{
18761876
"command": "codeQLDatabases.displayAllLanguagesSelected",
1877-
"when": "codeQLDatabases.languageFilter == All"
1877+
"when": "!codeQLDatabases.languageFilter"
18781878
},
18791879
{
18801880
"command": "codeQLDatabases.displayCpp",

extensions/ql-vscode/src/common/query-language.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,9 @@ export const dbSchemeToLanguage: Record<string, QueryLanguage> = {
6262
export function isQueryLanguage(language: string): language is QueryLanguage {
6363
return Object.values(QueryLanguage).includes(language as QueryLanguage);
6464
}
65+
66+
export function tryGetQueryLanguage(
67+
language: string,
68+
): QueryLanguage | undefined {
69+
return isQueryLanguage(language) ? language : undefined;
70+
}

extensions/ql-vscode/src/common/vscode/abstract-webview.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { join } from "path";
1010

1111
import { App } from "../app";
12-
import { DisposableObject, DisposeHandler } from "../disposable-object";
12+
import { Disposable } from "../disposable-object";
1313
import { tmpDir } from "../../tmp-dir";
1414
import { getHtmlForWebview, WebviewMessage, WebviewKind } from "./webview-html";
1515

@@ -27,16 +27,16 @@ export type WebviewPanelConfig = {
2727
export abstract class AbstractWebview<
2828
ToMessage extends WebviewMessage,
2929
FromMessage extends WebviewMessage,
30-
> extends DisposableObject {
30+
> {
3131
protected panel: WebviewPanel | undefined;
3232
protected panelLoaded = false;
3333
protected panelLoadedCallBacks: Array<() => void> = [];
3434

3535
private panelResolves?: Array<(panel: WebviewPanel) => void>;
3636

37-
constructor(protected readonly app: App) {
38-
super();
39-
}
37+
private disposables: Disposable[] = [];
38+
39+
constructor(protected readonly app: App) {}
4040

4141
public async restoreView(panel: WebviewPanel): Promise<void> {
4242
this.panel = panel;
@@ -101,6 +101,7 @@ export abstract class AbstractWebview<
101101
this.panel = undefined;
102102
this.panelLoaded = false;
103103
this.onPanelDispose();
104+
this.disposeAll();
104105
}, null),
105106
);
106107

@@ -150,8 +151,27 @@ export abstract class AbstractWebview<
150151
return panel.webview.postMessage(msg);
151152
}
152153

153-
public dispose(disposeHandler?: DisposeHandler) {
154+
public dispose() {
154155
this.panel?.dispose();
155-
super.dispose(disposeHandler);
156+
this.disposeAll();
157+
}
158+
159+
private disposeAll() {
160+
while (this.disposables.length > 0) {
161+
const disposable = this.disposables.pop()!;
162+
disposable.dispose();
163+
}
164+
}
165+
166+
/**
167+
* Adds `obj` to a list of objects to dispose when the panel is disposed. Objects added by `push` are
168+
* disposed in reverse order of being added.
169+
* @param obj The object to take ownership of.
170+
*/
171+
protected push<T extends Disposable>(obj: T): T {
172+
if (obj !== undefined) {
173+
this.disposables.push(obj);
174+
}
175+
return obj;
156176
}
157177
}

extensions/ql-vscode/src/databases/local-databases-ui.ts

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ import {
5151
createMultiSelectionCommand,
5252
createSingleSelectionCommand,
5353
} from "../common/vscode/selection-commands";
54-
import { QueryLanguage } from "../common/query-language";
54+
import { QueryLanguage, tryGetQueryLanguage } from "../common/query-language";
55+
import { LanguageContextStore } from "../language-context-store";
5556

5657
enum SortOrder {
5758
NameAsc = "NameAsc",
@@ -60,8 +61,6 @@ enum SortOrder {
6061
DateAddedDesc = "DateAddedDesc",
6162
}
6263

63-
type LanguageFilter = QueryLanguage | "All";
64-
6564
/**
6665
* Tree data provider for the databases view.
6766
*/
@@ -70,14 +69,16 @@ class DatabaseTreeDataProvider
7069
implements TreeDataProvider<DatabaseItem>
7170
{
7271
private _sortOrder = SortOrder.NameAsc;
73-
private _languageFilter = "All" as LanguageFilter;
7472

7573
private readonly _onDidChangeTreeData = this.push(
7674
new EventEmitter<DatabaseItem | undefined>(),
7775
);
7876
private currentDatabaseItem: DatabaseItem | undefined;
7977

80-
constructor(private databaseManager: DatabaseManager) {
78+
constructor(
79+
private databaseManager: DatabaseManager,
80+
private languageContext: LanguageContextStore,
81+
) {
8182
super();
8283

8384
this.currentDatabaseItem = databaseManager.currentDatabaseItem;
@@ -92,6 +93,11 @@ class DatabaseTreeDataProvider
9293
this.handleDidChangeCurrentDatabaseItem.bind(this),
9394
),
9495
);
96+
this.push(
97+
this.languageContext.onLanguageContextChanged(async () => {
98+
this._onDidChangeTreeData.fire(undefined);
99+
}),
100+
);
95101
}
96102

97103
public get onDidChangeTreeData(): Event<DatabaseItem | undefined> {
@@ -137,11 +143,9 @@ class DatabaseTreeDataProvider
137143
if (element === undefined) {
138144
// Filter items by language
139145
const displayItems = this.databaseManager.databaseItems.filter((item) => {
140-
if (this.languageFilter === "All") {
141-
return true;
142-
} else {
143-
return item.language === this.languageFilter;
144-
}
146+
return this.languageContext.shouldInclude(
147+
tryGetQueryLanguage(item.language),
148+
);
145149
});
146150

147151
// Sort items
@@ -178,15 +182,6 @@ class DatabaseTreeDataProvider
178182
this._sortOrder = newSortOrder;
179183
this._onDidChangeTreeData.fire(undefined);
180184
}
181-
182-
public get languageFilter() {
183-
return this._languageFilter;
184-
}
185-
186-
public set languageFilter(newLanguageFilter: LanguageFilter) {
187-
this._languageFilter = newLanguageFilter;
188-
this._onDidChangeTreeData.fire(undefined);
189-
}
190185
}
191186

192187
/** Gets the first element in the given list, if any, or undefined if the list is empty or undefined. */
@@ -223,14 +218,15 @@ export class DatabaseUI extends DisposableObject {
223218
public constructor(
224219
private app: App,
225220
private databaseManager: DatabaseManager,
221+
private languageContext: LanguageContextStore,
226222
private readonly queryServer: QueryRunner | undefined,
227223
private readonly storagePath: string,
228224
readonly extensionPath: string,
229225
) {
230226
super();
231227

232228
this.treeDataProvider = this.push(
233-
new DatabaseTreeDataProvider(databaseManager),
229+
new DatabaseTreeDataProvider(databaseManager, languageContext),
234230
);
235231
this.push(
236232
window.createTreeView("codeQLDatabases", {
@@ -269,7 +265,7 @@ export class DatabaseUI extends DisposableObject {
269265
"codeQLDatabases.sortByName": this.handleSortByName.bind(this),
270266
"codeQLDatabases.sortByDateAdded": this.handleSortByDateAdded.bind(this),
271267
"codeQLDatabases.displayAllLanguages":
272-
this.handleChangeLanguageFilter.bind(this, "All"),
268+
this.handleClearLanguageFilter.bind(this),
273269
"codeQLDatabases.displayCpp": this.handleChangeLanguageFilter.bind(
274270
this,
275271
QueryLanguage.Cpp,
@@ -303,7 +299,7 @@ export class DatabaseUI extends DisposableObject {
303299
QueryLanguage.Swift,
304300
),
305301
"codeQLDatabases.displayAllLanguagesSelected":
306-
this.handleChangeLanguageFilter.bind(this, "All"),
302+
this.handleClearLanguageFilter.bind(this),
307303
"codeQLDatabases.displayCppSelected":
308304
this.handleChangeLanguageFilter.bind(this, QueryLanguage.Cpp),
309305
"codeQLDatabases.displayCsharpSelected":
@@ -612,13 +608,12 @@ export class DatabaseUI extends DisposableObject {
612608
}
613609
}
614610

615-
private async handleChangeLanguageFilter(languageFilter: LanguageFilter) {
616-
this.treeDataProvider.languageFilter = languageFilter;
617-
await this.app.commands.execute(
618-
"setContext",
619-
"codeQLDatabases.languageFilter",
620-
languageFilter,
621-
);
611+
private async handleClearLanguageFilter() {
612+
await this.languageContext.clearLanguageContext();
613+
}
614+
615+
private async handleChangeLanguageFilter(languageFilter: QueryLanguage) {
616+
await this.languageContext.setLanguageContext(languageFilter);
622617
}
623618

624619
private async handleUpgradeCurrentDatabase(): Promise<void> {

extensions/ql-vscode/src/extension.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ import { TestManagerBase } from "./query-testing/test-manager-base";
135135
import { NewQueryRunner, QueryRunner, QueryServerClient } from "./query-server";
136136
import { QueriesModule } from "./queries-panel/queries-module";
137137
import { OpenReferencedFileCodeLensProvider } from "./local-queries/open-referenced-file-code-lens-provider";
138+
import { LanguageContextStore } from "./language-context-store";
138139

139140
/**
140141
* extension.ts
@@ -774,10 +775,15 @@ async function activateWithInstalledDistribution(
774775
void dbm.loadPersistedState();
775776

776777
ctx.subscriptions.push(dbm);
778+
779+
void extLogger.log("Initializing language context.");
780+
const languageContext = new LanguageContextStore(app);
781+
777782
void extLogger.log("Initializing database panel.");
778783
const databaseUI = new DatabaseUI(
779784
app,
780785
dbm,
786+
languageContext,
781787
qs,
782788
getContextStoragePath(ctx),
783789
ctx.extensionPath,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { App } from "./common/app";
2+
import { DisposableObject } from "./common/disposable-object";
3+
import { AppEvent, AppEventEmitter } from "./common/events";
4+
import { QueryLanguage } from "./common/query-language";
5+
6+
type LanguageFilter = QueryLanguage | "All";
7+
8+
export class LanguageContextStore extends DisposableObject {
9+
public readonly onLanguageContextChanged: AppEvent<void>;
10+
private readonly onLanguageContextChangedEmitter: AppEventEmitter<void>;
11+
12+
private languageFilter: LanguageFilter;
13+
14+
constructor(private readonly app: App) {
15+
super();
16+
// State initialization
17+
this.languageFilter = "All";
18+
19+
// Set up event emitters
20+
this.onLanguageContextChangedEmitter = this.push(
21+
app.createEventEmitter<void>(),
22+
);
23+
this.onLanguageContextChanged = this.onLanguageContextChangedEmitter.event;
24+
}
25+
26+
public async clearLanguageContext() {
27+
this.languageFilter = "All";
28+
this.onLanguageContextChangedEmitter.fire();
29+
await this.app.commands.execute(
30+
"setContext",
31+
"codeQLDatabases.languageFilter",
32+
"",
33+
);
34+
}
35+
36+
public async setLanguageContext(language: QueryLanguage) {
37+
this.languageFilter = language;
38+
this.onLanguageContextChangedEmitter.fire();
39+
await this.app.commands.execute(
40+
"setContext",
41+
"codeQLDatabases.languageFilter",
42+
language,
43+
);
44+
}
45+
46+
public shouldInclude(language: QueryLanguage | undefined): boolean {
47+
return this.languageFilter === "All" || this.languageFilter === language;
48+
}
49+
}

0 commit comments

Comments
 (0)