Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions language/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const lineTokens = (input: string, lineNumber: number, lineIndex: number): Token
return tokens;
}

const PROGRAMPARMS_NAME = `PROGRAMPARMS`;

export default class Parser {
parsedCache: {[thePath: string]: Cache} = {};
tables: TableDetail = {};
Expand Down Expand Up @@ -951,40 +953,48 @@ export default class Parser {

case `DCL-PI`:
//Procedures can only exist in the global scope.
if (currentProcName) {
if (parts.length > 0) {
if (parts.length > 0) {
if (currentProcName) {
currentGroup = `procedures`;
currentItem = scopes[0].procedures.find(proc => proc.name === currentProcName);
} else {
currentItem = new Declaration(`struct`);
currentItem.name = PROGRAMPARMS_NAME;
}

if (currentItem) {
const endInline = tokens.findIndex(part => part.value.toUpperCase() === `END-PI`);

if (currentItem) {

// Indicates that the PI starts and ends on the same line
if (endInline >= 0) {
tokens.splice(endInline, 1);
currentItem.readParms = false;
resetDefinition = true;
}

currentItem.keyword = {
...currentItem.keyword,
...Parser.expandKeywords(tokens.slice(2))
}
currentItem.readParms = true;
// Indicates that the PI starts and ends on the same line
if (endInline >= 0) {
tokens.splice(endInline, 1);
currentItem.readParms = false;
resetDefinition = true;
}

currentDescription = [];
currentItem.keyword = {
...currentItem.keyword,
...Parser.expandKeywords(tokens.slice(2))
}
currentItem.readParms = true;

currentDescription = [];
}
}
break;

case `END-PI`:
//Procedures can only exist in the global scope.
currentItem = scopes[0].procedures.find(proc => proc.name === currentProcName);
if (currentProcName) {
currentItem = scopes[0].procedures.find(proc => proc.name === currentProcName);

if (currentItem && currentItem.type === `procedure`) {
currentItem.readParms = false;
if (currentItem && currentItem.type === `procedure`) {
currentItem.readParms = false;
resetDefinition = true;
}
} else if (currentItem && currentItem.name === PROGRAMPARMS_NAME) {
// Assign this scopes parameters to the subitems of the program parameters struct
scopes[0].parameters = currentItem.subItems;
resetDefinition = true;
}
break;
Expand Down Expand Up @@ -1202,7 +1212,7 @@ export default class Parser {
currentItem.subItems.push(currentSub);
currentSub = undefined;

if (currentItem.type === `struct`) {
if (currentItem.type === `struct` && currentItem.name !== PROGRAMPARMS_NAME) {
resetDefinition = true;
}
}
Expand Down
10 changes: 6 additions & 4 deletions tests/suite/partial.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ test("Parser partial tests", { timeout }, async () => {
const parser = setupParser(projectPath);
const list = await getSourcesList(projectPath);

totalFiles += list.length;

for (let i = 0; i < list.length; i++) {
const relativePath = list[i];
const basename = path.basename(relativePath);
Expand Down Expand Up @@ -51,13 +53,13 @@ test("Parser partial tests", { timeout }, async () => {
lengths.push(pe - ps);
}

const lengthsAverage = lengths.reduce((a, b) => a + b, 0) / lengths.length;
const total = lengths.reduce((a, b) => a + b, 0);
const last = lengths[lengths.length - 1];
// const lengthsAverage = lengths.reduce((a, b) => a + b, 0) / lengths.length;
// const total = lengths.reduce((a, b) => a + b, 0);
// const last = lengths[lengths.length - 1];
// console.log(`\tAverage: ${lengthsAverage}ms, Full: ${last}ms, Total: ${total}`);
// console.log(``);
}
}

console.log(`Parsed ${totalFiles} files, ${SPLIT_SIZE} each.`);
console.log(`Parsed ${totalFiles} files, ${SPLIT_SIZE} times each.`);
});
53 changes: 52 additions & 1 deletion tests/suite/references.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,14 @@ test("references_9", async () => {
const cache = await parser.getDocs(uri, lines, {ignoreCache: true, withIncludes: true, collectReferences: true});

const procedure = cache.find(`InputIsValid`);
const validationResult = procedure.scope.find(`validationResult`);

const validationResult = procedure.scope.find(`validationResult`);
expect(validationResult.references.length).toEqual(7);
expect(validationResult.references.every(ref => lines.substring(ref.offset.start, ref.offset.end) === `validationResult`)).toBe(true);

const comp = procedure.scope.find(`comp`);
expect(comp.references.length).toEqual(2);
expect(comp.references.every(ref => lines.substring(ref.offset.start, ref.offset.end) === `comp`)).toBe(true);
});

test('references_10', async () => {
Expand Down Expand Up @@ -1833,4 +1837,51 @@ test('references_27_fixed_reference', async () => {

expect(offsetContent.toUpperCase()).toBe(`WCFGKEY`);
}
});

test('reference_28_parameters', async () => {
const lines = [
`**free`,
``,
`ctl-opt dftactgrp(*no);`,
``,
`dcl-pi upddept;`,
` deptno char(3);`,
` deptname char(36);`,
` mgrno char(6);`,
` admrdept char(3);`,
` location char(16);`,
`end-pi;`,
``,
`dcl-ds result qualified dim(1);`,
` success char(1);`,
`end-ds;`,
``,
`exec sql`,
` update dept`,
` set deptname = :deptname,`,
` mgrno = :mgrno,`,
` admrdept = :admrdept,`,
` location = :location`,
` where deptno = :deptno;`,
``,
`if (SQLCOD = 0);`,
` result(1).success = 'Y';`,
`else;`,
` result(1).success = 'N';`,
`endif;`,
``,
`dcl-s return char(length) inz('Y');`,
``,
`exec sql set result sets array :result for 1 rows;`,
`// Hello`,
`return;`,
].join(`\n`);

const cache = await parser.getDocs(uri, lines, { ignoreCache: true, withIncludes: true, collectReferences: true });

const deptno = cache.find(`deptno`);
expect(deptno).toBeDefined();
expect(deptno.references.length).toBe(2);
expect(deptno.references.every(ref => lines.substring(ref.offset.start, ref.offset.end) === `deptno`)).toBe(true);
});
Loading