diff --git a/src/language/linter.js b/src/language/linter.js index 69fdb377..75667d43 100644 --- a/src/language/linter.js +++ b/src/language/linter.js @@ -246,7 +246,10 @@ module.exports = class Linter { let value; if (statement.length >= 1) { - if (statement[0].type === `directive` && statement[0].value.toUpperCase() === `/EOF`) break; + if (statement[0].type === `directive` && statement[0].value.toUpperCase() === `/EOF`) { + // End of file + break; + } switch (statement[0].type) { case `format`: diff --git a/src/language/parser.js b/src/language/parser.js index 117fafbb..0d3fded6 100644 --- a/src/language/parser.js +++ b/src/language/parser.js @@ -284,7 +284,7 @@ module.exports = class Parser { if (comment === `/`) { // Directives can be parsed by the free format parser - line = line.substring(7); + line = line.substring(6); lineIsFree = true; } else { if (spec === ` `) { diff --git a/tests/rpgle/eof4.rpgle b/tests/rpgle/eof4.rpgle new file mode 100644 index 00000000..606150f8 --- /dev/null +++ b/tests/rpgle/eof4.rpgle @@ -0,0 +1,13 @@ + D UPPERCASE PR 4096 Varying + D String 4096 Const Varying + D Escaped n Const Options(*NoPass) + /EoF + Converts all of the letters in String to their + UPPER CASE equivalents. Non-alphabetic characters + remain unchanged. + + Escaped = *ON = converts characters that would crash iPDF and + HTML to approximately equivalent characters. + For example, translate " and ' to ` . + (Default) + *OFF= Do not convert any characters other than A-Z. \ No newline at end of file diff --git a/tests/suite/index.js b/tests/suite/index.js index c5a59130..78bd4aba 100644 --- a/tests/suite/index.js +++ b/tests/suite/index.js @@ -2023,7 +2023,8 @@ module.exports = { ` inputDS Likeds(astructure);`, ` End-Pi;`, ` Dsply 'Inside';`, - ` Return;` + ` Return;`, + `End-Proc;` ].join(`\n`); const parser = new Parser(); @@ -2044,29 +2045,117 @@ module.exports = { assert.strictEqual(parmInputDs.subItems.length, 2); }, - // eof1: async () => { - // const lines = [ - // ` D UPPERCASE PR 4096 Varying`, - // ` D String 4096 Const Varying`, - // ` D Escaped n Const Options(*NoPass)`, - // ` /EoF`, - // ` Converts all of the letters in String to their`, - // ` UPPER CASE equivalents. Non-alphabetic characters`, - // ` remain unchanged.`, - // ``, - // ` Escaped = *ON = converts characters that would crash iPDF and`, - // ` HTML to approximately equivalent characters.`, - // ` For example, translate " and ' to \` .`, - // ` (Default)`, - // ` *OFF= Do not convert any characters other than A-Z.`, - // ].join(`\n`); - - // const parser = new Parser(); - // const cache = await parser.getDocs(URI, lines); - - // const uppercase = cache.find(`UPPERCASE`); - // assert.strictEqual(uppercase.name, `UPPERCASE`); - // assert.strictEqual(uppercase.position.line, 0); - // assert.strictEqual(uppercase.subItems, 2); - // } + eof1: async () => { + const lines = [ + ` D UPPERCASE PR 4096 Varying`, + ` D String 4096 Const Varying`, + ` D Escaped n Const Options(*NoPass)`, + ` /EoF`, + ` Converts all of the letters in String to their`, + ` UPPER CASE equivalents. Non-alphabetic characters`, + ` remain unchanged.`, + ``, + ` Escaped = *ON = converts characters that would crash iPDF and`, + ` HTML to approximately equivalent characters.`, + ` For example, translate " and ' to \` .`, + ` (Default)`, + ` *OFF= Do not convert any characters other than A-Z.`, + ].join(`\n`); + + const parser = new Parser(); + const cache = await parser.getDocs(URI, lines); + + const uppercase = cache.find(`UPPERCASE`); + assert.strictEqual(uppercase.name, `UPPERCASE`); + assert.strictEqual(uppercase.position.line, 0); + assert.strictEqual(uppercase.subItems.length, 2); + }, + + eof2: async () => { + const lines = [ + ` D UPPERCASE PR 4096 Varying`, + ` D String 4096 Const Varying`, + ` D Escaped n Const Options(*NoPass)`, + ` /EoF`, + ``, + ` D LOWERCASE PR 4096 Varying`, + ` D String 4096 Const Varying`, + ` D Escaped n Const Options(*NoPass)`, + ].join(`\n`); + + const parser = new Parser(); + const cache = await parser.getDocs(URI, lines); + + assert.strictEqual(cache.procedures.length, 1); + + const uppercase = cache.find(`UPPERCASE`); + assert.strictEqual(uppercase.name, `UPPERCASE`); + assert.strictEqual(uppercase.position.line, 0); + assert.strictEqual(uppercase.subItems.length, 2); + }, + + /** + * Similar to linter18 test + */ + eof3: async () => { + const lines = [ + `**FREE`, + `Dcl-s MyVariable2 Char(20);`, + ``, + `theProcedure();`, + `Dsply MyVariable2;`, + ``, + `Dcl-Proc theProcedure;`, + ` Dcl-S mylocal char(20);`, + ` MyVariable2 = 'Hello world';`, + ` mylocal = Myvariable2;`, + `End-Proc;`, + ``, + `/eof`, + ``, + `Dcl-Proc theProcedure2;`, + ` Dcl-S mylocal char(20);`, + ` MyVariable2 = 'Hello world';`, + ` mylocal = Myvariable2;`, + `End-Proc;`, + ].join(`\n`); + + const parser = new Parser(); + const cache = await parser.getDocs(URI, lines); + const { errors } = Linter.getErrors(lines, { + NoGlobalsInProcedures: true + }, cache); + + assert.strictEqual(cache.procedures.length, 1); + assert.strictEqual(errors.length, 2); + }, + + eof4: async () => { + const lines = [ + `**FREE`, + ``, + `Ctl-Opt DftActGrp(*No);`, + ``, + `/copy './tests/rpgle/eof4.rpgle'`, + ``, + `Dcl-s MyVariable2 Char(20);`, + ``, + `CallP UPPERCASE(myVariable:*on);`, + ``, + `Return;` + ].join(`\n`); + + const parser = new Parser(); + const cache = await parser.getDocs(URI, lines); + + assert.strictEqual(cache.variables.length, 1, `Expect length of 1`); + assert.strictEqual(cache.procedures.length, 1, `Expect length of 1`); + + const uppercase = cache.find(`UPPERCASE`); + + assert.strictEqual(uppercase.subItems.length, 2, `Expect length of 2`); + + assert.strictEqual(uppercase.position.path, `'./tests/rpgle/eof4.rpgle'`, `Path is incorrect`); + assert.strictEqual(uppercase.position.line, 0, `Index of 0 expected`); + }, } \ No newline at end of file