Merge from vscode bd0efff9e3f36d6b3e1045cee9887003af8034d7

This commit is contained in:
ADS Merger
2020-05-06 02:35:49 +00:00
parent 9a7810cbee
commit 8420d9f04e
243 changed files with 4276 additions and 2478 deletions

View File

@@ -0,0 +1,311 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { notebookProviderExtensionPoint, notebookRendererExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol';
import { Emitter, Event } from 'vs/base/common/event';
import { INotebookTextModel, INotebookMimeTypeSelector, INotebookRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
import { Iterable } from 'vs/base/common/iterator';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { IEditorService, ICustomEditorViewTypesHandler, ICustomEditorInfo } from 'vs/workbench/services/editor/common/editorService';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { NotebookEditorModelManager } from 'vs/workbench/contrib/notebook/common/notebookEditorModel';
import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/common/notebookService';
function MODEL_ID(resource: URI): string {
return resource.toString();
}
export class NotebookProviderInfoStore {
private readonly contributedEditors = new Map<string, NotebookProviderInfo>();
clear() {
this.contributedEditors.clear();
}
get(viewType: string): NotebookProviderInfo | undefined {
return this.contributedEditors.get(viewType);
}
add(info: NotebookProviderInfo): void {
if (this.contributedEditors.has(info.id)) {
console.log(`Custom editor with id '${info.id}' already registered`);
return;
}
this.contributedEditors.set(info.id, info);
}
getContributedNotebook(resource: URI): readonly NotebookProviderInfo[] {
return [...Iterable.filter(this.contributedEditors.values(), customEditor => customEditor.matches(resource))];
}
public [Symbol.iterator](): Iterator<NotebookProviderInfo> {
return this.contributedEditors.values();
}
}
export class NotebookOutputRendererInfoStore {
private readonly contributedRenderers = new Map<string, NotebookOutputRendererInfo>();
clear() {
this.contributedRenderers.clear();
}
get(viewType: string): NotebookOutputRendererInfo | undefined {
return this.contributedRenderers.get(viewType);
}
add(info: NotebookOutputRendererInfo): void {
if (this.contributedRenderers.has(info.id)) {
console.log(`Custom notebook output renderer with id '${info.id}' already registered`);
return;
}
this.contributedRenderers.set(info.id, info);
}
getContributedRenderer(mimeType: string): readonly NotebookOutputRendererInfo[] {
return Array.from(this.contributedRenderers.values()).filter(customEditor =>
customEditor.matches(mimeType));
}
}
class ModelData implements IDisposable {
private readonly _modelEventListeners = new DisposableStore();
constructor(
public model: NotebookTextModel,
onWillDispose: (model: INotebookTextModel) => void
) {
this._modelEventListeners.add(model.onWillDispose(() => onWillDispose(model)));
}
dispose(): void {
this._modelEventListeners.dispose();
}
}
export class NotebookService extends Disposable implements INotebookService, ICustomEditorViewTypesHandler {
_serviceBrand: undefined;
private readonly _notebookProviders = new Map<string, { controller: IMainNotebookController, extensionData: NotebookExtensionDescription }>();
private readonly _notebookRenderers = new Map<number, { extensionData: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, preloads: URI[] }>();
notebookProviderInfoStore: NotebookProviderInfoStore = new NotebookProviderInfoStore();
notebookRenderersInfoStore: NotebookOutputRendererInfoStore = new NotebookOutputRendererInfoStore();
private readonly _models: { [modelId: string]: ModelData; };
private _onDidChangeActiveEditor = new Emitter<{ viewType: string, uri: URI }>();
onDidChangeActiveEditor: Event<{ viewType: string, uri: URI }> = this._onDidChangeActiveEditor.event;
private readonly _onDidChangeViewTypes = new Emitter<void>();
onDidChangeViewTypes: Event<void> = this._onDidChangeViewTypes.event;
private cutItems: NotebookCellTextModel[] | undefined;
modelManager: NotebookEditorModelManager;
constructor(
@IExtensionService private readonly extensionService: IExtensionService,
@IEditorService private readonly editorService: IEditorService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
this._models = {};
this.modelManager = this.instantiationService.createInstance(NotebookEditorModelManager);
notebookProviderExtensionPoint.setHandler((extensions) => {
this.notebookProviderInfoStore.clear();
for (const extension of extensions) {
for (const notebookContribution of extension.value) {
this.notebookProviderInfoStore.add(new NotebookProviderInfo({
id: notebookContribution.viewType,
displayName: notebookContribution.displayName,
selector: notebookContribution.selector || [],
providerDisplayName: extension.description.isBuiltin ? nls.localize('builtinProviderDisplayName', "Built-in") : extension.description.displayName || extension.description.identifier.value,
}));
}
}
// console.log(this._notebookProviderInfoStore);
});
notebookRendererExtensionPoint.setHandler((renderers) => {
this.notebookRenderersInfoStore.clear();
for (const extension of renderers) {
for (const notebookContribution of extension.value) {
this.notebookRenderersInfoStore.add(new NotebookOutputRendererInfo({
id: notebookContribution.viewType,
displayName: notebookContribution.displayName,
mimeTypes: notebookContribution.mimeTypes || []
}));
}
}
// console.log(this.notebookRenderersInfoStore);
});
this.editorService.registerCustomEditorViewTypesHandler('Notebook', this);
}
getViewTypes(): ICustomEditorInfo[] {
return [...this.notebookProviderInfoStore].map(info => ({
id: info.id,
displayName: info.displayName,
providerDisplayName: info.providerDisplayName
}));
}
async canResolve(viewType: string): Promise<boolean> {
if (!this._notebookProviders.has(viewType)) {
// this awaits full activation of all matching extensions
await this.extensionService.activateByEvent(`onNotebookEditor:${viewType}`);
}
return this._notebookProviders.has(viewType);
}
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: IMainNotebookController) {
this._notebookProviders.set(viewType, { extensionData, controller });
this._onDidChangeViewTypes.fire();
}
unregisterNotebookProvider(viewType: string): void {
this._notebookProviders.delete(viewType);
this._onDidChangeViewTypes.fire();
}
registerNotebookRenderer(handle: number, extensionData: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, preloads: URI[]) {
this._notebookRenderers.set(handle, { extensionData, type, selectors, preloads });
}
unregisterNotebookRenderer(handle: number) {
this._notebookRenderers.delete(handle);
}
getRendererInfo(handle: number): INotebookRendererInfo | undefined {
const renderer = this._notebookRenderers.get(handle);
if (renderer) {
return {
id: renderer.extensionData.id,
extensionLocation: URI.revive(renderer.extensionData.location),
preloads: renderer.preloads
};
}
return undefined; // {{SQL CARBON EDIT}} strict-null-check
}
async resolveNotebook(viewType: string, uri: URI): Promise<NotebookTextModel | undefined> {
const provider = this._notebookProviders.get(viewType);
if (!provider) {
return undefined;
}
const notebookModel = await provider.controller.resolveNotebook(viewType, uri);
if (!notebookModel) {
return undefined;
}
// new notebook model created
const modelId = MODEL_ID(uri);
const modelData = new ModelData(
notebookModel,
(model) => this._onWillDispose(model),
);
this._models[modelId] = modelData;
return modelData.model;
}
async executeNotebook(viewType: string, uri: URI): Promise<void> {
let provider = this._notebookProviders.get(viewType);
if (provider) {
return provider.controller.executeNotebook(viewType, uri, new CancellationTokenSource().token); // Cancellation for notebooks - TODO
}
return;
}
async executeNotebookCell(viewType: string, uri: URI, handle: number, token: CancellationToken): Promise<void> {
const provider = this._notebookProviders.get(viewType);
if (provider) {
await provider.controller.executeNotebookCell(uri, handle, token);
}
}
getContributedNotebookProviders(resource: URI): readonly NotebookProviderInfo[] {
return this.notebookProviderInfoStore.getContributedNotebook(resource);
}
getContributedNotebookProvider(viewType: string): NotebookProviderInfo | undefined {
return this.notebookProviderInfoStore.get(viewType);
}
getContributedNotebookOutputRenderers(mimeType: string): readonly NotebookOutputRendererInfo[] {
return this.notebookRenderersInfoStore.getContributedRenderer(mimeType);
}
getNotebookProviderResourceRoots(): URI[] {
let ret: URI[] = [];
this._notebookProviders.forEach(val => {
ret.push(URI.revive(val.extensionData.location));
});
return ret;
}
destoryNotebookDocument(viewType: string, notebook: INotebookTextModel): void {
let provider = this._notebookProviders.get(viewType);
if (provider) {
provider.controller.destoryNotebookDocument(notebook);
}
}
updateActiveNotebookDocument(viewType: string, resource: URI): void {
this._onDidChangeActiveEditor.fire({ viewType, uri: resource });
}
setToCopy(items: NotebookCellTextModel[]) {
this.cutItems = items;
}
getToCopy(): NotebookCellTextModel[] | undefined {
return this.cutItems;
}
async save(viewType: string, resource: URI, token: CancellationToken): Promise<boolean> {
let provider = this._notebookProviders.get(viewType);
if (provider) {
return provider.controller.save(resource, token);
}
return false;
}
onDidReceiveMessage(viewType: string, uri: URI, message: any): void {
let provider = this._notebookProviders.get(viewType);
if (provider) {
return provider.controller.onDidReceiveMessage(uri, message);
}
}
private _onWillDispose(model: INotebookTextModel): void {
let modelId = MODEL_ID(model.uri);
let modelData = this._models[modelId];
delete this._models[modelId];
modelData?.dispose();
// this._onModelRemoved.fire(model);
}
}