Skip to content

Commit a432e02

Browse files
authored
Add CodeLenses for BPLs, DTLs, KPIs and Rules (#1303)
1 parent 7a0df21 commit a432e02

File tree

3 files changed

+81
-44
lines changed

3 files changed

+81
-44
lines changed

src/commands/newFile.ts

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -555,17 +555,7 @@ Method OnProcessInput(pInput As %RegisteredObject, pOutput As %RegisteredObject)
555555
${typeof desc == "string" ? "/// " + desc.replace(/\n/g, "\n/// ") : ""}
556556
Class ${cls} Extends Ens.BusinessProcessBPL [ ClassType = persistent, ProcedureBlock ]
557557
{
558-
${
559-
api
560-
? `
561-
/*
562-
You can edit this class in the Business Process Editor by pasting the following URL into your web browser.
563-
You can also edit this XML block directly.
564-
${api.config.https ? "https" : "http"}://${api.config.host}:${api.config.port}${
565-
api.config.pathPrefix
566-
}/csp/${api.config.ns.toLowerCase()}/EnsPortal.BPLEditor.zen?BP=${cls}.BPL\n*/\n`
567-
: ""
568-
}
558+
569559
/// BPL Definition
570560
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
571561
{
@@ -652,17 +642,7 @@ Class ${cls} Extends Ens.DataTransformDTL [ DependsOn = ${
652642
sourceCls == targetCls ? sourceCls : `(${sourceCls}, ${targetCls})`
653643
} ]
654644
{
655-
${
656-
api
657-
? `
658-
/*
659-
You can edit this class in the Data Transformation Editor by pasting the following URL into your web browser.
660-
You can also edit this XML block directly.
661-
${api.config.https ? "https" : "http"}://${api.config.host}:${api.config.port}${
662-
api.config.pathPrefix
663-
}/csp/${api.config.ns.toLowerCase()}/EnsPortal.DTLEditor.zen?DT=${cls}.DTL\n*/\n`
664-
: ""
665-
}
645+
666646
Parameter IGNOREMISSINGSOURCE = 1;
667647
668648
Parameter REPORTERRORS = 1;
@@ -816,16 +796,7 @@ XData RuleDefinition [ XMLNamespace = "http://www.intersystems.com/rule" ]
816796
${typeof desc == "string" ? "/// " + desc.replace(/\n/g, "\n/// ") : ""}
817797
Class ${cls} Extends %DeepSee.KPI
818798
{
819-
${
820-
api
821-
? `
822-
/*
823-
You can test this KPI by pasting the following URL into your web browser.
824-
${api.config.https ? "https" : "http"}://${api.config.host}:${api.config.port}${
825-
api.config.pathPrefix
826-
}/csp/${api.config.ns.toLowerCase()}/${cls}.cls\n*/\n`
827-
: ""
828-
}
799+
829800
Parameter DOMAIN = "${kpiDomain}";
830801
831802
Parameter RESOURCE = "${kpiResource == "No Resource" ? "" : kpiResource}";

src/extension.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ import { FileDecorationProvider } from "./providers/FileDecorationProvider";
127127
import { RESTDebugPanel } from "./commands/restDebugPanel";
128128
import { modifyWsFolder } from "./commands/addServerNamespaceToWorkspace";
129129
import { WebSocketTerminalProfileProvider, launchWebSocketTerminal } from "./commands/webSocketTerminal";
130+
import { getCSPToken } from "./utils/getCSPToken";
130131

131132
const packageJson = vscode.extensions.getExtension(extensionId).packageJSON;
132133
const extensionVersion = packageJson.version;
@@ -1324,6 +1325,26 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
13241325
vscode.commands.registerCommand("vscode-objectscript.importXMLFiles", importXMLFiles),
13251326
vscode.commands.registerCommand("vscode-objectscript.exportToXMLFile", exportDocumentsToXMLFile),
13261327
vscode.commands.registerCommand("vscode-objectscript.extractXMLFileContents", extractXMLFileContents),
1328+
vscode.commands.registerCommand(
1329+
"vscode-objectscript.openPathInBrowser",
1330+
async (path: string, docUri: vscode.Uri) => {
1331+
if (typeof path == "string" && docUri && docUri instanceof vscode.Uri) {
1332+
const api = new AtelierAPI(docUri);
1333+
let uri = vscode.Uri.parse(
1334+
`${api.config.https ? "https" : "http"}://${api.config.host}:${api.config.port}${
1335+
api.config.pathPrefix
1336+
}${path}`
1337+
);
1338+
const token = await getCSPToken(api, path.split("?")[0]).catch(() => "");
1339+
if (token.length > 0) {
1340+
uri = uri.with({
1341+
query: uri.query.length ? `${uri.query}&CSPCHD=${token}` : `CSPCHD=${token}`,
1342+
});
1343+
}
1344+
vscode.env.openExternal(uri);
1345+
}
1346+
}
1347+
),
13271348

13281349
/* Anything we use from the VS Code proposed API */
13291350
...proposed

src/providers/ObjectScriptCodeLensProvider.ts

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
import * as vscode from "vscode";
22
import { config } from "../extension";
33
import { currentFile } from "../utils";
4+
import { AtelierAPI } from "../api";
45

56
export class ObjectScriptCodeLensProvider implements vscode.CodeLensProvider {
67
public provideCodeLenses(
78
document: vscode.TextDocument,
89
token: vscode.CancellationToken
910
): vscode.ProviderResult<vscode.CodeLens[]> {
1011
if (document.languageId == "objectscript-class") {
11-
return this.classMethods(document);
12+
return this.classMembers(document);
1213
}
1314
if (["objectscript", "objectscript-int"].includes(document.languageId)) {
1415
return this.routineLabels(document);
1516
}
1617
return [];
1718
}
1819

19-
private classMethods(document: vscode.TextDocument): vscode.CodeLens[] {
20+
private classMembers(document: vscode.TextDocument): vscode.CodeLens[] {
2021
const file = currentFile(document);
2122
const result = new Array<vscode.CodeLens>();
22-
23-
const className = file.name.split(".").slice(0, -1).join(".");
24-
23+
const className = file.name.slice(0, -4);
2524
const { debugThisMethod, copyToClipboard } = config("debug");
26-
if (!debugThisMethod && !copyToClipboard) {
27-
// Return early if both types are turned off
28-
return result;
29-
}
25+
const methodPattern = /(?:^(ClassMethod|Query)\s)([^(]+)\((.*)/i;
26+
const xdataPattern = /^XData\s([^[{\s]+)/i;
27+
const superPattern = new RegExp(
28+
`^\\s*Class\\s+${className.replace(/\./g, "\\.")}\\s+Extends\\s+(?:(?:\\(([^)]+)\\))|(?:([^\\s]+)))`,
29+
"i"
30+
);
31+
const api = new AtelierAPI(document.uri);
3032

31-
const pattern = /(?:^(ClassMethod|Query)\s)([^(]+)\((.*)/i;
33+
let superclasses: string[] = [];
3234
let inComment = false;
3335
for (let i = 0; i < document.lineCount; i++) {
3436
const line = document.lineAt(i);
@@ -45,8 +47,51 @@ export class ObjectScriptCodeLensProvider implements vscode.CodeLensProvider {
4547
continue;
4648
}
4749

48-
const methodMatch = text.match(pattern);
49-
if (methodMatch) {
50+
const methodMatch = text.match(methodPattern);
51+
const xdataMatch = text.match(xdataPattern);
52+
const superMatch = text.match(superPattern);
53+
if (superMatch) {
54+
const [, superclassesList, superclass] = superMatch;
55+
if (superclass) {
56+
superclasses = [superclass];
57+
} else {
58+
superclasses = superclassesList.replace(/\s+/g, "").split(",");
59+
}
60+
} else if (xdataMatch && api.active) {
61+
let [, xdataName] = xdataMatch;
62+
xdataName = xdataName.trim();
63+
let cmd: vscode.Command = undefined;
64+
if (
65+
(xdataName == "BPL" && superclasses.includes("Ens.BusinessProcessBPL")) ||
66+
(xdataName == "DTL" && superclasses.includes("Ens.DataTransformDTL"))
67+
) {
68+
cmd = {
69+
title: "Open Graphical Editor",
70+
command: "vscode-objectscript.openPathInBrowser",
71+
tooltip: "Open graphical editor in an external browser",
72+
arguments: [
73+
`/csp/${api.config.ns.toLowerCase()}/EnsPortal.${
74+
xdataName == "BPL" ? `BPLEditor.zen?BP=${className}.BPL` : `DTLEditor.zen?DT=${className}.DTL`
75+
}`,
76+
document.uri,
77+
],
78+
};
79+
} else if (xdataName == "RuleDefinition" && superclasses.includes("Ens.Rule.Definition")) {
80+
cmd = {
81+
title: "Reopen in Graphical Editor",
82+
command: "workbench.action.toggleEditorType",
83+
tooltip: "Replace text editor with graphical editor",
84+
};
85+
} else if (xdataName == "KPI" && superclasses.includes("%DeepSee.KPI")) {
86+
cmd = {
87+
title: "Test KPI",
88+
command: "vscode-objectscript.openPathInBrowser",
89+
tooltip: "Open testing page in an external browser",
90+
arguments: [`/csp/${api.config.ns.toLowerCase()}/${className}.cls`, document.uri],
91+
};
92+
}
93+
if (cmd) result.push(new vscode.CodeLens(new vscode.Range(i, 0, i, 80), cmd));
94+
} else if (methodMatch && (debugThisMethod || copyToClipboard)) {
5095
const [, kind, name, paramsRaw] = methodMatch;
5196
let params = paramsRaw;
5297
params = params.replace(/"[^"]*"/g, '""');

0 commit comments

Comments
 (0)