Skip to content

Commit

Permalink
Keyword references
Browse files Browse the repository at this point in the history
Signed-off-by: Liam Barry Allan <[email protected]>
  • Loading branch information
worksofliam committed Nov 24, 2022
1 parent 9752676 commit aa1a36d
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 73 deletions.
146 changes: 74 additions & 72 deletions server/src/language/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ export default class Linter {

let part;

if (statement.length > 0 && [`declare`, `end`].includes(statement[0].type) === false) {
if (statement.length > 0) {
// const isSQL = (statement[0].type === `word` && statement[0].value.toUpperCase() === `EXEC`);

for (let i = 0; i < statement.length; i++) {
Expand Down Expand Up @@ -949,89 +949,91 @@ export default class Linter {
}
}

if (rules.RequiresParameter && !inPrototype) {
// Check the procedure reference has a block following it
const definedProcedure = globalProcs.find(proc => proc.name.toUpperCase() === upperName);
if (definedProcedure) {
let requiresBlock = false;
if (statement.length <= i + 1) {
requiresBlock = true;
} else if (statement[i + 1].type !== `openbracket`) {
requiresBlock = true;
}
const isDeclare = [`declare`, `end`].includes(statement[0].type);
if ((isDeclare && i >= 2) || !isDeclare) {
if (rules.RequiresParameter && !inPrototype) {

// Check the procedure reference has a block following it
const definedProcedure = globalProcs.find(proc => proc.name.toUpperCase() === upperName);
if (definedProcedure) {
let requiresBlock = false;
if (statement.length <= i + 1) {
requiresBlock = true;
} else if (statement[i + 1].type !== `openbracket`) {
requiresBlock = true;
}

if (requiresBlock) {
errors.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: part.position, end: part.position + part.value.length },
type: `RequiresParameter`,
});
if (requiresBlock) {
errors.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: part.position, end: part.position + part.value.length },
type: `RequiresParameter`,
});
}
}
}
}

if (rules.CollectReferences) {
if (statement[i - 1] && statement[i - 1].type === `dot`) {
break;
}
if (rules.CollectReferences) {
if (statement[i - 1] && statement[i - 1].type === `dot`) break;

let defRef;
if (currentProcedure && currentProcedure.scope) {
defRef = currentProcedure.scope.find(upperName);
let defRef;
if (currentProcedure && currentProcedure.scope) {
defRef = currentProcedure.scope.find(upperName);

if (!defRef) {
defRef = currentProcedure.subItems.find(def => def.name.toUpperCase() === upperName);
if (!defRef) {
defRef = currentProcedure.subItems.find(def => def.name.toUpperCase() === upperName);
}
}
}

if (!defRef) {
defRef = globalScope.find(upperName);
}

if (defRef) {
if (defRef.position.line !== statementStart.line) {
defRef.references.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: part.position, end: part.position + part.value.length },
});
if (!defRef) {
defRef = globalScope.find(upperName);
}

if (defRef.keyword[`QUALIFIED`]) {
let nextPartIndex = i + 1;
if (defRef) {
if (defRef.position.line !== statementStart.line) {
defRef.references.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: part.position, end: part.position + part.value.length },
});
}

if (defRef.keyword[`QUALIFIED`]) {
let nextPartIndex = i + 1;

if (statement[nextPartIndex]) {
// First, check if there is an array call here and skip over it
if (statement[nextPartIndex].type === `openbracket`) {
nextPartIndex = statement.findIndex((value, index) => index > nextPartIndex && value.type === `closebracket`);
if (statement[nextPartIndex]) {
// First, check if there is an array call here and skip over it
if (statement[nextPartIndex].type === `openbracket`) {
nextPartIndex = statement.findIndex((value, index) => index > nextPartIndex && value.type === `closebracket`);

if (nextPartIndex >= 0) nextPartIndex++;
}
if (nextPartIndex >= 0) nextPartIndex++;
}

// Check if the next part is a dot
if (statement[nextPartIndex] && statement[nextPartIndex].type === `dot`) {
nextPartIndex++;

// Check if the next part is a word
if (statement[nextPartIndex] && statement[nextPartIndex].type === `word` && statement[nextPartIndex].value) {
const subItemPart = statement[nextPartIndex];
const subItemName = subItemPart.value.toUpperCase();

// Find the subitem
const subItemDef = defRef.subItems.find(subfield => subfield.name.toUpperCase() == subItemName);
if (subItemDef) {
subItemDef.references.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: subItemPart.position, end: subItemPart.position + subItemPart.value.length },
});
// Check if the next part is a dot
if (statement[nextPartIndex] && statement[nextPartIndex].type === `dot`) {
nextPartIndex++;

// Check if the next part is a word
if (statement[nextPartIndex] && statement[nextPartIndex].type === `word` && statement[nextPartIndex].value) {
const subItemPart = statement[nextPartIndex];
const subItemName = subItemPart.value.toUpperCase();

// Find the subitem
const subItemDef = defRef.subItems.find(subfield => subfield.name.toUpperCase() == subItemName);
if (subItemDef) {
subItemDef.references.push({
range: new Range(
statementStart,
statementEnd
),
offset: { position: subItemPart.position, end: subItemPart.position + subItemPart.value.length },
});
}
}
}
}
Expand All @@ -1053,7 +1055,7 @@ export default class Linter {
newValue: `*BLANK`
});

} else if (rules.StringLiteralDupe && !isEmbeddedSQL) {
} else if (rules.StringLiteralDupe && !isEmbeddedSQL && statement[0].type !== `declare`) {
let foundBefore = stringLiterals.find(literal => literal.value === part.value);

// If it does not exist on our list, we can add it
Expand Down
33 changes: 32 additions & 1 deletion tests/suite/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2851,7 +2851,7 @@ exports.linter40_return = async () => {
const procedure = cache.find(`InputIsValid`);
const validationResult = procedure.scope.find(`validationResult`);

assert.strictEqual(validationResult.references.length, 5);
assert.strictEqual(validationResult.references.length, 6);
}

exports.linter41 = async () => {
Expand Down Expand Up @@ -3108,4 +3108,35 @@ exports.issue_170a = async () => {
assert.strictEqual(Move1.references.length, 0);

assert.deepStrictEqual(errors.length, 2);
}

exports.linter40_keywordrefs = async () => {
const lines = [
`**free`,
`Dcl-C RANDOMLEN 286;`,
`Dcl-s somevar Int(10) inz(randomLen);`,
].join(`\n`);

const parser = parserSetup();
const cache = await parser.getDocs(uri, lines);
const { errors } = Linter.getErrors({ uri, content: lines }, {
CollectReferences: true,
IncorrectVariableCase: true
}, cache);

const RANDOMLEN = cache.find(`RANDOMLEN`);

assert.strictEqual(RANDOMLEN.references.length, 1);
assert.deepStrictEqual(RANDOMLEN.references[0], {
range: Range.create(2, 0, 2, 42),
offset: { position: 32, end: 41 },
});

assert.strictEqual(errors.length, 1);
assert.deepStrictEqual(errors[0], {
range: Range.create(2, 0, 2, 42),
offset: { position: 32, end: 41 },
type: `IncorrectVariableCase`,
newValue: `RANDOMLEN`,
});
}

0 comments on commit aa1a36d

Please sign in to comment.