modelServiceImpl.ts 16.7 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

A
Alex Dima 已提交
7
import * as nls from 'vs/nls';
S
Sandeep Somavarapu 已提交
8
import network = require('vs/base/common/network');
J
Johannes Rieken 已提交
9 10 11 12
import Event, { Emitter } from 'vs/base/common/event';
import { EmitterEvent } from 'vs/base/common/eventEmitter';
import { MarkedString } from 'vs/base/common/htmlContent';
import { IDisposable } from 'vs/base/common/lifecycle';
A
Alex Dima 已提交
13 14
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
J
Johannes Rieken 已提交
15 16 17
import { TPromise } from 'vs/base/common/winjs.base';
import { IMarker, IMarkerService } from 'vs/platform/markers/common/markers';
import { Range } from 'vs/editor/common/core/range';
A
Alex Dima 已提交
18
import * as editorCommon from 'vs/editor/common/editorCommon';
J
Johannes Rieken 已提交
19
import { Model } from 'vs/editor/common/model/model';
A
Alex Dima 已提交
20
import { IMode, LanguageIdentifier } from 'vs/editor/common/modes';
21
import { IModelService } from 'vs/editor/common/services/modelService';
22
import * as platform from 'vs/base/common/platform';
J
Johannes Rieken 已提交
23 24
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { DEFAULT_INDENTATION, DEFAULT_TRIM_AUTO_WHITESPACE } from 'vs/editor/common/config/defaultConfig';
A
Alex Dima 已提交
25
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
26
import { RawText } from 'vs/editor/common/model/textModel';
A
Alex Dima 已提交
27
import { IRawTextSource } from 'vs/editor/common/model/textSource';
E
Erich Gamma 已提交
28

B
Benjamin Pasero 已提交
29
function MODEL_ID(resource: URI): string {
A
Alex Dima 已提交
30 31 32 33
	return resource.toString();
}

class ModelData implements IDisposable {
A
Alex Dima 已提交
34
	model: editorCommon.IModel;
E
Erich Gamma 已提交
35

A
Alex Dima 已提交
36 37
	private _markerDecorations: string[];
	private _modelEventsListener: IDisposable;
E
Erich Gamma 已提交
38

A
Alex Dima 已提交
39
	constructor(model: editorCommon.IModel, eventsHandler: (modelData: ModelData, events: EmitterEvent[]) => void) {
E
Erich Gamma 已提交
40
		this.model = model;
A
Alex Dima 已提交
41 42

		this._markerDecorations = [];
A
Alex Dima 已提交
43
		this._modelEventsListener = model.addBulkListener((events) => eventsHandler(this, events));
E
Erich Gamma 已提交
44 45 46
	}

	public dispose(): void {
A
Alex Dima 已提交
47 48 49
		this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, []);
		this._modelEventsListener.dispose();
		this._modelEventsListener = null;
E
Erich Gamma 已提交
50
		this.model = null;
A
Alex Dima 已提交
51
	}
E
Erich Gamma 已提交
52

A
Alex Dima 已提交
53
	public getModelId(): string {
54
		return MODEL_ID(this.model.uri);
A
Alex Dima 已提交
55 56
	}

B
Benjamin Pasero 已提交
57
	public acceptMarkerDecorations(newDecorations: editorCommon.IModelDeltaDecoration[]): void {
A
Alex Dima 已提交
58
		this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, newDecorations);
E
Erich Gamma 已提交
59
	}
A
Alex Dima 已提交
60
}
E
Erich Gamma 已提交
61

