Skip to content

Commit

Permalink
#78477 Update markers of resource when updated
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Sep 2, 2019
1 parent e4b2df1 commit b8d5f4c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 70 deletions.
19 changes: 10 additions & 9 deletions src/vs/workbench/contrib/markers/browser/markers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import Constants from './constants';
import { URI } from 'vs/base/common/uri';
import { groupBy } from 'vs/base/common/arrays';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { Event } from 'vs/base/common/event';
import { ResourceMap } from 'vs/base/common/map';

export const IMarkersWorkbenchService = createDecorator<IMarkersWorkbenchService>('markersWorkbenchService');

Expand All @@ -38,17 +40,16 @@ export class MarkersWorkbenchService extends Disposable implements IMarkersWorkb
super();
this.markersModel = this._register(instantiationService.createInstance(MarkersModel, this.readMarkers()));

for (const group of groupBy(this.readMarkers(), compareMarkersByUri)) {
this.markersModel.setResourceMarkers(group[0].resource, group);
}

this._register(markerService.onMarkerChanged(resources => this.onMarkerChanged(resources)));
this.markersModel.setResourceMarkers(groupBy(this.readMarkers(), compareMarkersByUri).map(group => [group[0].resource, group]));
this._register(Event.debounce<URI[], ResourceMap<URI>>(markerService.onMarkerChanged, (resourcesMap, resources) => {
resourcesMap = resourcesMap ? resourcesMap : new ResourceMap<URI>();
resources.forEach(resource => resourcesMap!.set(resource, resource));
return resourcesMap;
}, 0)(resourcesMap => this.onMarkerChanged(resourcesMap.values())));
}

private onMarkerChanged(resources: URI[]): void {
for (const resource of resources) {
this.markersModel.setResourceMarkers(resource, this.readMarkers(resource));
}
this.markersModel.setResourceMarkers(resources.map(resource => [resource, this.readMarkers(resource)]));
}

private readMarkers(resource?: URI): IMarker[] {
Expand Down Expand Up @@ -76,4 +77,4 @@ export class ActivityUpdater extends Disposable implements IWorkbenchContributio
const message = localize('totalProblems', 'Total {0} Problems', total);
this.activity.value = this.activityService.showActivity(Constants.MARKERS_PANEL_ID, new NumberBadge(total, () => message));
}
}
}
73 changes: 47 additions & 26 deletions src/vs/workbench/contrib/markers/browser/markersModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class ResourceMarkers {
@memoize
get name(): string { return basename(this.resource); }

constructor(readonly id: string, readonly resource: URI, readonly markers: Marker[]) { }
constructor(readonly id: string, readonly resource: URI, public markers: Marker[]) { }
}

export class Marker {
Expand Down Expand Up @@ -90,12 +90,18 @@ export class RelatedInformation {
) { }
}

export interface MarkerChangesEvent {
readonly added: ResourceMarkers[];
readonly removed: ResourceMarkers[];
readonly updated: ResourceMarkers[];
}

