From 2782bd950d09ed27b08d8202db034357dcc97d4e Mon Sep 17 00:00:00 2001 From: worksofliam Date: Wed, 17 Jul 2024 12:24:12 -0400 Subject: [PATCH 1/5] Initial work for compiling legacy sources Signed-off-by: worksofliam --- src/api/CompileTools.ts | 34 ++++++++++++++++++++++++++++++++++ src/api/IBMi.ts | 5 ++++- src/typings.ts | 2 +- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/api/CompileTools.ts b/src/api/CompileTools.ts index 884c34ccc..8fa6f95c3 100644 --- a/src/api/CompileTools.ts +++ b/src/api/CompileTools.ts @@ -225,6 +225,11 @@ export namespace CompileTools { evfeventInfo.object = name.toUpperCase(); evfeventInfo.extension = ext; + if (chosenAction.command.includes(`SRCFILE`)) { + variables[`&SRCLIB`] = evfeventInfo.library; + variables[`&SRCPF`] = `QTMPSRC`; + variables[`&SRCFILE`] = `${evfeventInfo.library}/QTMPSRC`; + } switch (chosenAction.type) { case `file`: @@ -330,6 +335,35 @@ export namespace CompileTools { try { writeEmitter.fire(`Running Action: ${chosenAction.name} (${new Date().toLocaleTimeString()})` + NEWLINE); + // If &SRCFILE is set, we need to copy the file to a temporary source file from the IFS + if (variables[`&FULLPATH`] && variables[`&SRCFILE`] && evfeventInfo.object) { + const [lib, srcpf] = variables[`&SRCFILE`].split(`/`); + + const createSourceFile = content.toCl(`CRTSRCPF`, { + rcdlen: 112, //NICE: this configurable in a VS Code setting? + file: srcpf, + lib, + }); + + const copyFromStreamfile = content.toCl(`CPYFRMSTMF`, { + fromstmf: variables[`&FULLPATH`], + tombr: Tools.qualifyPath(lib, srcpf, evfeventInfo.object), + mbropt: `*REPLACE`, + dbfccsid: `*FILE`, + stmfccsid: 1208, + }); + + // We don't care if this fails. Usually it's because the source file already exists. + await runCommand(instance, {command: createSourceFile, environment: `ile`, noLibList: true}); + + const copyResult = await runCommand(instance, {command: copyFromStreamfile, environment: `ile`, noLibList: true}); + + if (copyResult.code !== 0) { + writeEmitter.fire(`Failed to copy file to a temporary member.\n\t${copyResult.stderr}\n\n`); + closeEmitter.fire(copyResult.code || 1); + } + } + const commandResult = await runCommand(instance, { title: chosenAction.name, environment, diff --git a/src/api/IBMi.ts b/src/api/IBMi.ts index 16bcd974d..58c70da79 100644 --- a/src/api/IBMi.ts +++ b/src/api/IBMi.ts @@ -1046,7 +1046,10 @@ export default class IBMi { this.appendOutput(JSON.stringify(result, null, 4) + `\n\n`); - return result; + return { + ...result, + code: result.code || 0, + }; } private appendOutput(content: string) { diff --git a/src/typings.ts b/src/typings.ts index 838939edf..cceef76f0 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -57,7 +57,7 @@ export interface CommandData extends StandardIO { } export interface CommandResult { - code: number | null; + code: number; stdout: string; stderr: string; command?: string; From 1176ee8f03f6d6b28eecc517f2aadb212c17d468 Mon Sep 17 00:00:00 2001 From: worksofliam Date: Wed, 17 Jul 2024 12:41:08 -0400 Subject: [PATCH 2/5] Correct CL commands used to create temp member Signed-off-by: worksofliam --- src/api/CompileTools.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api/CompileTools.ts b/src/api/CompileTools.ts index 8fa6f95c3..81c5a2394 100644 --- a/src/api/CompileTools.ts +++ b/src/api/CompileTools.ts @@ -225,7 +225,7 @@ export namespace CompileTools { evfeventInfo.object = name.toUpperCase(); evfeventInfo.extension = ext; - if (chosenAction.command.includes(`SRCFILE`)) { + if (chosenAction.command.includes(`&SRCFILE`)) { variables[`&SRCLIB`] = evfeventInfo.library; variables[`&SRCPF`] = `QTMPSRC`; variables[`&SRCFILE`] = `${evfeventInfo.library}/QTMPSRC`; @@ -341,13 +341,12 @@ export namespace CompileTools { const createSourceFile = content.toCl(`CRTSRCPF`, { rcdlen: 112, //NICE: this configurable in a VS Code setting? - file: srcpf, - lib, + file: `${lib}/${srcpf}`, }); const copyFromStreamfile = content.toCl(`CPYFRMSTMF`, { fromstmf: variables[`&FULLPATH`], - tombr: Tools.qualifyPath(lib, srcpf, evfeventInfo.object), + tombr: `'${Tools.qualifyPath(lib, srcpf, evfeventInfo.object)}'`, mbropt: `*REPLACE`, dbfccsid: `*FILE`, stmfccsid: 1208, @@ -356,6 +355,7 @@ export namespace CompileTools { // We don't care if this fails. Usually it's because the source file already exists. await runCommand(instance, {command: createSourceFile, environment: `ile`, noLibList: true}); + // Attempt to copy to member const copyResult = await runCommand(instance, {command: copyFromStreamfile, environment: `ile`, noLibList: true}); if (copyResult.code !== 0) { From 9251712e5d33ffad89cae94d184d1686b204e255 Mon Sep 17 00:00:00 2001 From: worksofliam Date: Wed, 17 Jul 2024 12:41:22 -0400 Subject: [PATCH 3/5] Test case for compiling DSPF from local Signed-off-by: worksofliam --- src/testing/action.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/testing/action.ts b/src/testing/action.ts index 64abedc47..b2e3b3611 100644 --- a/src/testing/action.ts +++ b/src/testing/action.ts @@ -16,7 +16,15 @@ export const helloWorldProject: Folder = { name: `DeleteMe_${Tools.makeid()}`, files: [ new File("hello.pgm.rpgle", ['**free', 'dsply \'Hello World\';', 'return;']), - new File("thebadone.pgm.rpgle", ['**free', 'dsply Hello world;', 'return;']) + new File("thebadone.pgm.rpgle", ['**free', 'dsply Hello world;', 'return;']), + new File("ugly.dspf", [ + ` A INDARA`, + ` A CA12(12)`, + ` A R DETAIL `, + ` A 6 10'ID'`, + ` A DSPATR(HI)`, + ` A DSPATR(UL)`, + ]) ], } @@ -72,6 +80,21 @@ export const ActionSuite: TestSuite = { await testHelloWorldProgram(uri, action, currentLibrary); } }, + { + name: `Create display file (from local, custom action)`, test: async () => { + const uri = helloWorldProject.files![2].localPath!; + const action: Action = { + command: `CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) TEXT('DSPF from local')`, + environment: `ile`, + type: `file`, + name: `Create Display File (CRTDSPF)`, + }; + + const success = await CompileTools.runAction(instance, uri, action, `all`); + console.log(success); + assert.ok(success); + } + }, { name: `Create Bound RPG Program (from IFS, custom action)`, test: async () => { const action: Action = { From 31c45015a4ece3053a5bb913243e31a195ec2179 Mon Sep 17 00:00:00 2001 From: worksofliam Date: Wed, 17 Jul 2024 12:57:36 -0400 Subject: [PATCH 4/5] Ability to show errors from temp members Signed-off-by: worksofliam --- src/api/Tools.ts | 5 +++++ src/api/errors/diagnostics.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/api/Tools.ts b/src/api/Tools.ts index cedd8c869..c7e33a5df 100644 --- a/src/api/Tools.ts +++ b/src/api/Tools.ts @@ -310,6 +310,11 @@ export namespace Tools { return possibleDoc; } + export function findExistingDocumentByName(nameAndExt: string) { + const possibleDoc = vscode.workspace.textDocuments.find(document => document.fileName.toLowerCase().endsWith(nameAndExt.toLowerCase())); + return possibleDoc ? possibleDoc.uri : undefined; + } + /** * We convert member to lowercase as members are case insensitive. */ diff --git a/src/api/errors/diagnostics.ts b/src/api/errors/diagnostics.ts index 29bc71e77..b029a18a1 100644 --- a/src/api/errors/diagnostics.ts +++ b/src/api/errors/diagnostics.ts @@ -169,6 +169,18 @@ export function handleEvfeventLines(lines: string[], instance: Instance, evfeven } continue; } + + // If we get there, that means that even though we compiled from local, we likely had to use a temp member. + // We should try to find the file in the workspace. Since we can use findFile (it's async), then we look for open + // tabs like we do below. + if (evfeventInfo.extension) { + const baseName = file.split(`/`).pop(); + const openFile = Tools.findExistingDocumentByName(`${baseName}.${evfeventInfo.extension}`); + if (openFile) { + ileDiagnostics.set(openFile, diagnostics); + continue; + } + } } } From e5d4c9501f78a5a15cd3b6db34d7c058eb8eebf9 Mon Sep 17 00:00:00 2001 From: worksofliam Date: Wed, 17 Jul 2024 13:05:28 -0400 Subject: [PATCH 5/5] New item in actions setup Signed-off-by: worksofliam --- src/api/local/LocalLanguageActions.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/api/local/LocalLanguageActions.ts b/src/api/local/LocalLanguageActions.ts index 119bb0169..20a54772a 100644 --- a/src/api/local/LocalLanguageActions.ts +++ b/src/api/local/LocalLanguageActions.ts @@ -129,6 +129,17 @@ export const LocalLanguageActions: Record = { environment: `ile`, } ], + DSPF: [ + { + "name": "Create DSPF", + "command": "CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) RSTDSP(*NO) OPTION(*EVENTF)", + "environment": "ile", + "deployFirst": true, + "extensions": [ + "dspf" + ] + } + ], "Service Programs": [ { "extensions": [