mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 05:19:39 +00:00
Change document tracker to be opted out of per callee origin.
This commit is contained in:
parent
aba193c3a4
commit
537deb5209
|
@ -9,11 +9,12 @@ import { loadMessageBundle } from 'vscode-nls';
|
|||
const localize = loadMessageBundle();
|
||||
|
||||
export default class MergeConflictCodeLensProvider implements vscode.CodeLensProvider, vscode.Disposable {
|
||||
|
||||
private codeLensRegistrationHandle: vscode.Disposable | null;
|
||||
private config: interfaces.IExtensionConfiguration;
|
||||
private tracker: interfaces.IDocumentMergeConflictTracker;
|
||||
|
||||
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
|
||||
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
|
||||
this.tracker = trackerService.createTracker('codelens');
|
||||
}
|
||||
|
||||
begin(config: interfaces.IExtensionConfiguration) {
|
||||
|
|
|
@ -29,8 +29,10 @@ enum NavigationDirection {
|
|||
export default class CommandHandler implements vscode.Disposable {
|
||||
|
||||
private disposables: vscode.Disposable[] = [];
|
||||
private tracker: interfaces.IDocumentMergeConflictTracker;
|
||||
|
||||
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
|
||||
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
|
||||
this.tracker = trackerService.createTracker('commands');
|
||||
}
|
||||
|
||||
begin() {
|
||||
|
|
|
@ -8,29 +8,70 @@ import { MergeConflictParser } from './mergeConflictParser';
|
|||
import * as interfaces from './interfaces';
|
||||
import { Delayer } from './delayer';
|
||||
|
||||
export default class DocumentMergeConflictTracker implements vscode.Disposable, interfaces.IDocumentMergeConflictTracker {
|
||||
class ScanTask {
|
||||
public origins: Set<string> = new Set<string>();
|
||||
public delayTask: Delayer<interfaces.IDocumentMergeConflict[]>;
|
||||
|
||||
private cache: Map<string, Delayer<interfaces.IDocumentMergeConflict[]>> = new Map();
|
||||
private delayExpireTime: number = 150;
|
||||
constructor(delayTime: number, initialOrigin: string) {
|
||||
this.origins.add(initialOrigin);
|
||||
this.delayTask = new Delayer<interfaces.IDocumentMergeConflict[]>(delayTime);
|
||||
}
|
||||
|
||||
public addOrigin(name: string): boolean {
|
||||
if (this.origins.has(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public hasOrigin(name: string): boolean {
|
||||
return this.origins.has(name);
|
||||
}
|
||||
}
|
||||
|
||||
class OriginDocumentMergeConflictTracker implements interfaces.IDocumentMergeConflictTracker {
|
||||
constructor(private parent: DocumentMergeConflictTracker, private origin: string) {
|
||||
}
|
||||
|
||||
getConflicts(document: vscode.TextDocument): PromiseLike<interfaces.IDocumentMergeConflict[]> {
|
||||
return this.parent.getConflicts(document, this.origin);
|
||||
}
|
||||
|
||||
isPending(document: vscode.TextDocument): boolean {
|
||||
return this.parent.isPending(document, this.origin);
|
||||
}
|
||||
|
||||
forget(document: vscode.TextDocument) {
|
||||
this.parent.forget(document);
|
||||
}
|
||||
}
|
||||
|
||||
export default class DocumentMergeConflictTracker implements vscode.Disposable, interfaces.IDocumentMergeConflictTrackerService {
|
||||
private cache: Map<string, ScanTask> = new Map();
|
||||
private delayExpireTime: number = 300;
|
||||
|
||||
getConflicts(document: vscode.TextDocument, origin: string): PromiseLike<interfaces.IDocumentMergeConflict[]> {
|
||||
// Attempt from cache
|
||||
|
||||
let key = this.getCacheKey(document);
|
||||
|
||||
if (!key) {
|
||||
// Document doesnt have a uri, can't cache it, so return
|
||||
return Promise.resolve(this.getConflictsOrEmpty(document));
|
||||
return Promise.resolve(this.getConflictsOrEmpty(document, [origin]));
|
||||
}
|
||||
|
||||
let cacheItem = this.cache.get(key);
|
||||
if (!cacheItem) {
|
||||
cacheItem = new Delayer<interfaces.IDocumentMergeConflict[]>(this.delayExpireTime);
|
||||
cacheItem = new ScanTask(this.delayExpireTime, origin);
|
||||
this.cache.set(key, cacheItem);
|
||||
}
|
||||
else {
|
||||
cacheItem.addOrigin(origin);
|
||||
}
|
||||
|
||||
return cacheItem.trigger(() => {
|
||||
let conflicts = this.getConflictsOrEmpty(document);
|
||||
return cacheItem.delayTask.trigger(() => {
|
||||
let conflicts = this.getConflictsOrEmpty(document, Array.from(cacheItem!.origins));
|
||||
|
||||
if (this.cache) {
|
||||
this.cache.delete(key!);
|
||||
|
@ -40,6 +81,29 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
|||
});
|
||||
}
|
||||
|
||||
isPending(document: vscode.TextDocument, origin: string): boolean {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let key = this.getCacheKey(document);
|
||||
if (!key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var task = this.cache.get(key);
|
||||
|
||||
if (!task) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return task.hasOrigin(origin);
|
||||
}
|
||||
|
||||
createTracker(origin: string): interfaces.IDocumentMergeConflictTracker {
|
||||
return new OriginDocumentMergeConflictTracker(this, origin);
|
||||
}
|
||||
|
||||
forget(document: vscode.TextDocument) {
|
||||
let key = this.getCacheKey(document);
|
||||
|
||||
|
@ -52,12 +116,12 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
|||
this.cache.clear();
|
||||
}
|
||||
|
||||
private getConflictsOrEmpty(document: vscode.TextDocument): interfaces.IDocumentMergeConflict[] {
|
||||
private getConflictsOrEmpty(document: vscode.TextDocument, origins: string[]): interfaces.IDocumentMergeConflict[] {
|
||||
let stepStart = process.hrtime();
|
||||
const containsConflict = MergeConflictParser.containsConflict(document);
|
||||
let stepEnd = process.hrtime(stepStart);
|
||||
|
||||
console.info('%s -> Check document execution time: %dms', document.uri.toString(), stepEnd[1] / 1000000);
|
||||
console.info('[%s] %s -> Check document execution time: %dms', origins.join(', '), document.uri.toString(), stepEnd[1] / 1000000);
|
||||
|
||||
if (!containsConflict) {
|
||||
return [];
|
||||
|
@ -67,7 +131,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
|||
const conflicts = MergeConflictParser.scanDocument(document);
|
||||
stepEnd = process.hrtime(stepStart);
|
||||
|
||||
console.info('%s -> Find conflict regions execution time: %dms', document.uri.toString(), stepEnd[1] / 1000000);
|
||||
console.info('[%s] %s -> Find conflict regions execution time: %dms', origins.join(', '), document.uri.toString(), stepEnd[1] / 1000000);
|
||||
|
||||
return conflicts;
|
||||
}
|
||||
|
@ -79,4 +143,5 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
|||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,5 +37,11 @@ export interface IDocumentMergeConflictDescriptor {
|
|||
|
||||
export interface IDocumentMergeConflictTracker {
|
||||
getConflicts(document: vscode.TextDocument): PromiseLike<IDocumentMergeConflict[]>;
|
||||
isPending(document: vscode.TextDocument): boolean;
|
||||
forget(document: vscode.TextDocument);
|
||||
}
|
||||
|
||||
export interface IDocumentMergeConflictTrackerService {
|
||||
createTracker(origin: string): IDocumentMergeConflictTracker;
|
||||
forget(document: vscode.TextDocument);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ export default class MergeDectorator implements vscode.Disposable {
|
|||
private currentColorRgb = `32,200,94`;
|
||||
private incomingColorRgb = `24,134,255`;
|
||||
private config: interfaces.IExtensionConfiguration;
|
||||
private tracker: interfaces.IDocumentMergeConflictTracker;
|
||||
|
||||
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
|
||||
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
|
||||
this.tracker = trackerService.createTracker('decorator');
|
||||
}
|
||||
|
||||
begin(config: interfaces.IExtensionConfiguration) {
|
||||
|
@ -149,10 +151,14 @@ export default class MergeDectorator implements vscode.Disposable {
|
|||
return;
|
||||
}
|
||||
|
||||
// If we have a pending scan from the same origin, exit early.
|
||||
if (this.tracker.isPending(editor.document)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let conflicts = await this.tracker.getConflicts(editor.document);
|
||||
|
||||
if (conflicts.length === 0) {
|
||||
// TODO: Remove decorations
|
||||
this.removeDecorations(editor);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue