Skip to content

Commit 16ea703

Browse files
resolve merge conflicts
Signed-off-by: Sanjula Ganepola <[email protected]>
2 parents 9a3ff7c + 75dd815 commit 16ea703

File tree

4 files changed

+146
-37
lines changed

4 files changed

+146
-37
lines changed

extension/server/src/data.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ export function dspffdToRecordFormats(data: any, aliases = false): Declaration[]
5858
field: ``,
5959
pos: ``
6060
});
61-
62-
currentSubfield.tags.push({tag: `description`, content: text.trim()})
61+
62+
currentSubfield.tags.push({tag: `description`, content: text.trim()});
6363

6464
recordFormat.subItems.push(currentSubfield);
6565
});

extension/server/src/providers/codeActions.ts

Lines changed: 141 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default async function genericCodeActionsProvider(params: CodeActionParam
3434

3535
const extractOption = getExtractProcedureAction(document, docs, range);
3636
if (extractOption) {
37-
return [extractOption];
37+
actions.push(extractOption);
3838
}
3939

4040
const linterActions = await getLinterCodeActions(docs, document, range);
@@ -47,6 +47,11 @@ export default async function genericCodeActionsProvider(params: CodeActionParam
4747
if (testActions) {
4848
actions.push(...testActions);
4949
}
50+
51+
const monitorAction = surroundWithMonitorAction(isFree, document, docs, range);
52+
if (monitorAction) {
53+
actions.push(monitorAction);
54+
}
5055
}
5156
}
5257

@@ -327,11 +332,105 @@ function getAssertion(type: RpgleVariableType): string {
327332
}
328333
}
329334

330-
331335
function asPosix(inPath?: string) {
332336
return inPath ? inPath.split(path.sep).join(path.posix.sep) : ``;
333337
}
334338