A
Alex Dima 已提交
62 63
class ModelMarkerHandler {

64
	public static setMarkers(modelData: ModelData, markerService: IMarkerService): void {
E
Erich Gamma 已提交
65 66

		// Limit to the first 500 errors/warnings
67
		const markers = markerService.read({ resource: modelData.model.uri, take: 500 });
E
Erich Gamma 已提交
68

B
Benjamin Pasero 已提交
69
		let newModelDecorations: editorCommon.IModelDeltaDecoration[] = markers.map((marker) => {
A
Alex Dima 已提交
70 71
			return {
				range: this._createDecorationRange(modelData.model, marker),
E
Erich Gamma 已提交
72 73 74
				options: this._createDecorationOption(marker)
			};
		});
A
Alex Dima 已提交
75 76

		modelData.acceptMarkerDecorations(newModelDecorations);
E
Erich Gamma 已提交
77 78
	}

79
	private static _createDecorationRange(model: editorCommon.IModel, rawMarker: IMarker): Range {
A
Alex Dima 已提交
80
		let marker = model.validateRange(new Range(rawMarker.startLineNumber, rawMarker.startColumn, rawMarker.endLineNumber, rawMarker.endColumn));
81
		let ret: Range = new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn);
E
Erich Gamma 已提交
82
		if (ret.isEmpty()) {
A
Alex Dima 已提交
83
			let word = model.getWordAtPosition(ret.getStartPosition());
E
Erich Gamma 已提交
84
			if (word) {
85
				ret = new Range(ret.startLineNumber, word.startColumn, ret.endLineNumber, word.endColumn);
E
Erich Gamma 已提交
86
			} else {
A
Alex Dima 已提交
87 88
				let maxColumn = model.getLineLastNonWhitespaceColumn(marker.startLineNumber) ||
					model.getLineMaxColumn(marker.startLineNumber);
E
Erich Gamma 已提交
89 90 91

				if (maxColumn === 1) {
					// empty line
92
					// console.warn('marker on empty line:', marker);
E
Erich Gamma 已提交
93 94
				} else if (ret.endColumn >= maxColumn) {
					// behind eol
95
					ret = new Range(ret.startLineNumber, maxColumn - 1, ret.endLineNumber, maxColumn);
E
Erich Gamma 已提交
96 97
				} else {
					// extend marker to width = 1
98
					ret = new Range(ret.startLineNumber, ret.startColumn, ret.endLineNumber, ret.endColumn + 1);
E
Erich Gamma 已提交
99 100 101
				}
			}
		} else if (rawMarker.endColumn === Number.MAX_VALUE && rawMarker.startColumn === 1 && ret.startLineNumber === ret.endLineNumber) {
A
Alex Dima 已提交
102
			let minColumn = model.getLineFirstNonWhitespaceColumn(rawMarker.startLineNumber);
E
Erich Gamma 已提交
103
			if (minColumn < ret.endColumn) {
104
				ret = new Range(ret.startLineNumber, minColumn, ret.endLineNumber, ret.endColumn);
E
Erich Gamma 已提交
105 106 107 108 109 110
				rawMarker.startColumn = minColumn;
			}
		}
		return ret;
	}

B
Benjamin Pasero 已提交
111
	private static _createDecorationOption(marker: IMarker): editorCommon.IModelDecorationOptions {
E
Erich Gamma 已提交
112 113 114 115 116 117 118 119 120 121 122

		let className: string;
		let color: string;
		let darkColor: string;

		switch (marker.severity) {
			case Severity.Ignore:
				// do something
				break;
			case Severity.Warning:
			case Severity.Info:
A
Alex Dima 已提交
123
				className = editorCommon.ClassName.EditorWarningDecoration;
E
Erich Gamma 已提交
124 125 126 127 128
				color = 'rgba(18,136,18,0.7)';
				darkColor = 'rgba(18,136,18,0.7)';
				break;
			case Severity.Error:
			default:
A
Alex Dima 已提交
129
				className = editorCommon.ClassName.EditorErrorDecoration;
E
Erich Gamma 已提交
130 131 132 133 134
				color = 'rgba(255,18,18,0.7)';
				darkColor = 'rgba(255,18,18,0.7)';
				break;
		}

135 136
		let hoverMessage: MarkedString[] = null;
		let {message, source} = marker;
E
Erich Gamma 已提交
137

138
		if (typeof message === 'string') {
J
Joao Moreno 已提交
139 140
			message = message.trim();

141
			if (source) {
J
Joao Moreno 已提交
142 143 144 145 146
				if (/\n/g.test(message)) {
					message = nls.localize('diagAndSourceMultiline', "[{0}]\n{1}", source, message);
				} else {
					message = nls.localize('diagAndSource', "[{0}] {1}", source, message);
				}
147
			}
J
Joao Moreno 已提交
148

149
			hoverMessage = [{ language: '_', value: message }];
150 151
		}

E
Erich Gamma 已提交
152
		return {
A
Alex Dima 已提交
153
			stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
E
Erich Gamma 已提交
154
			className,
155
			hoverMessage,
E
Erich Gamma 已提交
156 157 158
			overviewRuler: {
				color,
				darkColor,
A
Alex Dima 已提交
159
				position: editorCommon.OverviewRulerLane.Right
E
Erich Gamma 已提交
160 161 162 163 164
			}
		};
	}
}

