@theia/plugin-ext 1.71.0-next.8 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/plugin-api-rpc.d.ts +76 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +9 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +13 -6
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +2 -6
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/main-file-system-event-service.d.ts +10 -2
- package/lib/main/browser/main-file-system-event-service.d.ts.map +1 -1
- package/lib/main/browser/main-file-system-event-service.js +19 -2
- package/lib/main/browser/main-file-system-event-service.js.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.js +2 -0
- package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +1 -0
- package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.js +13 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +9 -2
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/scm-main.d.ts +33 -2
- package/lib/main/browser/scm-main.d.ts.map +1 -1
- package/lib/main/browser/scm-main.js +237 -3
- package/lib/main/browser/scm-main.js.map +1 -1
- package/lib/main/browser/scm-main.spec.d.ts +2 -0
- package/lib/main/browser/scm-main.spec.d.ts.map +1 -0
- package/lib/main/browser/scm-main.spec.js +87 -0
- package/lib/main/browser/scm-main.spec.js.map +1 -0
- package/lib/main/browser/test-main.d.ts +3 -2
- package/lib/main/browser/test-main.d.ts.map +1 -1
- package/lib/main/browser/test-main.js +12 -1
- package/lib/main/browser/test-main.js.map +1 -1
- package/lib/plugin/file-system-event-service-ext-impl.d.ts +11 -5
- package/lib/plugin/file-system-event-service-ext-impl.d.ts.map +1 -1
- package/lib/plugin/file-system-event-service-ext-impl.js +28 -9
- package/lib/plugin/file-system-event-service-ext-impl.js.map +1 -1
- package/lib/plugin/plugin-context.js +4 -4
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/scm.d.ts +8 -2
- package/lib/plugin/scm.d.ts.map +1 -1
- package/lib/plugin/scm.js +188 -5
- package/lib/plugin/scm.js.map +1 -1
- package/lib/plugin/scm.spec.d.ts +2 -0
- package/lib/plugin/scm.spec.d.ts.map +1 -0
- package/lib/plugin/scm.spec.js +461 -0
- package/lib/plugin/scm.spec.js.map +1 -0
- package/lib/plugin/terminal-ext.d.ts +13 -3
- package/lib/plugin/terminal-ext.d.ts.map +1 -1
- package/lib/plugin/terminal-ext.js +51 -10
- package/lib/plugin/terminal-ext.js.map +1 -1
- package/lib/plugin/terminal-ext.spec.d.ts +2 -0
- package/lib/plugin/terminal-ext.spec.d.ts.map +1 -0
- package/lib/plugin/terminal-ext.spec.js +285 -0
- package/lib/plugin/terminal-ext.spec.js.map +1 -0
- package/lib/plugin/test-item.d.ts.map +1 -1
- package/lib/plugin/test-item.js +8 -3
- package/lib/plugin/test-item.js.map +1 -1
- package/lib/plugin/tests.d.ts.map +1 -1
- package/lib/plugin/tests.js +15 -3
- package/lib/plugin/tests.js.map +1 -1
- package/lib/plugin/type-converters.d.ts +2 -2
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +3 -9
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +1 -1
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +1 -1
- package/lib/plugin/types-impl.js.map +1 -1
- package/lib/plugin/workspace.d.ts.map +1 -1
- package/lib/plugin/workspace.js +17 -3
- package/lib/plugin/workspace.js.map +1 -1
- package/package.json +39 -39
- package/src/common/plugin-api-rpc.ts +78 -0
- package/src/hosted/browser/hosted-plugin.ts +13 -6
- package/src/main/browser/main-context.ts +3 -7
- package/src/main/browser/main-file-system-event-service.ts +26 -6
- package/src/main/browser/menus/menus-contribution-handler.ts +2 -0
- package/src/main/browser/menus/plugin-menu-command-adapter.ts +15 -2
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +12 -3
- package/src/main/browser/scm-main.spec.ts +105 -0
- package/src/main/browser/scm-main.ts +272 -4
- package/src/main/browser/test-main.ts +13 -3
- package/src/plugin/file-system-event-service-ext-impl.ts +40 -14
- package/src/plugin/plugin-context.ts +7 -7
- package/src/plugin/scm.spec.ts +615 -0
- package/src/plugin/scm.ts +224 -6
- package/src/plugin/terminal-ext.spec.ts +350 -0
- package/src/plugin/terminal-ext.ts +58 -12
- package/src/plugin/test-item.ts +8 -3
- package/src/plugin/tests.ts +14 -3
- package/src/plugin/type-converters.ts +7 -13
- package/src/plugin/types-impl.ts +2 -2
- package/src/plugin/workspace.ts +17 -3
|
@@ -38,6 +38,13 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
38
38
|
|
|
39
39
|
private readonly _terminals = new Map<string, TerminalExtImpl>();
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Stores the API objects (Proxies) returned to plugins for each terminal.
|
|
43
|
+
* This ensures that events fire with the same object instance that plugins received,
|
|
44
|
+
* allowing strict equality checks (===) to work correctly.
|
|
45
|
+
*/
|
|
46
|
+
private readonly _terminalApiObjects = new Map<string, theia.Terminal>();
|
|
47
|
+
|
|
41
48
|
private readonly _pseudoTerminals = new Map<string, PseudoTerminal>();
|
|
42
49
|
|
|
43
50
|
private static nextProviderId = 0;
|
|
@@ -66,8 +73,8 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
66
73
|
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TERMINAL_MAIN);
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
get terminals():
|
|
70
|
-
return [...this._terminals.
|
|
76
|
+
get terminals(): theia.Terminal[] {
|
|
77
|
+
return [...this._terminals.keys()].map(id => this.getApiObject(id)).filter((t): t is theia.Terminal => t !== undefined);
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
get defaultShell(): string {
|
|
@@ -84,7 +91,9 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
84
91
|
createTerminal(
|
|
85
92
|
plugin: Plugin,
|
|
86
93
|
nameOrOptions: theia.TerminalOptions | theia.PseudoTerminalOptions | theia.ExtensionTerminalOptions | string | undefined,
|
|
87
|
-
shellPath?: string,
|
|
94
|
+
shellPath?: string,
|
|
95
|
+
shellArgs?: string[] | string,
|
|
96
|
+
apiObjectWrapper?: (terminal: TerminalExtImpl) => theia.Terminal
|
|
88
97
|
): theia.Terminal {
|
|
89
98
|
const id = `plugin-terminal-${UUID.uuid4()}`;
|
|
90
99
|
let options: TerminalOptions;
|
|
@@ -110,7 +119,15 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
110
119
|
let parentId;
|
|
111
120
|
if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) {
|
|
112
121
|
const parentTerminal = options.location.parentTerminal;
|
|
113
|
-
|
|
122
|
+
// Check both the API proxy objects and the raw terminals, since
|
|
123
|
+
// plugins receive the proxy but _terminals stores the raw object.
|
|
124
|
+
for (const [k, v] of this._terminalApiObjects) {
|
|
125
|
+
if (v === parentTerminal) {
|
|
126
|
+
parentId = k;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!parentId) {
|
|
114
131
|
for (const [k, v] of this._terminals) {
|
|
115
132
|
if (v === parentTerminal) {
|
|
116
133
|
parentId = k;
|
|
@@ -136,7 +153,16 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
136
153
|
if (typeof nameOrOptions === 'object' && 'pty' in nameOrOptions) {
|
|
137
154
|
creationOptions = nameOrOptions;
|
|
138
155
|
}
|
|
139
|
-
|
|
156
|
+
const terminal = this.obtainTerminal(id, options.name || 'Terminal', creationOptions);
|
|
157
|
+
|
|
158
|
+
// If a wrapper function is provided, wrap the terminal and register the API object
|
|
159
|
+
// This ensures events fire with the same object instance that plugins received
|
|
160
|
+
if (apiObjectWrapper) {
|
|
161
|
+
const apiObject = apiObjectWrapper(terminal);
|
|
162
|
+
this._terminalApiObjects.set(id, apiObject);
|
|
163
|
+
return apiObject;
|
|
164
|
+
}
|
|
165
|
+
return terminal;
|
|
140
166
|
}
|
|
141
167
|
|
|
142
168
|
attachPtyToTerminal(terminalId: number, pty: theia.Pseudoterminal): void {
|
|
@@ -153,6 +179,13 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
153
179
|
return terminal;
|
|
154
180
|
}
|
|
155
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Gets the API object for a terminal by ID, falling back to the raw terminal if not set.
|
|
184
|
+
*/
|
|
185
|
+
protected getApiObject(id: string): theia.Terminal | undefined {
|
|
186
|
+
return this._terminalApiObjects.get(id) ?? this._terminals.get(id);
|
|
187
|
+
}
|
|
188
|
+
|
|
156
189
|
$terminalOnInput(id: string, data: string): void {
|
|
157
190
|
const terminal = this._pseudoTerminals.get(id);
|
|
158
191
|
if (!terminal) {
|
|
@@ -168,7 +201,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
168
201
|
}
|
|
169
202
|
if (!terminal.state.isInteractedWith) {
|
|
170
203
|
terminal.state = { ...terminal.state, isInteractedWith: true };
|
|
171
|
-
this.
|
|
204
|
+
const apiObject = this.getApiObject(id);
|
|
205
|
+
if (apiObject) {
|
|
206
|
+
this.onDidChangeTerminalStateEmitter.fire(apiObject);
|
|
207
|
+
}
|
|
172
208
|
}
|
|
173
209
|
}
|
|
174
210
|
|
|
@@ -179,7 +215,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
179
215
|
}
|
|
180
216
|
if (terminal.state.shell !== shellType) {
|
|
181
217
|
terminal.state = { ...terminal.state, shell: shellType };
|
|
182
|
-
this.
|
|
218
|
+
const apiObject = this.getApiObject(id);
|
|
219
|
+
if (apiObject) {
|
|
220
|
+
this.onDidChangeTerminalStateEmitter.fire(apiObject);
|
|
221
|
+
}
|
|
183
222
|
}
|
|
184
223
|
}
|
|
185
224
|
|
|
@@ -194,7 +233,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
194
233
|
$terminalCreated(id: string, name: string): void {
|
|
195
234
|
const terminal = this.obtainTerminal(id, name);
|
|
196
235
|
terminal.id.resolve(id);
|
|
197
|
-
this.
|
|
236
|
+
const apiObject = this.getApiObject(id);
|
|
237
|
+
if (apiObject) {
|
|
238
|
+
this.onDidOpenTerminalEmitter.fire(apiObject);
|
|
239
|
+
}
|
|
198
240
|
}
|
|
199
241
|
|
|
200
242
|
$terminalNameChanged(id: string, name: string): void {
|
|
@@ -234,8 +276,12 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
234
276
|
const terminal = this._terminals.get(id);
|
|
235
277
|
if (terminal) {
|
|
236
278
|
terminal.exitStatus = exitStatus ?? { code: undefined, reason: TerminalExitReason.Unknown };
|
|
237
|
-
this.
|
|
279
|
+
const apiObject = this.getApiObject(id);
|
|
280
|
+
if (apiObject) {
|
|
281
|
+
this.onDidCloseTerminalEmitter.fire(apiObject);
|
|
282
|
+
}
|
|
238
283
|
this._terminals.delete(id);
|
|
284
|
+
this._terminalApiObjects.delete(id);
|
|
239
285
|
}
|
|
240
286
|
const pseudoTerminal = this._pseudoTerminals.get(id);
|
|
241
287
|
if (pseudoTerminal) {
|
|
@@ -245,8 +291,8 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
245
291
|
}
|
|
246
292
|
|
|
247
293
|
private activeTerminalId: string | undefined;
|
|
248
|
-
get activeTerminal():
|
|
249
|
-
return this.activeTerminalId && this.
|
|
294
|
+
get activeTerminal(): theia.Terminal | undefined {
|
|
295
|
+
return this.activeTerminalId && this.getApiObject(this.activeTerminalId) || undefined;
|
|
250
296
|
}
|
|
251
297
|
$currentTerminalChanged(id: string | undefined): void {
|
|
252
298
|
this.activeTerminalId = id;
|
|
@@ -319,7 +365,7 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
319
365
|
|
|
320
366
|
async $provideTerminalLinks(line: string, terminalId: string, token: theia.CancellationToken): Promise<ProvidedTerminalLink[]> {
|
|
321
367
|
const links: ProvidedTerminalLink[] = [];
|
|
322
|
-
const terminal = this.
|
|
368
|
+
const terminal = this.getApiObject(terminalId);
|
|
323
369
|
if (terminal) {
|
|
324
370
|
for (const [providerId, provider] of this.terminalLinkProviders) {
|
|
325
371
|
const providedLinks = await provider.provideTerminalLinks({ line, terminal }, token);
|
package/src/plugin/test-item.ts
CHANGED
|
@@ -132,9 +132,14 @@ export class TestItemCollection implements theia.TestItemCollection {
|
|
|
132
132
|
return this.values.size;
|
|
133
133
|
}
|
|
134
134
|
replace(items: readonly theia.TestItem[]): void {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
const toDelete = new Set(this.values.values.map(item => item.id));
|
|
136
|
+
for (const item of items) {
|
|
137
|
+
toDelete.delete(item.id);
|
|
138
|
+
this.add(item);
|
|
139
|
+
}
|
|
140
|
+
for (const id of toDelete) {
|
|
141
|
+
this.delete(id);
|
|
142
|
+
}
|
|
138
143
|
}
|
|
139
144
|
|
|
140
145
|
forEach(callback: (item: theia.TestItem, collection: theia.TestItemCollection) => unknown, thisArg?: unknown): void {
|
package/src/plugin/tests.ts
CHANGED
|
@@ -299,6 +299,10 @@ export class TestRun implements theia.TestRun {
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
end(): void {
|
|
302
|
+
if (this.ended) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
this.changeBatcher.flush();
|
|
302
306
|
this.ended = true;
|
|
303
307
|
this.proxy.$notifyTestRunEnded(this.controller.id, this.id);
|
|
304
308
|
}
|
|
@@ -428,9 +432,16 @@ export class TestingExtImpl implements TestingExt {
|
|
|
428
432
|
$onResolveChildren(controllerId: string, path: string[]): void {
|
|
429
433
|
const controller = this.withController(controllerId);
|
|
430
434
|
if (controller.resolveHandler) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
controller.resolveHandler
|
|
435
|
+
if (path.length === 0) {
|
|
436
|
+
// Root-level resolve: discover top-level test items
|
|
437
|
+
controller.resolveHandler(undefined);
|
|
438
|
+
} else {
|
|
439
|
+
const item = controller.items.find(path);
|
|
440
|
+
// The `main` side should only request resolution for items with `canResolveChildren`, but with event batching,
|
|
441
|
+
// the flag can be out of sync with the state on the `plugin` side. The state on the `plugin` side is authoritative.
|
|
442
|
+
if (item?.canResolveChildren) {
|
|
443
|
+
controller.resolveHandler(item);
|
|
444
|
+
}
|
|
434
445
|
}
|
|
435
446
|
}
|
|
436
447
|
}
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
DecorationOptions, EditorPosition, Plugin, Position, WorkspaceTextEditDto, WorkspaceFileEditDto, Selection, TaskDto, WorkspaceEditDto
|
|
23
23
|
} from '../common/plugin-api-rpc';
|
|
24
24
|
import * as model from '../common/plugin-api-rpc-model';
|
|
25
|
-
import { LanguageFilter, LanguageSelector
|
|
25
|
+
import { LanguageFilter, LanguageSelector } from '@theia/editor/lib/common/language-selector';
|
|
26
26
|
import { MarkdownString as PluginMarkdownStringImpl } from './markdown-string';
|
|
27
27
|
import * as types from './types-impl';
|
|
28
28
|
import { UriComponents } from '../common/uri-components';
|
|
@@ -246,27 +246,21 @@ export function fromDocumentSelector(selector: theia.DocumentSelector | undefine
|
|
|
246
246
|
return {
|
|
247
247
|
language: selector.language,
|
|
248
248
|
scheme: selector.scheme,
|
|
249
|
-
pattern: fromGlobPattern(selector.pattern
|
|
249
|
+
pattern: selector.pattern && fromGlobPattern(selector.pattern)
|
|
250
250
|
} as LanguageFilter;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
export function fromGlobPattern(pattern: theia.GlobPattern): string | RelativePattern {
|
|
255
|
+
export function fromGlobPattern(pattern: theia.GlobPattern): string | types.RelativePattern {
|
|
256
256
|
if (typeof pattern === 'string') {
|
|
257
257
|
return pattern;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return pattern;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function isRelativePattern(obj: {}): obj is theia.RelativePattern {
|
|
268
|
-
const rp = obj as theia.RelativePattern;
|
|
269
|
-
return rp && typeof rp.baseUri === 'string' && typeof rp.pattern === 'string';
|
|
260
|
+
return new types.RelativePattern(
|
|
261
|
+
pattern.baseUri ?? pattern.base, // preserve backwards compatibility with older extensions: legacy relative pattern shape did not have the `baseUri` property
|
|
262
|
+
pattern.pattern
|
|
263
|
+
);
|
|
270
264
|
}
|
|
271
265
|
|
|
272
266
|
export function fromCompletionItemKind(kind?: types.CompletionItemKind): model.CompletionItemKind {
|
package/src/plugin/types-impl.ts
CHANGED
|
@@ -737,7 +737,7 @@ export class ThemeIcon {
|
|
|
737
737
|
|
|
738
738
|
static readonly Folder: ThemeIcon = new ThemeIcon('folder');
|
|
739
739
|
|
|
740
|
-
|
|
740
|
+
constructor(public id: string, public color?: ThemeColor) {
|
|
741
741
|
}
|
|
742
742
|
|
|
743
743
|
}
|
|
@@ -816,7 +816,7 @@ export class RelativePattern {
|
|
|
816
816
|
}
|
|
817
817
|
set baseUri(baseUri: URI) {
|
|
818
818
|
this._baseUri = baseUri;
|
|
819
|
-
this.
|
|
819
|
+
this._base = baseUri.fsPath;
|
|
820
820
|
}
|
|
821
821
|
|
|
822
822
|
constructor(base: theia.WorkspaceFolder | URI | string, public pattern: string) {
|
package/src/plugin/workspace.ts
CHANGED
|
@@ -39,7 +39,6 @@ import { Disposable, URI } from './types-impl';
|
|
|
39
39
|
import { normalize } from '@theia/core/lib/common/paths';
|
|
40
40
|
import { relative } from '../common/paths-util';
|
|
41
41
|
import { Schemes, UriComponents } from '../common/uri-components';
|
|
42
|
-
import { toWorkspaceFolder } from './type-converters';
|
|
43
42
|
import { MessageRegistryExt } from './message-registry';
|
|
44
43
|
import * as Converter from './type-converters';
|
|
45
44
|
import { FileStat } from '@theia/filesystem/lib/common/files';
|
|
@@ -120,7 +119,22 @@ export class WorkspaceExtImpl implements WorkspaceExt {
|
|
|
120
119
|
|
|
121
120
|
$onWorkspaceFoldersChanged(event: WorkspaceRootsChangeEvent): void {
|
|
122
121
|
const newRoots = event.roots || [];
|
|
123
|
-
const
|
|
122
|
+
const oldFoldersByUri = new Map<string, theia.WorkspaceFolder>();
|
|
123
|
+
if (this.folders) {
|
|
124
|
+
for (const folder of this.folders) {
|
|
125
|
+
oldFoldersByUri.set(folder.uri.toString(), folder);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const newFolders = newRoots.map((root, index) => {
|
|
129
|
+
const existing = oldFoldersByUri.get(root);
|
|
130
|
+
if (existing) {
|
|
131
|
+
// Preserve object identity even if the index changed,
|
|
132
|
+
// since extensions may use folder objects as Map keys.
|
|
133
|
+
Object.assign(existing, { index });
|
|
134
|
+
return existing;
|
|
135
|
+
}
|
|
136
|
+
return this.toWorkspaceFolder(root, index);
|
|
137
|
+
});
|
|
124
138
|
const delta = this.deltaFolders(this.folders, newFolders);
|
|
125
139
|
|
|
126
140
|
this.folders = newFolders;
|
|
@@ -347,7 +361,7 @@ export class WorkspaceExtImpl implements WorkspaceExt {
|
|
|
347
361
|
const folderPath = folder.uri.toString();
|
|
348
362
|
|
|
349
363
|
if (resourcePath === folderPath) {
|
|
350
|
-
return
|
|
364
|
+
return folder;
|
|
351
365
|
}
|
|
352
366
|
|
|
353
367
|
if (resourcePath.startsWith(folderPath)
|