Skip to content

Commit 0d0ae64

Browse files
authored
Merge branch 'main' into shati-patel/run-query-context-menu-local
2 parents 9704b49 + aa4d3f4 commit 0d0ae64

File tree

15 files changed

+333
-265
lines changed

15 files changed

+333
-265
lines changed

extensions/ql-vscode/package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,11 @@
503503
},
504504
{
505505
"command": "codeQLQueries.runLocalQueryFromQueriesPanel",
506-
"title": "Run local query",
506+
"title": "Run local query"
507+
},
508+
{
509+
"command": "codeQL.runLocalQueryFromFileTab",
510+
"title": "CodeQL: Run local query",
507511
"icon": "$(run)"
508512
},
509513
{
@@ -881,6 +885,13 @@
881885
}
882886
],
883887
"menus": {
888+
"editor/title": [
889+
{
890+
"command": "codeQL.runLocalQueryFromFileTab",
891+
"group": "navigation",
892+
"when": "config.codeQL.queriesPanel && resourceExtname == .ql && codeQL.currentDatabaseItem"
893+
}
894+
],
884895
"view/title": [
885896
{
886897
"command": "codeQLDatabases.sortByName",
@@ -1177,6 +1188,10 @@
11771188
"command": "codeQLQueries.runLocalQueryFromQueriesPanel",
11781189
"when": "false"
11791190
},
1191+
{
1192+
"command": "codeQL.runLocalQueryFromFileTab",
1193+
"when": "false"
1194+
},
11801195
{
11811196
"command": "codeQL.runQueryContextEditor",
11821197
"when": "false"

extensions/ql-vscode/src/common/commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ export type LocalQueryCommands = {
132132
) => Promise<void>;
133133
"codeQLQueries.runLocalQueryFromQueriesPanel": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>;
134134
"codeQLQueries.runLocalQueryContextMenu": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>;
135+
"codeQL.runLocalQueryFromFileTab": (uri: Uri) => Promise<void>;
135136
"codeQL.runQueries": ExplorerSelectionCommandFunction<Uri>;
136137
"codeQL.quickEval": (uri: Uri) => Promise<void>;
137138
"codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>;

extensions/ql-vscode/src/data-extensions-editor/auto-model.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
ModelRequest,
88
} from "./auto-model-api";
99
import type { UsageSnippetsBySignature } from "./auto-model-usages-query";
10+
import { groupMethods, sortGroupNames, sortMethods } from "./shared/sorting";
11+
import { Mode } from "./shared/mode";
1012

1113
// Soft limit on the number of candidates to send to the model.
1214
// Note that the model may return fewer than this number of candidates.
@@ -19,18 +21,22 @@ export function createAutoModelRequest(
1921
externalApiUsages: ExternalApiUsage[],
2022
modeledMethods: Record<string, ModeledMethod>,
2123
usages: UsageSnippetsBySignature,
24+
mode: Mode,
2225
): ModelRequest {
2326
const request: ModelRequest = {
2427
language,
2528
samples: [],
2629
candidates: [],
2730
};
2831

29-
// Sort by number of usages so we always send the most used methods first
30-
externalApiUsages = [...externalApiUsages];
31-
externalApiUsages.sort((a, b) => b.usages.length - a.usages.length);
32+
// Sort the same way as the UI so we send the first ones listed in the UI first
33+
const grouped = groupMethods(externalApiUsages, mode);
34+
const sortedGroupNames = sortGroupNames(grouped);
35+
const sortedExternalApiUsages = sortedGroupNames.flatMap((name) =>
36+
sortMethods(grouped[name]),
37+
);
3238

33-
for (const externalApiUsage of externalApiUsages) {
39+
for (const externalApiUsage of sortedExternalApiUsages) {
3440
const modeledMethod: ModeledMethod = modeledMethods[
3541
externalApiUsage.signature
3642
] ?? {

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
457457
externalApiUsages,
458458
modeledMethods,
459459
usages,
460+
this.mode,
460461
);
461462

462463
await this.showProgress({

extensions/ql-vscode/src/view/data-extensions-editor/modeled.ts renamed to extensions/ql-vscode/src/data-extensions-editor/shared/modeled-percentage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
1+
import { ExternalApiUsage } from "../external-api-usage";
22

33
export function calculateModeledPercentage(
44
externalApiUsages: Array<Pick<ExternalApiUsage, "supported">>,
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { ExternalApiUsage } from "../external-api-usage";
2+
import { Mode } from "./mode";
3+
import { calculateModeledPercentage } from "./modeled-percentage";
4+
5+
export function groupMethods(
6+
externalApiUsages: ExternalApiUsage[],
7+
mode: Mode,
8+
): Record<string, ExternalApiUsage[]> {
9+
const groupedByLibrary: Record<string, ExternalApiUsage[]> = {};
10+
11+
for (const externalApiUsage of externalApiUsages) {
12+
// Group by package if using framework mode
13+
const key =
14+
mode === Mode.Framework
15+
? externalApiUsage.packageName
16+
: externalApiUsage.library;
17+
18+
groupedByLibrary[key] ??= [];
19+
groupedByLibrary[key].push(externalApiUsage);
20+
}
21+
22+
return groupedByLibrary;
23+
}
24+
25+
export function sortGroupNames(
26+
methods: Record<string, ExternalApiUsage[]>,
27+
): string[] {
28+
return Object.keys(methods).sort((a, b) =>
29+
compareGroups(methods[a], a, methods[b], b),
30+
);
31+
}
32+
33+
export function sortMethods(
34+
externalApiUsages: ExternalApiUsage[],
35+
): ExternalApiUsage[] {
36+
const sortedExternalApiUsages = [...externalApiUsages];
37+
sortedExternalApiUsages.sort((a, b) => compareMethod(a, b));
38+
return sortedExternalApiUsages;
39+
}
40+
41+
function compareGroups(
42+
a: ExternalApiUsage[],
43+
aName: string,
44+
b: ExternalApiUsage[],
45+
bName: string,
46+
): number {
47+
const supportedPercentageA = calculateModeledPercentage(a);
48+
const supportedPercentageB = calculateModeledPercentage(b);
49+
50+
// Sort first by supported percentage ascending
51+
if (supportedPercentageA > supportedPercentageB) {
52+
return 1;
53+
}
54+
if (supportedPercentageA < supportedPercentageB) {
55+
return -1;
56+
}
57+
58+
const numberOfUsagesA = a.reduce((acc, curr) => acc + curr.usages.length, 0);
59+
const numberOfUsagesB = b.reduce((acc, curr) => acc + curr.usages.length, 0);
60+
61+
// If the number of usages is equal, sort by number of methods descending
62+
if (numberOfUsagesA === numberOfUsagesB) {
63+
const numberOfMethodsA = a.length;
64+
const numberOfMethodsB = b.length;
65+
66+
// If the number of methods is equal, sort by library name ascending
67+
if (numberOfMethodsA === numberOfMethodsB) {
68+
return aName.localeCompare(bName);
69+
}
70+
71+
return numberOfMethodsB - numberOfMethodsA;
72+
}
73+
74+
// Then sort by number of usages descending
75+
return numberOfUsagesB - numberOfUsagesA;
76+
}
77+
78+
function compareMethod(a: ExternalApiUsage, b: ExternalApiUsage): number {
79+
// Sort first by supported, putting unmodeled methods first.
80+
if (a.supported && !b.supported) {
81+
return 1;
82+
}
83+
if (!a.supported && b.supported) {
84+
return -1;
85+
}
86+
// Then sort by number of usages descending
87+
return b.usages.length - a.usages.length;
88+
}

extensions/ql-vscode/src/local-queries/local-queries.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export class LocalQueries extends DisposableObject {
105105
this.runQueryFromQueriesPanel.bind(this),
106106
"codeQLQueries.runLocalQueryContextMenu":
107107
this.runQueryFromQueriesPanel.bind(this),
108+
"codeQL.runLocalQueryFromFileTab": this.runQuery.bind(this),
108109
"codeQL.runQueries": createMultiSelectionCommand(
109110
this.runQueries.bind(this),
110111
),

extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
1010
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
1111
import { assertNever } from "../../common/helpers-pure";
1212
import { vscode } from "../vscode-api";
13-
import { calculateModeledPercentage } from "./modeled";
13+
import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
1414
import { LinkIconButton } from "../variant-analysis/LinkIconButton";
1515
import { ViewTitle } from "../common";
1616
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";

extensions/ql-vscode/src/view/data-extensions-editor/LibraryRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
55
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
66
import { pluralize } from "../../common/word";
77
import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid";
8-
import { calculateModeledPercentage } from "./modeled";
8+
import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
99
import { decimalFormatter, percentFormatter } from "./formatters";
1010
import { Codicon } from "../common";
1111
import { Mode } from "../../data-extensions-editor/shared/mode";

extensions/ql-vscode/src/view/data-extensions-editor/ModeledMethodDataGrid.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
99
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
1010
import { useMemo } from "react";
1111
import { Mode } from "../../data-extensions-editor/shared/mode";
12+
import { sortMethods } from "../../data-extensions-editor/shared/sorting";
1213

1314
type Props = {
1415
externalApiUsages: ExternalApiUsage[];
@@ -26,21 +27,10 @@ export const ModeledMethodDataGrid = ({
2627
mode,
2728
onChange,
2829
}: Props) => {
29-
const sortedExternalApiUsages = useMemo(() => {
30-
const sortedExternalApiUsages = [...externalApiUsages];
31-
sortedExternalApiUsages.sort((a, b) => {
32-
// Sort first by supported, putting unmodeled methods first.
33-
if (a.supported && !b.supported) {
34-
return 1;
35-
}
36-
if (!a.supported && b.supported) {
37-
return -1;
38-
}
39-
// Then sort by number of usages descending
40-
return b.usages.length - a.usages.length;
41-
});
42-
return sortedExternalApiUsages;
43-
}, [externalApiUsages]);
30+
const sortedExternalApiUsages = useMemo(
31+
() => sortMethods(externalApiUsages),
32+
[externalApiUsages],
33+
);
4434

4535
return (
4636
<VSCodeDataGrid>

0 commit comments

Comments
 (0)