165 166 167 168 169 170 171 172
interface IRawConfig {
	files?: {
		eol?: any;
	};
	editor?: {
		tabSize?: any;
		insertSpaces?: any;
		detectIndentation?: any;
173
		trimAutoWhitespace?: any;
174 175 176
	};
}

177 178
const DEFAULT_EOL = (platform.isLinux || platform.isMacintosh) ? editorCommon.DefaultEndOfLine.LF : editorCommon.DefaultEndOfLine.CRLF;

E
Erich Gamma 已提交
179
export class ModelServiceImpl implements IModelService {
180
	public _serviceBrand: any;
E
Erich Gamma 已提交
181 182 183

	private _markerService: IMarkerService;
	private _markerServiceSubscription: IDisposable;
184 185
	private _configurationService: IConfigurationService;
	private _configurationServiceSubscription: IDisposable;
E
Erich Gamma 已提交
186

A
Alex Dima 已提交
187 188 189
	private _onModelAdded: Emitter<editorCommon.IModel>;
	private _onModelRemoved: Emitter<editorCommon.IModel>;
	private _onModelModeChanged: Emitter<{ model: editorCommon.IModel; oldModeId: string; }>;
190

191 192 193
	private _modelCreationOptionsByLanguage: {
		[language: string]: editorCommon.ITextModelCreationOptions;
	};
A
Alex Dima 已提交
194 195 196 197

