Skip to content

Commit 533fccb

Browse files
committed
fix: align ts types with json schema
1 parent 00f17fb commit 533fccb

File tree

5 files changed

+162
-93
lines changed

5 files changed

+162
-93
lines changed

clients/cobol-lsp-vscode-extension/src/__tests__/services/BridgeForGitSupport.spec.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
* Broadcom, Inc. - initial API and implementation
1313
*/
1414

15-
import { B4GTypeMetadata, decodeBridgeJson } from "../../services/BridgeForGit";
15+
import {
16+
B4GTypeMetadata,
17+
decodeBridgeJson,
18+
} from "../../services/BridgeForGitLoader";
1619
import { loadProcessorsConfigForDocument } from "../../services/ProcessorGroups";
1720
import * as path from "path";
1821

clients/cobol-lsp-vscode-extension/src/__tests__/services/ProcessorGroups.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ it("Processor groups configuration matches program relative to workspace", async
217217
scopeUri: WORKSPACE_URI + "/IDMS/TEST.cob",
218218
section: "cobol-lsp.dialects",
219219
};
220-
const result = await loadProcessorGroupDialectConfig(item, {});
220+
const result = await loadProcessorGroupDialectConfig(item, []);
221221
expect(result).toStrictEqual(["IDMS"]);
222222
});
223223

clients/cobol-lsp-vscode-extension/src/services/ProcessorGroups.ts

+37-91
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
* Broadcom, Inc. - initial API and implementation
1313
*/
1414

15-
import * as fs from "fs";
1615
import * as path from "path";
1716
import { Minimatch } from "minimatch";
1817
import { SettingsUtils } from "./util/SettingsUtils";
@@ -29,11 +28,14 @@ import {
2928
B4GTypeMetadata,
3029
decodeBridgeJson,
3130
loadBridgeJsonContent,
32-
} from "./BridgeForGit";
33-
34-
const PROCESSOR_GROUP_FOLDER = ".cobolplugin";
35-
const PROCESSOR_GROUP_PGM = "pgm_conf.json";
36-
const PROCESSOR_GROUP_PROC = "proc_grps.json";
31+
} from "./BridgeForGitLoader";
32+
import {
33+
Preprocessor,
34+
ProcessorGroup,
35+
ProgramsConfig,
36+
readProcessorGroupsFileContent,
37+
readProgramConfigFileContent,
38+
} from "./ProcessorGroupsLoader";
3739