339+
function lineAt(document: TextDocument, line: number): string {
340+
return document.getText(Range.create(line, 0, line, 1000)).trimEnd();
341+
}
342+
343+
function getBodyRangeForRange(docs: Cache, rangeStart: number, rangeEnd: number, document: TextDocument) {
344+
let validStart = -1;
345+
let validEnd = -1;
346+
347+
const currentProcedure = docs.procedures.find(sub => rangeStart >= sub.position.range.line && rangeEnd <= sub.range.end!);
348+
349+
if (currentProcedure && currentProcedure.scope && currentProcedure.range.end) {
350+
validStart = currentProcedure.scope.getDefinitionBlockEnd(document.uri) + 1;
351+
validEnd = currentProcedure.range.end - 1;
352+
} else {
353+
validStart = docs.getDefinitionBlockEnd(document.uri) + 1;
354+
const firstProc = docs.procedures.find(p => !Object.keys(p.keyword).some(k => k.toLowerCase().startsWith(`ext`)));
355+
validEnd = firstProc && firstProc.range.start ? firstProc.range.start - 1 : document.lineCount - 1;
356+
}
357+
358+
if (validStart < 0 || validEnd < 0) {
359+
return;
360+
}
361+
362+
return { validStart, validEnd };
363+
}
364+
365+
function determineIndent(line: string): number {
366+
const match = line.match(/^\s+/);
367+
if (match) {
368+
return match[0].length;
369+
}
370+
return 0;
371+
}
372+
373+
export function surroundWithMonitorAction(isFree: boolean, document: TextDocument, docs: Cache, range: Range): CodeAction | undefined {
374+
let rangeStart = range.start.line;
375+
let rangeEnd = range.end.line;
376+
377+
if (rangeStart === rangeEnd) {
378+
// Only works for multi-line selections
379+
return;
380+
}
381+
382+
const validRange = getBodyRangeForRange(docs, rangeStart, rangeEnd, document);
383+
384+
if (!validRange) {
385+
return;
386+
}
387+
388+
let indent = 0;
389+
390+
if (isFree) {
391+
indent = determineIndent(lineAt(document, rangeStart));
392+
} else {
393+
const freePortion = lineAt(document, rangeStart).substring(7);
394+
indent = determineIndent(freePortion) + 7;
395+
}
396+
397+
const newLine = `\n`;
398+
const indentStr = ` `.repeat(indent);
399+
const space = `${newLine}${indentStr}`;
400+
401+
if (rangeStart >= validRange.validStart && rangeEnd <= validRange.validEnd) {
402+
const refactorAction = CodeAction.create(`Surround with monitor`, CodeActionKind.RefactorRewrite);
403+
404+
refactorAction.edit = {
405+
changes: {
406+
[document.uri]: [
407+
TextEdit.insert(
408+
Position.create(rangeStart, 0),
409+
`${indentStr}monitor;${newLine}`
410+
),
411+
TextEdit.insert(
412+
Position.create(rangeEnd + 1, 0),
413+
`${space}on-error *all;${space} // TODO: implement${space}endmon;${newLine}`
414+
)
415+
]
416+
},
417+
};
418+
419+
if (isFree) {
420+
// Then format the document
421+
refactorAction.command = {
422+
command: `editor.action.formatDocument`,
423+
title: `Format`
424+
};
425+
}
426+
427+
return refactorAction;
428+
}
429+
430+
431+
return;
432+
}
433+
335434
export function getSubroutineActions(document: TextDocument, docs: Cache, range: Range): CodeAction | undefined {
336435
if (range.start.line === range.end.line) {
337436
const currentGlobalSubroutine = docs.subroutines.find(sub => sub.position.range.line === range.start.line && sub.range.start && sub.range.end);
@@ -354,7 +453,7 @@ export function getSubroutineActions(document: TextDocument, docs: Cache, range:
354453
const newProcedure = [
355454
`Dcl-Proc ${currentGlobalSubroutine.name};`,
356455
` Dcl-Pi *N;`,
357-
...extracted.references.map((ref, i) => ` ${extracted.newParamNames[i]} ${ref.dec.type === `struct` ? `likeDS` : `like`}(${ref.dec.name});`),
456+
...extracted.references.map((ref, i) => ` ${extracted.newParamNames[i]} ${ref.dec.type === `struct` ? `LikeDS` : `Like`}(${ref.dec.name});`),
358457
` End-Pi;`,
359458
``,
360459
caseInsensitiveReplaceAll(extracted.newBody, `leavesr`, `return`),
@@ -393,39 +492,50 @@ export function getSubroutineActions(document: TextDocument, docs: Cache, range:
393492
}
394493

395494
export function getExtractProcedureAction(document: TextDocument, docs: Cache, range: Range): CodeAction | undefined {
396-
if (range.end.line > range.start.line) {
397-
const lastLine = document.offsetAt({ line: document.lineCount, character: 0 });
495+
const rangeStart = range.start.line;
496+
const rangeEnd = range.end.line;
497+
if (rangeEnd > rangeStart) {
398498

399-
const extracted = createExtract(document, range, docs);
499+
const validRange = getBodyRangeForRange(docs, rangeStart, rangeEnd, document);
400500

401-
const newProcedure = [
402-
`Dcl-Proc NewProcedure;`,
403-
` Dcl-Pi *N;`,
404-
...extracted.references.map((ref, i) => ` ${extracted.newParamNames[i]} ${ref.dec.type === `struct` ? `likeDS` : `like`}(${ref.dec.name});`),
405-
` End-Pi;`,
406-
``,
407-
extracted.newBody,
408-
`End-Proc;`
409-
].join(`\n`)
501+
if (!validRange) {
502+
return;
503+
}
410504

411-
const newAction = CodeAction.create(`Extract to new procedure`, CodeActionKind.RefactorExtract);
505+
// Ensure the selected range is within a body range
506+
if (rangeStart >= validRange.validStart && rangeEnd <= validRange.validEnd) {
507+
const extracted = createExtract(document, range, docs);
412508

413-
// First do the exit
414-
newAction.edit = {
415-
changes: {
416-
[document.uri]: [
417-
TextEdit.replace(extracted.range, `NewProcedure(${extracted.references.map(r => r.dec.name).join(`:`)});`),
418-
TextEdit.insert(document.positionAt(lastLine), `\n\n` + newProcedure)
419-
]
420-
},
421-
};
509+
const newProcedure = [
510+
`Dcl-Proc NewProcedure;`,
511+
` Dcl-Pi *N;`,
512+
...extracted.references.map((ref, i) => ` ${extracted.newParamNames[i]} ${ref.dec.type === `struct` ? `LikeDS` : `Like`}(${ref.dec.name});`),
513+
` End-Pi;`,
514+
``,
515+
extracted.newBody,
516+
`End-Proc;`
517+
].join(`\n`)
422518

423-
// Then format the document
424-
newAction.command = {
425-
command: `editor.action.formatDocument`,
426-
title: `Format`
427-
};
519+
const newAction = CodeAction.create(`Extract to new procedure`, CodeActionKind.RefactorExtract);
520+
const lastLine = document.offsetAt({ line: document.lineCount, character: 0 });
428521

429-
return newAction;
522+
// First do the exit
523+
newAction.edit = {
524+
changes: {
525+
[document.uri]: [
526+
TextEdit.replace(extracted.range, `NewProcedure(${extracted.references.map(r => r.dec.name).join(`:`)});`),
527+
TextEdit.insert(document.positionAt(lastLine), `\n\n` + newProcedure)
528+
]
529+
},
530+
};
531+
532+
// Then format the document
533+
newAction.command = {
534+
command: `editor.action.formatDocument`,
535+
title: `Format`
536+
};
537+
538+
return newAction;
539+
}
430540
}
431541
}

extension/server/src/providers/linter/codeActions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { CodeAction, CodeActionKind, CodeActionParams, Range } from 'vscode-languageserver';
2-
import { getActions, getExtractProcedureAction, getSubroutineActions, refreshLinterDiagnostics } from '.';
3-
import { documents, parser } from '..';
1+
import { Range } from 'vscode-languageserver';
2+
import { getActions, refreshLinterDiagnostics } from '.';
43
import { TextDocument } from 'vscode-languageserver-textdocument';
54
import Cache from '../../../../../language/models/cache';
65

language/models/cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export default class Cache {
9595
* @param {string} fsPath Path to check
9696
* @returns {number} Line number
9797
*/
98-
getDefinitionBlockEnd(fsPath) {
98+
getDefinitionBlockEnd(fsPath: string) {
9999
const lasts = [
100100
this.procedures.filter(d => d.position.path === fsPath && d.keyword[`EXTPROC`] !== undefined).pop(),
101101
this.structs.filter(d => d.position.path === fsPath).pop(),

0 commit comments

Comments
 (0)