	/**
	 * All the models known in the system.
	 */
B
Benjamin Pasero 已提交
198
	private _models: { [modelId: string]: ModelData; };
E
Erich Gamma 已提交
199

200
	constructor(
201 202
		@IMarkerService markerService: IMarkerService,
		@IConfigurationService configurationService: IConfigurationService,
203
	) {
E
Erich Gamma 已提交
204
		this._markerService = markerService;
205
		this._configurationService = configurationService;
B
Benjamin Pasero 已提交
206
		this._models = {};
207
		this._modelCreationOptionsByLanguage = Object.create(null);
B
Benjamin Pasero 已提交
208 209 210 211 212 213 214
		this._onModelAdded = new Emitter<editorCommon.IModel>();
		this._onModelRemoved = new Emitter<editorCommon.IModel>();
		this._onModelModeChanged = new Emitter<{ model: editorCommon.IModel; oldModeId: string; }>();

		if (this._markerService) {
			this._markerServiceSubscription = this._markerService.onMarkerChanged(this._handleMarkerChange, this);
		}
215

216 217 218
		this._configurationServiceSubscription = this._configurationService.onDidUpdateConfiguration(e => this._updateModelOptions());
		this._updateModelOptions();
	}
J
Joao Moreno 已提交
219

220 221 222 223 224 225
	private static _readModelOptions(config: IRawConfig): editorCommon.ITextModelCreationOptions {
		let tabSize = DEFAULT_INDENTATION.tabSize;
		if (config.editor && typeof config.editor.tabSize !== 'undefined') {
			let parsedTabSize = parseInt(config.editor.tabSize, 10);
			if (!isNaN(parsedTabSize)) {
				tabSize = parsedTabSize;
226
			}
227
		}
228

229 230 231 232
		let insertSpaces = DEFAULT_INDENTATION.insertSpaces;
		if (config.editor && typeof config.editor.insertSpaces !== 'undefined') {
			insertSpaces = (config.editor.insertSpaces === 'false' ? false : Boolean(config.editor.insertSpaces));
		}
233

234 235 236 237 238 239 240
		let newDefaultEOL = DEFAULT_EOL;
		const eol = config.files && config.files.eol;
		if (eol === '\r\n') {
			newDefaultEOL = editorCommon.DefaultEndOfLine.CRLF;
		} else if (eol === '\n') {
			newDefaultEOL = editorCommon.DefaultEndOfLine.LF;
		}
241

242 243 244 245
		let trimAutoWhitespace = DEFAULT_TRIM_AUTO_WHITESPACE;
		if (config.editor && typeof config.editor.trimAutoWhitespace !== 'undefined') {
			trimAutoWhitespace = (config.editor.trimAutoWhitespace === 'false' ? false : Boolean(config.editor.trimAutoWhitespace));
		}
246

247 248 249 250
		let detectIndentation = DEFAULT_INDENTATION.detectIndentation;
		if (config.editor && typeof config.editor.detectIndentation !== 'undefined') {
			detectIndentation = (config.editor.detectIndentation === 'false' ? false : Boolean(config.editor.detectIndentation));
		}
251

252 253 254 255 256 257
		return {
			tabSize: tabSize,
			insertSpaces: insertSpaces,
			detectIndentation: detectIndentation,
			defaultEOL: newDefaultEOL,
			trimAutoWhitespace: trimAutoWhitespace
258
		};
E
Erich Gamma 已提交
259 260
	}

261 262 263 264 265 266 267
	public getCreationOptions(language: string): editorCommon.ITextModelCreationOptions {
		let creationOptions = this._modelCreationOptionsByLanguage[language];
		if (!creationOptions) {
			creationOptions = ModelServiceImpl._readModelOptions(this._configurationService.getConfiguration({ overrideIdentifier: language }));
			this._modelCreationOptionsByLanguage[language] = creationOptions;
		}
		return creationOptions;
268 269
	}

270 271 272
	private _updateModelOptions(): void {
		let oldOptionsByLanguage = this._modelCreationOptionsByLanguage;
		this._modelCreationOptionsByLanguage = Object.create(null);
273

274
		// Update options on all models
A
Alex Dima 已提交
275 276 277 278
		let keys = Object.keys(this._models);
		for (let i = 0, len = keys.length; i < len; i++) {
			let modelId = keys[i];
			let modelData = this._models[modelId];
279 280 281 282 283 284
			const language = modelData.model.getLanguageIdentifier().language;
			const oldOptions = oldOptionsByLanguage[language];
			const newOptions = this.getCreationOptions(language);
			ModelServiceImpl._setModelOptionsForModel(modelData.model, newOptions, oldOptions);
		}
	}
285

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
	private static _setModelOptionsForModel(model: editorCommon.IModel, newOptions: editorCommon.ITextModelCreationOptions, currentOptions: editorCommon.ITextModelCreationOptions): void {
		if (currentOptions
			&& (currentOptions.detectIndentation === newOptions.detectIndentation)
			&& (currentOptions.insertSpaces === newOptions.insertSpaces)
			&& (currentOptions.tabSize === newOptions.tabSize)
			&& (currentOptions.trimAutoWhitespace === newOptions.trimAutoWhitespace)
		) {
			// Same indent opts, no need to touch the model
			return;
		}

		if (newOptions.detectIndentation) {
			model.detectIndentation(newOptions.insertSpaces, newOptions.tabSize);
			model.updateOptions({
				trimAutoWhitespace: newOptions.trimAutoWhitespace
			});
		} else {
			model.updateOptions({
				insertSpaces: newOptions.insertSpaces,
				tabSize: newOptions.tabSize,
				trimAutoWhitespace: newOptions.trimAutoWhitespace
			});
308
		}
309 310
	}

E
Erich Gamma 已提交
311
	public dispose(): void {
B
Benjamin Pasero 已提交
312
		if (this._markerServiceSubscription) {
E
Erich Gamma 已提交
313 314
			this._markerServiceSubscription.dispose();
		}
315
		this._configurationServiceSubscription.dispose();
E
Erich Gamma 已提交
316 317 318
	}

