Skip to content

Commit

Permalink
Show references for RPGLE variables (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
worksofliam committed Jan 24, 2022
1 parent 5857af3 commit 77c112e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 18 deletions.
30 changes: 23 additions & 7 deletions src/language/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module.exports = class Linter {
* PrettyComments?: boolean,
* NoGlobalSubroutines?: boolean,
* NoLocalSubroutines?: boolean,
* CollectReferences?: boolean,
* }} rules
* @param {Cache|null} [globalScope]
*/
Expand Down Expand Up @@ -244,13 +245,7 @@ module.exports = class Linter {
currentStatement = currentStatement.trim();

const currentProcedure = globalScope.procedures.find(proc => lineNumber >= proc.range.start && lineNumber <= proc.range.end);
let currentScope;

try {
currentScope = globalScope.merge(inProcedure && currentProcedure ? currentProcedure.scope : undefined);
} catch (e) {
console.log(e);
}
const currentScope = globalScope.merge(inProcedure && currentProcedure ? currentProcedure.scope : undefined);

const statement = Statement.parseStatement(currentStatement);
let value;
Expand Down Expand Up @@ -647,6 +642,27 @@ module.exports = class Linter {
}
}
}

if (rules.CollectReferences) {
let defRef;
if (currentProcedure) {
defRef = currentProcedure.scope.find(upperName);
}

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

if (defRef) {
defRef.references.push({
range: new vscode.Range(
statementStart,
statementEnd
),
offset: {position: part.position, length: part.position + part.value.length},
})
}
}
break;

case `string`:
Expand Down
4 changes: 4 additions & 0 deletions src/language/models/declaration.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const vscode = require(`vscode`);
const Cache = require(`./cache`);

module.exports = class Declaration {
Expand All @@ -18,6 +19,9 @@ module.exports = class Declaration {
/** @type {{path: string, line: number}} */
this.position = undefined;

/** @type {{range: vscode.Range, offset: {position: number, length: number}}[]} */
this.references = [];

// Not used in subitem:
/** @type {Declaration[]} */
this.subItems = [];
Expand Down
87 changes: 76 additions & 11 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,6 @@ module.exports = class Worker {
/** @type {vscode.CodeAction[]} */
let actions = [];

/** @type {vscode.CodeAction} */
let action;

const isFree = (document.getText(new vscode.Range(0, 0, 0, 6)).toUpperCase() === `**FREE`);
const text = document.getText();
if (isFree) {
Expand Down Expand Up @@ -366,7 +363,6 @@ module.exports = class Worker {

vscode.languages.registerDefinitionProvider({ language: `rpgle` }, {
provideDefinition: async (document, position, token) => {
const isFree = (document.getText(new vscode.Range(0, 0, 0, 6)).toUpperCase() === `**FREE`);
const doc = await this.parser.getDocs(document.uri);
const range = document.getWordRangeAtPosition(position);
const word = document.getText(range).toUpperCase();
Expand All @@ -378,18 +374,87 @@ module.exports = class Worker {
const def = doc[type].find(def => def.name.toUpperCase() === word);
if (def) {
let {finishedPath, type} = Generic.getPathInfo(document.uri, def.position.path);
if (type === `member`) {
finishedPath = `${finishedPath}.rpgle`;
if (document.uri.path.startsWith(finishedPath)) {
return new vscode.Location(
document.uri,
new vscode.Range(def.position.line, 0, def.position.line, 0)
);

} else {
if (type === `member`) {
finishedPath = `${finishedPath}.rpgle`;
}

return new vscode.Location(
vscode.Uri.parse(finishedPath).with({scheme: type, path: finishedPath}),
new vscode.Range(def.position.line, 0, def.position.line, 0)
);
}

}
}
}
}}
),

vscode.languages.registerReferenceProvider({ language: `rpgle` }, {
provideReferences: async (document, position, context, token) => {
if (Configuration.get(`rpgleLinterSupportEnabled`)) {

/** @type {vscode.Location[]} */
let refs = [];

const range = document.getWordRangeAtPosition(position);
const word = document.getText(range).toUpperCase();

const lineNumber = position.line;
const isFree = (document.getText(new vscode.Range(0, 0, 0, 6)).toUpperCase() === `**FREE`);
const text = document.getText();
if (isFree) {
const docs = await this.parser.getDocs(document.uri);

// Updates docs
Linter.getErrors(text, {
CollectReferences: true,
}, docs);

// If they're typing inside of a procedure, let's get the stuff from there too
const currentProcedure = docs.procedures.find(proc => lineNumber >= proc.range.start && lineNumber <= proc.range.end);

if (currentProcedure) {
const localDef = currentProcedure.scope.find(word);

if (localDef) {
localDef.references.forEach(ref => {
refs.push(new vscode.Location(
document.uri,
Worker.calculateOffset(document, ref)
))
});
}
}

return new vscode.Location(
vscode.Uri.parse(finishedPath).with({scheme: type, path: finishedPath}),
new vscode.Range(def.position.line, 0, def.position.line, 0)
);
// Otherwise, maybe it's a global variable
if (refs.length === 0) {
const globalDef = docs.find(word);

if (globalDef) {
globalDef.references.forEach(ref => {
refs.push(new vscode.Location(
document.uri,
Worker.calculateOffset(document, ref)
))
});
}
}
}

return refs;
}
}}),

return [];
}
}),

vscode.languages.registerCompletionItemProvider({language: `rpgle`, }, {
provideCompletionItems: async (document, position) => {
Expand Down

0 comments on commit 77c112e

Please sign in to comment.