export class MarkersModel {

private cachedSortedResources: ResourceMarkers[] | undefined = undefined;

private readonly _onDidChange = new Emitter<URI>();
readonly onDidChange: Event<URI> = this._onDidChange.event;
private readonly _onDidChange = new Emitter<MarkerChangesEvent>();
readonly onDidChange: Event<MarkerChangesEvent> = this._onDidChange.event;

get resourceMarkers(): ResourceMarkers[] {
if (!this.cachedSortedResources) {
Expand All @@ -115,33 +121,48 @@ export class MarkersModel {
return withUndefinedAsNull(this.resourcesByUri.get(resource.toString()));
}

setResourceMarkers(resource: URI, rawMarkers: IMarker[]): void {
if (isFalsyOrEmpty(rawMarkers)) {
this.resourcesByUri.delete(resource.toString());
} else {

const resourceMarkersId = this.id(resource.toString());
const markersCountByKey = new Map<string, number>();
const markers = mergeSort(rawMarkers.map((rawMarker) => {
const key = IMarkerData.makeKey(rawMarker);
const index = markersCountByKey.get(key) || 0;
markersCountByKey.set(key, index + 1);

const markerId = this.id(resourceMarkersId, key, index);

let relatedInformation: RelatedInformation[] | undefined = undefined;
if (rawMarker.relatedInformation) {
relatedInformation = rawMarker.relatedInformation.map((r, index) => new RelatedInformation(this.id(markerId, r.resource.toString(), r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn, index), rawMarker, r));
setResourceMarkers(resourcesMarkers: [URI, IMarker[]][]): void {
const change: MarkerChangesEvent = { added: [], removed: [], updated: [] };
for (const [resource, rawMarkers] of resourcesMarkers) {
let resourceMarkers = this.resourcesByUri.get(resource.toString());
if (isFalsyOrEmpty(rawMarkers)) {
if (resourceMarkers) {
this.resourcesByUri.delete(resource.toString());
change.removed.push(resourceMarkers);
}

return new Marker(markerId, rawMarker, relatedInformation);
}), compareMarkers);

this.resourcesByUri.set(resource.toString(), new ResourceMarkers(resourceMarkersId, resource, markers));
} else {
const resourceMarkersId = this.id(resource.toString());
const markersCountByKey = new Map<string, number>();
const markers = mergeSort(rawMarkers.map((rawMarker) => {
const key = IMarkerData.makeKey(rawMarker);
const index = markersCountByKey.get(key) || 0;
markersCountByKey.set(key, index + 1);

const markerId = this.id(resourceMarkersId, key, index);

let relatedInformation: RelatedInformation[] | undefined = undefined;
if (rawMarker.relatedInformation) {
relatedInformation = rawMarker.relatedInformation.map((r, index) => new RelatedInformation(this.id(markerId, r.resource.toString(), r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn, index), rawMarker, r));
}

return new Marker(markerId, rawMarker, relatedInformation);
}), compareMarkers);

if (resourceMarkers) {
resourceMarkers.markers = markers;
change.updated.push(resourceMarkers);
} else {
resourceMarkers = new ResourceMarkers(resourceMarkersId, resource, markers);
change.added.push(resourceMarkers);
}
this.resourcesByUri.set(resource.toString(), resourceMarkers);
}
}

this.cachedSortedResources = undefined;
this._onDidChange.fire(resource);
if (change.added.length || change.removed.length || change.updated.length) {
this._onDidChange.fire(change);
}
}

private id(...values: (string | number)[]): string {
Expand Down
69 changes: 35 additions & 34 deletions src/vs/workbench/contrib/markers/browser/markersPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Panel } from 'vs/workbench/browser/panel';
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { Marker, ResourceMarkers, RelatedInformation, MarkersModel } from 'vs/workbench/contrib/markers/browser/markersModel';
import { Marker, ResourceMarkers, RelatedInformation, MarkersModel, MarkerChangesEvent } from 'vs/workbench/contrib/markers/browser/markersModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { MarkersFilterActionViewItem, MarkersFilterAction, IMarkersFilterActionChangeEvent, IMarkerFilterController } from 'vs/workbench/contrib/markers/browser/markersPanelActions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
Expand Down Expand Up @@ -49,18 +49,19 @@ import { MementoObject } from 'vs/workbench/common/memento';
function createModelIterator(model: MarkersModel): Iterator<ITreeElement<TreeElement>> {
const resourcesIt = Iterator.fromArray(model.resourceMarkers);

return Iterator.map(resourcesIt, m => {
const markersIt = Iterator.fromArray(m.markers);
return Iterator.map(resourcesIt, m => ({ element: m, children: createResourceMarkersIterator(m) }));
}

const children = Iterator.map(markersIt, m => {
const relatedInformationIt = Iterator.from(m.relatedInformation);
const children = Iterator.map(relatedInformationIt, r => ({ element: r }));
function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterator<ITreeElement<TreeElement>> {
const markersIt = Iterator.fromArray(resourceMarkers.markers);

return { element: m, children };
});
return Iterator.map(markersIt, m => {
const relatedInformationIt = Iterator.from(m.relatedInformation);
const children = Iterator.map(relatedInformationIt, r => ({ element: r }));

return { element: m, children };
});

}

export class MarkersPanel extends Panel implements IMarkerFilterController {
Expand Down Expand Up @@ -229,13 +230,26 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
return false;
}

private refreshPanel(marker?: Marker): void {
private refreshPanel(markerOrChange?: Marker | MarkerChangesEvent): void {
if (this.isVisible()) {
this.cachedFilterStats = undefined;

if (marker) {
this.tree.rerender(marker);
if (markerOrChange) {
if (markerOrChange instanceof Marker) {
this.tree.rerender(markerOrChange);
} else {
if (markerOrChange.added.length || markerOrChange.removed.length) {
// Reset complete tree
this.tree.setChildren(null, createModelIterator(this.markersWorkbenchService.markersModel));
} else {
// Update resource
for (const updated of markerOrChange.updated) {
this.tree.setChildren(updated, createResourceMarkersIterator(updated));
}
}
}
} else {
// Reset complete tree
this.tree.setChildren(null, createModelIterator(this.markersWorkbenchService.markersModel));
}

Expand Down Expand Up @@ -396,29 +410,13 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
}

private createListeners(): void {
const onModelOrActiveEditorChanged = Event.debounce<URI | true, { resources: URI[], activeEditorChanged: boolean }>(Event.any<any>(this.markersWorkbenchService.markersModel.onDidChange, Event.map(this.editorService.onDidActiveEditorChange, () => true)), (result, e) => {
if (!result) {
result = {
resources: [],
activeEditorChanged: false
};
}
if (e === true) {
result.activeEditorChanged = true;
this._register(Event.any<MarkerChangesEvent | void>(this.markersWorkbenchService.markersModel.onDidChange, this.editorService.onDidActiveEditorChange)(changes => {
if (changes) {
this.onDidChangeModel(changes);
} else {
result.resources.push(e);
}
return result;
}, 0);

this._register(onModelOrActiveEditorChanged(({ resources, activeEditorChanged }) => {
if (resources) {
this.onDidChangeModel(resources);
}
if (activeEditorChanged) {
this.onActiveEditorChanged();
}
}, this));
}));
this._register(this.tree.onDidChangeSelection(() => this.onSelected()));
this._register(this.filterAction.onDidChange((event: IMarkersFilterActionChangeEvent) => {
if (event.filterText || event.useFilesExclude) {
Expand All @@ -428,18 +426,21 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
this.actions.forEach(a => this._register(a));
}

private onDidChangeModel(resources: URI[]) {
for (const resource of resources) {
private onDidChangeModel(change: MarkerChangesEvent) {
const resourceMarkers = [...change.added, ...change.removed, ...change.updated];
const resources: URI[] = [];
for (const { resource } of resourceMarkers) {
this.markersViewModel.remove(resource);
const resourceMarkers = this.markersWorkbenchService.markersModel.getResourceMarkers(resource);
if (resourceMarkers) {
for (const marker of resourceMarkers.markers) {
this.markersViewModel.add(marker);
}
}
resources.push(resource);
}
this.currentResourceGotAddedToMarkersData = this.currentResourceGotAddedToMarkersData || this.isCurrentResourceGotAddedToMarkersData(resources);
this.refreshPanel();
this.refreshPanel(change);
this.updateRangeHighlights();
if (this.currentResourceGotAddedToMarkersData) {
this.autoReveal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TestMarkersModel extends MarkersModel {
const markers = byResource[key];
const resource = markers[0].resource;

this.setResourceMarkers(resource, markers);
this.setResourceMarkers([[resource, markers]]);
});
}
}
Expand Down

0 comments on commit b8d5f4c

Please sign in to comment.