Skip to content

Commit 10b04f4

Browse files
committed
Merge remote-tracking branch 'upstream/master' into dtl
2 parents 9934a47 + 5f7402d commit 10b04f4

23 files changed

+1058
-1211
lines changed

package-lock.json

Lines changed: 167 additions & 288 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,22 +581,22 @@
581581
},
582582
{
583583
"command": "vscode-objectscript.addItemsToProject",
584-
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && explorerResourceIsRoot && !listMultiSelection",
584+
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && resourcePath =~ /^\\/?$/ && !listMultiSelection",
585585
"group": "objectscript_prj@1"
586586
},
587587
{
588588
"command": "vscode-objectscript.removeFromProject",
589-
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && !explorerResourceIsRoot && !listMultiSelection",
589+
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && !(resourcePath =~ /^\\/?$/) && !listMultiSelection",
590590
"group": "objectscript_prj@2"
591591
},
592592
{
593593
"command": "vscode-objectscript.removeItemsFromProject",
594-
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && explorerResourceIsRoot && !listMultiSelection",
594+
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && resourcePath =~ /^\\/?$/ && !listMultiSelection",
595595
"group": "objectscript_prj@2"
596596
},
597597
{
598598
"command": "vscode-objectscript.modifyProjectMetadata",
599-
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && explorerResourceIsRoot && !listMultiSelection",
599+
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && resourcePath =~ /^\\/?$/ && !listMultiSelection",
600600
"group": "objectscript_prj@3"
601601
},
602602
{
@@ -1289,7 +1289,11 @@
12891289
"type": "string"
12901290
},
12911291
"internalPort": {
1292-
"description": "Target port inside the service in docker-compose.",
1292+
"description": "Target webserver port inside the service in docker-compose.",
1293+
"type": "number"
1294+
},
1295+
"internalSuperserverPort": {
1296+
"description": "Target superserver port inside the service in docker-compose.",
12931297
"type": "number"
12941298
},
12951299
"file": {
@@ -1795,7 +1799,7 @@
17951799
"eslint-plugin-promise": "^7.1.0",
17961800
"glob": "^11.0.1",
17971801
"globals": "^15.12.0",
1798-
"mocha": "^9.1.3",
1802+
"mocha": "^11.1.0",
17991803
"path-browserify": "^1.0.1",
18001804
"prettier": "^3.3.1",
18011805
"ts-loader": "^9.5.1",

src/api/index.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { currentWorkspaceFolder, outputChannel, outputConsole } from "../utils";
1818
const DEFAULT_API_VERSION = 1;
1919
const DEFAULT_SERVER_VERSION = "2016.2.0";
2020
import * as Atelier from "./atelier";
21+
import { isfsConfig } from "../utils/FileProviderUtil";
2122

2223
// Map of the authRequest promises for each username@host:port target to avoid concurrency issues
2324
const authRequestMap = new Map<string, Promise<any>>();
@@ -30,6 +31,7 @@ interface ConnectionSettings {
3031
https: boolean;
3132
host: string;
3233
port: number;
34+
superserverPort?: number;
3335
pathPrefix: string;
3436
ns: string;
3537
username: string;
@@ -67,6 +69,9 @@ export class AtelierAPI {
6769
const wsKey = this.configName.toLowerCase();
6870
const host = this.externalServer ? this._config.host : workspaceState.get(wsKey + ":host", this._config.host);
6971
const port = this.externalServer ? this._config.port : workspaceState.get(wsKey + ":port", this._config.port);
72+
const superserverPort = this.externalServer
73+
? this._config.superserverPort
74+
: workspaceState.get(wsKey + ":superserverPort", this._config.superserverPort);
7075
const password = workspaceState.get(wsKey + ":password", this._config.password);
7176
const apiVersion = workspaceState.get(wsKey + ":apiVersion", DEFAULT_API_VERSION);
7277
const serverVersion = workspaceState.get(wsKey + ":serverVersion", DEFAULT_SERVER_VERSION);
@@ -80,6 +85,7 @@ export class AtelierAPI {
8085
https,
8186
host,
8287
port,
88+
superserverPort,
8389
pathPrefix,
8490
ns,
8591
username,
@@ -120,9 +126,9 @@ export class AtelierAPI {
120126
workspaceFolderName = parts[0];
121127
namespace = parts[1];
122128
} else {
123-
const params = new URLSearchParams(wsOrFile.query);
124-
if (params.has("ns") && params.get("ns") != "") {
125-
namespace = params.get("ns");
129+
const { ns } = isfsConfig(wsOrFile);
130+
if (ns) {
131+
namespace = ns;
126132
}
127133
}
128134
} else {
@@ -138,10 +144,6 @@ export class AtelierAPI {
138144
this.setConnection(workspaceFolderName || currentWorkspaceFolder(), namespace);
139145
}
140146

141-
public get enabled(): boolean {
142-
return this._config.active;
143-
}
144-
145147
public setNamespace(namespace: string): void {
146148
this.namespace = namespace;
147149
}
@@ -211,6 +213,7 @@ export class AtelierAPI {
211213
webServer: { scheme, host, port, pathPrefix = "" },
212214
username,
213215
password,
216+
superServer,
214217
} = getResolvedConnectionSpec(serverName, config("intersystems.servers", workspaceFolderName).get(serverName));
215218
this._config = {
216219
serverName,
@@ -221,6 +224,7 @@ export class AtelierAPI {
221224
ns,
222225
host,
223226
port,
227+
superserverPort: superServer.port,
224228
username,
225229
password,
226230
pathPrefix,
@@ -241,6 +245,7 @@ export class AtelierAPI {
241245
webServer: { scheme, host, port, pathPrefix = "" },
242246
username,
243247
password,
248+
superServer,
244249
} = resolvedSpec;
245250
this._config = {
246251
serverName: "",
@@ -251,6 +256,7 @@ export class AtelierAPI {
251256
ns,
252257
host,
253258
port,
259+
superserverPort: superServer.port,
254260
username,
255261
password,
256262
pathPrefix,

src/commands/addServerNamespaceToWorkspace.ts

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from "../extension";
1212
import { cspAppsForUri, handleError, notIsfs } from "../utils";
1313
import { pickProject } from "./project";
14+
import { isfsConfig, IsfsUriParam } from "../utils/FileProviderUtil";
1415

1516
/**
1617
* @param message The prefix of the message to show when the server manager API can't be found.
@@ -143,9 +144,7 @@ export async function addServerNamespaceToWorkspace(resource?: vscode.Uri): Prom
143144
return;
144145
}
145146
// Generate the name
146-
const params = new URLSearchParams(uri.query);
147-
const project = params.get("project");
148-
const csp = params.has("csp");
147+
const { csp, project } = isfsConfig(uri);
149148
const name = `${project ? `${project} - ${serverName}:${namespace}` : !csp ? `${serverName}:${namespace}` : ["", "/"].includes(uri.path) ? `${serverName}:${namespace} web files` : `${serverName} (${uri.path})`}${
150149
scheme == FILESYSTEM_READONLY_SCHEMA && !project ? " (read-only)" : ""
151150
}`;
@@ -188,7 +187,7 @@ export async function getServerManagerApi(): Promise<any> {
188187
/** Prompt the user to fill in the `path` and `query` of `uri`. */
189188
async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefined> {
190189
if (notIsfs(uri)) return;
191-
const params = new URLSearchParams(uri.query);
190+
const { project, csp, system, generated, mapped, filter } = isfsConfig(uri);
192191
const api = new AtelierAPI(uri);
193192

194193
// Prompt the user for the files to show
@@ -211,9 +210,7 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
211210
detail: "Choose an existing project, or create a new one.",
212211
},
213212
];
214-
quickPick.activeItems = [
215-
params.has("project") ? quickPick.items[2] : params.has("csp") ? quickPick.items[1] : quickPick.items[0],
216-
];
213+
quickPick.activeItems = [project ? quickPick.items[2] : csp ? quickPick.items[1] : quickPick.items[0]];
217214

218215
quickPick.onDidChangeSelection((items) => {
219216
switch (items[0].label) {
@@ -258,7 +255,7 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
258255
// Catch handler reported the error already
259256
return;
260257
} else if (cspApps.length == 0) {
261-
vscode.window.showWarningMessage(`No web applications are configured to use namespace ${api.ns}.`, "Dismiss");
258+
vscode.window.showWarningMessage(`No web applications are configured in namespace ${api.ns}.`, "Dismiss");
262259
return;
263260
}
264261
}
@@ -292,43 +289,43 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
292289
if (!newPath) {
293290
return;
294291
}
295-
newParams = "csp";
292+
newParams = IsfsUriParam.CSP;
296293
} else if (filterType == "project") {
297294
// Prompt for project
298295
const project = await pickProject(new AtelierAPI(uri));
299296
if (!project) {
300297
return;
301298
}
302-
newParams = `project=${project}`;
299+
newParams = `${IsfsUriParam.Project}=${project}`;
303300
} else {
304301
// Prompt the user for other query parameters
305302
const items = [
306303
{
307304
label: "$(filter) Filter",
308305
detail: "Comma-delimited list of search options, e.g. '*.cls,*.inc,*.mac,*.int'",
309-
picked: params.has("filter"),
310-
value: "filter",
306+
picked: filter != "",
307+
value: IsfsUriParam.Filter,
311308
},
312309
{
313310
label: "$(server-process) Show Generated",
314311
detail: "Also show files tagged as generated, e.g. by compilation.",
315-
picked: params.has("generated"),
316-
value: "generated",
312+
picked: generated,
313+
value: IsfsUriParam.Generated,
317314
},
318315
{
319316
label: "$(references) Hide Mapped",
320317
detail: `Hide files that are mapped into ${api.ns} from another code database.`,
321-
picked: params.has("mapped"),
322-
value: "mapped",
318+
picked: !mapped,
319+
value: IsfsUriParam.Mapped,
323320
},
324321
];
325322
if (api.ns != "%SYS") {
326323
// Only show system item for non-%SYS namespaces
327324
items.push({
328325
label: "$(library) Show System",
329326
detail: "Also show '%' items and INFORMATION.SCHEMA items.",
330-
picked: params.has("system"),
331-
value: "system",
327+
picked: system,
328+
value: IsfsUriParam.System,
332329
});
333330
}
334331
const otherParams = await vscode.window.showQuickPick(items, {
@@ -340,37 +337,29 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
340337
return;
341338
}
342339
// Build the new query parameter string
343-
params.delete("csp");
344-
params.delete("project");
345-
params.delete("filter");
346-
params.delete("flat");
347-
params.delete("generated");
348-
params.delete("mapped");
349-
params.delete("system");
350-
params.delete("type");
340+
const params = new URLSearchParams();
351341
for (const otherParam of otherParams) {
352342
switch (otherParam.value) {
353-
case "filter": {
343+
case IsfsUriParam.Filter: {
354344
// Prompt for filter
355-
const filter = await vscode.window.showInputBox({
345+
const newFilter = await vscode.window.showInputBox({
356346
title: "Enter a filter string.",
357347
ignoreFocusOut: true,
358-
value: params.get("filter"),
348+
value: filter,
359349
placeHolder: "*.cls,*.inc,*.mac,*.int",
360350
prompt:
361351
"Patterns are comma-delimited and may contain both * (zero or more characters) and ? (a single character) as wildcards. To exclude items, prefix the pattern with a single quote.",
362352
});
363-
if (filter && filter.length) {
364-
params.set(otherParam.value, filter);
353+
if (newFilter && newFilter.length) {
354+
params.set(otherParam.value, newFilter);
365355
}
366356
break;
367357
}
368-
case "generated":
369-
case "system":
370-
params.set(otherParam.value, "1");
371-
break;
372-
case "mapped":
358+
case IsfsUriParam.Mapped:
373359
params.set(otherParam.value, "0");
360+
break;
361+
default: // system and generated
362+
params.set(otherParam.value, "1");
374363
}
375364
}
376365
newParams = params.toString();

src/commands/compile.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ import {
2323
exportedUris,
2424
handleError,
2525
isClassDeployed,
26+
isClassOrRtn,
2627
notIsfs,
2728
notNull,
2829
outputChannel,
30+
RateLimiter,
2931
routineNameTypeRegex,
30-
throttleRequests,
3132
} from "../utils";
3233
import { StudioActions } from "./studio";
3334
import { NodeBase, PackageNode, RootNode } from "../explorer/nodes";
35+
import { updateIndexForDocument } from "../utils/documentIndex";
3436

3537
async function compileFlags(): Promise<string> {
3638
const defaultFlags = config().compileFlags;
@@ -226,6 +228,10 @@ export async function loadChanges(files: (CurrentTextFile | CurrentBinaryFile)[]
226228
file.uri,
227229
Buffer.isBuffer(content) ? content : new TextEncoder().encode(content.join("\n"))
228230
);
231+
if (isClassOrRtn(file.uri)) {
232+
// Update the document index
233+
updateIndexForDocument(file.uri, undefined, undefined, content);
234+
}
229235
exportedUris.push(file.uri.toString());
230236
} else if (filesystemSchemas.includes(file.uri.scheme)) {
231237
fileSystemProvider.fireFileChanged(file.uri);
@@ -414,9 +420,10 @@ export async function namespaceCompile(askFlags = false): Promise<any> {
414420

415421
async function importFiles(files: vscode.Uri[], noCompile = false) {
416422
const toCompile: CurrentFile[] = [];
423+
const rateLimiter = new RateLimiter(50);
417424
await Promise.allSettled<void>(
418-
files.map(
419-
throttleRequests((uri: vscode.Uri) => {
425+
files.map((uri) =>
426+
rateLimiter.call(async () => {
420427
return vscode.workspace.fs
421428
.readFile(uri)
422429
.then((contentBytes) => {
@@ -661,7 +668,7 @@ export async function importLocalFilesToServerSideFolder(wsFolderUri: vscode.Uri
661668
return;
662669
}
663670
// Filter out non-ISC files
664-
uris = uris.filter((uri) => ["cls", "mac", "int", "inc"].includes(uri.path.split(".").pop().toLowerCase()));
671+
uris = uris.filter(isClassOrRtn);
665672
if (uris.length == 0) {
666673
vscode.window.showErrorMessage("No classes or routines were selected.", "Dismiss");
667674
return;
@@ -711,9 +718,10 @@ export async function importLocalFilesToServerSideFolder(wsFolderUri: vscode.Uri
711718
docs.map((e) => e.name)
712719
);
713720
// Import the files
721+
const rateLimiter = new RateLimiter(50);
714722
return Promise.allSettled<string>(
715-
docs.map(
716-
throttleRequests((doc: { name: string; content: string; uri: vscode.Uri }) => {
723+
docs.map((doc) =>
724+
rateLimiter.call(async () => {
717725
// Allow importing over deployed classes since the XML import
718726
// command and SMP, terminal, and Studio imports allow it
719727
return importFileFromContent(doc.name, doc.content, api, false, true).then(() => {

0 commit comments

Comments
 (0)