1414package org .eclipse .jdt .ls .core .internal .handlers ;
1515
1616import java .util .ArrayList ;
17+ import java .util .Arrays ;
18+ import java .util .Comparator ;
1719import java .util .Iterator ;
1820import java .util .List ;
19- import java .util .ListIterator ;
2021import java .util .Map ;
2122
2223import org .eclipse .core .runtime .CoreException ;
@@ -95,48 +96,62 @@ private static final void addSnippetsIfApplicable(LinkedCorrectionProposalCore p
9596 LinkedProposalPositionGroupCore group = it .next ();
9697 ProposalCore [] proposalList = group .getProposals ();
9798 PositionInformation [] positionList = group .getPositions ();
99+ Arrays .sort (positionList , new Comparator <PositionInformation >() {
100+ @ Override
101+ public int compare (PositionInformation p1 , PositionInformation p2 ) {
102+ return p1 .getOffset () - p2 .getOffset ();
103+ }
104+ });
98105 StringBuilder snippet = new StringBuilder ();
99106 snippet .append (SNIPPET_CHOICE_INDICATOR );
100- if (proposalList .length > 0 ) {
101- for (int i = 0 ; i < positionList .length ; i ++) {
102- int offset = positionList [i ].getOffset ();
103- int length = positionList [i ].getLength ();
104- // Create snippet on first iteration
105- if (i == 0 ) {
106- LinkedPosition linkedPosition = new LinkedPosition (JsonRpcHelpers .toDocument (buffer ), positionList [i ].getOffset (), positionList [i ].getLength (), positionList [i ].getSequenceRank ());
107- for (int j = 0 ; j < proposalList .length ; j ++) {
108- org .eclipse .text .edits .TextEdit editWithText = findReplaceOrInsertEdit (proposalList [j ].computeEdits (0 , linkedPosition , '\u0000' , 0 , new LinkedModeModel ()));
109- if (editWithText != null ) {
110- if (snippet .charAt (snippet .length ()-1 ) != SNIPPET_CHOICE_INDICATOR ) {
111- snippet .append (SNIPPET_CHOICE_DELIMITER );
112- }
113- snippet .append (((ReplaceEdit ) editWithText ).getText ());
107+ for (int i = 0 ; i < positionList .length ; i ++) {
108+ int offset = positionList [i ].getOffset ();
109+ int length = positionList [i ].getLength ();
110+ // Create snippet on first iteration
111+ if (i == 0 ) {
112+ LinkedPosition linkedPosition = new LinkedPosition (JsonRpcHelpers .toDocument (buffer ), positionList [i ].getOffset (), positionList [i ].getLength (), positionList [i ].getSequenceRank ());
113+ for (int j = 0 ; j < proposalList .length ; j ++) {
114+ org .eclipse .text .edits .TextEdit editWithText = findReplaceOrInsertEdit (proposalList [j ].computeEdits (0 , linkedPosition , '\u0000' , 0 , new LinkedModeModel ()));
115+ if (editWithText != null ) {
116+ if (snippet .charAt (snippet .length () - 1 ) != SNIPPET_CHOICE_INDICATOR ) {
117+ snippet .append (SNIPPET_CHOICE_DELIMITER );
114118 }
115- }
116- // If snippet is empty, ignore this group
117- if (snippet .toString ().equals (String .valueOf (SNIPPET_CHOICE_INDICATOR ))) {
118- break ;
119- }
120- snippet .append (SNIPPET_CHOICE_POSTFIX );
121- // If snippet only has one choice, remove choice indicators
122- if (snippet .indexOf (SNIPPET_CHOICE_DELIMITER ) == -1 ) {
123- snippet .setCharAt (0 , ':' );
124- snippet .deleteCharAt (snippet .length () - 2 );
119+ snippet .append (((ReplaceEdit ) editWithText ).getText ());
125120 }
126121 }
122+ // // If snippet is empty, ignore this group
123+ // if (snippet.toString().equals(String.valueOf(SNIPPET_CHOICE_INDICATOR))) {
124+ // break;
125+ // }
126+ snippet .append (SNIPPET_CHOICE_POSTFIX );
127+ // If snippet only has one choice, remove choice indicators
128+ if (snippet .indexOf (SNIPPET_CHOICE_DELIMITER ) == -1 ) {
129+ snippet .setCharAt (0 , ':' );
130+ snippet .deleteCharAt (snippet .length () - 2 );
131+ }
127132 snippets .add (new Triple (snippet .toString (), offset , length ));
133+ } else {
134+ Triple currentSnippet = snippets .get (snippets .size () - 1 );
135+ currentSnippet .offset .add (offset );
136+ currentSnippet .length .add (length );
128137 }
129138 }
130139 }
131140 if (!snippets .isEmpty ()) {
132141 // Sort snippets in descending order based on offset, so that the edits are applied in an order that does not alter the offset of later edits
133142 snippets .sort (null );
134- ListIterator <Triple > li = snippets .listIterator (snippets .size ());
135- while ( li . hasPrevious () ) {
136- Triple element = li . previous ( );
143+ // ListIterator<Triple> li = snippets.listIterator(snippets.size());
144+ for ( int i = snippets . size () - 1 ; i >= 0 ; i -- ) {
145+ Triple element = snippets . get ( i );
137146 element .snippet = SNIPPET_PREFIX + snippetNumber + element .snippet ;
138147 snippetNumber ++;
148+ for (int j = 1 ; j < element .offset .size (); j ++) {
149+ snippets .add (new Triple (element .snippet .toString (), element .offset .get (j ), element .length .get (j )));
150+ element .offset .remove (j );
151+ element .length .remove (j );
152+ }
139153 }
154+ snippets .sort (null );
140155 for (int i = 0 ; i < edit .getDocumentChanges ().size (); i ++) {
141156 if (edit .getDocumentChanges ().get (i ).isLeft ()) {
142157 List <TextEdit > edits = edit .getDocumentChanges ().get (i ).getLeft ().getEdits ();
@@ -146,10 +161,14 @@ private static final void addSnippetsIfApplicable(LinkedCorrectionProposalCore p
146161 int rangeStart = JsonRpcHelpers .toOffset (buffer , editRange .getStart ().getLine (), editRange .getStart ().getCharacter ());
147162 int rangeEnd = rangeStart + replacementText .length ();
148163 for (int k = 0 ; k < snippets .size (); k ++) {
149- if (snippets .get (k ).offset >= rangeStart && snippets .get (k ).offset <= rangeEnd ) {
150- int replaceStart = snippets .get (k ).offset - rangeStart ;
151- int replaceEnd = replaceStart + snippets .get (k ).length ;
152- replacementText .replace (replaceStart , replaceEnd , snippets .get (k ).snippet );
164+ Triple snippetHolder = snippets .get (k );
165+ if (snippetHolder .offset .get (0 ) >= rangeStart && snippetHolder .offset .get (0 ) <= rangeEnd ) {
166+ int replaceStart = snippetHolder .offset .get (0 ) - rangeStart ;
167+ int replaceEnd = replaceStart + snippetHolder .length .get (0 );
168+ if (snippetHolder .snippet .endsWith (":}" )) {
169+ snippetHolder .snippet = snippetHolder .snippet .replaceFirst (":" , ":" + replacementText .substring (replaceStart , replaceEnd ));
170+ }
171+ replacementText .replace (replaceStart , replaceEnd , snippetHolder .snippet );
153172 }
154173 }
155174 SnippetTextEdit newEdit = new SnippetTextEdit (editRange , replacementText .toString ());
@@ -180,18 +199,18 @@ private static final org.eclipse.text.edits.TextEdit findReplaceOrInsertEdit(org
180199
181200 private static final class Triple implements Comparable <Triple > {
182201 public String snippet ;
183- public int offset ;
184- public int length ;
202+ public List < Integer > offset = new ArrayList <>() ;
203+ public List < Integer > length = new ArrayList <>() ;
185204
186205 Triple (String snippet , int offset , int length ) {
187206 this .snippet = snippet ;
188- this .offset = offset ;
189- this .length = length ;
207+ this .offset . add ( offset ) ;
208+ this .length . add ( length ) ;
190209 }
191210
192211 @ Override
193212 public int compareTo (Triple other ) {
194- return other .offset - this .offset ;
213+ return other .offset . get ( 0 ) - this .offset . get ( 0 ) ;
195214 }
196215 }
197216}
0 commit comments