Lines 30-394
Link Here
|
30 |
*/ |
30 |
*/ |
31 |
package org.netbeans.modules.java.hints; |
31 |
package org.netbeans.modules.java.hints; |
32 |
|
32 |
|
33 |
import org.netbeans.modules.java.hints.spi.support.FixFactory; |
|
|
34 |
import com.sun.source.tree.IfTree; |
33 |
import com.sun.source.tree.IfTree; |
35 |
import com.sun.source.tree.Tree; |
34 |
import com.sun.source.tree.Tree; |
36 |
import com.sun.source.tree.Tree.Kind; |
35 |
import com.sun.source.tree.Tree.Kind; |
37 |
import com.sun.source.util.TreePath; |
36 |
import com.sun.source.util.TreePath; |
38 |
import java.io.IOException; |
|
|
39 |
import java.util.ArrayList; |
37 |
import java.util.ArrayList; |
40 |
import java.util.Collections; |
|
|
41 |
import java.util.EnumSet; |
38 |
import java.util.EnumSet; |
42 |
import java.util.List; |
39 |
import java.util.List; |
43 |
import java.util.Set; |
40 |
import org.netbeans.api.annotations.common.NonNull; |
44 |
import org.netbeans.api.java.lexer.JavaTokenId; |
41 |
import org.netbeans.modules.java.hints.spi.support.FixFactory; |
45 |
import org.netbeans.api.java.source.CompilationInfo; |
|
|
46 |
import org.netbeans.api.java.source.JavaSource; |
47 |
import org.netbeans.api.java.source.Task; |
48 |
import org.netbeans.api.java.source.TreePathHandle; |
49 |
import org.netbeans.api.java.source.WorkingCopy; |
50 |
import org.netbeans.modules.java.hints.spi.AbstractHint; |
51 |
import org.netbeans.spi.editor.hints.ChangeInfo; |
52 |
import org.netbeans.spi.editor.hints.ErrorDescription; |
42 |
import org.netbeans.spi.editor.hints.ErrorDescription; |
53 |
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory; |
|
|
54 |
import org.netbeans.spi.editor.hints.Fix; |
43 |
import org.netbeans.spi.editor.hints.Fix; |
55 |
import org.openide.filesystems.FileObject; |
44 |
import org.netbeans.spi.editor.hints.Severity; |
56 |
import org.openide.util.Exceptions; |
45 |
import org.netbeans.spi.java.hints.Hint; |
|
|
46 |
import org.netbeans.spi.java.hints.HintContext; |
47 |
import org.netbeans.spi.java.hints.JavaFixUtilities; |
48 |
import org.netbeans.spi.java.hints.TriggerTreeKind; |
57 |
import org.openide.util.NbBundle; |
49 |
import org.openide.util.NbBundle; |
58 |
|
50 |
|
59 |
/** |
51 |
/** |
60 |
* |
52 |
* |
61 |
* @author phrebejk |
53 |
* @author phrebejk |
|
|
54 |
* @author markiewb (refactoring) |
62 |
*/ |
55 |
*/ |
63 |
public class EmptyStatements extends AbstractHint { |
56 |
public class EmptyStatements { |
64 |
|
57 |
|
65 |
private static final String SUPPRESS_WARNINGS_KEY = "empty-statement"; |
58 |
private static final String SUPPRESS_WARNINGS_KEY = "empty-statement"; |
66 |
|
59 |
|
67 |
static final EnumSet<JavaTokenId> nonRelevant = EnumSet.<JavaTokenId>of( |
60 |
@Hint(displayName = "#LBL_Empty_BLOCK", description = "#DSC_Empty_BLOCK", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_BLOCK") |
68 |
JavaTokenId.LINE_COMMENT, |
61 |
@TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) |
69 |
JavaTokenId.BLOCK_COMMENT, |
62 |
@NbBundle.Messages({"ERR_EmptyBLOCK=Remove semicolon"}) |
70 |
JavaTokenId.JAVADOC_COMMENT, |
63 |
public static ErrorDescription forBLOCK(HintContext ctx) { |
71 |
JavaTokenId.WHITESPACE |
|
|
72 |
); |
73 |
|
64 |
|
74 |
private String EMPTY_STATEMENTS_ID = "EmptyStatements_"; // NOI18N |
65 |
Tree parent = ctx.getPath().getParentPath().getLeaf(); |
75 |
|
66 |
if (!EnumSet.of(Kind.BLOCK).contains(parent.getKind())) { |
76 |
private Tree.Kind treeKind; |
67 |
return null; |
77 |
private Set<Tree.Kind> treeKinds = EnumSet.<Tree.Kind>of(Tree.Kind.EMPTY_STATEMENT); |
|
|
78 |
private Set<Tree.Kind> NO_KINDS = EnumSet.noneOf(Tree.Kind.class); |
79 |
|
80 |
private static EmptyStatements delegate; |
81 |
private static EmptyStatements esFor; |
82 |
private static EmptyStatements esWhile; |
83 |
private static EmptyStatements esDoWhile; |
84 |
private static EmptyStatements esIf; |
85 |
private static EmptyStatements esBlock; |
86 |
|
87 |
private EmptyStatements( Tree.Kind treeKind ) { |
88 |
super( treeKind == Tree.Kind.IF ? false : true, true, HintSeverity.WARNING, SUPPRESS_WARNINGS_KEY ); |
89 |
this.treeKind = treeKind; |
90 |
} |
68 |
} |
91 |
|
69 |
|
92 |
public static EmptyStatements createDelegate() { |
70 |
final List<Fix> fixes = new ArrayList<>(); |
93 |
return getDelegate(); |
71 |
fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath(), SUPPRESS_WARNINGS_KEY)); |
94 |
} |
72 |
fixes.add(JavaFixUtilities.removeFromParent(ctx, Bundle.ERR_EmptyBLOCK(), ctx.getPath())); |
95 |
|
73 |
|
96 |
public static EmptyStatements createFor() { |
74 |
return createErrorDescription(ctx, ctx.getPath().getLeaf(), fixes, Kind.BLOCK); |
97 |
EmptyStatements d = getDelegate(); |
|
|
98 |
d.esFor = new EmptyStatements( Tree.Kind.FOR_LOOP ); |
99 |
return d.esFor; |
100 |
} |
75 |
} |
101 |
|
76 |
|
102 |
public static EmptyStatements createWhile() { |
77 |
@Hint(displayName = "#LBL_Empty_WHILE_LOOP", description = "#DSC_Empty_WHILE_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_WHILE_LOOP") |
103 |
EmptyStatements d = getDelegate(); |
78 |
@TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) |
104 |
d.esWhile = new EmptyStatements( Tree.Kind.WHILE_LOOP ); |
79 |
public static ErrorDescription forWHILE_LOOP(HintContext ctx) { |
105 |
return d.esWhile; |
80 |
final TreePath parentPath = ctx.getPath().getParentPath(); |
|
|
81 |
final Tree parentLeaf = parentPath.getLeaf(); |
82 |
if (!EnumSet.of(Kind.WHILE_LOOP).contains(parentLeaf.getKind())) { |
83 |
return null; |
106 |
} |
84 |
} |
107 |
|
85 |
|
108 |
public static EmptyStatements createDoWhile() { |
86 |
final List<Fix> fixes = new ArrayList<>(); |
109 |
EmptyStatements d = getDelegate(); |
87 |
fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), parentPath, SUPPRESS_WARNINGS_KEY)); |
110 |
d.esDoWhile = new EmptyStatements( Tree.Kind.DO_WHILE_LOOP ); |
|
|
111 |
return d.esDoWhile; |
112 |
} |
113 |
|
88 |
|
114 |
public static EmptyStatements createIf() { |
89 |
return createErrorDescription(ctx, parentLeaf, fixes, Kind.WHILE_LOOP); |
115 |
EmptyStatements d = getDelegate(); |
|
|
116 |
d.esIf = new EmptyStatements( Tree.Kind.IF ); |
117 |
return d.esIf; |
118 |
} |
90 |
} |
119 |
|
91 |
|
120 |
public static EmptyStatements createBlock() { |
92 |
@Hint(displayName = "#LBL_Empty_IF", description = "#DSC_Empty_IF", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_IF", enabled = false) |
121 |
EmptyStatements d = getDelegate(); |
93 |
@TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) |
122 |
d.esBlock = new EmptyStatements( Tree.Kind.BLOCK ); |
94 |
public static ErrorDescription forIF(HintContext ctx) { |
123 |
return d.esBlock; |
95 |
final TreePath treePath = ctx.getPath(); |
124 |
} |
|
|
125 |
|
96 |
|
126 |
public static synchronized EmptyStatements getDelegate() { |
|
|
127 |
if ( delegate == null ) { |
128 |
delegate = new EmptyStatements(null); |
129 |
} |
130 |
return delegate; |
131 |
} |
132 |
|
133 |
public Set<Kind> getTreeKinds() { |
134 |
return treeKind == null ? treeKinds : NO_KINDS; |
135 |
} |
136 |
|
137 |
public List<ErrorDescription> run(CompilationInfo compilationInfo, TreePath treePath) { |
138 |
|
139 |
Tree tree = treePath.getLeaf(); |
140 |
|
141 |
if( tree.getKind() != Tree.Kind.EMPTY_STATEMENT ) { |
142 |
return null; |
143 |
} |
144 |
|
145 |
Tree parent = treePath.getParentPath().getLeaf(); |
97 |
Tree parent = treePath.getParentPath().getLeaf(); |
146 |
|
98 |
if (!EnumSet.of(Kind.IF).contains(parent.getKind())) { |
147 |
if ( !isEnabled(parent.getKind()) ) { |
|
|
148 |
return null; |
99 |
return null; |
149 |
} |
100 |
} |
150 |
|
101 |
|
151 |
ErrorDescription ed = null; |
102 |
TreePath treePathForWarning = treePath; |
152 |
|
103 |
IfTree it = (IfTree) parent; |
153 |
switch( parent.getKind() ) { |
104 |
if (it.getThenStatement() != null |
154 |
case FOR_LOOP: |
105 |
&& it.getThenStatement().getKind() == Tree.Kind.EMPTY_STATEMENT) { |
155 |
case ENHANCED_FOR_LOOP: |
106 |
treePathForWarning = treePath.getParentPath(); |
156 |
case WHILE_LOOP: |
|
|
157 |
case DO_WHILE_LOOP: |
158 |
|
159 |
ed = createErrorDescription(treePath.getParentPath(), parent.getKind(), compilationInfo); |
160 |
if ( ed != null ) { |
161 |
return Collections.singletonList(ed); |
162 |
} |
107 |
} |
163 |
break; |
108 |
if (it.getElseStatement() != null |
164 |
case BLOCK: |
109 |
&& it.getElseStatement().getKind() == Tree.Kind.EMPTY_STATEMENT) { |
165 |
ed = createErrorDescription(treePath, parent.getKind(), compilationInfo); |
110 |
treePathForWarning = treePath; |
166 |
if ( ed != null ) { |
|
|
167 |
return Collections.singletonList(ed); |
168 |
} |
111 |
} |
169 |
break; |
|
|
170 |
case IF: |
171 |
List<ErrorDescription> result = new ArrayList<ErrorDescription>(2); |
172 |
IfTree it = (IfTree)parent; |
173 |
if ( it.getThenStatement() != null && |
174 |
it.getThenStatement().getKind() == Tree.Kind.EMPTY_STATEMENT ) { |
175 |
result.add( createErrorDescription(treePath.getParentPath(), parent.getKind(), compilationInfo) ); |
176 |
} |
177 |
if ( it.getElseStatement() != null && |
178 |
it.getElseStatement().getKind() == Tree.Kind.EMPTY_STATEMENT ) { |
179 |
result.add( createErrorDescription(treePath, parent.getKind(), compilationInfo) ); |
180 |
} |
181 |
return result; |
182 |
} |
183 |
|
112 |
|
184 |
return Collections.<ErrorDescription>emptyList(); |
113 |
final List<Fix> fixes = new ArrayList<>(); |
185 |
} |
114 |
fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), treePathForWarning, SUPPRESS_WARNINGS_KEY)); |
186 |
|
115 |
|
187 |
public void cancel() { |
116 |
return createErrorDescription(ctx, parent, fixes, parent.getKind()); |
188 |
// Does nothing |
|
|
189 |
} |
117 |
} |
190 |
|
118 |
|
191 |
public String getId() { |
119 |
@Hint(displayName = "#LBL_Empty_FOR_LOOP", description = "#DSC_Empty_FOR_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_FOR_LOOP") |
192 |
return EMPTY_STATEMENTS_ID + treeKind; |
120 |
@TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) |
193 |
} |
121 |
public static ErrorDescription forFOR_LOOP(HintContext ctx) { |
194 |
|
122 |
|
195 |
public String getDisplayName() { |
123 |
Tree parent = ctx.getPath().getParentPath().getLeaf(); |
196 |
if ( treeKind == null ) { |
124 |
if (!EnumSet.of(Kind.FOR_LOOP, Kind.ENHANCED_FOR_LOOP).contains(parent.getKind())) { |
197 |
return "Empty Statements Delegate"; // NOI18N |
125 |
return null; |
198 |
} |
126 |
} |
199 |
return NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + treeKind.toString() ); // NOI18N |
|
|
200 |
} |
201 |
|
127 |
|
202 |
public String getDescription() { |
128 |
final List<Fix> fixes = new ArrayList<>(); |
203 |
if ( treeKind == null ) { |
129 |
fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath().getParentPath(), SUPPRESS_WARNINGS_KEY)); |
204 |
return "Empty Statements Delegate"; // NOI18N |
|
|
205 |
} |
206 |
return NbBundle.getMessage(EmptyStatements.class, "DSC_Empty_" + treeKind.toString() ); // NOI18N |
207 |
} |
208 |
|
130 |
|
209 |
// Private methods --------------------------------------------------------- |
131 |
return createErrorDescription(ctx, parent, fixes, parent.getKind()); |
210 |
|
|
|
211 |
private ErrorDescription createErrorDescription( TreePath tp, Tree.Kind kind, CompilationInfo info ) { |
212 |
|
213 |
return ErrorDescriptionFactory.createErrorDescription( |
214 |
getSeverity().toEditorSeverity(), |
215 |
// getDisplayName(), |
216 |
NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + kind.toString()), |
217 |
// Collections.<Fix>singletonList(new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info) ) ), |
218 |
FixFactory.createSuppressWarnings( info, tp, SUPPRESS_WARNINGS_KEY), |
219 |
info.getFileObject(), |
220 |
(int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf()), |
221 |
(int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf())); |
222 |
} |
132 |
} |
223 |
|
133 |
|
224 |
private boolean isEnabled( Tree.Kind kind ) { |
134 |
@Hint(displayName = "#LBL_Empty_DO_WHILE_LOOP", description = "#DSC_Empty_DO_WHILE_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_DO_WHILE_LOOP") |
225 |
switch( kind ) { |
135 |
@TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) |
226 |
case FOR_LOOP: |
136 |
public static ErrorDescription forDO_WHILE_LOOP(HintContext ctx) { |
227 |
case ENHANCED_FOR_LOOP: |
|
|
228 |
return esFor.isEnabled(); |
229 |
case WHILE_LOOP: |
230 |
return esWhile.isEnabled(); |
231 |
case DO_WHILE_LOOP: |
232 |
return esDoWhile.isEnabled(); |
233 |
case BLOCK: |
234 |
return esBlock.isEnabled(); |
235 |
case IF: |
236 |
return esIf.isEnabled(); |
237 |
} |
238 |
return false; |
239 |
} |
240 |
|
137 |
|
241 |
/* |
138 |
Tree parent = ctx.getPath().getParentPath().getLeaf(); |
242 |
private List<ErrorDescription> checkifStatements( StatementTree thenSt, StatementTree elseSt, TreePath tp, CompilationInfo info ) { |
139 |
if (!Kind.DO_WHILE_LOOP.equals(parent.getKind())) { |
243 |
|
|
|
244 |
boolean fixThen = false; |
245 |
boolean fixElse = false; |
246 |
|
247 |
if ( thenSt != null && |
248 |
thenSt.getKind() != Tree.Kind.EMPTY_STATEMENT && |
249 |
thenSt.getKind() != Tree.Kind.BLOCK && |
250 |
thenSt.getKind() != Tree.Kind.ERRONEOUS && |
251 |
!isErroneousExpression( thenSt )) { |
252 |
fixThen = true; |
253 |
} |
254 |
|
255 |
if ( elseSt != null && |
256 |
elseSt.getKind() != Tree.Kind.EMPTY_STATEMENT && |
257 |
elseSt.getKind() != Tree.Kind.BLOCK && |
258 |
elseSt.getKind() != Tree.Kind.ERRONEOUS && |
259 |
!isErroneousExpression( elseSt )) { |
260 |
fixElse = true; |
261 |
} |
262 |
|
263 |
List<ErrorDescription> result = new ArrayList<ErrorDescription>(); |
264 |
|
265 |
if ( fixThen ) { |
266 |
EmptyStatementFix bf = new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info)); |
267 |
bf.fixThen = fixThen; |
268 |
bf.fixElse = fixElse; |
269 |
result.add( ErrorDescriptionFactory.createErrorDescription( |
270 |
getSeverity().toEditorSeverity(), |
271 |
getDisplayName(), |
272 |
Collections.<Fix>singletonList( bf ), |
273 |
info.getFileObject(), |
274 |
(int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), thenSt ), |
275 |
(int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), thenSt ) ) ); |
276 |
} |
277 |
|
278 |
if ( fixElse ) { |
279 |
EmptyStatementFix bf = new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info)); |
280 |
bf.fixThen = fixThen; |
281 |
bf.fixElse = fixElse; |
282 |
result.add( ErrorDescriptionFactory.createErrorDescription( |
283 |
getSeverity().toEditorSeverity(), |
284 |
getDisplayName(), |
285 |
Collections.<Fix>singletonList( bf ), |
286 |
info.getFileObject(), |
287 |
(int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), elseSt ), |
288 |
(int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), elseSt ) ) ); |
289 |
|
290 |
} |
291 |
|
292 |
return result; |
293 |
} |
294 |
|
295 |
private boolean isErroneousExpression(StatementTree statement) { |
296 |
if ( statement instanceof ExpressionStatementTree ) { |
297 |
if ( ((ExpressionStatementTree)statement).getExpression().getKind() == Kind.ERRONEOUS ) { |
298 |
return true; |
299 |
} |
300 |
} |
301 |
return false; |
302 |
} |
303 |
*/ |
304 |
|
305 |
private static class EmptyStatementFix implements Fix, Task<WorkingCopy> { |
306 |
|
307 |
|
308 |
FileObject file; |
309 |
TreePathHandle tph; |
310 |
Tree.Kind kind; |
311 |
|
312 |
boolean fixThen; |
313 |
boolean fixElse; |
314 |
|
315 |
public EmptyStatementFix(FileObject file, TreePathHandle tph, Tree.Kind kind ) { |
316 |
this.file = file; |
317 |
this.tph = tph; |
318 |
this.kind = kind; |
319 |
} |
320 |
|
321 |
public String getText() { |
322 |
return NbBundle.getMessage(Braces.class, "LBL_Empty_Fix" + kind.toString()); // NOI18N |
323 |
} |
324 |
|
325 |
public ChangeInfo implement() { |
326 |
JavaSource js = JavaSource.forFileObject(file); |
327 |
try { |
328 |
js.runModificationTask(this).commit(); |
329 |
} |
330 |
catch( IOException e ) { |
331 |
Exceptions.printStackTrace(e); |
332 |
} |
333 |
return null; |
140 |
return null; |
334 |
} |
141 |
} |
335 |
|
142 |
|
336 |
public void run(WorkingCopy copy) throws Exception { |
143 |
final List<Fix> fixes = new ArrayList<>(); |
337 |
/* |
144 |
fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath().getParentPath(), SUPPRESS_WARNINGS_KEY)); |
338 |
copy.toPhase(JavaSource.Phase.PARSED); |
|
|
339 |
TreePath path = tph.resolve(copy); |
340 |
|
145 |
|
341 |
if ( path != null ) { |
146 |
return createErrorDescription(ctx, parent, fixes, parent.getKind()); |
342 |
|
|
|
343 |
TreeMaker make = copy.getTreeMaker(); |
344 |
Tree oldTree = path.getLeaf(); |
345 |
|
346 |
switch( oldTree.getKind() ) { |
347 |
case FOR_LOOP: |
348 |
ForLoopTree oldFor = (ForLoopTree)oldTree; |
349 |
StatementTree oldBlock = oldFor.getStatement(); |
350 |
BlockTree newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
351 |
copy.rewrite(oldBlock, newBlock); |
352 |
break; |
353 |
case ENHANCED_FOR_LOOP: |
354 |
EnhancedForLoopTree oldEnhancedFor = (EnhancedForLoopTree)oldTree; |
355 |
oldBlock = oldEnhancedFor.getStatement(); |
356 |
newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
357 |
copy.rewrite(oldBlock, newBlock); |
358 |
break; |
359 |
case WHILE_LOOP: |
360 |
WhileLoopTree oldWhile = (WhileLoopTree)oldTree; |
361 |
oldBlock = oldWhile.getStatement(); |
362 |
newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
363 |
copy.rewrite(oldBlock, newBlock); |
364 |
break; |
365 |
case DO_WHILE_LOOP: |
366 |
DoWhileLoopTree oldDoWhile = (DoWhileLoopTree)oldTree; |
367 |
oldBlock = oldDoWhile.getStatement(); |
368 |
newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
369 |
copy.rewrite(oldBlock, newBlock); |
370 |
break; |
371 |
case IF: |
372 |
IfTree oldIf = (IfTree)oldTree; |
373 |
if ( fixThen ) { |
374 |
oldBlock = oldIf.getThenStatement(); |
375 |
newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
376 |
copy.rewrite(oldBlock, newBlock); |
377 |
} |
147 |
} |
378 |
if ( fixElse ) { |
|
|
379 |
oldBlock = oldIf.getElseStatement(); |
380 |
newBlock = make.Block(Collections.<StatementTree>singletonList(oldBlock), false); |
381 |
copy.rewrite(oldBlock, newBlock); |
382 |
} |
383 |
|
148 |
|
384 |
} |
149 |
/** |
385 |
} |
150 |
* package private for reuse in unit tests. |
386 |
*/ |
151 |
*/ |
|
|
152 |
static String getDisplayName(@NonNull Kind treeKind) { |
153 |
//same pattern as in @Hint(displayName = "#LBL_Empty_XXXX" |
154 |
return NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + treeKind.toString()); // NOI18N |
387 |
} |
155 |
} |
388 |
|
156 |
|
389 |
|
157 |
private static ErrorDescription createErrorDescription(HintContext ctx, final Tree leaf, final List<Fix> fixes, Kind treeKind) { |
|
|
158 |
int start = (int) ctx.getInfo().getTrees().getSourcePositions().getStartPosition(ctx.getInfo().getCompilationUnit(), leaf); |
159 |
int end = (int) ctx.getInfo().getTrees().getSourcePositions().getEndPosition(ctx.getInfo().getCompilationUnit(), leaf); |
160 |
return org.netbeans.spi.java.hints.ErrorDescriptionFactory.forSpan(ctx, start, end, getDisplayName(treeKind), fixes.toArray(new Fix[fixes.size()])); |
390 |
} |
161 |
} |
391 |
|
|
|
392 |
|
393 |
|
394 |
} |
162 |
} |