Skip to content

Commit 5c817e7

Browse files
committed
additional edits + comments
1 parent 3a6bfa0 commit 5c817e7

File tree

1 file changed

+41
-19
lines changed

1 file changed

+41
-19
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionResolveHandler.java

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.eclipse.core.runtime.IProgressMonitor;
2525
import org.eclipse.jdt.core.IBuffer;
2626
import org.eclipse.jdt.core.ICompilationUnit;
27-
import org.eclipse.jdt.core.IJavaElement;
2827
import org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore;
2928
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore;
3029
import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroupCore;
@@ -84,18 +83,31 @@ public CodeAction resolve(CodeAction params, IProgressMonitor monitor) {
8483
return params;
8584
}
8685

86+
/***
87+
* Supports linked correction proposals by converting them to snippets.
88+
* Represents a
89+
* {@link org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroupCore}
90+
* with snippet choice syntax if the group has multiple proposals, otherwise
91+
* represents it as a placeholder.
92+
*
93+
* @param proposal
94+
* the proposal to add support for
95+
* @param edit
96+
* the current edit to be returned with the code action
97+
* @throws CoreException
98+
*/
8799
private static final void addSnippetsIfApplicable(LinkedCorrectionProposalCore proposal, WorkspaceEdit edit) throws CoreException {
88-
Object modifiedElement = proposal.getChange().getModifiedElement();
89-
ICompilationUnit compilationUnit = (ICompilationUnit) ((IJavaElement) modifiedElement).getAncestor(IJavaElement.COMPILATION_UNIT);
100+
ICompilationUnit compilationUnit = proposal.getCompilationUnit();
90101
IBuffer buffer = compilationUnit.getBuffer();
91102
LinkedProposalModelCore linkedProposals = proposal.getLinkedProposalModel();
92103
List<Triple> snippets = new ArrayList<>();
93104
Iterator<LinkedProposalPositionGroupCore> it = linkedProposals.getPositionGroupCoreIterator();
94-
int snippetNumber = 1;
105+
95106
while (it.hasNext()) {
96107
LinkedProposalPositionGroupCore group = it.next();
97108
ProposalCore[] proposalList = group.getProposals();
98109
PositionInformation[] positionList = group.getPositions();
110+
// Sorts in ascending order to ensure first position in list has the smallest offset
99111
Arrays.sort(positionList, new Comparator<PositionInformation>() {
100112
@Override
101113
public int compare(PositionInformation p1, PositionInformation p2) {
@@ -104,12 +116,16 @@ public int compare(PositionInformation p1, PositionInformation p2) {
104116
});
105117
StringBuilder snippet = new StringBuilder();
106118
snippet.append(SNIPPET_CHOICE_INDICATOR);
119+
107120
for (int i = 0; i < positionList.length; i++) {
108121
int offset = positionList[i].getOffset();
109122
int length = positionList[i].getLength();
123+
110124
// Create snippet on first iteration
111125
if (i == 0) {
112126
LinkedPosition linkedPosition = new LinkedPosition(JsonRpcHelpers.toDocument(buffer), positionList[i].getOffset(), positionList[i].getLength(), positionList[i].getSequenceRank());
127+
128+
// Groups with no proposals will have the snippet text added while amending the WorkspaceEdit
113129
for (int j = 0; j < proposalList.length; j++) {
114130
org.eclipse.text.edits.TextEdit editWithText = findReplaceOrInsertEdit(proposalList[j].computeEdits(0, linkedPosition, '\u0000', 0, new LinkedModeModel()));
115131
if (editWithText != null) {
@@ -119,39 +135,42 @@ public int compare(PositionInformation p1, PositionInformation p2) {
119135
snippet.append(((ReplaceEdit) editWithText).getText());
120136
}
121137
}
122-
// // If snippet is empty, ignore this group
123-
// if (snippet.toString().equals(String.valueOf(SNIPPET_CHOICE_INDICATOR))) {
124-
// break;
125-
// }
138+
126139
snippet.append(SNIPPET_CHOICE_POSTFIX);
127140
// If snippet only has one choice, remove choice indicators
128141
if (snippet.indexOf(SNIPPET_CHOICE_DELIMITER) == -1) {
129142
snippet.setCharAt(0, ':');
130143
snippet.deleteCharAt(snippet.length() - 2);
131144
}
145+
// Snippet is added with smallest offset as 0th element
132146
snippets.add(new Triple(snippet.toString(), offset, length));
133147
} else {
148+
// Add offset/length values from additional positions in group to previously created snippet
134149
Triple currentSnippet = snippets.get(snippets.size() - 1);
135150
currentSnippet.offset.add(offset);
136151
currentSnippet.length.add(length);
137152
}
138153
}
139154
}
140155
if (!snippets.isEmpty()) {
141-
// 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
156+
// Sort snippets based on offset of earliest occurrence to enable correct numbering
142157
snippets.sort(null);
143-
// ListIterator<Triple> li = snippets.listIterator(snippets.size());
158+
int snippetNumber = 1;
144159
for (int i = snippets.size() - 1; i >= 0; i--) {
145160
Triple element = snippets.get(i);
146161
element.snippet = SNIPPET_PREFIX + snippetNumber + element.snippet;
147162
snippetNumber++;
163+
// Separate snippets with multiple positions into individual instances in list
148164
for (int j = 1; j < element.offset.size(); j++) {
149165
snippets.add(new Triple(element.snippet.toString(), element.offset.get(j), element.length.get(j)));
150166
element.offset.remove(j);
151167
element.length.remove(j);
152168
}
153169
}
170+
// Re-sort snippets (with the added individual instances) by offset in descending order,
171+
// so that the amendments to the text edit are applied in an order that does not alter the offset of later amendments
154172
snippets.sort(null);
173+
155174
for (int i = 0; i < edit.getDocumentChanges().size(); i++) {
156175
if (edit.getDocumentChanges().get(i).isLeft()) {
157176
List<TextEdit> edits = edit.getDocumentChanges().get(i).getLeft().getEdits();
@@ -160,20 +179,22 @@ public int compare(PositionInformation p1, PositionInformation p2) {
160179
StringBuilder replacementText = new StringBuilder(edits.get(j).getNewText());
161180
int rangeStart = JsonRpcHelpers.toOffset(buffer, editRange.getStart().getLine(), editRange.getStart().getCharacter());
162181
int rangeEnd = rangeStart + replacementText.length();
182+
163183
for (int k = 0; k < snippets.size(); k++) {
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));
184+
Triple currentSnippet = snippets.get(k);
185+
if (currentSnippet.offset.get(0) >= rangeStart && currentSnippet.offset.get(0) <= rangeEnd) {
186+
int replaceStart = currentSnippet.offset.get(0) - rangeStart;
187+
int replaceEnd = replaceStart + currentSnippet.length.get(0);
188+
// If snippet text has not been added due to no elements in the proposal list, create snippet based on the text in the given position range
189+
if (currentSnippet.snippet.endsWith(":}")) {
190+
currentSnippet.snippet = currentSnippet.snippet.replaceFirst(":", ":" + replacementText.substring(replaceStart, replaceEnd));
170191
}
171-
replacementText.replace(replaceStart, replaceEnd, snippetHolder.snippet);
192+
replacementText.replace(replaceStart, replaceEnd, currentSnippet.snippet);
172193
}
173194
}
195+
174196
SnippetTextEdit newEdit = new SnippetTextEdit(editRange, replacementText.toString());
175-
edits.remove(j);
176-
edits.add(j, newEdit);
197+
edits.set(j, newEdit);
177198
}
178199
}
179200
}
@@ -208,6 +229,7 @@ private static final class Triple implements Comparable<Triple> {
208229
this.length.add(length);
209230
}
210231

232+
// Sorts in descending order based on 0th (smallest) element of offset list
211233
@Override
212234
public int compareTo(Triple other) {
213235
return other.offset.get(0) - this.offset.get(0);

0 commit comments

Comments
 (0)