Merge VS Code 1.21 source code (#1067)

* Initial VS Code 1.21 file copy with patches

* A few more merges

* Post npm install

* Fix batch of build breaks

* Fix more build breaks

* Fix more build errors

* Fix more build breaks

* Runtime fixes 1

* Get connection dialog working with some todos

* Fix a few packaging issues

* Copy several node_modules to package build to fix loader issues

* Fix breaks from master

* A few more fixes

* Make tests pass

* First pass of license header updates

* Second pass of license header updates

* Fix restore dialog issues

* Remove add additional themes menu items

* fix select box issues where the list doesn't show up

* formatting

* Fix editor dispose issue

* Copy over node modules to correct location on all platforms
This commit is contained in:
Karl Burtram
2018-04-04 15:27:51 -07:00
committed by GitHub
parent 5fba3e31b4
commit dafb780987
9412 changed files with 141255 additions and 98813 deletions

View File

@@ -5,39 +5,42 @@
'use strict';
import Event from 'vs/base/common/event';
import URI from 'vs/base/common/uri';
import URI, { UriComponents } from 'vs/base/common/uri';
import { sequence, always } from 'vs/base/common/async';
import { illegalState } from 'vs/base/common/errors';
import { TPromise } from 'vs/base/common/winjs.base';
import { ExtHostDocumentSaveParticipantShape, MainThreadEditorsShape, IWorkspaceResourceEdit } from 'vs/workbench/api/node/extHost.protocol';
import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, ResourceTextEditDto } from 'vs/workbench/api/node/extHost.protocol';
import { TextEdit } from 'vs/workbench/api/node/extHostTypes';
import { fromRange, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/node/extHostTypeConverters';
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import * as vscode from 'vscode';
import { LinkedList } from 'vs/base/common/linkedList';
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
type Listener = [Function, any, IExtensionDescription];
export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSaveParticipantShape {
private _documents: ExtHostDocuments;
private _mainThreadEditors: MainThreadEditorsShape;
private _callbacks = new LinkedList<[Function, any]>();
private _badListeners = new WeakMap<Function, number>();
private _thresholds: { timeout: number; errors: number; };
private readonly _callbacks = new LinkedList<Listener>();
private readonly _badListeners = new WeakMap<Function, number>();
constructor(documents: ExtHostDocuments, mainThreadEditors: MainThreadEditorsShape, thresholds: { timeout: number; errors: number; } = { timeout: 1500, errors: 3 }) {
this._documents = documents;
this._mainThreadEditors = mainThreadEditors;
this._thresholds = thresholds;
constructor(
private readonly _logService: ILogService,
private readonly _documents: ExtHostDocuments,
private readonly _mainThreadEditors: MainThreadTextEditorsShape,
private readonly _thresholds: { timeout: number; errors: number; } = { timeout: 1500, errors: 3 }
) {
//
}
dispose(): void {
this._callbacks.clear();
}
get onWillSaveTextDocumentEvent(): Event<vscode.TextDocumentWillSaveEvent> {
getOnWillSaveTextDocumentEvent(extension: IExtensionDescription): Event<vscode.TextDocumentWillSaveEvent> {
return (listener, thisArg, disposables) => {
const remove = this._callbacks.push([listener, thisArg]);
const remove = this._callbacks.push([listener, thisArg, extension]);
const result = { dispose: remove };
if (Array.isArray(disposables)) {
disposables.push(result);
@@ -46,13 +49,14 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
};
}
$participateInSave(resource: URI, reason: SaveReason): TPromise<boolean[]> {
$participateInSave(data: UriComponents, reason: SaveReason): Thenable<boolean[]> {
const resource = URI.revive(data);
const entries = this._callbacks.toArray();
let didTimeout = false;
let didTimeoutHandle = setTimeout(() => didTimeout = true, this._thresholds.timeout);
const promise = sequence(entries.map(([fn, thisArg]) => {
const promise = sequence(entries.map(listener => {
return () => {
if (didTimeout) {
@@ -61,18 +65,17 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
}
const document = this._documents.getDocumentData(resource).document;
return this._deliverEventAsyncAndBlameBadListeners(fn, thisArg, <any>{ document, reason: TextDocumentSaveReason.to(reason) });
return this._deliverEventAsyncAndBlameBadListeners(listener, <any>{ document, reason: TextDocumentSaveReason.to(reason) });
};
}));
return always(promise, () => clearTimeout(didTimeoutHandle));
}
private _deliverEventAsyncAndBlameBadListeners(listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): TPromise<any> {
private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
const errors = this._badListeners.get(listener);
if (errors > this._thresholds.errors) {
// bad listener - ignore
return TPromise.wrap(false);
return Promise.resolve(false);
}
return this._deliverEventAsync(listener, thisArg, stubEvent).then(() => {
@@ -80,6 +83,10 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
return true;
}, err => {
this._logService.error('[onWillSaveTextDocument]', extension.id);
this._logService.error(err);
if (!(err instanceof Error) || (<Error>err).message !== 'concurrent_edits') {
const errors = this._badListeners.get(listener);
this._badListeners.set(listener, !errors ? 1 : errors + 1);
@@ -93,9 +100,9 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
});
}
private _deliverEventAsync(listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): TPromise<any> {
private _deliverEventAsync(listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
const promises: TPromise<vscode.TextEdit[]>[] = [];
const promises: Promise<vscode.TextEdit[]>[] = [];
const { document, reason } = stubEvent;
const { version } = document;
@@ -107,7 +114,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
if (Object.isFrozen(promises)) {
throw illegalState('waitUntil can not be called async');
}
promises.push(TPromise.wrap(p));
promises.push(Promise.resolve(p));
}
});
@@ -115,20 +122,27 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
// fire event
listener.apply(thisArg, [event]);
} catch (err) {
return TPromise.wrapError(err);
return Promise.reject(err);
}
// freeze promises after event call
Object.freeze(promises);
return new TPromise<vscode.TextEdit[][]>((resolve, reject) => {
return new Promise<vscode.TextEdit[][]>((resolve, reject) => {
// join on all listener promises, reject after timeout
const handle = setTimeout(() => reject(new Error('timeout')), this._thresholds.timeout);
return always(TPromise.join(promises), () => clearTimeout(handle)).then(resolve, reject);
return Promise.all(promises).then(edits => {
clearTimeout(handle);
resolve(edits);
}).catch(err => {
clearTimeout(handle);
reject(err);
});
}).then(values => {
let workspaceResourceEdit: IWorkspaceResourceEdit = {
const resourceEdit: ResourceTextEditDto = {
resource: document.uri,
edits: []
};
@@ -136,10 +150,10 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
for (const value of values) {
if (Array.isArray(value) && (<vscode.TextEdit[]>value).every(e => e instanceof TextEdit)) {
for (const { newText, newEol, range } of value) {
workspaceResourceEdit.edits.push({
resourceEdit.edits.push({
range: range && fromRange(range),
newText,
newEol: EndOfLine.from(newEol)
text: newText,
eol: EndOfLine.from(newEol)
});
}
}
@@ -147,16 +161,16 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
// apply edits if any and if document
// didn't change somehow in the meantime
if (workspaceResourceEdit.edits.length === 0) {
return undefined;
if (resourceEdit.edits.length === 0) {
return <any>undefined;
}
if (version === document.version) {
return this._mainThreadEditors.$tryApplyWorkspaceEdit([workspaceResourceEdit]);
return <any>this._mainThreadEditors.$tryApplyWorkspaceEdit({ edits: [resourceEdit] });
}
// TODO@joh bubble this to listener?
return TPromise.wrapError(new Error('concurrent_edits'));
return Promise.reject(new Error('concurrent_edits'));
});
}
}