mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 18:48:33 -05:00
Merge from master
This commit is contained in:
@@ -2,10 +2,9 @@
|
||||
* 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 { TPromise } from 'vs/base/common/winjs.base';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { first } from 'vs/base/common/async';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
@@ -22,6 +21,7 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
class ResourceModelCollection extends ReferenceCollection<TPromise<ITextEditorModel>> {
|
||||
|
||||
private providers: { [scheme: string]: ITextModelContentProvider[] } = Object.create(null);
|
||||
private modelsToDispose = new Set<string>();
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@@ -31,21 +31,39 @@ class ResourceModelCollection extends ReferenceCollection<TPromise<ITextEditorMo
|
||||
super();
|
||||
}
|
||||
|
||||
createReferencedObject(key: string): TPromise<ITextEditorModel> {
|
||||
createReferencedObject(key: string, skipActivateProvider?: boolean): TPromise<ITextEditorModel> {
|
||||
this.modelsToDispose.delete(key);
|
||||
|
||||
const resource = URI.parse(key);
|
||||
|
||||
// File or remote file provider already known
|
||||
if (this.fileService.canHandleResource(resource)) {
|
||||
return this.textFileService.models.loadOrCreate(resource, { reason: LoadReason.REFERENCE });
|
||||
}
|
||||
|
||||
return this.resolveTextModelContent(key).then(() => this.instantiationService.createInstance(ResourceEditorModel, resource));
|
||||
// Virtual documents
|
||||
if (this.providers[resource.scheme]) {
|
||||
return this.resolveTextModelContent(key).then(() => this.instantiationService.createInstance(ResourceEditorModel, resource));
|
||||
}
|
||||
|
||||
// Either unknown schema, or not yet registered, try to activate
|
||||
if (!skipActivateProvider) {
|
||||
return this.fileService.activateProvider(resource.scheme).then(() => this.createReferencedObject(key, true));
|
||||
}
|
||||
|
||||
return TPromise.wrapError<ITextEditorModel>(new Error('resource is not available'));
|
||||
}
|
||||
|
||||
destroyReferencedObject(modelPromise: TPromise<ITextEditorModel>): void {
|
||||
modelPromise.done(model => {
|
||||
if (model instanceof TextFileEditorModel) {
|
||||
this.textFileService.models.disposeModel(model);
|
||||
} else {
|
||||
model.dispose();
|
||||
destroyReferencedObject(key: string, modelPromise: TPromise<ITextEditorModel>): void {
|
||||
this.modelsToDispose.add(key);
|
||||
|
||||
modelPromise.then(model => {
|
||||
if (this.modelsToDispose.has(key)) {
|
||||
if (model instanceof TextFileEditorModel) {
|
||||
this.textFileService.models.disposeModel(model);
|
||||
} else {
|
||||
model.dispose();
|
||||
}
|
||||
}
|
||||
}, err => {
|
||||
// ignore
|
||||
@@ -82,11 +100,10 @@ class ResourceModelCollection extends ReferenceCollection<TPromise<ITextEditorMo
|
||||
private resolveTextModelContent(key: string): TPromise<ITextModel> {
|
||||
const resource = URI.parse(key);
|
||||
const providers = this.providers[resource.scheme] || [];
|
||||
const factories = providers.map(p => () => p.provideTextContent(resource));
|
||||
const factories = providers.map(p => () => TPromise.wrap(p.provideTextContent(resource)));
|
||||
|
||||
return first(factories).then(model => {
|
||||
if (!model) {
|
||||
console.error(`Unable to open '${resource}' resource is not available.`); // TODO PII
|
||||
return TPromise.wrapError<ITextModel>(new Error('resource is not available'));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -58,30 +55,33 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
|
||||
test('resolve resource', function () {
|
||||
const dispose = accessor.textModelResolverService.registerTextModelContentProvider('test', {
|
||||
provideTextContent: function (resource: URI): TPromise<ITextModel> {
|
||||
provideTextContent: function (resource: URI): Thenable<ITextModel> {
|
||||
if (resource.scheme === 'test') {
|
||||
let modelContent = 'Hello Test';
|
||||
let mode = accessor.modeService.getOrCreateMode('json');
|
||||
return TPromise.as(accessor.modelService.createModel(modelContent, mode, resource));
|
||||
let languageSelection = accessor.modeService.create('json');
|
||||
return Promise.resolve(accessor.modelService.createModel(modelContent, languageSelection, resource));
|
||||
}
|
||||
|
||||
return TPromise.as(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
let resource = URI.from({ scheme: 'test', authority: null, path: 'thePath' });
|
||||
let input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, 'The Name', 'The Description', resource);
|
||||
|
||||
return input.resolve().then(model => {
|
||||
return input.resolve().then(async model => {
|
||||
assert.ok(model);
|
||||
assert.equal(snapshotToString((model as ResourceEditorModel).createSnapshot()), 'Hello Test');
|
||||
|
||||
let disposed = false;
|
||||
once(model.onDispose)(() => {
|
||||
disposed = true;
|
||||
let disposedPromise = new Promise(resolve => {
|
||||
once(model.onDispose)(() => {
|
||||
disposed = true;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
input.dispose();
|
||||
await disposedPromise;
|
||||
assert.equal(disposed, true);
|
||||
|
||||
dispose.dispose();
|
||||
@@ -130,14 +130,14 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
|
||||
test('even loading documents should be refcounted', async () => {
|
||||
let resolveModel: Function;
|
||||
let waitForIt = new TPromise(c => resolveModel = c);
|
||||
let waitForIt = new Promise(c => resolveModel = c);
|
||||
|
||||
const disposable = accessor.textModelResolverService.registerTextModelContentProvider('test', {
|
||||
provideTextContent: (resource: URI): TPromise<ITextModel> => {
|
||||
provideTextContent: (resource: URI): Thenable<ITextModel> => {
|
||||
return waitForIt.then(_ => {
|
||||
let modelContent = 'Hello Test';
|
||||
let mode = accessor.modeService.getOrCreateMode('json');
|
||||
return accessor.modelService.createModel(modelContent, mode, resource);
|
||||
let languageSelection = accessor.modeService.create('json');
|
||||
return accessor.modelService.createModel(modelContent, languageSelection, resource);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -161,7 +161,10 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
modelRef1.dispose();
|
||||
assert(!textModel.isDisposed(), 'the text model should still not be disposed');
|
||||
|
||||
let p1 = new Promise(resolve => textModel.onWillDispose(resolve));
|
||||
modelRef2.dispose();
|
||||
|
||||
await p1;
|
||||
assert(textModel.isDisposed(), 'the text model should finally be disposed');
|
||||
|
||||
disposable.dispose();
|
||||
|
||||
Reference in New Issue
Block a user