Skip to content

Commit fbacd65

Browse files
committed
debt - no guessing-caching, better use of gc-signals, command converter using gc-signals, main side heap service
1 parent c57c31a commit fbacd65

13 files changed

Lines changed: 292 additions & 256 deletions

src/vs/workbench/api/node/extHost.api.impl.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ import { ExtHostMessageService } from 'vs/workbench/api/node/extHostMessageServi
2828
import { ExtHostEditors } from 'vs/workbench/api/node/extHostEditors';
2929
import { ExtHostLanguages } from 'vs/workbench/api/node/extHostLanguages';
3030
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
31-
import * as ExtHostTypeConverters from 'vs/workbench/api/node/extHostTypeConverters';
32-
import { registerApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
31+
import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
3332
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
3433
import Modes = require('vs/editor/common/modes');
3534
import URI from 'vs/base/common/uri';
@@ -58,16 +57,17 @@ export interface IExtensionApiFactory {
5857
export function createApiFactory(threadService: IThreadService, extensionService: ExtHostExtensionService, contextService: IWorkspaceContextService, telemetryService: ITelemetryService): IExtensionApiFactory {
5958

6059

60+
6161
// Addressable instances
6262
const col = new InstanceCollection();
63-
const extHostHeapMonitor = col.define(ExtHostContext.ExtHostHeapService).set<ExtHostHeapService>(new ExtHostHeapService());
63+
const extHostHeapService = col.define(ExtHostContext.ExtHostHeapService).set<ExtHostHeapService>(new ExtHostHeapService());
6464
const extHostDocuments = col.define(ExtHostContext.ExtHostDocuments).set<ExtHostDocuments>(new ExtHostDocuments(threadService));
6565
const extHostDocumentSaveParticipant = col.define(ExtHostContext.ExtHostDocumentSaveParticipant).set<ExtHostDocumentSaveParticipant>(new ExtHostDocumentSaveParticipant(extHostDocuments, threadService.get(MainContext.MainThreadWorkspace)));
6666
const extHostEditors = col.define(ExtHostContext.ExtHostEditors).set<ExtHostEditors>(new ExtHostEditors(threadService, extHostDocuments));
67-
const extHostCommands = col.define(ExtHostContext.ExtHostCommands).set<ExtHostCommands>(new ExtHostCommands(threadService, extHostEditors));
67+
const extHostCommands = col.define(ExtHostContext.ExtHostCommands).set<ExtHostCommands>(new ExtHostCommands(threadService, extHostEditors, extHostHeapService));
6868
const extHostConfiguration = col.define(ExtHostContext.ExtHostConfiguration).set<ExtHostConfiguration>(new ExtHostConfiguration(threadService.get(MainContext.MainThreadConfiguration)));
6969
const extHostDiagnostics = col.define(ExtHostContext.ExtHostDiagnostics).set<ExtHostDiagnostics>(new ExtHostDiagnostics(threadService));
70-
const languageFeatures = col.define(ExtHostContext.ExtHostLanguageFeatures).set<ExtHostLanguageFeatures>(new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostHeapMonitor, extHostDiagnostics));
70+
const languageFeatures = col.define(ExtHostContext.ExtHostLanguageFeatures).set<ExtHostLanguageFeatures>(new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics));
7171
const extHostFileSystemEvent = col.define(ExtHostContext.ExtHostFileSystemEventService).set<ExtHostFileSystemEventService>(new ExtHostFileSystemEventService());
7272
const extHostQuickOpen = col.define(ExtHostContext.ExtHostQuickOpen).set<ExtHostQuickOpen>(new ExtHostQuickOpen(threadService));
7373
const extHostTerminalService = col.define(ExtHostContext.ExtHostTerminalService).set<ExtHostTerminalService>(new ExtHostTerminalService(threadService));
@@ -88,10 +88,8 @@ export function createApiFactory(threadService: IThreadService, extensionService
8888
mainThreadErrors.onUnexpectedExtHostError(errors.transformErrorForSerialization(err));
8989
});
9090

91-
// the converter might create delegate commands to avoid sending args
92-
// around all the time
93-
ExtHostTypeConverters.Command.initialize(extHostCommands);
94-
registerApiCommands(extHostCommands);
91+
// Register API-ish commands
92+
ExtHostApiCommands.register(extHostCommands);
9593

