Skip to content

Commit

Permalink
Merge pull request #93 from IBM/fix/export_casing
Browse files Browse the repository at this point in the history
Fix/export_casing
  • Loading branch information
worksofliam authored Oct 16, 2024
2 parents a97dbcb + 1f59b77 commit a7d6e30
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
7 changes: 6 additions & 1 deletion cli/src/targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ export class Targets {
}
}

// Exports are always uppercase
target.exports = target.exports.map(e => e.toUpperCase());

this.addNewTarget(target);
}

Expand Down Expand Up @@ -972,6 +975,8 @@ export class Targets {
// define exported functions
if (cache.keyword[`NOMAIN`]) {
ileObject.type = `MODULE`;

// Note that we store exports as uppercase.
ileObject.exports = cache.procedures
.filter((proc: any) => proc.keyword[`EXPORT`])
.map(ref => ref.name.toUpperCase());
Expand Down Expand Up @@ -1328,7 +1333,7 @@ export class Targets {

for (const exportName of target.exports) {
// We loop through each export of the service program and find the module that exports it
const foundModule = allModules.find(mod => mod.exports && mod.exports.includes(exportName));
const foundModule = allModules.find(mod => mod.exports && mod.exports.includes(exportName.toUpperCase()));
if (foundModule) {
const alreadyBound = target.deps.some(dep => dep.systemName === foundModule.systemName && dep.type === `MODULE`);
if (!alreadyBound) {
Expand Down
80 changes: 80 additions & 0 deletions cli/test/fixtures/mixedCaseExport/qrpglesrc/modexcept.sqlrpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
**free
//%METADATA *
// %TEXT module for exceptions. *
//%EMETADATA *
ctl-opt nomain ;

dcl-pr getRandomMethodA char(10);
inProdCode char(10) const;
inState char(2) const;
inEffectiveDate date const;
inSignedDate date const;
inReceivedDate date const;
inIssuedDate date const;
inExceptionID char(10) const;
inExceptionCode char(10) const;
END-PR;
//*************************************************************************************************
dcl-proc getRandomMethodA export;
dcl-pi getRandomMethodA char(10);
inProdCode char(10) const;
inState char(2) const;
inEffectiveDate date const;
inSignedDate date const;
inReceivedDate date const;
inIssuedDate date const;
inExceptionID char(10) const;
inExceptionCode char(10) const;
END-PI;
dcl-s rtAction char(10);

if sqlstt = '00000';
return rtAction;
else;
return '';
ENDIF;
END-PROC;

dcl-proc BigFootLivesInSc export;
dcl-pi BigFootLivesInSc ind;
inProdCode char(10) const;
inState char(2) const;
inEffectiveDate date const;
inStrategy char(10) const;
END-PI;
dcl-s authCode char(10);

authCode = getRandomMethodA(inProdCode:inState:inEffectiveDate:
inEffectiveDate:inEffectiveDate:inEffectiveDate:'STRATEGY':inStrategy);

if authCode = '' or authCode = 'ALLOW';
return *on;
else;
return *off;
ENDIF;
END-PROC;

dcl-proc validateCoolness export;
dcl-pi validateCoolness ind;
inPolYear packed(3:0) const;
inPolMon packed(2:0) const;
inPolSeq packed(6:0) const;
inProdCode char(10) const;
inStateCode char(2) const;
inTheDate date const;
END-PI;
dcl-s strategyID char(10);
dcl-s rtError ind inz(*on);

ENDIF;
exec sql fetch next from allocCheck into :strategyID;
dow sqlstt = '00000';
if not BigFootLivesInSc(inProdCode:inStateCode:inTheDate:strategyID);
rtError = *off;
ENDIF;
ENDDO;

return rtError;

END-PROC;

5 changes: 5 additions & 0 deletions cli/test/fixtures/mixedCaseExport/qsrvsrc/modexcept.bnd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
strpgmexp signature( 'V2021.02')
export symbol(getRandomMethodA)
export symbol(BigFootLivesInSc)
export symbol(validateCoolness)
endpgmexp
47 changes: 47 additions & 0 deletions cli/test/mixedCaseExport.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { beforeAll, describe, expect, test } from 'vitest';

import { Targets } from '../src/targets'
import path from 'path';
import { getFiles } from '../src/utils';
import { setupFixture } from './fixtures/projects';
import { scanGlob } from '../src/extensions';

const cwd = setupFixture(`mixedCaseExport`);

let files = getFiles(cwd, scanGlob);

async function setupScopeAnalysis(targets: Targets) {
targets.loadObjectsFromPaths(files);
const parsePromises = files.map(f => targets.parseFile(f));
await Promise.all(parsePromises);

expect(targets.getTargets().length).toBeGreaterThan(0);
targets.resolveBinder();
}

describe.skipIf(files.length === 0)(`pr with mixed case exports exports `, () => {
const targets = new Targets(cwd);

beforeAll(async () => {
await setupScopeAnalysis(targets);
});

test(`Correct check exports no matter the casing`, async () => {
const allLogs = targets.logger.getAllLogs();

const [srvPgmObj] = targets.getResolvedObjects(`SRVPGM`);
expect(srvPgmObj).toBeDefined();
expect(srvPgmObj.systemName).toBe(`MODEXCEPT`);
expect(srvPgmObj.type).toBe(`SRVPGM`);

const srvPgmTarget = targets.getTarget({ systemName: `MODEXCEPT`, type: `SRVPGM` });
expect(srvPgmTarget).toBeDefined();

expect(srvPgmTarget.deps.length).toBe(1);

expect(srvPgmTarget.exports.length).toBe(3);
expect(srvPgmTarget.exports).toStrictEqual(srvPgmTarget.deps[0].exports);

expect(allLogs[srvPgmObj.relativePath].length).toBe(0);
});
});

0 comments on commit a7d6e30

Please sign in to comment.