3840
export async function loadProcessorGroupCopybookPaths(
3941
documentUri: string,
@@ -128,51 +130,33 @@ export async function loadProcessorGroupDialectConfig(
128130
readProgramConfigFileContent(),
129131
decodeBridgeJson(await loadBridgeJsonContent(Uri.parse(item.scopeUri))),
130132
);
131-
if (pgCfg === undefined) {
133+
if (pgCfg === undefined || pgCfg.preprocessor == undefined) {
132134
return configObject;
133135
}
136+
134137
const dialects: Preprocessor[] = [];
135138

136-
if (Array.isArray(pgCfg.preprocessor)) {
137-
for (const pp of pgCfg.preprocessor as Preprocessor) {
138-
if (typeof pp === "object" && pp) {
139-
dialects.push(pp["name"]);
140-
}
141-
if (typeof pp === "string" && pp) {
142-
dialects.push(pp);
143-
}
139+
const preprocessors = Array.isArray(pgCfg.preprocessor)
140+
? pgCfg.preprocessor
141+
: [pgCfg.preprocessor];
142+
for (const pp of preprocessors) {
143+
if (typeof pp === "object" && pp) {
144+
dialects.push(pp["name"]);
145+
}
146+
if (typeof pp === "string" && pp) {
147+
dialects.push(pp);
144148
}
145-
} else if (pgCfg.preprocessor !== undefined) {
146-
dialects.push(pgCfg.preprocessor);
147149
}
148150

149151
// "SQL" is not a real dialect, we will use it only to set up sql backend for now
150-
return dialects.filter((name) => name != "SQL") || configObject;
152+
const result = dialects.filter((name) => name != "SQL");
153+
return result.length > 0 ? result : configObject;
151154
} catch (e) {
152155
console.error(JSON.stringify(e));
153156
return configObject;
154157
}
155158
}
156159

157-
type ProgramsConfig = {
158-
pgms: {
159-
program: string;
160-
pgroup: string;
161-
}[];
162-
};
163-
164-
type Preprocessor = string | string[];
165-
166-
type ProcessorConfig = {
167-
name: string;
168-
libs?: string[];
169-
preprocessor?: Preprocessor[];
170-
};
171-
172-
type ProcessorsConfig = {
173-
pgroups: ProcessorConfig[];
174-
};
175-
176160
function matchProcessorGroup(
177161
pgmCfg: ProgramsConfig,
178162
documentPath: string,
@@ -219,56 +203,12 @@ function pathMatches(program: string, documentPath: string) {
219203
documentPath.toUpperCase();
220204
}
221205

222-
const loadProcessorConfigurations = (
223-
processorsJsonContent: string,
224-
): ProcessorConfig[] => {
225-
const procCfg: ProcessorsConfig = JSON.parse(processorsJsonContent);
226-
return procCfg.pgroups;
227-
};
228-
229-
export function readProcessorGroupsFileContent(): ProcessorConfig[] {
230-
const ws = SettingsUtils.getWorkspaceFoldersPath(true);
231-
if (ws.length < 1) {
232-
return [];
233-
}
234-
const cfgPath = path.join(ws[0], PROCESSOR_GROUP_FOLDER);
235-
const procCfgPath = path.join(cfgPath, PROCESSOR_GROUP_PROC);
236-
if (!fs.existsSync(procCfgPath)) {
237-
return [];
238-
}
239-
try {
240-
return JSON.parse(fs.readFileSync(procCfgPath).toString()).pgroups;
241-
} catch (e) {
242-
console.error(e);
243-
return [];
244-
}
245-
}
246-
247-
export const readProgramConfigFileContent = (): ProgramsConfig => {
248-
const EMPTY = { pgms: [] };
249-
const ws = SettingsUtils.getWorkspaceFoldersPath(true);
250-
if (ws.length < 1) {
251-
return EMPTY;
252-
}
253-
const cfgPath = path.join(ws[0], PROCESSOR_GROUP_FOLDER);
254-
const pgmCfgPath = path.join(cfgPath, PROCESSOR_GROUP_PGM);
255-
if (!fs.existsSync(pgmCfgPath)) {
256-
return EMPTY;
257-
}
258-
try {
259-
return JSON.parse(fs.readFileSync(pgmCfgPath).toString());
260-
} catch (e) {
261-
console.error(e);
262-
return EMPTY;
263-
}
264-
};
265-
266206
export const loadProcessorsConfigForDocument = (
267207
documentUri: string,
268-
pgroups: ProcessorConfig[],
208+
pgroups: ProcessorGroup[],
269209
pgmCfg: ProgramsConfig,
270210
b4g: B4GTypeMetadata | undefined,
271-
): ProcessorConfig | undefined => {
211+
): ProcessorGroup | undefined => {
272212
if (pgroups.length === 0) {
273213
return undefined;
274214
}
@@ -306,13 +246,19 @@ function selectProcessorGroup(
306246
: b4g.elements[selectedElement].processorGroup;
307247
}
308248

309-
async function loadProcessorGroupSettings<T>(
249+
async function loadProcessorGroupSettings<T extends string | string[]>(
310250
documentUri: string,
311-
atrtibute: string,
251+
atrtibute:
252+
| "libs"
253+
| "name"
254+
| "target-sql-backend"
255+
| "compiler-options"
256+
| "copybook-file-encoding"
257+
| "copybook-extensions",
312258
configObject: T,
313259
dialect: string = "COBOL",
314260
): Promise<T> {
315-
const pgCfg: ProcessorConfig | undefined = loadProcessorsConfigForDocument(
261+
const pgCfg: ProcessorGroup | undefined = loadProcessorsConfigForDocument(
316262
documentUri,
317263
readProcessorGroupsFileContent(),
318264
readProgramConfigFileContent(),
@@ -323,19 +269,19 @@ async function loadProcessorGroupSettings<T>(
323269
}
324270
try {
325271
if (dialect && dialect !== "COBOL") {
326-
for (const pp of pgCfg.preprocessor as Preprocessor) {
272+
for (const pp of pgCfg.preprocessor as Preprocessor[]) {
327273
if (
328274
pp &&
329275
typeof pp === "object" &&
330276
pp["name"] === dialect &&
331-
pp[atrtibute]
277+
pp[atrtibute] !== undefined
332278
) {
333-
return pp[atrtibute];
279+
return pp[atrtibute] as T;
334280
}
335281
}
336282
} else {
337-
if (pgCfg[atrtibute as keyof ProcessorConfig]) {
338-
return pgCfg[atrtibute as keyof ProcessorConfig] as T;
283+
if (pgCfg[atrtibute] !== undefined) {
284+
return pgCfg[atrtibute] as T;
339285
}
340286
}
341287

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (c) 2024 Broadcom.
3+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4+
*
5+
* This program and the accompanying materials are made
6+
* available under the terms of the Eclipse Public License 2.0
7+
* which is available at https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Broadcom, Inc. - initial API and implementation
13+
*/
14+
import * as path from "path";
15+
import * as fs from "fs";
16+
import { SettingsUtils } from "./util/SettingsUtils";
17+
import * as t from "io-ts";
18+
import { PathReporter } from "io-ts/lib/PathReporter";
19+
import { isLeft } from "fp-ts/Either";
20+
21+
const PROCESSOR_GROUP_FOLDER = ".cobolplugin";
22+
const PROCESSOR_GROUP_PGM = "pgm_conf.json";
23+
const PROCESSOR_GROUP_PROC = "proc_grps.json";
24+
25+
const ProgramsConfigModel = t.type({
26+
pgms: t.array(
27+
t.type({
28+
program: t.string,
29+
pgroup: t.string,
30+
}),
31+
),
32+
});
33+
34+
export type ProgramsConfig = t.TypeOf<typeof ProgramsConfigModel>;
35+
36+
const PreprocessorModel = t.union([
37+
t.string,
38+
t.intersection([
39+
t.type({ name: t.string }),
40+
t.partial({
41+
libs: t.array(t.string),
42+
"copybook-extensions": t.array(t.string),
43+
"compiler-options": t.array(t.string),
44+
"copybook-file-encoding": t.string,
45+
"target-sql-backend": t.string,
46+
}),
47+
]),
48+
]);
49+
50+
export type Preprocessor = t.TypeOf<typeof PreprocessorModel>;
51+
52+
const ProcessorGroupModel = t.intersection([
53+
t.type({
54+
name: t.string,
55+
}),
56+
t.partial({
57+
preprocessor: t.union([PreprocessorModel, t.array(PreprocessorModel)]),
58+
libs: t.array(t.string),
59+
"copybook-extensions": t.array(t.string),
60+
"compiler-options": t.array(t.string),
61+
"copybook-file-encoding": t.string,
62+
"target-sql-backend": t.string,
63+
}),
64+
]);
65+
66+
export type ProcessorGroup = t.TypeOf<typeof ProcessorGroupModel>;
67+
68+
export const readProgramConfigFileContent = (): ProgramsConfig => {
69+
const EMPTY = { pgms: [] };
70+
const ws = SettingsUtils.getWorkspaceFoldersPath(true);
71+
if (ws.length < 1) {
72+
return EMPTY;
73+
}
74+
const cfgPath = path.join(ws[0], PROCESSOR_GROUP_FOLDER);
75+
const pgmCfgPath = path.join(cfgPath, PROCESSOR_GROUP_PGM);
76+
if (!fs.existsSync(pgmCfgPath)) {
77+
return EMPTY;
78+
}
79+
try {
80+
const json = JSON.parse(fs.readFileSync(pgmCfgPath).toString());
81+
const decoded = ProgramsConfigModel.decode(json);
82+
if (isLeft(decoded)) {
83+
throw Error(
84+
`Could not validate data: ${PathReporter.report(decoded).join("\n")}`,
85+
);
86+
}
87+
return decoded.right;
88+
} catch (e) {
89+
console.error(e);
90+
return EMPTY;
91+
}
92+
};
93+
94+
export function readProcessorGroupsFileContent(): ProcessorGroup[] {
95+
const ws = SettingsUtils.getWorkspaceFoldersPath(true);
96+
if (ws.length < 1) {
97+
return [];
98+
}
99+
const cfgPath = path.join(ws[0], PROCESSOR_GROUP_FOLDER);
100+
const procCfgPath = path.join(cfgPath, PROCESSOR_GROUP_PROC);
101+
if (!fs.existsSync(procCfgPath)) {
102+
return [];
103+
}
104+
try {
105+
const ProcessorGrpupsModel = t.type({
106+
pgroups: t.array(ProcessorGroupModel),
107+
});
108+
const json = JSON.parse(fs.readFileSync(procCfgPath).toString());
109+
const decoded = ProcessorGrpupsModel.decode(json);
110+
if (isLeft(decoded)) {
111+
throw Error(
112+
`Could not validate data: ${PathReporter.report(decoded).join("\n")}`,
113+
);
114+
}
115+
return decoded.right.pgroups;
116+
} catch (e) {
117+
console.error(e);
118+
return [];
119+
}
120+
}

0 commit comments

Comments
 (0)