Initial VS Code 1.19 source merge (#571)

* Initial 1.19 xcopy

* Fix yarn build

* Fix numerous build breaks

* Next batch of build break fixes

* More build break fixes

* Runtime breaks

* Additional post merge fixes

* Fix windows setup file

* Fix test failures.

* Update license header blocks to refer to source eula
This commit is contained in:
Karl Burtram
2018-01-28 23:37:17 -08:00
committed by GitHub
parent 9a1ac20710
commit 251ae01c3e
8009 changed files with 93378 additions and 35634 deletions

View File

@@ -1,158 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import Event, { Emitter } from 'vs/base/common/event';
import { ICommonCodeEditor, ICommonDiffEditor, IDecorationRenderOptions, IModelDecorationOptions, IModel } from 'vs/editor/common/editorCommon';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
export abstract class AbstractCodeEditorService implements ICodeEditorService {
_serviceBrand: any;
private _onCodeEditorAdd: Emitter<ICommonCodeEditor>;
private _onCodeEditorRemove: Emitter<ICommonCodeEditor>;
private _codeEditors: { [editorId: string]: ICommonCodeEditor; };
private _onDiffEditorAdd: Emitter<ICommonDiffEditor>;
private _onDiffEditorRemove: Emitter<ICommonDiffEditor>;
private _diffEditors: { [editorId: string]: ICommonDiffEditor; };
constructor() {
this._codeEditors = Object.create(null);
this._diffEditors = Object.create(null);
this._onCodeEditorAdd = new Emitter<ICommonCodeEditor>();
this._onCodeEditorRemove = new Emitter<ICommonCodeEditor>();
this._onDiffEditorAdd = new Emitter<ICommonDiffEditor>();
this._onDiffEditorRemove = new Emitter<ICommonDiffEditor>();
}
addCodeEditor(editor: ICommonCodeEditor): void {
this._codeEditors[editor.getId()] = editor;
this._onCodeEditorAdd.fire(editor);
}
get onCodeEditorAdd(): Event<ICommonCodeEditor> {
return this._onCodeEditorAdd.event;
}
removeCodeEditor(editor: ICommonCodeEditor): void {
if (delete this._codeEditors[editor.getId()]) {
this._onCodeEditorRemove.fire(editor);
}
}
get onCodeEditorRemove(): Event<ICommonCodeEditor> {
return this._onCodeEditorRemove.event;
}
getCodeEditor(editorId: string): ICommonCodeEditor {
return this._codeEditors[editorId] || null;
}
listCodeEditors(): ICommonCodeEditor[] {
return Object.keys(this._codeEditors).map(id => this._codeEditors[id]);
}
addDiffEditor(editor: ICommonDiffEditor): void {
this._diffEditors[editor.getId()] = editor;
this._onDiffEditorAdd.fire(editor);
}
get onDiffEditorAdd(): Event<ICommonDiffEditor> {
return this._onDiffEditorAdd.event;
}
removeDiffEditor(editor: ICommonDiffEditor): void {
if (delete this._diffEditors[editor.getId()]) {
this._onDiffEditorRemove.fire(editor);
}
}
get onDiffEditorRemove(): Event<ICommonDiffEditor> {
return this._onDiffEditorRemove.event;
}
getDiffEditor(editorId: string): ICommonDiffEditor {
return this._diffEditors[editorId] || null;
}
listDiffEditors(): ICommonDiffEditor[] {
return Object.keys(this._diffEditors).map(id => this._diffEditors[id]);
}
getFocusedCodeEditor(): ICommonCodeEditor {
let editorWithWidgetFocus: ICommonCodeEditor = null;
let editors = this.listCodeEditors();
for (let i = 0; i < editors.length; i++) {
let editor = editors[i];
if (editor.isFocused()) {
// bingo!
return editor;
}
if (editor.hasWidgetFocus()) {
editorWithWidgetFocus = editor;
}
}
return editorWithWidgetFocus;
}
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
abstract removeDecorationType(key: string): void;
abstract resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions;
private _transientWatchers: { [uri: string]: ModelTransientSettingWatcher; } = {};
public setTransientModelProperty(model: IModel, key: string, value: any): void {
const uri = model.uri.toString();
let w: ModelTransientSettingWatcher;
if (this._transientWatchers.hasOwnProperty(uri)) {
w = this._transientWatchers[uri];
} else {
w = new ModelTransientSettingWatcher(uri, model, this);
this._transientWatchers[uri] = w;
}
w.set(key, value);
}
public getTransientModelProperty(model: IModel, key: string): any {
const uri = model.uri.toString();
if (!this._transientWatchers.hasOwnProperty(uri)) {
return undefined;
}
return this._transientWatchers[uri].get(key);
}
_removeWatcher(w: ModelTransientSettingWatcher): void {
delete this._transientWatchers[w.uri];
}
}
export class ModelTransientSettingWatcher {
public readonly uri: string;
private readonly _values: { [key: string]: any; };
constructor(uri: string, model: IModel, owner: AbstractCodeEditorService) {
this.uri = uri;
this._values = {};
model.onWillDispose(() => owner._removeWatcher(this));
}
public set(key: string, value: any): void {
this._values[key] = value;
}
public get(key: string): any {
return this._values[key];
}
}

View File

@@ -1,391 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nls from 'vs/nls';
import { flatten } from 'vs/base/common/arrays';
import { IStringDictionary, forEach, values, groupBy, size } from 'vs/base/common/collections';
import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
import { IFileService, IFileChange } from 'vs/platform/files/common/files';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { Range, IRange } from 'vs/editor/common/core/range';
import { Selection, ISelection } from 'vs/editor/common/core/selection';
import { IIdentifiedSingleEditOperation, IModel, EndOfLineSequence, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
export interface IResourceEdit {
resource: URI;
range?: IRange;
newText: string;
newEol?: EndOfLineSequence;
}
interface IRecording {
stop(): void;
hasChanged(resource: URI): boolean;
allChanges(): IFileChange[];
}
class ChangeRecorder {
private _fileService: IFileService;
constructor(fileService?: IFileService) {
this._fileService = fileService;
}
public start(): IRecording {
const changes: IStringDictionary<IFileChange[]> = Object.create(null);
let stop: IDisposable;
if (this._fileService) {
stop = this._fileService.onFileChanges((event) => {
event.changes.forEach(change => {
const key = String(change.resource);
let array = changes[key];
if (!array) {
changes[key] = array = [];
}
array.push(change);
});
});
}
return {
stop: () => { return stop && stop.dispose(); },
hasChanged: (resource: URI) => !!changes[resource.toString()],
allChanges: () => flatten(values(changes))
};
}
}
class EditTask implements IDisposable {
private _initialSelections: Selection[];
private _endCursorSelection: Selection;
private get _model(): IModel { return this._modelReference.object.textEditorModel; }
private _modelReference: IReference<ITextEditorModel>;
private _edits: IIdentifiedSingleEditOperation[];
private _newEol: EndOfLineSequence;
constructor(modelReference: IReference<ITextEditorModel>) {
this._endCursorSelection = null;
this._modelReference = modelReference;
this._edits = [];
}
public addEdit(edit: IResourceEdit): void {
if (typeof edit.newEol === 'number') {
// honor eol-change
this._newEol = edit.newEol;
}
if (edit.range || edit.newText) {
// create edit operation
let range: Range;
if (!edit.range) {
range = this._model.getFullModelRange();
} else {
range = Range.lift(edit.range);
}
this._edits.push(EditOperation.replaceMove(range, edit.newText));
}
}
public apply(): void {
if (this._edits.length > 0) {
this._edits = this._edits.map((value, index) => ({ value, index })).sort((a, b) => {
let ret = Range.compareRangesUsingStarts(a.value.range, b.value.range);
if (ret === 0) {
ret = a.index - b.index;
}
return ret;
}).map(element => element.value);
this._initialSelections = this._getInitialSelections();
this._model.pushStackElement();
this._model.pushEditOperations(this._initialSelections, this._edits, (edits) => this._getEndCursorSelections(edits));
this._model.pushStackElement();
}
if (this._newEol !== undefined) {
this._model.pushStackElement();
this._model.setEOL(this._newEol);
this._model.pushStackElement();
}
}
protected _getInitialSelections(): Selection[] {
const firstRange = this._edits[0].range;
const initialSelection = new Selection(
firstRange.startLineNumber,
firstRange.startColumn,
firstRange.endLineNumber,
firstRange.endColumn
);
return [initialSelection];
}
private _getEndCursorSelections(inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] {
let relevantEditIndex = 0;
for (let i = 0; i < inverseEditOperations.length; i++) {
const editRange = inverseEditOperations[i].range;
for (let j = 0; j < this._initialSelections.length; j++) {
const selectionRange = this._initialSelections[j];
if (Range.areIntersectingOrTouching(editRange, selectionRange)) {
relevantEditIndex = i;
break;
}
}
}
const srcRange = inverseEditOperations[relevantEditIndex].range;
this._endCursorSelection = new Selection(
srcRange.endLineNumber,
srcRange.endColumn,
srcRange.endLineNumber,
srcRange.endColumn
);
return [this._endCursorSelection];
}
public getEndCursorSelection(): Selection {
return this._endCursorSelection;
}
dispose() {
if (this._model) {
this._modelReference.dispose();
this._modelReference = null;
}
}
}
class SourceModelEditTask extends EditTask {
private _knownInitialSelections: Selection[];
constructor(modelReference: IReference<ITextEditorModel>, initialSelections: Selection[]) {
super(modelReference);
this._knownInitialSelections = initialSelections;
}
protected _getInitialSelections(): Selection[] {
return this._knownInitialSelections;
}
}
class BulkEditModel implements IDisposable {
private _textModelResolverService: ITextModelService;
private _numberOfResourcesToModify: number = 0;
private _numberOfChanges: number = 0;
private _edits: IStringDictionary<IResourceEdit[]> = Object.create(null);
private _tasks: EditTask[];
private _sourceModel: URI;
private _sourceSelections: Selection[];
private _sourceModelTask: SourceModelEditTask;
constructor(textModelResolverService: ITextModelService, sourceModel: URI, sourceSelections: Selection[], edits: IResourceEdit[], private progress: IProgressRunner = null) {
this._textModelResolverService = textModelResolverService;
this._sourceModel = sourceModel;
this._sourceSelections = sourceSelections;
this._sourceModelTask = null;
for (let edit of edits) {
this._addEdit(edit);
}
}
public resourcesCount(): number {
return this._numberOfResourcesToModify;
}
public changeCount(): number {
return this._numberOfChanges;
}
private _addEdit(edit: IResourceEdit): void {
let array = this._edits[edit.resource.toString()];
if (!array) {
this._edits[edit.resource.toString()] = array = [];
this._numberOfResourcesToModify += 1;
}
this._numberOfChanges += 1;
array.push(edit);
}
public prepare(): TPromise<BulkEditModel> {
if (this._tasks) {
throw new Error('illegal state - already prepared');
}
this._tasks = [];
const promises: TPromise<any>[] = [];
if (this.progress) {
this.progress.total(this._numberOfResourcesToModify * 2);
}
forEach(this._edits, entry => {
const promise = this._textModelResolverService.createModelReference(URI.parse(entry.key)).then(ref => {
const model = ref.object;
if (!model || !model.textEditorModel) {
throw new Error(`Cannot load file ${entry.key}`);
}
const textEditorModel = model.textEditorModel;
let task: EditTask;
if (this._sourceModel && textEditorModel.uri.toString() === this._sourceModel.toString()) {
this._sourceModelTask = new SourceModelEditTask(ref, this._sourceSelections);
task = this._sourceModelTask;
} else {
task = new EditTask(ref);
}
entry.value.forEach(edit => task.addEdit(edit));
this._tasks.push(task);
if (this.progress) {
this.progress.worked(1);
}
});
promises.push(promise);
});
return TPromise.join(promises).then(_ => this);
}
public apply(): Selection {
this._tasks.forEach(task => this.applyTask(task));
let r: Selection = null;
if (this._sourceModelTask) {
r = this._sourceModelTask.getEndCursorSelection();
}
return r;
}
private applyTask(task: EditTask): void {
task.apply();
if (this.progress) {
this.progress.worked(1);
}
}
dispose(): void {
this._tasks = dispose(this._tasks);
}
}
export interface BulkEdit {
progress(progress: IProgressRunner): void;
add(edit: IResourceEdit[]): void;
finish(): TPromise<ISelection>;
ariaMessage(): string;
}
export function bulkEdit(textModelResolverService: ITextModelService, editor: ICommonCodeEditor, edits: IResourceEdit[], fileService?: IFileService, progress: IProgressRunner = null): TPromise<any> {
let bulk = createBulkEdit(textModelResolverService, editor, fileService);
bulk.add(edits);
bulk.progress(progress);
return bulk.finish();
}
export function createBulkEdit(textModelResolverService: ITextModelService, editor?: ICommonCodeEditor, fileService?: IFileService): BulkEdit {
let all: IResourceEdit[] = [];
let recording = new ChangeRecorder(fileService).start();
let progressRunner: IProgressRunner;
function progress(progress: IProgressRunner) {
progressRunner = progress;
}
function add(edits: IResourceEdit[]): void {
all.push(...edits);
}
function getConcurrentEdits() {
let names: string[];
for (let edit of all) {
if (recording.hasChanged(edit.resource)) {
if (!names) {
names = [];
}
names.push(edit.resource.fsPath);
}
}
if (names) {
return nls.localize('conflict', "These files have changed in the meantime: {0}", names.join(', '));
}
return undefined;
}
function finish(): TPromise<ISelection> {
if (all.length === 0) {
return TPromise.as(undefined);
}
let concurrentEdits = getConcurrentEdits();
if (concurrentEdits) {
return TPromise.wrapError<ISelection>(new Error(concurrentEdits));
}
let uri: URI;
let selections: Selection[];
if (editor && editor.getModel()) {
uri = editor.getModel().uri;
selections = editor.getSelections();
}
const model = new BulkEditModel(textModelResolverService, uri, selections, all, progressRunner);
return model.prepare().then(_ => {
let concurrentEdits = getConcurrentEdits();
if (concurrentEdits) {
throw new Error(concurrentEdits);
}
recording.stop();
const result = model.apply();
model.dispose();
return result;
});
}
function ariaMessage(): string {
let editCount = all.length;
let resourceCount = size(groupBy(all, edit => edit.resource.toString()));
if (editCount === 0) {
return nls.localize('summary.0', "Made no edits");
} else if (editCount > 1 && resourceCount > 1) {
return nls.localize('summary.nm', "Made {0} text edits in {1} files", editCount, resourceCount);
} else {
return nls.localize('summary.n0', "Made {0} text edits in one file", editCount, resourceCount);
}
}
return {
progress,
add,
finish,
ariaMessage
};
}

View File

@@ -1,80 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import Event from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ICommonCodeEditor, ICommonDiffEditor, isCommonCodeEditor, isCommonDiffEditor, IDecorationRenderOptions, IModelDecorationOptions, IModel } from 'vs/editor/common/editorCommon';
import { IEditor } from 'vs/platform/editor/common/editor';
export var ICodeEditorService = createDecorator<ICodeEditorService>('codeEditorService');
export interface ICodeEditorService {
_serviceBrand: any;
onCodeEditorAdd: Event<ICommonCodeEditor>;
onCodeEditorRemove: Event<ICommonCodeEditor>;
onDiffEditorAdd: Event<ICommonDiffEditor>;
onDiffEditorRemove: Event<ICommonDiffEditor>;
addCodeEditor(editor: ICommonCodeEditor): void;
removeCodeEditor(editor: ICommonCodeEditor): void;
getCodeEditor(editorId: string): ICommonCodeEditor;
listCodeEditors(): ICommonCodeEditor[];
addDiffEditor(editor: ICommonDiffEditor): void;
removeDiffEditor(editor: ICommonDiffEditor): void;
getDiffEditor(editorId: string): ICommonDiffEditor;
listDiffEditors(): ICommonDiffEditor[];
/**
* Returns the current focused code editor (if the focus is in the editor or in an editor widget) or null.
*/
getFocusedCodeEditor(): ICommonCodeEditor;
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
removeDecorationType(key: string): void;
resolveDecorationOptions(typeKey: string, writable: boolean): IModelDecorationOptions;
setTransientModelProperty(model: IModel, key: string, value: any): void;
getTransientModelProperty(model: IModel, key: string): any;
}
/**
* Uses `editor.getControl()` and returns either a `codeEditor` or a `diffEditor` or nothing.
*/
export function getCodeOrDiffEditor(editor: IEditor): { codeEditor: ICommonCodeEditor; diffEditor: ICommonDiffEditor } {
if (editor) {
let control = editor.getControl();
if (control) {
if (isCommonCodeEditor(control)) {
return {
codeEditor: control,
diffEditor: null
};
}
if (isCommonDiffEditor(control)) {
return {
codeEditor: null,
diffEditor: control
};
}
}
}
return {
codeEditor: null,
diffEditor: null
};
}
/**
* Uses `editor.getControl()` and returns either the code editor, or the modified editor of a diff editor or nothing.
*/
export function getCodeEditor(editor: IEditor): ICommonCodeEditor {
let r = getCodeOrDiffEditor(editor);
return r.codeEditor || (r.diffEditor && r.diffEditor.getModifiedEditor()) || null;
}

View File

@@ -342,7 +342,7 @@ export abstract class BaseEditorSimpleWorker {
// ---- BEGIN minimal edits ---------------------------------------------------------------
private static _diffLimit = 10000;
private static readonly _diffLimit = 10000;
public computeMoreMinimalEdits(modelUrl: string, edits: TextEdit[]): TPromise<TextEdit[]> {
const model = this._getModel(modelUrl);
@@ -517,7 +517,7 @@ export abstract class BaseEditorSimpleWorker {
* @internal
*/
export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IRequestHandler, IDisposable {
_requestHandlerTrait: any;
_requestHandlerBrand: any;
private _models: { [uri: string]: MirrorModel; };

View File

@@ -20,7 +20,6 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IRange } from 'vs/editor/common/core/range';
import { IModeService } from 'vs/editor/common/services/modeService';
/**
* Stop syncing a model to the worker if it was not needed for 1 min.
@@ -51,8 +50,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
constructor(
@IModelService modelService: IModelService,
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,
@IModeService modeService: IModeService
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService
) {
super();
this._modelService = modelService;
@@ -67,7 +65,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
return wireCancellationToken(token, this._workerManager.withWorker().then(client => client.computeLinks(model.uri)));
}
}));
this._register(modes.SuggestRegistry.register('*', new WordBasedCompletionItemProvider(this._workerManager, configurationService, modeService, this._modelService)));
this._register(modes.SuggestRegistry.register('*', new WordBasedCompletionItemProvider(this._workerManager, configurationService, this._modelService)));
}
public dispose(): void {
@@ -114,23 +112,20 @@ class WordBasedCompletionItemProvider implements modes.ISuggestSupport {
private readonly _workerManager: WorkerManager;
private readonly _configurationService: ITextResourceConfigurationService;
private readonly _modeService: IModeService;
private readonly _modelService: IModelService;
constructor(
workerManager: WorkerManager,
configurationService: ITextResourceConfigurationService,
modeService: IModeService,
modelService: IModelService
) {
this._workerManager = workerManager;
this._configurationService = configurationService;
this._modeService = modeService;
this._modelService = modelService;
}
provideCompletionItems(model: editorCommon.IModel, position: Position): TPromise<modes.ISuggestResult> {
const { wordBasedSuggestions } = this._configurationService.getConfiguration<IEditorOptions>(model.uri, position, 'editor');
const { wordBasedSuggestions } = this._configurationService.getValue<IEditorOptions>(model.uri, position, 'editor');
if (!wordBasedSuggestions) {
return undefined;
}

View File

@@ -36,13 +36,16 @@ export class LanguagesRegistry {
private _nameMap: { [name: string]: LanguageIdentifier; };
private _lowercaseNameMap: { [name: string]: LanguageIdentifier; };
constructor(useModesRegistry = true) {
private _warnOnOverwrite: boolean;
constructor(useModesRegistry = true, warnOnOverwrite = false) {
this._nextLanguageId = 1;
this._languages = {};
this._mimeTypesMap = {};
this._nameMap = {};
this._lowercaseNameMap = {};
this._languageIds = [];
this._warnOnOverwrite = warnOnOverwrite;
if (useModesRegistry) {
this._registerLanguages(ModesRegistry.getLanguages());
@@ -100,10 +103,10 @@ export class LanguagesRegistry {
this._languages[langId] = resolvedLanguage;
}
LanguagesRegistry._mergeLanguage(resolvedLanguage, lang);
this._mergeLanguage(resolvedLanguage, lang);
}
private static _mergeLanguage(resolvedLanguage: IResolvedLanguage, lang: ILanguageExtensionPoint): void {
private _mergeLanguage(resolvedLanguage: IResolvedLanguage, lang: ILanguageExtensionPoint): void {
const langId = lang.id;
let primaryMime: string = null;
@@ -124,21 +127,21 @@ export class LanguagesRegistry {
if (Array.isArray(lang.extensions)) {
for (let extension of lang.extensions) {
mime.registerTextMime({ id: langId, mime: primaryMime, extension: extension });
mime.registerTextMime({ id: langId, mime: primaryMime, extension: extension }, this._warnOnOverwrite);
resolvedLanguage.extensions.push(extension);
}
}
if (Array.isArray(lang.filenames)) {
for (let filename of lang.filenames) {
mime.registerTextMime({ id: langId, mime: primaryMime, filename: filename });
mime.registerTextMime({ id: langId, mime: primaryMime, filename: filename }, this._warnOnOverwrite);
resolvedLanguage.filenames.push(filename);
}
}
if (Array.isArray(lang.filenamePatterns)) {
for (let filenamePattern of lang.filenamePatterns) {
mime.registerTextMime({ id: langId, mime: primaryMime, filepattern: filenamePattern });
mime.registerTextMime({ id: langId, mime: primaryMime, filepattern: filenamePattern }, this._warnOnOverwrite);
}
}
@@ -150,7 +153,7 @@ export class LanguagesRegistry {
try {
let firstLineRegex = new RegExp(firstLineRegexStr);
if (!strings.regExpLeadsToEndlessLoop(firstLineRegex)) {
mime.registerTextMime({ id: langId, mime: primaryMime, firstline: firstLineRegex });
mime.registerTextMime({ id: langId, mime: primaryMime, firstline: firstLineRegex }, this._warnOnOverwrite);
}
} catch (err) {
// Most likely, the regex was bad

View File

@@ -11,11 +11,6 @@ import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
export var IModeService = createDecorator<IModeService>('modeService');
export interface IModeLookupResult {
modeId: string;
isInstantiated: boolean;
}
export interface ILanguageExtensionPoint {
id: string;
extensions?: string[];
@@ -58,7 +53,6 @@ export interface IModeService {
getConfigurationFiles(modeId: string): string[];
// --- instantiation
lookup(commaSeparatedMimetypesOrCommaSeparatedIds: string): IModeLookupResult[];
getMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): IMode;
getOrCreateMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): TPromise<IMode>;
getOrCreateModeByLanguageName(languageName: string): TPromise<IMode>;

View File

@@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
import { FrankensteinMode } from 'vs/editor/common/modes/abstractMode';
import { LanguagesRegistry } from 'vs/editor/common/services/languagesRegistry';
import { IModeLookupResult, IModeService } from 'vs/editor/common/services/modeService';
import { IModeService } from 'vs/editor/common/services/modeService';
export class ModeServiceImpl implements IModeService {
public _serviceBrand: any;
@@ -21,10 +21,10 @@ export class ModeServiceImpl implements IModeService {
private readonly _onDidCreateMode: Emitter<IMode> = new Emitter<IMode>();
public readonly onDidCreateMode: Event<IMode> = this._onDidCreateMode.event;
constructor() {
constructor(warnOnOverwrite = false) {
this._instantiatedModes = {};
this._registry = new LanguagesRegistry();
this._registry = new LanguagesRegistry(true, warnOnOverwrite);
}
protected _onReady(): TPromise<boolean> {
@@ -93,22 +93,6 @@ export class ModeServiceImpl implements IModeService {
// --- instantiation
public lookup(commaSeparatedMimetypesOrCommaSeparatedIds: string): IModeLookupResult[] {
var r: IModeLookupResult[] = [];
var modeIds = this._registry.extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds);
for (var i = 0; i < modeIds.length; i++) {
var modeId = modeIds[i];
r.push({
modeId: modeId,
isInstantiated: this._instantiatedModes.hasOwnProperty(modeId)
});
}
return r;
}
public getMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): IMode {
var modeIds = this._registry.extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds);

View File

@@ -7,9 +7,8 @@
import * as nls from 'vs/nls';
import network = require('vs/base/common/network');
import Event, { Emitter } from 'vs/base/common/event';
import { EmitterEvent } from 'vs/base/common/eventEmitter';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
@@ -25,7 +24,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
import { IRawTextSource, TextSource, RawTextSource, ITextSource } from 'vs/editor/common/model/textSource';
import * as textModelEvents from 'vs/editor/common/model/textModelEvents';
import { IModelLanguageChangedEvent } from 'vs/editor/common/model/textModelEvents';
import { ClassName } from 'vs/editor/common/model/intervalTree';
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
import { EditOperation } from 'vs/editor/common/core/editOperation';
@@ -40,26 +39,28 @@ class ModelData implements IDisposable {
model: editorCommon.IModel;
private _markerDecorations: string[];
private _modelEventsListener: IDisposable;
private _modelEventListeners: IDisposable[];
constructor(model: editorCommon.IModel, eventsHandler: (modelData: ModelData, events: EmitterEvent[]) => void) {
constructor(
model: editorCommon.IModel,
onWillDispose: (model: editorCommon.IModel) => void,
onDidChangeLanguage: (model: editorCommon.IModel, e: IModelLanguageChangedEvent) => void
) {
this.model = model;
this._markerDecorations = [];
this._modelEventsListener = model.addBulkListener((events) => eventsHandler(this, events));
this._modelEventListeners = [];
this._modelEventListeners.push(model.onWillDispose(() => onWillDispose(model)));
this._modelEventListeners.push(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e)));
}
public dispose(): void {
this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, []);
this._modelEventsListener.dispose();
this._modelEventsListener = null;
this._modelEventListeners = dispose(this._modelEventListeners);
this.model = null;
}
public getModelId(): string {
return MODEL_ID(this.model.uri);
}
public acceptMarkerDecorations(newDecorations: editorCommon.IModelDeltaDecoration[]): void {
this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, newDecorations);
}
@@ -272,7 +273,7 @@ export class ModelServiceImpl implements IModelService {
public getCreationOptions(language: string, resource: URI): editorCommon.ITextModelCreationOptions {
let creationOptions = this._modelCreationOptionsByLanguageAndResource[language + resource];
if (!creationOptions) {
creationOptions = ModelServiceImpl._readModelOptions(this._configurationService.getConfiguration({ overrideIdentifier: language, resource }));
creationOptions = ModelServiceImpl._readModelOptions(this._configurationService.getValue({ overrideIdentifier: language, resource }));
this._modelCreationOptionsByLanguageAndResource[language + resource] = creationOptions;
}
return creationOptions;
@@ -366,7 +367,11 @@ export class ModelServiceImpl implements IModelService {
throw new Error('ModelService: Cannot add model because it already exists!');
}
let modelData = new ModelData(model, (modelData, events) => this._onModelEvents(modelData, events));
let modelData = new ModelData(
model,
(model) => this._onWillDispose(model),
(model, e) => this._onDidChangeLanguage(model, e)
);
this._models[modelId] = modelData;
return modelData;
@@ -559,7 +564,7 @@ export class ModelServiceImpl implements IModelService {
// --- end IModelService
private _onModelDisposing(model: editorCommon.IModel): void {
private _onWillDispose(model: editorCommon.IModel): void {
let modelId = MODEL_ID(model.uri);
let modelData = this._models[modelId];
@@ -570,30 +575,12 @@ export class ModelServiceImpl implements IModelService {
this._onModelRemoved.fire(model);
}
private _onModelEvents(modelData: ModelData, events: EmitterEvent[]): void {
// First look for dispose
for (let i = 0, len = events.length; i < len; i++) {
let e = events[i];
if (e.type === textModelEvents.TextModelEventType.ModelDispose) {
this._onModelDisposing(modelData.model);
// no more processing since model got disposed
return;
}
}
// Second, look for mode change
for (let i = 0, len = events.length; i < len; i++) {
let e = events[i];
if (e.type === textModelEvents.TextModelEventType.ModelLanguageChanged) {
const model = modelData.model;
const oldModeId = (<textModelEvents.IModelLanguageChangedEvent>e.data).oldLanguage;
const newModeId = model.getLanguageIdentifier().language;
const oldOptions = this.getCreationOptions(oldModeId, model.uri);
const newOptions = this.getCreationOptions(newModeId, model.uri);
ModelServiceImpl._setModelOptionsForModel(model, newOptions, oldOptions);
this._onModelModeChanged.fire({ model, oldModeId });
}
}
private _onDidChangeLanguage(model: editorCommon.IModel, e: IModelLanguageChangedEvent): void {
const oldModeId = e.oldLanguage;
const newModeId = model.getLanguageIdentifier().language;
const oldOptions = this.getCreationOptions(oldModeId, model.uri);
const newOptions = this.getCreationOptions(newModeId, model.uri);
ModelServiceImpl._setModelOptionsForModel(model, newOptions, oldOptions);
this._onModelModeChanged.fire({ model, oldModeId });
}
}

View File

@@ -21,15 +21,15 @@ export interface ITextResourceConfigurationService {
onDidChangeConfiguration: Event<IConfigurationChangeEvent>;
/**
* Fetches the appropriate section of the for the given resource with appropriate overrides (e.g. language).
* This will be an object keyed off the section name.
* Fetches the value of the section for the given resource by applying language overrides.
* 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. Can be `null` or `undefined`.
* @param postion - Position in the resource for which configuration has to be fetched. Can be `null` or `undefined`.
* @param section - Section of the configuraion. Can be `null` or `undefined`.
*
*/
getConfiguration<T>(resource: URI, section?: string): T;
getConfiguration<T>(resource: URI, position?: IPosition, section?: string): T;
getValue<T>(resource: URI, section?: string): T;
getValue<T>(resource: URI, position?: IPosition, section?: string): T;
}

View File

@@ -28,13 +28,13 @@ export class TextResourceConfigurationService extends Disposable implements ITex
this._register(this.configurationService.onDidChangeConfiguration(e => this._onDidChangeConfiguration.fire(e)));
}
getConfiguration<T>(resource: URI, section?: string): T
getConfiguration<T>(resource: URI, at?: IPosition, section?: string): T
getConfiguration<T>(resource: URI, arg2?: any, arg3?: any): T {
getValue<T>(resource: URI, section?: string): T;
getValue<T>(resource: URI, at?: IPosition, section?: string): T;
getValue<T>(resource: URI, arg2?: any, arg3?: any): T {
const position: IPosition = Position.isIPosition(arg2) ? arg2 : null;
const section: string = position ? (typeof arg3 === 'string' ? arg3 : void 0) : (typeof arg2 === 'string' ? arg2 : void 0);
const language = resource ? this.getLanguage(resource, position) : void 0;
return this.configurationService.getConfiguration<T>(section, { resource, overrideIdentifier: language });
return this.configurationService.getValue<T>(section, { resource, overrideIdentifier: language });
}
private getLanguage(resource: URI, position: IPosition): string {

View File

@@ -84,7 +84,7 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
};
};
let foreignProxy = <T><any>{};
let foreignProxy = {} as T;
for (let i = 0; i < foreignMethods.length; i++) {
foreignProxy[foreignMethods[i]] = createProxyMethod(foreignMethods[i], proxyMethodRequest);
}