import { textChanges , SourceFile , Node , startEndOverlapsWithStartEnd , BaseChange } from 'typescript' ; import { lastOrUndefined } from './utils' ; interface ChangesFetchable { readonly changes : BaseChange [ ] ; } export class ProxyChangesTracker implements textChanges . ChangeTracker { private queue : Map < string , BaseChange [ ] > = new Map < string , BaseChange [ ] > ( ) ; private _needAnotherPass : boolean = false ; constructor ( private changeTracker ) { } checkOverlap ( ) { const lastChange = this . getLastChanges ( ) ; if ( lastChange ) { const changes = this . queue . get ( lastChange . sourceFile . path ) || [ ] ; if ( changes . some ( c => startEndOverlapsWithStartEnd ( c . range . pos , c . range . end , lastChange . range . pos , lastChange . range . end ) ) ) { this . popLastChanges ( ) ; this . _needAnotherPass = true ; } else { changes . push ( lastChange ) ; } this . queue . set ( lastChange . sourceFile . path , changes ) ; } } deleteNodeRange ( sourceFile , startNode , endNode , options ? ) { this . changeTracker . deleteNodeRange ( sourceFile , startNode , endNode , options ) ; this . checkOverlap ( ) ; } insertNodeBefore ( sourceFile , before , newNode ) { this . changeTracker . insertNodeBefore ( sourceFile , before , newNode ) ; this . checkOverlap ( ) ; } replaceNode ( sourceFile , oldNode , newNode , options ? ) { this . changeTracker . replaceNode ( sourceFile , oldNode , newNode , options ) ; this . checkOverlap ( ) ; } getLastChanges ( ) { const fetchable = ( this . changeTracker as unknown ) as ChangesFetchable ; return lastOrUndefined ( fetchable . changes ) ; } popLastChanges ( ) { const fetchable = ( this . changeTracker as unknown ) as ChangesFetchable ; return fetchable . changes . pop ( ) ; } needAnotherPass ( ) { return this . _needAnotherPass ; } }