	private _handleMarkerChange(changedResources: URI[]): void {
A
Alex Dima 已提交
319 320 321 322
		changedResources.forEach((resource) => {
			let modelId = MODEL_ID(resource);
			let modelData = this._models[modelId];
			if (!modelData) {
E
Erich Gamma 已提交
323 324
				return;
			}
325
			ModelMarkerHandler.setMarkers(modelData, this._markerService);
E
Erich Gamma 已提交
326 327 328
		});
	}

S
Sandeep Somavarapu 已提交
329 330 331
	private _cleanUp(model: editorCommon.IModel): void {
		// clean up markers for internal, transient models
		if (model.uri.scheme === network.Schemas.inMemory
B
Benjamin Pasero 已提交
332 333 334 335 336
			|| model.uri.scheme === network.Schemas.internal
			|| model.uri.scheme === network.Schemas.vscode) {
			if (this._markerService) {
				this._markerService.read({ resource: model.uri }).map(marker => marker.owner).forEach(owner => this._markerService.remove(owner, [model.uri]));
			}
S
Sandeep Somavarapu 已提交
337 338 339
		}
	}

E
Erich Gamma 已提交
340 341
	// --- begin IModelService

A
Alex Dima 已提交
342
	private _createModelData(value: string | IRawTextSource, languageIdentifier: LanguageIdentifier, resource: URI): ModelData {
A
Alex Dima 已提交
343
		// create & save the model
344 345
		const options = this.getCreationOptions(languageIdentifier.language);

346 347
		let rawText: editorCommon.IRawText = RawText.toRawText(value, options);
		let model: Model = new Model(rawText, languageIdentifier, resource);
348
		let modelId = MODEL_ID(model.uri);
E
Erich Gamma 已提交
349 350 351

		if (this._models[modelId]) {
			// There already exists a model with this id => this is a programmer error
352
			throw new Error('ModelService: Cannot add model because it already exists!');
E
Erich Gamma 已提交
353 354
		}

A
Alex Dima 已提交
355 356
		let modelData = new ModelData(model, (modelData, events) => this._onModelEvents(modelData, events));
		this._models[modelId] = modelData;
E
Erich Gamma 已提交
357

A
Alex Dima 已提交
358
		return modelData;
E
Erich Gamma 已提交
359 360
	}

A
Alex Dima 已提交
361
	public updateModel(model: editorCommon.IModel, value: string | IRawTextSource): void {
362 363
		let options = this.getCreationOptions(model.getLanguageIdentifier().language);
		let rawText: editorCommon.IRawText = RawText.toRawText(value, options);
364 365 366 367 368 369 370 371

		// Return early if the text is already set in that form
		if (model.equals(rawText)) {
			return;
		}

		// Otherwise update model
		model.setValueFromRawText(rawText);
372 373
	}

A
Alex Dima 已提交
374
	public createModel(value: string | IRawTextSource, modeOrPromise: TPromise<IMode> | IMode, resource: URI): editorCommon.IModel {
375 376 377
		let modelData: ModelData;

		if (!modeOrPromise || TPromise.is(modeOrPromise)) {
A
Alex Dima 已提交
378
			modelData = this._createModelData(value, PLAINTEXT_LANGUAGE_IDENTIFIER, resource);
379 380
			this.setMode(modelData.model, modeOrPromise);
		} else {
A
Alex Dima 已提交
381
			modelData = this._createModelData(value, modeOrPromise.getLanguageIdentifier(), resource);
382
		}
E
Erich Gamma 已提交
383

A
Alex Dima 已提交
384 385
		// handle markers (marker service => model)
		if (this._markerService) {
386
			ModelMarkerHandler.setMarkers(modelData, this._markerService);
E
Erich Gamma 已提交
387 388
		}

A
Alex Dima 已提交
389
		this._onModelAdded.fire(modelData.model);
E
Erich Gamma 已提交
390

A
Alex Dima 已提交
391
		return modelData.model;
E
Erich Gamma 已提交
392 393
	}

J
Johannes Rieken 已提交
394
	public setMode(model: editorCommon.IModel, modeOrPromise: TPromise<IMode> | IMode): void {
395 396 397 398 399 400
		if (!modeOrPromise) {
			return;
		}
		if (TPromise.is(modeOrPromise)) {
			modeOrPromise.then((mode) => {
				if (!model.isDisposed()) {
A
Alex Dima 已提交
401
					model.setMode(mode.getLanguageIdentifier());
402 403 404
				}
			});
		} else {
A
Alex Dima 已提交
405
			model.setMode(modeOrPromise.getLanguageIdentifier());
406 407 408
		}
	}

J
Johannes Rieken 已提交
409
	public destroyModel(resource: URI): void {
A
Alex Dima 已提交
410 411 412 413
		// We need to support that not all models get disposed through this service (i.e. model.dispose() should work!)
		let modelData = this._models[MODEL_ID(resource)];
		if (!modelData) {
			return;
E
Erich Gamma 已提交
414
		}
A
Alex Dima 已提交
415
		modelData.model.dispose();
E
Erich Gamma 已提交
416 417
	}

A
Alex Dima 已提交
418 419
	public getModels(): editorCommon.IModel[] {
		let ret: editorCommon.IModel[] = [];
A
Alex Dima 已提交
420 421 422 423 424

		let keys = Object.keys(this._models);
		for (let i = 0, len = keys.length; i < len; i++) {
			let modelId = keys[i];
			ret.push(this._models[modelId].model);
E
Erich Gamma 已提交
425
		}
A
Alex Dima 已提交
426

E
Erich Gamma 已提交
427 428 429
		return ret;
	}

A
Alex Dima 已提交
430
	public getModel(resource: URI): editorCommon.IModel {
A
Alex Dima 已提交
431 432 433 434
		let modelId = MODEL_ID(resource);
		let modelData = this._models[modelId];
		if (!modelData) {
			return null;
E
Erich Gamma 已提交
435
		}
A
Alex Dima 已提交
436
		return modelData.model;
E
Erich Gamma 已提交
437 438
	}

A
Alex Dima 已提交
439
	public get onModelAdded(): Event<editorCommon.IModel> {
440
		return this._onModelAdded ? this._onModelAdded.event : null;
E
Erich Gamma 已提交
441 442
	}

A
Alex Dima 已提交
443
	public get onModelRemoved(): Event<editorCommon.IModel> {
444
		return this._onModelRemoved ? this._onModelRemoved.event : null;
E
Erich Gamma 已提交
445 446
	}

A
Alex Dima 已提交
447
	public get onModelModeChanged(): Event<{ model: editorCommon.IModel; oldModeId: string; }> {
448
		return this._onModelModeChanged ? this._onModelModeChanged.event : null;
E
Erich Gamma 已提交
449 450 451 452
	}

