Skip to content

Commit 2fdafaf

Browse files
Move getCandidates to the shared directory
1 parent d9ae0c6 commit 2fdafaf

File tree

6 files changed

+178
-174
lines changed

6 files changed

+178
-174
lines changed

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

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,59 +5,6 @@ import type { AutoModelQueriesResult } from "./auto-model-codeml-queries";
55
import { assertNever } from "../common/helpers-pure";
66
import type { Log } from "sarif";
77
import { gzipEncode } from "../common/zlib";
8-
import type { Method, MethodSignature } from "./method";
9-
import type { ModeledMethod } from "./modeled-method";
10-
import { groupMethods, sortGroupNames, sortMethods } from "./shared/sorting";
11-
12-
/**
13-
* Return the candidates that the model should be run on. This includes limiting the number of
14-
* candidates to the candidate limit and filtering out anything that is already modeled and respecting
15-
* the order in the UI.
16-
* @param mode Whether it is application or framework mode.
17-
* @param methods all methods.
18-
* @param modeledMethodsBySignature the currently modeled methods.
19-
* @returns list of modeled methods that are candidates for modeling.
20-
*/
21-
export function getCandidates(
22-
mode: Mode,
23-
methods: readonly Method[],
24-
modeledMethodsBySignature: Record<string, readonly ModeledMethod[]>,
25-
processedByAutoModelMethods: Set<string>,
26-
): MethodSignature[] {
27-
// Filter out any methods already processed by auto-model
28-
methods = methods.filter(
29-
(m) => !processedByAutoModelMethods.has(m.signature),
30-
);
31-
32-
// Sort the same way as the UI so we send the first ones listed in the UI first
33-
const grouped = groupMethods(methods, mode);
34-
const sortedGroupNames = sortGroupNames(grouped);
35-
const sortedMethods = sortedGroupNames.flatMap((name) =>
36-
sortMethods(grouped[name]),
37-
);
38-
39-
const candidates: MethodSignature[] = [];
40-
41-
for (const method of sortedMethods) {
42-
const modeledMethods: ModeledMethod[] = [
43-
...(modeledMethodsBySignature[method.signature] ?? []),
44-
];
45-
46-
// Anything that is modeled is not a candidate
47-
if (modeledMethods.some((m) => m.type !== "none")) {
48-
continue;
49-
}
50-
51-
// A method that is supported is modeled outside of the model file, so it is not a candidate.
52-
if (method.supported) {
53-
continue;
54-
}
55-
56-
// The rest are candidates
57-
candidates.push(method);
58-
}
59-
return candidates;
60-
}
618

629
/**
6310
* Encode a SARIF log to the format expected by the server: JSON, GZIP-compressed, base64-encoded

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import type { ModeledMethod } from "./modeled-method";
33
import { load as loadYaml } from "js-yaml";
44
import type { ProgressCallback } from "../common/vscode/progress";
55
import { withProgress } from "../common/vscode/progress";
6-
import { createAutoModelRequest, getCandidates } from "./auto-model";
6+
import { createAutoModelRequest } from "./auto-model";
7+
import { getCandidates } from "./shared/auto-model-candidates";
78
import { runAutoModelQueries } from "./auto-model-codeml-queries";
89
import { loadDataExtensionYaml } from "./yaml";
910
import type { ModelRequest, ModelResponse } from "./auto-model-api";
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import type { Method, MethodSignature } from "../method";
2+
import type { ModeledMethod } from "../modeled-method";
3+
import type { Mode } from "./mode";
4+
import { groupMethods, sortGroupNames, sortMethods } from "./sorting";
5+
6+
/**
7+
* Return the candidates that the model should be run on. This includes limiting the number of
8+
* candidates to the candidate limit and filtering out anything that is already modeled and respecting
9+
* the order in the UI.
10+
* @param mode Whether it is application or framework mode.
11+
* @param methods all methods.
12+
* @param modeledMethodsBySignature the currently modeled methods.
13+
* @returns list of modeled methods that are candidates for modeling.
14+
*/
15+
16+
export function getCandidates(
17+
mode: Mode,
18+
methods: readonly Method[],
19+
modeledMethodsBySignature: Record<string, readonly ModeledMethod[]>,
20+
processedByAutoModelMethods: Set<string>,
21+
): MethodSignature[] {
22+
// Filter out any methods already processed by auto-model
23+
methods = methods.filter(
24+
(m) => !processedByAutoModelMethods.has(m.signature),
25+
);
26+
27+
// Sort the same way as the UI so we send the first ones listed in the UI first
28+
const grouped = groupMethods(methods, mode);
29+
const sortedGroupNames = sortGroupNames(grouped);
30+
const sortedMethods = sortedGroupNames.flatMap((name) =>
31+
sortMethods(grouped[name]),
32+
);
33+
34+
const candidates: MethodSignature[] = [];
35+
36+
for (const method of sortedMethods) {
37+
const modeledMethods: ModeledMethod[] = [
38+
...(modeledMethodsBySignature[method.signature] ?? []),
39+
];
40+
41+
// Anything that is modeled is not a candidate
42+
if (modeledMethods.some((m) => m.type !== "none")) {
43+
continue;
44+
}
45+
46+
// A method that is supported is modeled outside of the model file, so it is not a candidate.
47+
if (method.supported) {
48+
continue;
49+
}
50+
51+
// The rest are candidates
52+
candidates.push(method);
53+
}
54+
return candidates;
55+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
} from "@vscode/webview-ui-toolkit/react";
1515
import type { ModelEditorViewState } from "../../model-editor/shared/view-state";
1616
import type { AccessPathSuggestionOptions } from "../../model-editor/suggestions";
17-
import { getCandidates } from "../../model-editor/auto-model";
17+
import { getCandidates } from "../../model-editor/shared/auto-model-candidates";
1818

