@@ -3576,6 +3576,73 @@ export class TestState {
3576
3576
}
3577
3577
}
3578
3578
3579
+ public baselineLinkedEditing ( ) : void {
3580
+ const baselineFile = this . getBaselineFileNameForContainingTestFile ( ".linkedEditing.txt" ) ;
3581
+ const files = this . testData . files ;
3582
+
3583
+ let baselineContent = "" ;
3584
+ let offset = 0 ;
3585
+ for ( const f of files ) {
3586
+ const result = getLinkedEditingBaselineWorker ( f , offset , this . languageService ) ;
3587
+ baselineContent += result . baselineContent + `\n\n\n` ;
3588
+ offset = result . offset ;
3589
+ }
3590
+
3591
+ Harness . Baseline . runBaseline ( baselineFile , baselineContent ) ;
3592
+
3593
+ function getLinkedEditingBaselineWorker ( activeFile : FourSlashFile , offset : number , languageService : ts . LanguageService ) {
3594
+ const fileName = activeFile . fileName ;
3595
+ let baselineContent = `=== ${ fileName } ===\n` ;
3596
+
3597
+ // get linkedEdit at every position in the file, then group positions by their linkedEdit
3598
+ const linkedEditsInFile = new Map < string , number [ ] > ( ) ;
3599
+ for ( let pos = 0 ; pos < activeFile . content . length ; pos ++ ) {
3600
+ const linkedEditAtPosition = languageService . getLinkedEditingRangeAtPosition ( fileName , pos ) ;
3601
+ if ( ! linkedEditAtPosition ) continue ;
3602
+
3603
+ const linkedEditString = JSON . stringify ( linkedEditAtPosition ) ;
3604
+ const existingPositions = linkedEditsInFile . get ( linkedEditString ) ?? [ ] ;
3605
+ linkedEditsInFile . set ( linkedEditString , [ ...existingPositions , pos ] ) ;
3606
+ }
3607
+
3608
+ const linkedEditsByRange = [ ...linkedEditsInFile . entries ( ) ] . sort ( ( a , b ) => a [ 1 ] [ 0 ] - b [ 1 ] [ 0 ] ) ;
3609
+ if ( linkedEditsByRange . length === 0 ) {
3610
+ return { baselineContent : baselineContent + activeFile . content + `\n\n--No linked edits found--` , offset } ;
3611
+ }
3612
+
3613
+ let inlineLinkedEditBaselines : { start : number , end : number , index : number } [ ] = [ ] ;
3614
+ let linkedEditInfoBaseline = "" ;
3615
+ for ( const edit of linkedEditsByRange ) {
3616
+ const [ linkedEdit , positions ] = edit ;
3617
+ let rangeStart = 0 ;
3618
+ for ( let j = 0 ; j < positions . length - 1 ; j ++ ) {
3619
+ // for each distinct range in the list of positions, add an entry to the list of places that need to be annotated in the baseline
3620
+ if ( positions [ j ] + 1 !== positions [ j + 1 ] ) {
3621
+ inlineLinkedEditBaselines . push ( { start : positions [ rangeStart ] , end : positions [ j ] , index : offset } ) ;
3622
+ rangeStart = j + 1 ;
3623
+ }
3624
+ }
3625
+ inlineLinkedEditBaselines . push ( { start : positions [ rangeStart ] , end : positions [ positions . length - 1 ] , index : offset } ) ;
3626
+
3627
+ // add the LinkedEditInfo with its index to the baseline
3628
+ linkedEditInfoBaseline += `\n\n=== ${ offset } ===\n` + linkedEdit ;
3629
+ offset ++ ;
3630
+ }
3631
+
3632
+ inlineLinkedEditBaselines = inlineLinkedEditBaselines . sort ( ( a , b ) => a . start - b . start ) ;
3633
+ const fileText = activeFile . content ;
3634
+ baselineContent += fileText . slice ( 0 , inlineLinkedEditBaselines [ 0 ] . start ) ;
3635
+ for ( let i = 0 ; i < inlineLinkedEditBaselines . length ; i ++ ) {
3636
+ const e = inlineLinkedEditBaselines [ i ] ;
3637
+ const sliceEnd = inlineLinkedEditBaselines [ i + 1 ] ?. start ;
3638
+ baselineContent += `[|/*${ e . index } */` + fileText . slice ( e . start , e . end ) + `|]` + fileText . slice ( e . end , sliceEnd ) ;
3639
+ }
3640
+
3641
+ baselineContent += linkedEditInfoBaseline ;
3642
+ return { baselineContent, offset } ;
3643
+ }
3644
+ }
3645
+
3579
3646
public verifyMatchingBracePosition ( bracePosition : number , expectedMatchPosition : number ) {
3580
3647
const actual = this . languageService . getBraceMatchingAtPosition ( this . activeFile . fileName , bracePosition ) ;
3581
3648
0 commit comments