	// --- end IModelService

B
Benjamin Pasero 已提交
453
	private _onModelDisposing(model: editorCommon.IModel): void {
454
		let modelId = MODEL_ID(model.uri);
A
Alex Dima 已提交
455 456 457 458 459
		let modelData = this._models[modelId];

		delete this._models[modelId];
		modelData.dispose();

460
		this._cleanUp(model);
A
Alex Dima 已提交
461 462 463
		this._onModelRemoved.fire(model);
	}

A
Alex Dima 已提交
464
	private _onModelEvents(modelData: ModelData, events: EmitterEvent[]): void {
E
Erich Gamma 已提交
465

466
		// First look for dispose
A
Alex Dima 已提交
467 468
		for (let i = 0, len = events.length; i < len; i++) {
			let e = events[i];
A
Alex Dima 已提交
469
			if (e.getType() === editorCommon.EventType.ModelDispose) {
470 471 472 473 474
				this._onModelDisposing(modelData.model);
				// no more processing since model got disposed
				return;
			}
		}
E
Erich Gamma 已提交
475

476 477 478
		// Second, look for mode change
		for (let i = 0, len = events.length; i < len; i++) {
			let e = events[i];
A
Alex Dima 已提交
479
			if (e.getType() === editorCommon.EventType.ModelLanguageChanged) {
480 481 482 483 484 485 486
				const model = modelData.model;
				const oldModeId = (<editorCommon.IModelLanguageChangedEvent>e.getData()).oldLanguage;
				const newModeId = model.getLanguageIdentifier().language;
				const oldOptions = this.getCreationOptions(oldModeId);
				const newOptions = this.getCreationOptions(newModeId);
				ModelServiceImpl._setModelOptionsForModel(model, newOptions, oldOptions);
				this._onModelModeChanged.fire({ model, oldModeId });
E
Erich Gamma 已提交
487 488 489 490
			}
		}
	}
}