1919
const LibraryContainer = styled.div`
2020
background-color: var(--vscode-peekViewResult-background);
Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import {
22
createAutoModelRequest,
33
encodeSarif,
4-
getCandidates,
54
} from "../../../src/model-editor/auto-model";
65
import { Mode } from "../../../src/model-editor/shared/mode";
76
import { AutomodelMode } from "../../../src/model-editor/auto-model-api";
87
import type { AutoModelQueriesResult } from "../../../src/model-editor/auto-model-codeml-queries";
98
import type { Log } from "sarif";
109
import { gzipDecode } from "../../../src/common/zlib";
11-
import type { Method } from "../../../src/model-editor/method";
12-
import { EndpointType } from "../../../src/model-editor/method";
13-
import type { ModeledMethod } from "../../../src/model-editor/modeled-method";
1410

1511
describe("createAutoModelRequest", () => {
1612
const createSarifLog = (queryId: string): Log => {
@@ -84,118 +80,3 @@ describe("createAutoModelRequest", () => {
8480
expect(parsed).toEqual(result.candidates);
8581
});
8682
});
87-
88-
describe("getCandidates", () => {
89-
it("doesn't return methods that are already modelled", () => {
90-
const methods: Method[] = [
91-
{
92-
library: "my.jar",
93-
signature: "org.my.A#x()",
94-
endpointType: EndpointType.Method,
95-
packageName: "org.my",
96-
typeName: "A",
97-
methodName: "x",
98-
methodParameters: "()",
99-
supported: false,
100-
supportedType: "none",
101-
usages: [],
102-
},
103-
];
104-
const modeledMethods: Record<string, ModeledMethod[]> = {
105-
"org.my.A#x()": [
106-
{
107-
type: "neutral",
108-
kind: "sink",
109-
provenance: "manual",
110-
signature: "org.my.A#x()",
111-
endpointType: EndpointType.Method,
112-
packageName: "org.my",
113-
typeName: "A",
114-
methodName: "x",
115-
methodParameters: "()",
116-
},
117-
],
118-
};
119-
const candidates = getCandidates(
120-
Mode.Application,
121-
methods,
122-
modeledMethods,
123-
new Set(),
124-
);
125-
expect(candidates.length).toEqual(0);
126-
});
127-
128-
it("doesn't return methods that are supported from other sources", () => {
129-
const methods: Method[] = [
130-
{
131-
library: "my.jar",
132-
signature: "org.my.A#x()",
133-
endpointType: EndpointType.Method,
134-
packageName: "org.my",
135-
typeName: "A",
136-
methodName: "x",
137-
methodParameters: "()",
138-
supported: true,
139-
supportedType: "none",
140-
usages: [],
141-
},
142-
];
143-
const modeledMethods = {};
144-
const candidates = getCandidates(
145-
Mode.Application,
146-
methods,
147-
modeledMethods,
148-
new Set(),
149-
);
150-
expect(candidates.length).toEqual(0);
151-
});
152-
153-
it("doesn't return methods that are already processed by auto model", () => {
154-
const methods: Method[] = [
155-
{
156-
library: "my.jar",
157-
signature: "org.my.A#x()",
158-
endpointType: EndpointType.Method,
159-
packageName: "org.my",
160-
typeName: "A",
161-
methodName: "x",
162-
methodParameters: "()",
163-
supported: false,
164-
supportedType: "none",
165-
usages: [],
166-
},
167-
];
168-
const modeledMethods = {};
169-
const candidates = getCandidates(
170-
Mode.Application,
171-
methods,
172-
modeledMethods,
173-
new Set(["org.my.A#x()"]),
174-
);
175-
expect(candidates.length).toEqual(0);
176-
});
177-
178-
it("returns methods that are neither modeled nor supported from other sources", () => {
179-
const methods: Method[] = [];
180-
methods.push({
181-
library: "my.jar",
182-
signature: "org.my.A#x()",
183-
endpointType: EndpointType.Method,
184-
packageName: "org.my",
185-
typeName: "A",
186-
methodName: "x",
187-
methodParameters: "()",
188-
supported: false,
189-
supportedType: "none",
190-
usages: [],
191-
});
192-
const modeledMethods = {};
193-
const candidates = getCandidates(
194-
Mode.Application,
195-
methods,
196-
modeledMethods,
197-
new Set(),
198-
);
199-
expect(candidates.length).toEqual(1);
200-
});
201-
});
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import type { Method } from "../../../../src/model-editor/method";
2+
import { EndpointType } from "../../../../src/model-editor/method";
3+
import type { ModeledMethod } from "../../../../src/model-editor/modeled-method";
4+
import { getCandidates } from "../../../../src/model-editor/shared/auto-model-candidates";
5+
import { Mode } from "../../../../src/model-editor/shared/mode";
6+
7+
describe("getCandidates", () => {
8+
it("doesn't return methods that are already modelled", () => {
9+
const methods: Method[] = [
10+
{
11+
library: "my.jar",
12+
signature: "org.my.A#x()",
13+
endpointType: EndpointType.Method,
14+
packageName: "org.my",
15+
typeName: "A",
16+
methodName: "x",
17+
methodParameters: "()",
18+
supported: false,
19+
supportedType: "none",
20+
usages: [],
21+
},
22+
];
23+
const modeledMethods: Record<string, ModeledMethod[]> = {
24+
"org.my.A#x()": [
25+
{
26+
type: "neutral",
27+
kind: "sink",
28+
provenance: "manual",
29+
signature: "org.my.A#x()",
30+
endpointType: EndpointType.Method,
31+
packageName: "org.my",
32+
typeName: "A",
33+
methodName: "x",
34+
methodParameters: "()",
35+
},
36+
],
37+
};
38+
const candidates = getCandidates(
39+
Mode.Application,
40+
methods,
41+
modeledMethods,
42+
new Set(),
43+
);
44+
expect(candidates.length).toEqual(0);
45+
});
46+
47+
it("doesn't return methods that are supported from other sources", () => {
48+
const methods: Method[] = [
49+
{
50+
library: "my.jar",
51+
signature: "org.my.A#x()",
52+
endpointType: EndpointType.Method,
53+
packageName: "org.my",
54+
typeName: "A",
55+
methodName: "x",
56+
methodParameters: "()",
57+
supported: true,
58+
supportedType: "none",
59+
usages: [],
60+
},
61+
];
62+
const modeledMethods = {};
63+
const candidates = getCandidates(
64+
Mode.Application,
65+
methods,
66+
modeledMethods,
67+
new Set(),
68+
);
69+
expect(candidates.length).toEqual(0);
70+
});
71+
72+
it("doesn't return methods that are already processed by auto model", () => {
73+
const methods: Method[] = [
74+
{
75+
library: "my.jar",
76+
signature: "org.my.A#x()",
77+
endpointType: EndpointType.Method,
78+
packageName: "org.my",
79+
typeName: "A",
80+
methodName: "x",
81+
methodParameters: "()",
82+
supported: false,
83+
supportedType: "none",
84+
usages: [],
85+
},
86+
];
87+
const modeledMethods = {};
88+
const candidates = getCandidates(
89+
Mode.Application,
90+
methods,
91+
modeledMethods,
92+
new Set(["org.my.A#x()"]),
93+
);
94+
expect(candidates.length).toEqual(0);
95+
});
96+
97+
it("returns methods that are neither modeled nor supported from other sources", () => {
98+
const methods: Method[] = [];
99+
methods.push({
100+
library: "my.jar",
101+
signature: "org.my.A#x()",
102+
endpointType: EndpointType.Method,
103+
packageName: "org.my",
104+
typeName: "A",
105+
methodName: "x",
106+
methodParameters: "()",
107+
supported: false,
108+
supportedType: "none",
109+
usages: [],
110+
});
111+
const modeledMethods = {};
112+
const candidates = getCandidates(
113+
Mode.Application,
114+
methods,
115+
modeledMethods,
116+
new Set(),
117+
);
118+
expect(candidates.length).toEqual(1);
119+
});
120+
});

0 commit comments

Comments
 (0)