Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -22,7 +22,8 @@ import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/modes/linkCo
import { BasicInplaceReplace } from 'vs/editor/common/modes/supports/inplaceReplaceSupport';
import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService';
import { createMonacoBaseAPI } from 'vs/editor/common/standalone/standaloneBase';
import { getAllPropertyNames } from 'vs/base/common/types';
import * as types from 'vs/base/common/types';
import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl';
export interface IMirrorModel {
readonly uri: URI;
@@ -30,7 +31,11 @@ export interface IMirrorModel {
getValue(): string;
}
export interface IWorkerContext {
export interface IWorkerContext<H = undefined> {
/**
* A proxy to the main thread host object.
*/
host: H;
/**
* Get all available mirror models in this worker.
*/
@@ -322,17 +327,53 @@ declare var require: any;
/**
* @internal
*/
export abstract class BaseEditorSimpleWorker {
export class EditorSimpleWorker implements IRequestHandler, IDisposable {
_requestHandlerBrand: any;
private readonly _host: EditorWorkerHost;
private _models: { [uri: string]: MirrorModel; };
private readonly _foreignModuleFactory: IForeignModuleFactory | null;
private _foreignModule: any;
constructor(foreignModuleFactory: IForeignModuleFactory | null) {
constructor(host: EditorWorkerHost, foreignModuleFactory: IForeignModuleFactory | null) {
this._host = host;
this._models = Object.create(null);
this._foreignModuleFactory = foreignModuleFactory;
this._foreignModule = null;
}
protected abstract _getModel(uri: string): ICommonModel;
protected abstract _getModels(): ICommonModel[];
public dispose(): void {
this._models = Object.create(null);
}
protected _getModel(uri: string): ICommonModel {
return this._models[uri];
}
private _getModels(): ICommonModel[] {
let all: MirrorModel[] = [];
Object.keys(this._models).forEach((key) => all.push(this._models[key]));
return all;
}
public acceptNewModel(data: IRawModelData): void {
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId);
}
public acceptModelChanged(strURL: string, e: IModelChangedEvent): void {
if (!this._models[strURL]) {
return;
}
let model = this._models[strURL];
model.onEvents(e);
}
public acceptRemovedModel(strURL: string): void {
if (!this._models[strURL]) {
return;
}
delete this._models[strURL];
}
// ---- BEGIN diff --------------------------------------------------------------------------
@@ -440,7 +481,7 @@ export abstract class BaseEditorSimpleWorker {
}
// make sure diff won't take too long
if (Math.max(text.length, original.length) > BaseEditorSimpleWorker._diffLimit) {
if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) {
result.push({ range, text });
continue;
}
@@ -503,7 +544,7 @@ export abstract class BaseEditorSimpleWorker {
for (
let iter = model.createWordIterator(wordDefRegExp), e = iter.next();
!e.done && suggestions.length <= BaseEditorSimpleWorker._suggestionsLimit;
!e.done && suggestions.length <= EditorSimpleWorker._suggestionsLimit;
e = iter.next()
) {
const word = e.value;
@@ -591,8 +632,15 @@ export abstract class BaseEditorSimpleWorker {
// ---- BEGIN foreign module support --------------------------------------------------------------------------
public loadForeignModule(moduleId: string, createData: any): Promise<string[]> {
let ctx: IWorkerContext = {
public loadForeignModule(moduleId: string, createData: any, foreignHostMethods: string[]): Promise<string[]> {
const proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
return this._host.fhr(method, args);
};
const foreignHost = types.createProxyObject(foreignHostMethods, proxyMethodRequest);
let ctx: IWorkerContext<any> = {
host: foreignHost,
getMirrorModels: (): IMirrorModel[] => {
return this._getModels();
}
@@ -601,27 +649,14 @@ export abstract class BaseEditorSimpleWorker {
if (this._foreignModuleFactory) {
this._foreignModule = this._foreignModuleFactory(ctx, createData);
// static foreing module
let methods: string[] = [];
for (const prop of getAllPropertyNames(this._foreignModule)) {
if (typeof this._foreignModule[prop] === 'function') {
methods.push(prop);
}
}
return Promise.resolve(methods);
return Promise.resolve(types.getAllMethodNames(this._foreignModule));
}
// ESM-comment-begin
return new Promise<any>((resolve, reject) => {
require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => {
this._foreignModule = foreignModule.create(ctx, createData);
let methods: string[] = [];
for (const prop of getAllPropertyNames(this._foreignModule)) {
if (typeof this._foreignModule[prop] === 'function') {
methods.push(prop);
}
}
resolve(methods);
resolve(types.getAllMethodNames(this._foreignModule));
}, reject);
});
@@ -648,59 +683,12 @@ export abstract class BaseEditorSimpleWorker {
// ---- END foreign module support --------------------------------------------------------------------------
}
/**
* @internal
*/
export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IRequestHandler, IDisposable {
_requestHandlerBrand: any;
private _models: { [uri: string]: MirrorModel; };
constructor(foreignModuleFactory: IForeignModuleFactory | null) {
super(foreignModuleFactory);
this._models = Object.create(null);
}
public dispose(): void {
this._models = Object.create(null);
}
protected _getModel(uri: string): ICommonModel {
return this._models[uri];
}
protected _getModels(): ICommonModel[] {
let all: MirrorModel[] = [];
Object.keys(this._models).forEach((key) => all.push(this._models[key]));
return all;
}
public acceptNewModel(data: IRawModelData): void {
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId);
}
public acceptModelChanged(strURL: string, e: IModelChangedEvent): void {
if (!this._models[strURL]) {
return;
}
let model = this._models[strURL];
model.onEvents(e);
}
public acceptRemovedModel(strURL: string): void {
if (!this._models[strURL]) {
return;
}
delete this._models[strURL];
}
}
/**
* Called on the worker side
* @internal
*/
export function create(): IRequestHandler {
return new EditorSimpleWorkerImpl(null);
export function create(host: EditorWorkerHost): IRequestHandler {
return new EditorSimpleWorker(host, null);
}
// This is only available in a Web Worker

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { IntervalTimer } from 'vs/base/common/async';
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { SimpleWorkerClient, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker';
import { SimpleWorkerClient, logOnceWebWorkerWarning, IWorkerClient } from 'vs/base/common/worker/simpleWorker';
import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
@@ -15,7 +15,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { ITextModel } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWorker';
import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
@@ -133,6 +133,8 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider {
private readonly _configurationService: ITextResourceConfigurationService;
private readonly _modelService: IModelService;
readonly _debugDisplayName = 'wordbasedCompletions';
constructor(
workerManager: WorkerManager,
configurationService: ITextResourceConfigurationService,
@@ -222,12 +224,12 @@ class WorkerManager extends Disposable {
class EditorModelManager extends Disposable {
private readonly _proxy: EditorSimpleWorkerImpl;
private readonly _proxy: EditorSimpleWorker;
private readonly _modelService: IModelService;
private _syncedModels: { [modelUrl: string]: IDisposable[]; } = Object.create(null);
private _syncedModels: { [modelUrl: string]: IDisposable; } = Object.create(null);
private _syncedModelsLastUsedTime: { [modelUrl: string]: number; } = Object.create(null);
constructor(proxy: EditorSimpleWorkerImpl, modelService: IModelService, keepIdleModels: boolean) {
constructor(proxy: EditorSimpleWorker, modelService: IModelService, keepIdleModels: boolean) {
super();
this._proxy = proxy;
this._modelService = modelService;
@@ -295,14 +297,14 @@ class EditorModelManager extends Disposable {
versionId: model.getVersionId()
});
let toDispose: IDisposable[] = [];
toDispose.push(model.onDidChangeContent((e) => {
const toDispose = new DisposableStore();
toDispose.add(model.onDidChangeContent((e) => {
this._proxy.acceptModelChanged(modelUrl.toString(), e);
}));
toDispose.push(model.onWillDispose(() => {
toDispose.add(model.onWillDispose(() => {
this._stopModelSync(modelUrl);
}));
toDispose.push(toDisposable(() => {
toDispose.add(toDisposable(() => {
this._proxy.acceptRemovedModel(modelUrl);
}));
@@ -317,11 +319,6 @@ class EditorModelManager extends Disposable {
}
}
interface IWorkerClient<T> {
getProxyObject(): Promise<T>;
dispose(): void;
}
class SynchronousWorkerClient<T extends IDisposable> implements IWorkerClient<T> {
private readonly _instance: T;
private readonly _proxyObj: Promise<T>;
@@ -340,10 +337,24 @@ class SynchronousWorkerClient<T extends IDisposable> implements IWorkerClient<T>
}
}
export class EditorWorkerHost {
private readonly _workerClient: EditorWorkerClient;
constructor(workerClient: EditorWorkerClient) {
this._workerClient = workerClient;
}
// foreign host request
public fhr(method: string, args: any[]): Promise<any> {
return this._workerClient.fhr(method, args);
}
}
export class EditorWorkerClient extends Disposable {
private readonly _modelService: IModelService;
private _worker: IWorkerClient<EditorSimpleWorkerImpl> | null;
private _worker: IWorkerClient<EditorSimpleWorker> | null;
private readonly _workerFactory: DefaultWorkerFactory;
private _modelManager: EditorModelManager | null;
@@ -355,37 +366,43 @@ export class EditorWorkerClient extends Disposable {
this._modelManager = null;
}
private _getOrCreateWorker(): IWorkerClient<EditorSimpleWorkerImpl> {
// foreign host request
public fhr(method: string, args: any[]): Promise<any> {
throw new Error(`Not implemented!`);
}
private _getOrCreateWorker(): IWorkerClient<EditorSimpleWorker> {
if (!this._worker) {
try {
this._worker = this._register(new SimpleWorkerClient<EditorSimpleWorkerImpl>(
this._worker = this._register(new SimpleWorkerClient<EditorSimpleWorker, EditorWorkerHost>(
this._workerFactory,
'vs/editor/common/services/editorSimpleWorker'
'vs/editor/common/services/editorSimpleWorker',
new EditorWorkerHost(this)
));
} catch (err) {
logOnceWebWorkerWarning(err);
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null));
this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));
}
}
return this._worker;
}
protected _getProxy(): Promise<EditorSimpleWorkerImpl> {
protected _getProxy(): Promise<EditorSimpleWorker> {
return this._getOrCreateWorker().getProxyObject().then(undefined, (err) => {
logOnceWebWorkerWarning(err);
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null));
this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));
return this._getOrCreateWorker().getProxyObject();
});
}
private _getOrCreateModelManager(proxy: EditorSimpleWorkerImpl): EditorModelManager {
private _getOrCreateModelManager(proxy: EditorSimpleWorker): EditorModelManager {
if (!this._modelManager) {
this._modelManager = this._register(new EditorModelManager(proxy, this._modelService, false));
}
return this._modelManager;
}
protected _withSyncedResources(resources: URI[]): Promise<EditorSimpleWorkerImpl> {
protected _withSyncedResources(resources: URI[]): Promise<EditorSimpleWorker> {
return this._getProxy().then((proxy) => {
this._getOrCreateModelManager(proxy).ensureSyncedResources(resources);
return proxy;

View File

@@ -85,19 +85,7 @@ export function detectModeId(modelService: IModelService, modeService: IModeServ
}
// otherwise fallback to path based detection
let path: string | undefined;
if (resource.scheme === Schemas.data) {
const metadata = DataUri.parseMetaData(resource);
path = metadata.get(DataUri.META_DATA_LABEL);
} else {
path = resource.path.toLowerCase();
}
if (path) {
return modeService.getModeIdByFilepathOrFirstLine(path);
}
return null; // finally - we do not know the mode id
return modeService.getModeIdByFilepathOrFirstLine(resource);
}
export function cssEscape(val: string): string {

View File

@@ -323,11 +323,11 @@ export class LanguagesRegistry extends Disposable {
return [];
}
public getModeIdsFromFilepathOrFirstLine(filepath: string | null, firstLine?: string): string[] {
if (!filepath && !firstLine) {
public getModeIdsFromFilepathOrFirstLine(resource: URI | null, firstLine?: string): string[] {
if (!resource && !firstLine) {
return [];
}
let mimeTypes = mime.guessMimeTypes(filepath, firstLine);
let mimeTypes = mime.guessMimeTypes(resource, firstLine);
return this.extractModeIds(mimeTypes.join(','));
}

View File

@@ -63,10 +63,10 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
_serviceBrand: any;
private readonly _onDidChangeMarker = new Emitter<ITextModel>();
private readonly _onDidChangeMarker = this._register(new Emitter<ITextModel>());
readonly onDidChangeMarker: Event<ITextModel> = this._onDidChangeMarker.event;
private readonly _markerDecorations: Map<string, MarkerDecorations> = new Map<string, MarkerDecorations>();
private readonly _markerDecorations = new Map<string, MarkerDecorations>();
constructor(
@IModelService modelService: IModelService,
@@ -79,6 +79,12 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
this._register(this._markerService.onMarkerChanged(this._handleMarkerChange, this));
}
dispose() {
super.dispose();
this._markerDecorations.forEach(value => value.dispose());
this._markerDecorations.clear();
}
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null {
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
return markerDecorations ? withUndefinedAsNull(markerDecorations.getMarker(decoration)) : null;

View File

@@ -41,7 +41,7 @@ export interface IModeService {
getMimeForMode(modeId: string): string | null;
getLanguageName(modeId: string): string | null;
getModeIdForLanguageName(alias: string): string | null;
getModeIdByFilepathOrFirstLine(filepath: string, firstLine?: string): string | null;
getModeIdByFilepathOrFirstLine(resource: URI, firstLine?: string): string | null;
getModeId(commaSeparatedMimetypesOrCommaSeparatedIds: string): string | null;
getLanguageIdentifier(modeId: string | LanguageId): LanguageIdentifier | null;
getConfigurationFiles(modeId: string): URI[];
@@ -49,7 +49,7 @@ export interface IModeService {
// --- instantiation
create(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): ILanguageSelection;
createByLanguageName(languageName: string): ILanguageSelection;
createByFilepathOrFirstLine(filepath: string | null, firstLine?: string): ILanguageSelection;
createByFilepathOrFirstLine(rsource: URI | null, firstLine?: string): ILanguageSelection;
triggerMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): void;
}

View File

@@ -94,8 +94,8 @@ export class ModeServiceImpl implements IModeService {
return this._registry.getModeIdForLanguageNameLowercase(alias);
}
public getModeIdByFilepathOrFirstLine(filepath: string | null, firstLine?: string): string | null {
const modeIds = this._registry.getModeIdsFromFilepathOrFirstLine(filepath, firstLine);
public getModeIdByFilepathOrFirstLine(resource: URI | null, firstLine?: string): string | null {
const modeIds = this._registry.getModeIdsFromFilepathOrFirstLine(resource, firstLine);
if (modeIds.length > 0) {
return modeIds[0];
@@ -138,9 +138,9 @@ export class ModeServiceImpl implements IModeService {
});
}
public createByFilepathOrFirstLine(filepath: string | null, firstLine?: string): ILanguageSelection {
public createByFilepathOrFirstLine(resource: URI | null, firstLine?: string): ILanguageSelection {
return new LanguageSelection(this.onLanguagesMaybeChanged, () => {
const modeId = this.getModeIdByFilepathOrFirstLine(filepath, firstLine);
const modeId = this.getModeIdByFilepathOrFirstLine(resource, firstLine);
return this._createModeAndGetLanguageIdentifier(modeId);
});
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions';
@@ -30,7 +30,7 @@ class ModelData implements IDisposable {
private _languageSelection: ILanguageSelection | null;
private _languageSelectionListener: IDisposable | null;
private _modelEventListeners: IDisposable[];
private readonly _modelEventListeners = new DisposableStore();
constructor(
model: ITextModel,
@@ -42,9 +42,8 @@ class ModelData implements IDisposable {
this._languageSelection = null;
this._languageSelectionListener = null;
this._modelEventListeners = [];
this._modelEventListeners.push(model.onWillDispose(() => onWillDispose(model)));
this._modelEventListeners.push(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e)));
this._modelEventListeners.add(model.onWillDispose(() => onWillDispose(model)));
this._modelEventListeners.add(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e)));
}
private _disposeLanguageSelection(): void {
@@ -59,7 +58,7 @@ class ModelData implements IDisposable {
}
public dispose(): void {
this._modelEventListeners = dispose(this._modelEventListeners);
this._modelEventListeners.dispose();
this._disposeLanguageSelection();
}

View File

@@ -25,7 +25,7 @@ export interface ITextResourceConfigurationService {
* Value can be of native type or an object keyed off the section name.
*
* @param resource - Resource for which the configuration has to be fetched.
* @param postion - Position in the resource for which configuration has to be fetched.
* @param position - Position in the resource for which configuration has to be fetched.
* @param section - Section of the configuraion.
*
*/

View File

@@ -50,7 +50,7 @@ export class TextResourceConfigurationService extends Disposable implements ITex
if (model) {
return position ? this.modeService.getLanguageIdentifier(model.getLanguageIdAtPosition(position.lineNumber, position.column))!.language : model.getLanguageIdentifier().language;
}
return this.modeService.getModeIdByFilepathOrFirstLine(resource.path);
return this.modeService.getModeIdByFilepathOrFirstLine(resource);
}
}

View File

@@ -6,6 +6,7 @@
import { URI } from 'vs/base/common/uri';
import { EditorWorkerClient } from 'vs/editor/common/services/editorWorkerServiceImpl';
import { IModelService } from 'vs/editor/common/services/modelService';
import * as types from 'vs/base/common/types';
/**
* Create a new web worker that has model syncing capabilities built in.
@@ -48,11 +49,16 @@ export interface IWebWorkerOptions {
* A label to be used to identify the web worker for debugging purposes.
*/
label?: string;
/**
* An object that can be used by the web worker to make calls back to the main thread.
*/
host?: any;
}
class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWorker<T> {
private readonly _foreignModuleId: string;
private readonly _foreignModuleHost: { [method: string]: Function } | null;
private _foreignModuleCreateData: any | null;
private _foreignProxy: Promise<T> | null;
@@ -60,13 +66,28 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
super(modelService, opts.label);
this._foreignModuleId = opts.moduleId;
this._foreignModuleCreateData = opts.createData || null;
this._foreignModuleHost = opts.host || null;
this._foreignProxy = null;
}
// foreign host request
public fhr(method: string, args: any[]): Promise<any> {
if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') {
return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.'));
}
try {
return Promise.resolve(this._foreignModuleHost[method].apply(this._foreignModuleHost, args));
} catch (e) {
return Promise.reject(e);
}
}
private _getForeignProxy(): Promise<T> {
if (!this._foreignProxy) {
this._foreignProxy = this._getProxy().then((proxy) => {
return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData).then((foreignMethods) => {
const foreignHostMethods = this._foreignModuleHost ? types.getAllMethodNames(this._foreignModuleHost) : [];
return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData, foreignHostMethods).then((foreignMethods) => {
this._foreignModuleCreateData = null;
const proxyMethodRequest = (method: string, args: any[]): Promise<any> => {