33// See the LICENSE file in the project root for more information.
44
55using System ;
6- using System . Collections . Immutable ;
76using System . Composition ;
87using System . Linq ;
98using System . Threading ;
@@ -38,7 +37,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(DidChangeTextDocumentPar
3837 return SpecializedTasks . Default < object > ( ) ;
3938 }
4039
41- internal static bool AreChangesInReverseOrder ( ImmutableArray < TextDocumentContentChangeEvent > contentChanges )
40+ internal static bool AreChangesInReverseOrder ( TextDocumentContentChangeEvent [ ] contentChanges )
4241 {
4342 for ( var i = 1 ; i < contentChanges . Length ; i ++ )
4443 {
@@ -54,14 +53,8 @@ internal static bool AreChangesInReverseOrder(ImmutableArray<TextDocumentContent
5453 return true ;
5554 }
5655
57- private static SourceText GetUpdatedSourceText ( SumType < TextDocumentContentChangeEvent , TextDocumentContentChangeFullReplacementEvent > [ ] contentChanges , SourceText text )
56+ private static SourceText GetUpdatedSourceText ( TextDocumentContentChangeEvent [ ] contentChanges , SourceText text )
5857 {
59- ( var remainingContentChanges , text ) = GetUpdatedSourceTextAndChangesAfterFullTextReplacementHandled ( contentChanges , text ) ;
60-
61- // No range-based changes to apply.
62- if ( remainingContentChanges . IsEmpty )
63- return text ;
64-
6558 // Per the LSP spec, each text change builds upon the previous, so we don't need to translate any text
6659 // positions between changes. See
6760 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#didChangeTextDocumentParams
@@ -70,41 +63,20 @@ private static SourceText GetUpdatedSourceText(SumType<TextDocumentContentChange
7063 // If the host sends us changes in a way such that no earlier change can affect the position of a later change,
7164 // then we can merge the changes into a single TextChange, allowing creation of only a single new
7265 // source text.
73- if ( AreChangesInReverseOrder ( remainingContentChanges ) )
66+ if ( AreChangesInReverseOrder ( contentChanges ) )
7467 {
7568 // The changes were in reverse document order, so we can merge them into a single operation on the source text.
7669 // Note that the WithChanges implementation works more efficiently with it's input in forward document order.
77- var newChanges = remainingContentChanges . Reverse ( ) . SelectAsArray ( change => ProtocolConversions . ContentChangeEventToTextChange ( change , text ) ) ;
70+ var newChanges = contentChanges . Reverse ( ) . SelectAsArray ( change => ProtocolConversions . ContentChangeEventToTextChange ( change , text ) ) ;
7871 text = text . WithChanges ( newChanges ) ;
7972 }
8073 else
8174 {
8275 // The host didn't send us the items ordered, so we'll apply each one independently.
83- foreach ( var change in remainingContentChanges )
76+ foreach ( var change in contentChanges )
8477 text = text . WithChanges ( ProtocolConversions . ContentChangeEventToTextChange ( change , text ) ) ;
8578 }
8679
8780 return text ;
8881 }
89-
90- private static ( ImmutableArray < TextDocumentContentChangeEvent > , SourceText ) GetUpdatedSourceTextAndChangesAfterFullTextReplacementHandled ( SumType < TextDocumentContentChangeEvent , TextDocumentContentChangeFullReplacementEvent > [ ] contentChanges , SourceText text )
91- {
92- // Per the LSP spec, each content change can be either a TextDocumentContentChangeEvent or TextDocumentContentChangeFullReplacementEvent.
93- // The former is a range-based change while the latter is a full text replacement. If a TextDocumentContentChangeFullReplacementEvent is found,
94- // then make a full text replacement for that and return all subsequent changes as remaining range-based changes.
95- var lastFullTextChangeEventIndex = contentChanges . Length - 1 ;
96- for ( ; lastFullTextChangeEventIndex >= 0 ; lastFullTextChangeEventIndex -- )
97- {
98- var change = contentChanges [ lastFullTextChangeEventIndex ] ;
99- if ( change . Value is TextDocumentContentChangeFullReplacementEvent onlyTextEvent )
100- {
101- // Found a full text replacement. Create the new text and stop processing.
102- text = text . WithChanges ( [ new TextChange ( new TextSpan ( 0 , text . Length ) , onlyTextEvent . Text ) ] ) ;
103- break ;
104- }
105- }
106-
107- var remainingContentChanges = contentChanges . Skip ( lastFullTextChangeEventIndex + 1 ) . SelectAsArray ( c => c . First ) ;
108- return ( remainingContentChanges , text ) ;
109- }
11082}
0 commit comments