Skip to content

Commit 6e802b1

Browse files
authored
Merge pull request #2798 from github/koesie10/group-framework-mode-models
Group framework mode model files by package
2 parents c868bdc + 708c5bc commit 6e802b1

File tree

5 files changed

+86
-56
lines changed

5 files changed

+86
-56
lines changed

extensions/ql-vscode/src/model-editor/extension-pack-name.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function autoNameExtensionPack(
3737
};
3838
}
3939

40-
export function sanitizeExtensionPackName(name: string) {
40+
function sanitizeExtensionPackName(name: string) {
4141
// Lowercase everything
4242
name = name.toLowerCase();
4343

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ export class ModelEditorView extends AbstractWebview<
217217
});
218218
await saveModeledMethods(
219219
this.extensionPack,
220-
this.databaseItem.name,
221220
this.databaseItem.language,
222221
msg.methods,
223222
msg.modeledMethods,

extensions/ql-vscode/src/model-editor/modeled-method-fs.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { pathsEqual } from "../common/files";
1313

1414
export async function saveModeledMethods(
1515
extensionPack: ExtensionPack,
16-
databaseName: string,
1716
language: string,
1817
methods: Method[],
1918
modeledMethods: Record<string, ModeledMethod>,
@@ -28,7 +27,6 @@ export async function saveModeledMethods(
2827
);
2928

3029
const yamls = createDataExtensionYamls(
31-
databaseName,
3230
language,
3331
methods,
3432
modeledMethods,

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

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
} from "./predicates";
99

1010
import * as dataSchemaJson from "./data-schema.json";
11-
import { sanitizeExtensionPackName } from "./extension-pack-name";
1211
import { Mode } from "./shared/mode";
1312
import { assertNever } from "../common/helpers-pure";
1413

@@ -69,7 +68,6 @@ ${extensions.join("\n")}`;
6968
}
7069

7170
export function createDataExtensionYamls(
72-
databaseName: string,
7371
language: string,
7472
methods: Method[],
7573
newModeledMethods: Record<string, ModeledMethod>,
@@ -86,7 +84,6 @@ export function createDataExtensionYamls(
8684
);
8785
case Mode.Framework:
8886
return createDataExtensionYamlsForFrameworkMode(
89-
databaseName,
9087
language,
9188
methods,
9289
newModeledMethods,
@@ -97,31 +94,29 @@ export function createDataExtensionYamls(
9794
}
9895
}
9996

100-
export function createDataExtensionYamlsForApplicationMode(
97+
function createDataExtensionYamlsByGrouping(
10198
language: string,
10299
methods: Method[],
103100
newModeledMethods: Record<string, ModeledMethod>,
104101
existingModeledMethods: Record<string, Record<string, ModeledMethod>>,
102+
createFilename: (method: Method) => string,
105103
): Record<string, string> {
106-
const methodsByLibraryFilename: Record<
107-
string,
108-
Record<string, ModeledMethod>
109-
> = {};
104+
const methodsByFilename: Record<string, Record<string, ModeledMethod>> = {};
110105

111106
// We only want to generate a yaml file when it's a known external API usage
112107
// and there are new modeled methods for it. This avoids us overwriting other
113108
// files that may contain data we don't know about.
114109
for (const method of methods) {
115110
if (method.signature in newModeledMethods) {
116-
methodsByLibraryFilename[createFilenameForLibrary(method.library)] = {};
111+
methodsByFilename[createFilename(method)] = {};
117112
}
118113
}
119114

120-
// First populate methodsByLibraryFilename with any existing modeled methods.
115+
// First populate methodsByFilename with any existing modeled methods.
121116
for (const [filename, methods] of Object.entries(existingModeledMethods)) {
122-
if (filename in methodsByLibraryFilename) {
117+
if (filename in methodsByFilename) {
123118
for (const [signature, method] of Object.entries(methods)) {
124-
methodsByLibraryFilename[filename][signature] = method;
119+
methodsByFilename[filename][signature] = method;
125120
}
126121
}
127122
}
@@ -131,14 +126,14 @@ export function createDataExtensionYamlsForApplicationMode(
131126
for (const method of methods) {
132127
const newMethod = newModeledMethods[method.signature];
133128
if (newMethod) {
134-
const filename = createFilenameForLibrary(method.library);
135-
methodsByLibraryFilename[filename][newMethod.signature] = newMethod;
129+
const filename = createFilename(method);
130+
methodsByFilename[filename][newMethod.signature] = newMethod;
136131
}
137132
}
138133

139134
const result: Record<string, string> = {};
140135

141-
for (const [filename, methods] of Object.entries(methodsByLibraryFilename)) {
136+
for (const [filename, methods] of Object.entries(methodsByFilename)) {
142137
result[filename] = createDataExtensionYaml(
143138
language,
144139
Object.values(methods),
@@ -148,43 +143,34 @@ export function createDataExtensionYamlsForApplicationMode(
148143
return result;
149144
}
150145

151-
export function createDataExtensionYamlsForFrameworkMode(
152-
databaseName: string,
146+
export function createDataExtensionYamlsForApplicationMode(
153147
language: string,
154-
unmodeledMethods: Method[],
148+
methods: Method[],
155149
newModeledMethods: Record<string, ModeledMethod>,
156150
existingModeledMethods: Record<string, Record<string, ModeledMethod>>,
157-
prefix = "models/",
158-
suffix = ".model",
159151
): Record<string, string> {
160-
const parts = databaseName.split("/");
161-
const libraryName = parts
162-
.slice(1)
163-
.map((part) => sanitizeExtensionPackName(part))
164-
.join("-");
165-
const filename = `${prefix}${libraryName}${suffix}.yml`;
166-
167-
const methods: Record<string, ModeledMethod> = {};
168-
169-
// First populate methodsByLibraryFilename with any existing modeled methods.
170-
for (const [signature, method] of Object.entries(
171-
existingModeledMethods[filename] || {},
172-
)) {
173-
methods[signature] = method;
174-
}
175-
176-
// Add the new modeled methods, potentially overwriting existing modeled methods
177-
// but not removing existing modeled methods that are not in the new set.
178-
for (const method of unmodeledMethods) {
179-
const modeledMethod = newModeledMethods[method.signature];
180-
if (modeledMethod) {
181-
methods[modeledMethod.signature] = modeledMethod;
182-
}
183-
}
152+
return createDataExtensionYamlsByGrouping(
153+
language,
154+
methods,
155+
newModeledMethods,
156+
existingModeledMethods,
157+
(method) => createFilenameForLibrary(method.library),
158+
);
159+
}
184160

185-
return {
186-
[filename]: createDataExtensionYaml(language, Object.values(methods)),
187-
};
161+
export function createDataExtensionYamlsForFrameworkMode(
162+
language: string,
163+
methods: Method[],
164+
newModeledMethods: Record<string, ModeledMethod>,
165+
existingModeledMethods: Record<string, Record<string, ModeledMethod>>,
166+
): Record<string, string> {
167+
return createDataExtensionYamlsByGrouping(
168+
language,
169+
methods,
170+
newModeledMethods,
171+
existingModeledMethods,
172+
(method) => createFilenameForPackage(method.packageName),
173+
);
188174
}
189175

190176
export function createFilenameForLibrary(
@@ -214,6 +200,17 @@ export function createFilenameForLibrary(
214200
return `${prefix}${libraryName}${suffix}.yml`;
215201
}
216202

203+
export function createFilenameForPackage(
204+
packageName: string,
205+
prefix = "models/",
206+
suffix = ".model",
207+
) {
208+
// A package name is e.g. `com.google.common.io` or `System.Net.Http.Headers`
209+
// We want to place these into `models/com.google.common.io.model.yml` and
210+
// `models/System.Net.Http.Headers.model.yml` respectively.
211+
return `${prefix}${packageName}${suffix}.yml`;
212+
}
213+
217214
export function loadDataExtensionYaml(
218215
data: any,
219216
): Record<string, ModeledMethod> | undefined {

extensions/ql-vscode/test/unit-tests/model-editor/yaml.test.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
createDataExtensionYamlsForApplicationMode,
44
createDataExtensionYamlsForFrameworkMode,
55
createFilenameForLibrary,
6+
createFilenameForPackage,
67
loadDataExtensionYaml,
78
} from "../../../src/model-editor/yaml";
89
import { CallClassification } from "../../../src/model-editor/method";
@@ -598,7 +599,6 @@ describe("createDataExtensionYamlsForApplicationMode", () => {
598599
describe("createDataExtensionYamlsForFrameworkMode", () => {
599600
it("creates the correct YAML files when there are no existing modeled methods", () => {
600601
const yaml = createDataExtensionYamlsForFrameworkMode(
601-
"github/sql2o",
602602
"java",
603603
[
604604
{
@@ -723,7 +723,7 @@ describe("createDataExtensionYamlsForFrameworkMode", () => {
723723
);
724724

725725
expect(yaml).toEqual({
726-
"models/sql2o.model.yml": `extensions:
726+
"models/org.sql2o.model.yml": `extensions:
727727
- addsTo:
728728
pack: codeql/java-all
729729
extensible: sourceModel
@@ -751,7 +751,6 @@ describe("createDataExtensionYamlsForFrameworkMode", () => {
751751

752752
it("creates the correct YAML files when there are existing modeled methods", () => {
753753
const yaml = createDataExtensionYamlsForFrameworkMode(
754-
"github/sql2o",
755754
"java",
756755
[
757756
{
@@ -873,7 +872,7 @@ describe("createDataExtensionYamlsForFrameworkMode", () => {
873872
},
874873
},
875874
{
876-
"models/sql2o.model.yml": {
875+
"models/org.sql2o.model.yml": {
877876
"org.sql2o.Connection#createQuery(String)": {
878877
type: "neutral",
879878
input: "",
@@ -917,7 +916,7 @@ describe("createDataExtensionYamlsForFrameworkMode", () => {
917916
);
918917

919918
expect(yaml).toEqual({
920-
"models/sql2o.model.yml": `extensions:
919+
"models/org.sql2o.model.yml": `extensions:
921920
- addsTo:
922921
pack: codeql/java-all
923922
extensible: sourceModel
@@ -1044,3 +1043,40 @@ describe("createFilenameForLibrary", () => {
10441043
},
10451044
);
10461045
});
1046+
1047+
describe("createFilenameForPackage", () => {
1048+
const testCases = [
1049+
{
1050+
library: "System.Net.Http.Headers",
1051+
filename: "models/System.Net.Http.Headers.model.yml",
1052+
},
1053+
{
1054+
library: "System.Security.Cryptography.X509Certificates",
1055+
filename:
1056+
"models/System.Security.Cryptography.X509Certificates.model.yml",
1057+
},
1058+
{
1059+
library: "com.google.common.io",
1060+
filename: "models/com.google.common.io.model.yml",
1061+
},
1062+
{
1063+
library: "hudson.cli",
1064+
filename: "models/hudson.cli.model.yml",
1065+
},
1066+
{
1067+
library: "java.util",
1068+
filename: "models/java.util.model.yml",
1069+
},
1070+
{
1071+
library: "org.apache.commons.io",
1072+
filename: "models/org.apache.commons.io.model.yml",
1073+
},
1074+
];
1075+
1076+
test.each(testCases)(
1077+
"returns $filename if package name is $library",
1078+
({ library, filename }) => {
1079+
expect(createFilenameForPackage(library)).toEqual(filename);
1080+
},
1081+
);
1082+
});

0 commit comments

Comments
 (0)