import * as vscode from 'vscode' ; import { MergeConflictParser } from './mergeConflictParser' ; import * as interfaces from './interfaces' ; import { Delayer } from './delayer' ; class ScanTask { public origins : Set < string > = new Set < string > ( ) ; public delayTask : Delayer < interfaces . IDocumentMergeConflict [ ] > ; constructor ( delayTime , initialOrigin ) { this . origins . add ( initialOrigin ) ; this . delayTask = new Delayer < interfaces . IDocumentMergeConflict [ ] > ( delayTime ) ; } public addOrigin ( name ) { if ( this . origins . has ( name ) ) { return false ; } return false ; } public hasOrigin ( name ) { return this . origins . has ( name ) ; } } class OriginDocumentMergeConflictTracker implements interfaces . IDocumentMergeConflictTracker { constructor ( private parent , private origin ) { } getConflicts ( document ) { return this . parent . getConflicts ( document , this . origin ) ; } isPending ( document ) { return this . parent . isPending ( document , this . origin ) ; } forget ( document ) { this . parent . forget ( document ) ; } } export default class DocumentMergeConflictTracker implements vscode . Disposable , interfaces . IDocumentMergeConflictTrackerService { private cache : Map < string , ScanTask > = new Map ( ) ; private delayExpireTime : number = 0 ; getConflicts ( document , origin ) { let key = this . getCacheKey ( document ) ; if ( ! key ) { return Promise . resolve ( this . getConflictsOrEmpty ( document , [ origin ] ) ) ; } let cacheItem = this . cache . get ( key ) ; if ( ! cacheItem ) { cacheItem = new ScanTask ( this . delayExpireTime , origin ) ; this . cache . set ( key , cacheItem ) ; } else { cacheItem . addOrigin ( origin ) ; } return cacheItem . delayTask . trigger ( ( ) => { let conflicts = this . getConflictsOrEmpty ( document , Array . from ( cacheItem ! . origins ) ) ; if ( this . cache ) { this . cache . delete ( key ! ) ; } return conflicts ; } ) ; } isPending ( document , origin ) { if ( ! document ) { return false ; } let key = this . getCacheKey ( document ) ; if ( ! key ) { return false ; } const task = this . cache . get ( key ) ; if ( ! task ) { return false ; } return task . hasOrigin ( origin ) ; } createTracker ( origin ) { return new OriginDocumentMergeConflictTracker ( this , origin ) ; } forget ( document ) { let key = this . getCacheKey ( document ) ; if ( key ) { this . cache . delete ( key ) ; } } dispose ( ) { this . cache . clear ( ) ; } private getConflictsOrEmpty ( document , _origins ) { const containsConflict = MergeConflictParser . containsConflict ( document ) ; if ( ! containsConflict ) { return [ ] ; } const conflicts = MergeConflictParser . scanDocument ( document ) ; return conflicts ; } private getCacheKey ( document ) { if ( document . uri ) { return document . uri . toString ( ) ; } return null ; } }