9694
// TODO@joh,alex - this is lifecycle critical
9795
// fetch and store telemetry info

src/vs/workbench/api/node/extHost.contribution.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import { MainThreadTerminalService } from './mainThreadTerminalService';
3232
import { MainThreadWorkspace } from './mainThreadWorkspace';
3333
import { MainProcessExtensionService } from './mainThreadExtensionService';
3434
import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventService';
35-
import { MainThreadHeapService } from './mainThreadHeapService';
3635

3736
// --- other interested parties
3837
import { MainProcessTextMateSyntax } from 'vs/editor/node/textMate/TMSyntax';
@@ -41,6 +40,9 @@ import { JSONValidationExtensionPoint } from 'vs/platform/jsonschemas/common/jso
4140
import { LanguageConfigurationFileHandler } from 'vs/editor/node/languageConfiguration';
4241
import { SaveParticipant } from './mainThreadSaveParticipant';
4342

43+
// --- registers itself as service
44+
import './mainThreadHeapService';
45+
4446
export class ExtHostContribution implements IWorkbenchContribution {
4547

4648
constructor(
@@ -89,7 +91,6 @@ export class ExtHostContribution implements IWorkbenchContribution {
8991
create(JSONValidationExtensionPoint);
9092
create(LanguageConfigurationFileHandler);
9193
create(MainThreadFileSystemEventService);
92-
create(MainThreadHeapService);
9394
create(SaveParticipant);
9495
}
9596
}

src/vs/workbench/api/node/extHost.protocol.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,13 @@ export interface ObjectIdentifier {
276276
}
277277

278278
export namespace ObjectIdentifier {
279+
export const name = '$ident';
279280
export function mixin<T>(obj: T, id: number): T & ObjectIdentifier {
280-
Object.defineProperty(obj, '$ident', { value: id, enumerable: true });
281+
Object.defineProperty(obj, name, { value: id, enumerable: true });
281282
return <T & ObjectIdentifier>obj;
282283
}
283-
export function get(obj: any): number {
284-
return obj['$ident'];
284+
export function of(obj: any): number {
285+
return obj[name];
285286
}
286287
}
287288

src/vs/workbench/api/node/extHostApiCommands.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ import { IOutline } from 'vs/editor/contrib/quickOpen/common/quickOpen';
1818
import { IWorkspaceSymbolProvider, IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search';
1919
import { ICodeLensData } from 'vs/editor/contrib/codelens/common/codelens';
2020

21-
export function registerApiCommands(commands: ExtHostCommands) {
22-
new ExtHostApiCommands(commands).registerCommands();
23-
}
21+
export class ExtHostApiCommands {
2422

25-
class ExtHostApiCommands {
23+
static register(commands: ExtHostCommands) {
24+
return new ExtHostApiCommands(commands).registerCommands();
25+
}
2626

2727
private _commands: ExtHostCommands;
2828
private _disposables: IDisposable[] = [];
2929

30-
constructor(commands: ExtHostCommands) {
30+
private constructor(commands: ExtHostCommands) {
3131
this._commands = commands;
3232
}
3333

@@ -369,7 +369,7 @@ class ExtHostApiCommands {
369369
if (!Array.isArray(value)) {
370370
return;
371371
}
372-
return value.map(quickFix => typeConverters.Command.to(quickFix.command));
372+
return value.map(quickFix => this._commands.converter.fromInternal(quickFix.command));
373373
});
374374
}
375375

@@ -380,7 +380,7 @@ class ExtHostApiCommands {
380380
return value.map(item => {
381381
return new types.CodeLens(
382382
typeConverters.toRange(item.symbol.range),
383-
typeConverters.Command.to(item.symbol.command));
383+
this._commands.converter.fromInternal(item.symbol.command));
384384
});
385385
}
386386
});

src/vs/workbench/api/node/extHostCommands.ts

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import { ExtHostEditors } from 'vs/workbench/api/node/extHostEditors';
1212
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
1313
import * as extHostTypeConverter from 'vs/workbench/api/node/extHostTypeConverters';
1414
import { cloneAndChange } from 'vs/base/common/objects';
15-
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape } from './extHost.protocol';
15+
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier } from './extHost.protocol';
16+
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
17+
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
18+
import * as modes from 'vs/editor/common/modes';
19+
import * as vscode from 'vscode';
1620

1721
interface CommandHandler {
1822
callback: Function;
@@ -25,14 +29,21 @@ export class ExtHostCommands extends ExtHostCommandsShape {
2529
private _commands: { [n: string]: CommandHandler } = Object.create(null);
2630
private _proxy: MainThreadCommandsShape;
2731
private _extHostEditors: ExtHostEditors;
32+
private _converter: CommandsConverter;
2833

2934
constructor(
3035
threadService: IThreadService,
31-
extHostEditors: ExtHostEditors
36+
extHostEditors: ExtHostEditors,
37+
heapService: ExtHostHeapService
3238
) {
3339
super();
3440
this._extHostEditors = extHostEditors;
3541
this._proxy = threadService.get(MainContext.MainThreadCommands);
42+
this._converter = new CommandsConverter(this, heapService);
43+
}
44+
45+
get converter(): CommandsConverter {
46+
return this._converter;
3647
}
3748

3849
registerCommand(id: string, callback: <T>(...args: any[]) => T | Thenable<T>, thisArg?: any, description?: ICommandHandlerDescription): extHostTypes.Disposable {
@@ -137,3 +148,68 @@ export class ExtHostCommands extends ExtHostCommandsShape {
137148
return TPromise.as(result);
138149
}
139150
}
151+
152+
153+
export class CommandsConverter {
154+
155+
private _commands: ExtHostCommands;
156+
private _heap: ExtHostHeapService;
157+
158+
// --- conversion between internal and api commands
159+
constructor(commands: ExtHostCommands, heap: ExtHostHeapService) {
160+
161+
this._commands = commands;
162+
this._heap = heap;
163+
this._commands.registerCommand('_internal_command_delegation', this._executeConvertedCommand, this);
164+
}
165+
166+
toInternal(command: vscode.Command): modes.Command {
167+
168+
if (!command) {
169+
return;
170+
}
171+
172+
const result: modes.Command = {
173+
id: command.command,
174+
title: command.title
175+
};
176+
177+
if (!isFalsyOrEmpty(command.arguments)) {
178+
// we have a contributed command with arguments. that
179+
// means we don't want to send the arguments around
180+
181+
const id = this._heap.keep(command);
182+
ObjectIdentifier.mixin(result, id);
183+
184+
result.id = '_internal_command_delegation';
185+
result.arguments = [id];
186+
}
187+
188+
return result;
189+
}
190+
191+
fromInternal(command: modes.Command): vscode.Command {
192+
193+
if (!command) {
194+
return;
195+
}
196+
197+
const id = ObjectIdentifier.of(command);
198+
if (typeof id === 'number') {
199+
return this._heap.get<vscode.Command>(id);
200+
201+
} else {
202+
return {
203+
command: command.id,
204+
title: command.title,
205+
arguments: command.arguments
206+
};
207+
}
208+
}
209+
210+
private _executeConvertedCommand([id]: number[]) {
211+
const actualCmd = this._heap.get<vscode.Command>(id);
212+
return this._commands.executeCommand(actualCmd.command, ...actualCmd.arguments);
213+
}
214+
215+
}

src/vs/workbench/api/node/extHostHeapService.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,14 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape {
1111
private static _idPool = 0;
1212

1313
private _data: { [n: number]: any } = Object.create(null);
14-
private _callbacks: { [n: number]: Function } = Object.create(null);
1514

16-
keep(obj: any, callback?: () => any): number {
15+
keep(obj: any): number {
1716
const id = ExtHostHeapService._idPool++;
1817
this._data[id] = obj;
19-
if (typeof callback === 'function') {
20-
this._callbacks[id] = callback;
21-
}
2218
return id;
2319
}
2420

2521
delete(id: number): boolean {
26-
delete this._callbacks[id];
2722
return this._data[id];
2823
}
2924

@@ -33,7 +28,6 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape {
3328

3429
$onGarbageCollection(ids: number[]): void {
3530
for (const id of ids) {
36-
setTimeout(this._callbacks[id]);
3731
this.delete(id);
3832
}
3933
}

0 commit comments

Comments
 (0)