Skip to content

Commit acbad6f

Browse files
authored
Merge pull request #978 from intersystems-community/feature-974
implementing #974
2 parents 8d8a650 + 7efcc03 commit acbad6f

File tree

4 files changed

+143
-81
lines changed

4 files changed

+143
-81
lines changed

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,12 @@
12471247
"objectscript.debug.debugThisMethod": {
12481248
"type": "boolean",
12491249
"default": true,
1250-
"markdownDescription": "Show inline `Debug this method` CodeLens action for ClassMethods."
1250+
"markdownDescription": "Show inline `Debug Method` CodeLens action for ClassMethods and Routine Labels."
1251+
},
1252+
"objectscript.debug.copyToClipboard": {
1253+
"type": "boolean",
1254+
"default": true,
1255+
"markdownDescription": "Show inline `Copy Invocation` CodeLens action for ClassMethods and Routine Labels."
12511256
},
12521257
"objectscript.studioActionDebugOutput": {
12531258
"type": "boolean",

src/extension.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import { ObjectScriptDefinitionProvider } from "./providers/ObjectScriptDefiniti
5858
import { ObjectScriptFoldingRangeProvider } from "./providers/ObjectScriptFoldingRangeProvider";
5959
import { ObjectScriptHoverProvider } from "./providers/ObjectScriptHoverProvider";
6060
import { ObjectScriptRoutineSymbolProvider } from "./providers/ObjectScriptRoutineSymbolProvider";
61-
import { ObjectScriptClassCodeLensProvider } from "./providers/ObjectScriptClassCodeLensProvider";
61+
import { ObjectScriptCodeLensProvider } from "./providers/ObjectScriptCodeLensProvider";
6262
import { XmlContentProvider } from "./providers/XmlContentProvider";
6363

6464
import { AtelierAPI } from "./api";
@@ -705,9 +705,12 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
705705
Promise.all(files.map((file) => importFileOrFolder(file, true)))
706706
),
707707
vscode.commands.registerCommand("vscode-objectscript.export", exportAll),
708+
vscode.commands.registerCommand("vscode-objectscript.copyToClipboard", (command: string) => {
709+
vscode.env.clipboard.writeText(command);
710+
}),
708711
vscode.commands.registerCommand("vscode-objectscript.debug", (program: string, askArgs: boolean) => {
709712
const startDebugging = (args) => {
710-
const programWithArgs = program + `(${args})`;
713+
const programWithArgs = program + (program.includes("##class") || args.length ? `(${args})` : "");
711714
vscode.debug.startDebugging(undefined, {
712715
type: "objectscript",
713716
request: "launch",
@@ -848,8 +851,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
848851
vscode.debug.registerDebugAdapterDescriptorFactory("objectscript", debugAdapterFactory),
849852
debugAdapterFactory,
850853
vscode.languages.registerCodeLensProvider(
851-
documentSelector("objectscript-class"),
852-
new ObjectScriptClassCodeLensProvider()
854+
documentSelector("objectscript-class", "objectscript"),
855+
new ObjectScriptCodeLensProvider()
853856
),
854857
vscode.commands.registerCommand("vscode-objectscript.compileOnly", () => compileOnly(false)),
855858
vscode.commands.registerCommand("vscode-objectscript.compileOnlyWithFlags", () => compileOnly(true)),

src/providers/ObjectScriptClassCodeLensProvider.ts

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import * as vscode from "vscode";
2+
import { config } from "../extension";
3+
import { currentFile } from "../utils";
4+
5+
export class ObjectScriptCodeLensProvider implements vscode.CodeLensProvider {
6+
public provideCodeLenses(
7+
document: vscode.TextDocument,
8+
token: vscode.CancellationToken
9+
): vscode.ProviderResult<vscode.CodeLens[]> {
10+
const result = new Array<vscode.CodeLens>();
11+
12+
if (document.fileName.toLowerCase().endsWith(".cls")) {
13+
result.push(...this.classMethods(document));
14+
}
15+
if (document.fileName.toLowerCase().endsWith(".mac")) {
16+
result.push(...this.routineLabels(document));
17+
}
18+
return result;
19+
}
20+
21+
private classMethods(document: vscode.TextDocument): vscode.CodeLens[] {
22+
const file = currentFile(document);
23+
const result = new Array<vscode.CodeLens>();
24+
25+
if (!file.name.match(/\.cls$/i)) {
26+
return result;
27+
}
28+
const className = file.name.split(".").slice(0, -1).join(".");
29+
30+
const { debugThisMethod, copyToClipboard } = config("debug");
31+
const pattern = /(?:^ClassMethod\s)([^(]+)\((.*)/i;
32+
let inComment = false;
33+
for (let i = 0; i < document.lineCount; i++) {
34+
const line = document.lineAt(i);
35+
const text = this.stripLineComments(line.text);
36+
37+
if (text.match(/\/\*/)) {
38+
inComment = true;
39+
}
40+
41+
if (inComment) {
42+
if (text.match(/\*\//)) {
43+
inComment = false;
44+
}
45+
continue;
46+
}
47+
48+
const methodMatch = text.match(pattern);
49+
if (methodMatch) {
50+
const [, name, paramsRaw] = methodMatch;
51+
let params = paramsRaw;
52+
params = params.replace(/"[^"]*"/g, '""');
53+
params = params.replace(/{[^{}]*}|{[^{}]*{[^{}]*}[^{}]*}/g, '""');
54+
params = params.replace(/\([^()]*\)/g, "");
55+
params = params.split(")")[0];
56+
const paramsCount = params.length ? params.split(",").length : 0;
57+
58+
debugThisMethod && result.push(this.addDebugThisMethod(i, [`##class(${className}).${name}`, paramsCount > 0]));
59+
copyToClipboard &&
60+
result.push(this.addCopyToClipboard(i, [`##class(${className}).${name}(${Array(paramsCount).join(",")})`]));
61+
}
62+
}
63+
return result;
64+
}
65+
66+
private routineLabels(document: vscode.TextDocument): vscode.CodeLens[] {
67+
const file = currentFile(document);
68+
const result = new Array<vscode.CodeLens>();
69+
70+
if (!file.name.match(/\.mac$/i)) {
71+
return result;
72+
}
73+
const routineName = file.name.split(".").slice(0, -1).join(".");
74+
75+
const { debugThisMethod, copyToClipboard } = config("debug");
76+
77+
debugThisMethod && result.push(this.addDebugThisMethod(0, [`^${routineName}`, false]));
78+
copyToClipboard && result.push(this.addCopyToClipboard(0, [`^${routineName}`]));
79+
80+
let inComment = false;
81+
for (let i = 1; i < document.lineCount; i++) {
82+
const line = document.lineAt(i);
83+
const text = this.stripLineComments(line.text);
84+
85+
if (text.match(/\/\*/)) {
86+
inComment = true;
87+
}
88+
89+
if (inComment) {
90+
if (text.match(/\*\//)) {
91+
inComment = false;
92+
}
93+
continue;
94+
}
95+
96+
const labelMatch = text.match(/^(\w[^(\n\s]+)(?:\(([^)]*)\))?/i);
97+
if (labelMatch) {
98+
const [, name, parens] = labelMatch;
99+
100+
debugThisMethod && result.push(this.addDebugThisMethod(i, [`${name}^${routineName}`, parens !== "()"]));
101+
copyToClipboard && result.push(this.addCopyToClipboard(i, [`${name}^${routineName}`]));
102+
}
103+
}
104+
105+
return result;
106+
}
107+
108+
private addDebugThisMethod(line: number, args: any[]) {
109+
return new vscode.CodeLens(new vscode.Range(line, 0, line, 80), {
110+
title: `Debug this Method`,
111+
command: "vscode-objectscript.debug",
112+
arguments: args,
113+
});
114+
}
115+
116+
private addCopyToClipboard(line: number, args: any[]) {
117+
return new vscode.CodeLens(new vscode.Range(line, 0, line, 80), {
118+
title: `Copy Invocation`,
119+
command: "vscode-objectscript.copyToClipboard",
120+
arguments: args,
121+
});
122+
}
123+
124+
private stripLineComments(text: string) {
125+
text = text.replace(/\/\/.*$/, "");
126+
text = text.replace(/#+;.*$/, "");
127+
text = text.replace(/;.*$/, "");
128+
return text;
129+
}
130+
}

0 commit comments

Comments
 (0)