Path: blob/main/src/vs/workbench/contrib/editTelemetry/browser/helpers/annotatedDocuments.ts
5250 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../../../../base/common/lifecycle.js';6import { IObservable, mapObservableArrayCached, derived, derivedObservableWithCache, observableFromEvent, observableSignalFromEvent, IReader } from '../../../../../base/common/observable.js';7import { isDefined } from '../../../../../base/common/types.js';8import { URI } from '../../../../../base/common/uri.js';9import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';10import { EditorResourceAccessor } from '../../../../common/editor.js';11import { IEditorGroupsService } from '../../../../services/editor/common/editorGroupsService.js';12import { IDocumentWithAnnotatedEdits, EditSourceData, DocumentWithSourceAnnotatedEdits, CombineStreamedChanges, MinimizeEditsProcessor } from './documentWithAnnotatedEdits.js';13import { ObservableWorkspace, IObservableDocument } from './observableWorkspace.js';1415export interface IAnnotatedDocuments {16readonly documents: IObservable<readonly AnnotatedDocument[]>;17}1819export class AnnotatedDocuments extends Disposable implements IAnnotatedDocuments {20public readonly documents: IObservable<readonly AnnotatedDocument[]>;21private readonly _states;2223constructor(24private readonly _workspace: ObservableWorkspace,25@IInstantiationService private readonly _instantiationService: IInstantiationService26) {27super();2829const uriVisibilityProvider = this._instantiationService.createInstance(UriVisibilityProvider);3031this._states = mapObservableArrayCached(this, this._workspace.documents, (doc, store) => {32const docIsVisible = derived(reader => uriVisibilityProvider.isVisible(doc.uri, reader));33const wasEverVisible = derivedObservableWithCache<boolean>(this, (reader, lastVal) => lastVal || docIsVisible.read(reader));34return wasEverVisible.map(v => v ? store.add(this._instantiationService.createInstance(AnnotatedDocument, doc, docIsVisible)) : undefined);35});3637this.documents = this._states.map((vals, reader) => vals.map(v => v.read(reader)).filter(isDefined));3839this.documents.recomputeInitiallyAndOnChange(this._store);40}41}4243export class UriVisibilityProvider {44private readonly visibleUris: IObservable<Map<string, URI>>;4546constructor(47@IEditorGroupsService private readonly _editorGroupsService: IEditorGroupsService48) {49const onDidAddGroupSignal = observableSignalFromEvent(this, this._editorGroupsService.onDidAddGroup);50const onDidRemoveGroupSignal = observableSignalFromEvent(this, this._editorGroupsService.onDidRemoveGroup);51const groups = derived(this, reader => {52onDidAddGroupSignal.read(reader);53onDidRemoveGroupSignal.read(reader);54return this._editorGroupsService.groups;55});5657this.visibleUris = mapObservableArrayCached(this, groups, g => {58const editors = observableFromEvent(this, g.onDidModelChange, () => g.editors);59return editors.map(e => e.map(editor => EditorResourceAccessor.getCanonicalUri(editor)));60}).map((editors, reader) => {61const map = new Map<string, URI>();62for (const urisObs of editors) {63for (const uri of urisObs.read(reader)) {64if (isDefined(uri)) {65map.set(uri.toString(), uri);66}67}68}69return map;70});71}7273public isVisible(uri: URI, reader: IReader): boolean {74return this.visibleUris.read(reader).has(uri.toString());75}76}7778export class AnnotatedDocument extends Disposable {79public readonly documentWithAnnotations;8081constructor(82public readonly document: IObservableDocument,83public readonly isVisible: IObservable<boolean>,84@IInstantiationService private readonly _instantiationService: IInstantiationService85) {86super();8788let processedDoc: IDocumentWithAnnotatedEdits<EditSourceData> = this._store.add(new DocumentWithSourceAnnotatedEdits(document));89// Combine streaming edits into one and make edit smaller90processedDoc = this._store.add(this._instantiationService.createInstance((CombineStreamedChanges<EditSourceData>), processedDoc));91// Remove common suffix and prefix from edits92processedDoc = this._store.add(new MinimizeEditsProcessor(processedDoc));9394this.documentWithAnnotations = processedDoc;95}96}979899