]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.corext.fix; | |
12 | ||
13 | import java.lang.reflect.InvocationTargetException; | |
14 | import java.util.ArrayList; | |
15 | import java.util.HashSet; | |
16 | import java.util.Hashtable; | |
17 | import java.util.Iterator; | |
18 | import java.util.LinkedList; | |
19 | import java.util.List; | |
20 | import java.util.Map; | |
21 | import java.util.Map.Entry; | |
22 | ||
23 | import org.eclipse.swt.widgets.Display; | |
24 | import org.eclipse.swt.widgets.Shell; | |
25 | ||
26 | import org.eclipse.core.runtime.CoreException; | |
27 | import org.eclipse.core.runtime.IProgressMonitor; | |
28 | import org.eclipse.core.runtime.IStatus; | |
29 | import org.eclipse.core.runtime.NullProgressMonitor; | |
30 | import org.eclipse.core.runtime.OperationCanceledException; | |
31 | import org.eclipse.core.runtime.SubProgressMonitor; | |
32 | import org.eclipse.core.runtime.jobs.ISchedulingRule; | |
33 | ||
34 | import org.eclipse.core.resources.IFile; | |
35 | import org.eclipse.core.resources.IResource; | |
36 | import org.eclipse.core.resources.ProjectScope; | |
37 | import org.eclipse.core.resources.ResourcesPlugin; | |
38 | ||
39 | import org.eclipse.text.edits.MalformedTreeException; | |
40 | import org.eclipse.text.edits.TextEdit; | |
41 | import org.eclipse.text.edits.TextEditGroup; | |
42 | import org.eclipse.text.edits.UndoEdit; | |
43 | ||
44 | import org.eclipse.jface.operation.IRunnableContext; | |
45 | import org.eclipse.jface.operation.IRunnableWithProgress; | |
46 | ||
47 | import org.eclipse.jface.text.BadLocationException; | |
48 | import org.eclipse.jface.text.Document; | |
49 | import org.eclipse.jface.text.IDocument; | |
50 | import org.eclipse.jface.text.IRegion; | |
51 | ||
52 | import org.eclipse.ui.PlatformUI; | |
53 | ||
54 | import org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup; | |
55 | import org.eclipse.ltk.core.refactoring.Change; | |
56 | import org.eclipse.ltk.core.refactoring.CompositeChange; | |
57 | import org.eclipse.ltk.core.refactoring.ContentStamp; | |
58 | import org.eclipse.ltk.core.refactoring.GroupCategory; | |
59 | import org.eclipse.ltk.core.refactoring.GroupCategorySet; | |
60 | import org.eclipse.ltk.core.refactoring.NullChange; | |
61 | import org.eclipse.ltk.core.refactoring.PerformChangeOperation; | |
62 | import org.eclipse.ltk.core.refactoring.Refactoring; | |
63 | import org.eclipse.ltk.core.refactoring.RefactoringCore; | |
64 | import org.eclipse.ltk.core.refactoring.RefactoringStatus; | |
65 | import org.eclipse.ltk.core.refactoring.RefactoringTickProvider; | |
66 | import org.eclipse.ltk.core.refactoring.TextChange; | |
67 | import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup; | |
68 | import org.eclipse.ltk.core.refactoring.TextFileChange; | |
69 | import org.eclipse.ltk.ui.refactoring.RefactoringUI; | |
70 | ||
71 | import org.eclipse.jdt.core.ICompilationUnit; | |
72 | import org.eclipse.jdt.core.IJavaProject; | |
73 | import org.eclipse.jdt.core.IPackageFragment; | |
74 | import org.eclipse.jdt.core.JavaModelException; | |
75 | import org.eclipse.jdt.core.WorkingCopyOwner; | |
76 | import org.eclipse.jdt.core.dom.ASTParser; | |
77 | import org.eclipse.jdt.core.dom.ASTRequestor; | |
78 | import org.eclipse.jdt.core.dom.CompilationUnit; | |
79 | import org.eclipse.jdt.core.refactoring.CompilationUnitChange; | |
80 | ||
81 | import org.eclipse.jdt.internal.corext.dom.ASTBatchParser; | |
82 | import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.CleanUpChange; | |
83 | import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.MultiFixTarget; | |
84 | import org.eclipse.jdt.internal.corext.refactoring.Checks; | |
85 | import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange; | |
86 | import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange; | |
87 | import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; | |
88 | import org.eclipse.jdt.internal.corext.refactoring.util.TextEditUtil; | |
89 | import org.eclipse.jdt.internal.corext.util.Messages; | |
90 | ||
91 | import org.eclipse.jdt.ui.JavaElementLabels; | |
92 | import org.eclipse.jdt.ui.cleanup.CleanUpContext; | |
93 | import org.eclipse.jdt.ui.cleanup.CleanUpOptions; | |
94 | import org.eclipse.jdt.ui.cleanup.ICleanUp; | |
95 | import org.eclipse.jdt.ui.cleanup.ICleanUpFix; | |
96 | import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; | |
97 | import org.eclipse.jdt.ui.text.java.IProblemLocation; | |
98 | ||
99 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
100 | import org.eclipse.jdt.internal.ui.fix.CleanUpRefactoringWizard.CleanUpConfigurationPage; | |
101 | import org.eclipse.jdt.internal.ui.fix.IMultiFix.MultiFixContext; | |
102 | import org.eclipse.jdt.internal.ui.fix.MapCleanUpOptions; | |
103 | import org.eclipse.jdt.internal.ui.fix.MultiFixMessages; | |
104 | import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; | |
105 | import org.eclipse.jdt.internal.ui.refactoring.IScheduledRefactoring; | |
106 | import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper; | |
107 | import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal; | |
108 | import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; | |
109 | ||
110 | public class CleanUpRefactoring extends Refactoring implements IScheduledRefactoring { | |
111 | ||
112 | public static class CleanUpTarget { | |
113 | ||
114 | private final ICompilationUnit fCompilationUnit; | |
115 | ||
116 | public CleanUpTarget(ICompilationUnit unit) { | |
117 | fCompilationUnit= unit; | |
118 | } | |
119 | ||
120 | public ICompilationUnit getCompilationUnit() { | |
121 | return fCompilationUnit; | |
122 | } | |
123 | ||
124 | public void generated_3512855110069567600(CleanUpRefactoring cleanuprefactoring) { | |
125 | IJavaProject javaProject= getCompilationUnit().getJavaProject(); | |
126 | if (!cleanuprefactoring.fProjects.containsKey(javaProject)) | |
127 | cleanuprefactoring.fProjects.put(javaProject, new ArrayList<CleanUpTarget>()); | |
128 | ||
129 | List<CleanUpTarget> targets= cleanuprefactoring.fProjects.get(javaProject); | |
130 | targets.add(this); | |
131 | } | |
132 | } | |
133 | ||
134 | public static class MultiFixTarget extends CleanUpTarget { | |
135 | ||
136 | private final IProblemLocation[] fProblems; | |
137 | ||
138 | public MultiFixTarget(ICompilationUnit unit, IProblemLocation[] problems) { | |
139 | super(unit); | |
140 | fProblems= problems; | |
141 | } | |
142 | ||
143 | public IProblemLocation[] getProblems() { | |
144 | return fProblems; | |
145 | } | |
146 | } | |
147 | ||
148 | public static class CleanUpChange extends CompilationUnitChange { | |
149 | ||
150 | private UndoEdit fUndoEdit; | |
151 | ||
152 | public CleanUpChange(String name, ICompilationUnit cunit) { | |
153 | super(name, cunit); | |
154 | } | |
155 | ||
156 | /** | |
157 | * {@inheritDoc} | |
158 | */ | |
159 | @Override | |
160 | protected Change createUndoChange(UndoEdit edit, ContentStamp stampToRestore) { | |
161 | fUndoEdit= edit; | |
162 | return super.createUndoChange(edit, stampToRestore); | |
163 | } | |
164 | ||
165 | public UndoEdit getUndoEdit() { | |
166 | return fUndoEdit; | |
167 | } | |
168 | ||
169 | /* | |
170 | * @see org.eclipse.ltk.core.refactoring.TextChange#perform(org.eclipse.core.runtime.IProgressMonitor) | |
171 | */ | |
172 | @Override | |
173 | public Change perform(final IProgressMonitor pm) throws CoreException { | |
174 | if (Display.getCurrent() == null) { | |
175 | final Change[] result= new Change[1]; | |
176 | final CoreException[] exs= new CoreException[1]; | |
177 | Display.getDefault().syncExec(new Runnable() { | |
178 | public void run() { | |
179 | try { | |
180 | result[0]= CleanUpChange.super.perform(pm); | |
181 | } catch (CoreException e) { | |
182 | exs[0]= e; | |
183 | } | |
184 | } | |
185 | }); | |
186 | ||
187 | if (exs[0] != null) | |
188 | throw exs[0]; | |
189 | ||
190 | return result[0]; | |
191 | } else { | |
192 | return super.perform(pm); | |
193 | } | |
194 | } | |
195 | ||
196 | public IRegion[] generated_3577844454337008817(ICompilationUnit unit, IRegion[] changedRegions, IProgressMonitor monitor, ICleanUp[] cleanUps, CompositeChange result, LinkedList<UndoEdit> undoEdits, CleanUpPostSaveListener cleanuppostsavelistener) throws CoreException { | |
197 | result.add(this); | |
198 | ||
199 | setSaveMode(TextFileChange.LEAVE_DIRTY); | |
200 | initializeValidationData(new NullProgressMonitor()); | |
201 | ||
202 | PerformChangeOperation performChangeOperation= RefactoringUI.createUIAwareChangeOperation(this); | |
203 | performChangeOperation.setSchedulingRule(unit.getSchedulingRule()); | |
204 | ||
205 | if (changedRegions != null && changedRegions.length > 0 && cleanuppostsavelistener.requiresChangedRegions(cleanUps)) { | |
206 | changedRegions= cleanuppostsavelistener.performWithChangedRegionUpdate(performChangeOperation, changedRegions, unit, new SubProgressMonitor(monitor, 5)); | |
207 | } else { | |
208 | performChangeOperation.run(new SubProgressMonitor(monitor, 5)); | |
209 | } | |
210 | ||
211 | performChangeOperation.getUndoChange(); | |
212 | undoEdits.addFirst(getUndoEdit()); | |
213 | return changedRegions; | |
214 | } | |
215 | ||
216 | public TextChange generated_1297851598183582600(CleanUpChange change) { | |
217 | setSaveMode(change.getSaveMode()); | |
218 | return this; | |
219 | } | |
220 | } | |
221 | ||
222 | public static class FixCalculationException extends RuntimeException { | |
223 | ||
224 | private static final long serialVersionUID= 3807273310144726165L; | |
225 | ||
226 | private final CoreException fException; | |
227 | ||
228 | public FixCalculationException(CoreException exception) { | |
229 | fException= exception; | |
230 | } | |
231 | ||
232 | public CoreException getException() { | |
233 | return fException; | |
234 | } | |
235 | } | |
236 | ||
237 | static class ParseListElement { | |
238 | ||
239 | private final CleanUpTarget fTarget; | |
240 | private final ICleanUp[] fCleanUpsArray; | |
241 | ||
242 | public ParseListElement(CleanUpTarget cleanUpTarget, ICleanUp[] cleanUps) { | |
243 | fTarget= cleanUpTarget; | |
244 | fCleanUpsArray= cleanUps; | |
245 | } | |
246 | ||
247 | public CleanUpTarget getTarget() { | |
248 | return fTarget; | |
249 | } | |
250 | ||
251 | public ICleanUp[] getCleanUps() { | |
252 | return fCleanUpsArray; | |
253 | } | |
254 | ||
255 | public void generated_704773225463029839(CleanUpASTRequestor cleanupastrequestor) { | |
256 | cleanupastrequestor.fCompilationUnitParseElementMap.put(getTarget().getCompilationUnit(), this); | |
257 | } | |
258 | } | |
259 | ||
260 | final class CleanUpRefactoringProgressMonitor extends SubProgressMonitor { | |
261 | ||
262 | private double fRealWork; | |
263 | private int fFlushCount; | |
264 | private final int fSize; | |
265 | private final int fIndex; | |
266 | ||
267 | private CleanUpRefactoringProgressMonitor(IProgressMonitor monitor, int ticks, int size, int index) { | |
268 | super(monitor, ticks); | |
269 | fFlushCount= 0; | |
270 | fSize= size; | |
271 | fIndex= index; | |
272 | } | |
273 | ||
274 | /** | |
275 | * {@inheritDoc} | |
276 | */ | |
277 | @Override | |
278 | public void internalWorked(double work) { | |
279 | fRealWork+= work; | |
280 | } | |
281 | ||
282 | public void flush() { | |
283 | super.internalWorked(fRealWork); | |
284 | reset(); | |
285 | fFlushCount++; | |
286 | } | |
287 | ||
288 | public void reset() { | |
289 | fRealWork= 0.0; | |
290 | } | |
291 | ||
292 | @Override | |
293 | public void done() {} | |
294 | ||
295 | public int getIndex() { | |
296 | return fIndex + fFlushCount; | |
297 | } | |
298 | ||
299 | public String getSubTaskMessage(ICompilationUnit source) { | |
300 | String typeName= BasicElementLabels.getFileName(source); | |
301 | return Messages.format(FixMessages.CleanUpRefactoring_ProcessingCompilationUnit_message, new Object[] {new Integer(getIndex()), new Integer(fSize), typeName}); | |
302 | } | |
303 | ||
304 | public void generated_2876694169375894621(CleanUpASTRequestor cleanupastrequestor, ICompilationUnit source, CompilationUnit ast) { | |
305 | subTask(getSubTaskMessage(source)); | |
306 | ||
307 | ICompilationUnit primary= (ICompilationUnit)source.getPrimaryElement(); | |
308 | ParseListElement element= cleanupastrequestor.fCompilationUnitParseElementMap.get(primary); | |
309 | CleanUpTarget target= element.getTarget(); | |
310 | ||
311 | CleanUpContext context; | |
312 | if (target instanceof MultiFixTarget) { | |
313 | context= new MultiFixContext(source, ast, ((MultiFixTarget)target).getProblems()); | |
314 | } else { | |
315 | context= new CleanUpContext(source, ast); | |
316 | } | |
317 | ICleanUp[] rejectedCleanUps= cleanupastrequestor.calculateSolutions(context, element.getCleanUps()); | |
318 | ||
319 | if (rejectedCleanUps.length > 0) { | |
320 | cleanupastrequestor.fUndoneElements.add(new ParseListElement(target, rejectedCleanUps)); | |
321 | reset(); | |
322 | } else { | |
323 | flush(); | |
324 | } | |
325 | } | |
326 | ||
327 | public void generated_733833685706273047(IProgressMonitor monitor, List<ICompilationUnit> parseList, List<ICompilationUnit> sourceList, final CleanUpFixpointIterator cleanupfixpointiterator) | |
328 | throws CoreException { | |
329 | CleanUpASTRequestor requestor= new CleanUpASTRequestor(cleanupfixpointiterator.fParseList, cleanupfixpointiterator.fSolutions, this); | |
330 | if (parseList.size() > 0) { | |
331 | ASTBatchParser parser= new ASTBatchParser() { | |
332 | @Override | |
333 | protected ASTParser createParser(IJavaProject project) { | |
334 | ASTParser result= CleanUpFixpointIterator.createCleanUpASTParser(); | |
335 | result.setProject(project); | |
336 | ||
337 | Map<String, String> options= RefactoringASTParser.getCompilerOptions(project); | |
338 | options.putAll(cleanupfixpointiterator.fCleanUpOptions); | |
339 | result.setCompilerOptions(options); | |
340 | return result; | |
341 | } | |
342 | }; | |
343 | try { | |
344 | ICompilationUnit[] units= parseList.toArray(new ICompilationUnit[parseList.size()]); | |
345 | parser.createASTs(units, new String[0], requestor, this); | |
346 | } catch (FixCalculationException e) { | |
347 | throw e.getException(); | |
348 | } | |
349 | } | |
350 | ||
351 | for (Iterator<ICompilationUnit> iterator= sourceList.iterator(); iterator.hasNext();) { | |
352 | ICompilationUnit cu= iterator.next(); | |
353 | ||
354 | monitor.worked(1); | |
355 | ||
356 | requestor.acceptSource(cu); | |
357 | ||
358 | if (monitor.isCanceled()) | |
359 | throw new OperationCanceledException(); | |
360 | } | |
361 | ||
362 | cleanupfixpointiterator.fParseList= requestor.getUndoneElements(); | |
363 | cleanupfixpointiterator.fIndex= getIndex(); | |
364 | } | |
365 | } | |
366 | ||
367 | public static class CleanUpASTRequestor extends ASTRequestor { | |
368 | ||
369 | private final List<ParseListElement> fUndoneElements; | |
370 | private final Hashtable<ICompilationUnit, List<CleanUpChange>> fSolutions; | |
371 | private final Hashtable<ICompilationUnit, ParseListElement> fCompilationUnitParseElementMap; | |
372 | private final CleanUpRefactoringProgressMonitor fMonitor; | |
373 | ||
374 | public CleanUpASTRequestor(List<ParseListElement> parseList, Hashtable<ICompilationUnit, List<CleanUpChange>> solutions, CleanUpRefactoringProgressMonitor monitor) { | |
375 | fSolutions= solutions; | |
376 | fMonitor= monitor; | |
377 | fUndoneElements= new ArrayList<ParseListElement>(); | |
378 | fCompilationUnitParseElementMap= new Hashtable<ICompilationUnit, ParseListElement>(parseList.size()); | |
379 | for (Iterator<ParseListElement> iter= parseList.iterator(); iter.hasNext();) { | |
380 | ParseListElement element= iter.next(); | |
381 | element.generated_704773225463029839(CleanUpASTRequestor.this); | |
382 | } | |
383 | } | |
384 | ||
385 | /** | |
386 | * {@inheritDoc} | |
387 | */ | |
388 | @Override | |
389 | public void acceptAST(ICompilationUnit source, CompilationUnit ast) { | |
390 | ||
391 | fMonitor.generated_2876694169375894621(this, source, ast); | |
392 | } | |
393 | ||
394 | public void acceptSource(ICompilationUnit source) { | |
395 | acceptAST(source, null); | |
396 | } | |
397 | ||
398 | public List<ParseListElement> getUndoneElements() { | |
399 | return fUndoneElements; | |
400 | } | |
401 | ||
402 | ICleanUp[] calculateSolutions(CleanUpContext context, ICleanUp[] cleanUps) { | |
403 | List<ICleanUp>result= new ArrayList<ICleanUp>(); | |
404 | CleanUpChange solution; | |
405 | return context.generated_952798979635111062(CleanUpASTRequestor.this, cleanUps, result, solution); | |
406 | } | |
407 | ||
408 | public void integrateSolution(CleanUpChange solution, ICompilationUnit source) { | |
409 | ICompilationUnit primary= source.getPrimary(); | |
410 | ||
411 | List<CleanUpChange> changes= fSolutions.get(primary); | |
412 | if (changes == null) { | |
413 | changes= new ArrayList<CleanUpChange>(); | |
414 | fSolutions.put(primary, changes); | |
415 | } | |
416 | changes.add(solution); | |
417 | } | |
418 | } | |
419 | ||
420 | public class CleanUpFixpointIterator { | |
421 | ||
422 | private List<ParseListElement> fParseList; | |
423 | private final Hashtable<ICompilationUnit, List<CleanUpChange>> fSolutions; | |
424 | private final Hashtable<ICompilationUnit, ICompilationUnit> fWorkingCopies; // map from primary to working copy | |
425 | private final Map<String, String> fCleanUpOptions; | |
426 | private final int fSize; | |
427 | private int fIndex; | |
428 | ||
429 | public CleanUpFixpointIterator(CleanUpTarget[] targets, ICleanUp[] cleanUps) { | |
430 | fSolutions= new Hashtable<ICompilationUnit, List<CleanUpChange>>(targets.length); | |
431 | fWorkingCopies= new Hashtable<ICompilationUnit, ICompilationUnit>(); | |
432 | ||
433 | fParseList= new ArrayList<ParseListElement>(targets.length); | |
434 | for (int i= 0; i < targets.length; i++) { | |
435 | fParseList.add(new ParseListElement(targets[i], cleanUps)); | |
436 | } | |
437 | ||
438 | fCleanUpOptions= new Hashtable<String, String>(); | |
439 | for (int i= 0; i < cleanUps.length; i++) { | |
440 | ICleanUp cleanUp= cleanUps[i]; | |
441 | Map<String, String> currentCleanUpOption= cleanUp.getRequirements().getCompilerOptions(); | |
442 | if (currentCleanUpOption != null) | |
443 | fCleanUpOptions.putAll(currentCleanUpOption); | |
444 | } | |
445 | ||
446 | fSize= targets.length; | |
447 | fIndex= 1; | |
448 | } | |
449 | ||
450 | public boolean hasNext() { | |
451 | return !fParseList.isEmpty(); | |
452 | } | |
453 | ||
454 | public void next(IProgressMonitor monitor) throws CoreException { | |
455 | List<ICompilationUnit> parseList= new ArrayList<ICompilationUnit>(); | |
456 | List<ICompilationUnit> sourceList= new ArrayList<ICompilationUnit>(); | |
457 | ||
458 | try { | |
459 | for (Iterator<ParseListElement> iter= fParseList.iterator(); iter.hasNext();) { | |
460 | ParseListElement element= iter.next(); | |
461 | ||
462 | ICompilationUnit compilationUnit= element.getTarget().getCompilationUnit(); | |
463 | if (fSolutions.containsKey(compilationUnit)) { | |
464 | if (fWorkingCopies.containsKey(compilationUnit)) { | |
465 | compilationUnit= fWorkingCopies.get(compilationUnit); | |
466 | } else { | |
467 | compilationUnit= compilationUnit.getWorkingCopy(new WorkingCopyOwner() {}, null); | |
468 | fWorkingCopies.put(compilationUnit.getPrimary(), compilationUnit); | |
469 | } | |
470 | applyChange(compilationUnit, fSolutions.get(compilationUnit.getPrimary())); | |
471 | } | |
472 | ||
473 | if (requiresAST(element.getCleanUps())) { | |
474 | parseList.add(compilationUnit); | |
475 | } else { | |
476 | sourceList.add(compilationUnit); | |
477 | } | |
478 | } | |
479 | ||
480 | CleanUpRefactoringProgressMonitor cuMonitor= new CleanUpRefactoringProgressMonitor(monitor, parseList.size() + sourceList.size(), fSize, fIndex); | |
481 | cuMonitor.generated_733833685706273047(monitor, parseList, sourceList, CleanUpFixpointIterator.this); | |
482 | } finally { | |
483 | } | |
484 | } | |
485 | ||
486 | public void dispose() { | |
487 | for (Iterator<ICompilationUnit> iterator= fWorkingCopies.values().iterator(); iterator.hasNext();) { | |
488 | ICompilationUnit cu= iterator.next(); | |
489 | try { | |
490 | cu.discardWorkingCopy(); | |
491 | } catch (JavaModelException e) { | |
492 | JavaPlugin.log(e); | |
493 | } | |
494 | } | |
495 | fWorkingCopies.clear(); | |
496 | } | |
497 | ||
498 | private boolean requiresAST(ICleanUp[] cleanUps) { | |
499 | for (int i= 0; i < cleanUps.length; i++) { | |
500 | if (cleanUps[i].getRequirements().requiresAST()) | |
501 | return true; | |
502 | } | |
503 | return false; | |
504 | } | |
505 | ||
506 | public Change[] getResult() { | |
507 | ||
508 | Change[] result= new Change[fSolutions.size()]; | |
509 | int i=0; | |
510 | for (Iterator<Entry<ICompilationUnit, List<CleanUpChange>>> iterator= fSolutions.entrySet().iterator(); iterator.hasNext();) { | |
511 | Entry<ICompilationUnit, List<CleanUpChange>> entry= iterator.next(); | |
512 | ||
513 | List<CleanUpChange> changes= entry.getValue(); | |
514 | ICompilationUnit unit= entry.getKey(); | |
515 | ||
516 | int saveMode; | |
517 | if (fLeaveFilesDirty) { | |
518 | saveMode= TextFileChange.LEAVE_DIRTY; | |
519 | } else { | |
520 | saveMode= TextFileChange.KEEP_SAVE_STATE; | |
521 | } | |
522 | ||
523 | if (changes.size() == 1) { | |
524 | CleanUpChange change= changes.get(0); | |
525 | change.setSaveMode(saveMode); | |
526 | result[i]= change; | |
527 | } else { | |
528 | MultiStateCompilationUnitChange mscuc= new MultiStateCompilationUnitChange(getChangeName(unit), unit); | |
529 | mscuc.generated_3684191273689231377(result, i, changes, saveMode, CleanUpFixpointIterator.this); | |
530 | } | |
531 | ||
532 | i++; | |
533 | } | |
534 | ||
535 | return result; | |
536 | } | |
537 | ||
538 | public TextChange createGroupFreeChange(CleanUpChange change) { | |
539 | CleanUpChange result= new CleanUpChange(change.getName(), change.getCompilationUnit()); | |
540 | result.setEdit(change.getEdit()); | |
541 | return result.generated_1297851598183582600(change); | |
542 | } | |
543 | ||
544 | private void applyChange(ICompilationUnit compilationUnit, List<CleanUpChange> changes) throws JavaModelException, CoreException { | |
545 | IDocument document= new Document(changes.get(0).getCurrentContent(new NullProgressMonitor())); | |
546 | for (int i= 0; i < changes.size(); i++) { | |
547 | CleanUpChange change= changes.get(i); | |
548 | TextEdit edit= change.getEdit().copy(); | |
549 | ||
550 | try { | |
551 | edit.apply(document, TextEdit.UPDATE_REGIONS); | |
552 | } catch (MalformedTreeException e) { | |
553 | JavaPlugin.log(e); | |
554 | } catch (BadLocationException e) { | |
555 | JavaPlugin.log(e); | |
556 | } | |
557 | } | |
558 | compilationUnit.getBuffer().setContents(document.get()); | |
559 | } | |
560 | ||
561 | public Change[] generated_3192539793063366456(IJavaProject project, SubProgressMonitor subMonitor) throws CoreException { | |
562 | subMonitor.subTask(Messages.format(FixMessages.CleanUpRefactoring_Parser_Startup_message, BasicElementLabels.getResourceName(project.getProject()))); | |
563 | try { | |
564 | while (hasNext()) { | |
565 | next(subMonitor); | |
566 | } | |
567 | ||
568 | return getResult(); | |
569 | } finally { | |
570 | dispose(); | |
571 | subMonitor.done(); | |
572 | } | |
573 | } | |
574 | } | |
575 | ||
576 | private static final RefactoringTickProvider CLEAN_UP_REFACTORING_TICK_PROVIDER= new RefactoringTickProvider(0, 1, 0, 0); | |
577 | ||
578 | /** | |
579 | * A clean up is considered slow if its execution lasts longer then the value of | |
580 | * SLOW_CLEAN_UP_THRESHOLD in ms. | |
581 | */ | |
582 | private static final int SLOW_CLEAN_UP_THRESHOLD= 2000; | |
583 | ||
584 | private final List<ICleanUp> fCleanUps; | |
585 | private final Hashtable<IJavaProject, List<CleanUpTarget>> fProjects; | |
586 | public Change fChange; | |
587 | private boolean fLeaveFilesDirty; | |
588 | private final String fName; | |
589 | ||
590 | private boolean fUseOptionsFromProfile; | |
591 | ||
592 | public CleanUpRefactoring() { | |
593 | this(FixMessages.CleanUpRefactoring_Refactoring_name); | |
594 | } | |
595 | ||
596 | public CleanUpRefactoring(String name) { | |
597 | fName= name; | |
598 | fCleanUps= new ArrayList<ICleanUp>(); | |
599 | fProjects= new Hashtable<IJavaProject, List<CleanUpTarget>>(); | |
600 | fUseOptionsFromProfile= false; | |
601 | } | |
602 | ||
603 | public void setUseOptionsFromProfile(boolean enabled) { | |
604 | fUseOptionsFromProfile= enabled; | |
605 | } | |
606 | ||
607 | public void addCompilationUnit(ICompilationUnit unit) { | |
608 | addCleanUpTarget(new CleanUpTarget(unit)); | |
609 | } | |
610 | ||
611 | public void addCleanUpTarget(CleanUpTarget target) { | |
612 | ||
613 | target.generated_3512855110069567600(this); | |
614 | } | |
615 | ||
616 | public CleanUpTarget[] getCleanUpTargets() { | |
617 | List<CleanUpTarget> result= new ArrayList<CleanUpTarget>(); | |
618 | for (Iterator<List<CleanUpTarget>> iter= fProjects.values().iterator(); iter.hasNext();) { | |
619 | List<CleanUpTarget> projectTargets= iter.next(); | |
620 | result.addAll(projectTargets); | |
621 | } | |
622 | return result.toArray(new CleanUpTarget[result.size()]); | |
623 | } | |
624 | ||
625 | public int getCleanUpTargetsSize() { | |
626 | int result= 0; | |
627 | for (Iterator<List<CleanUpTarget>> iter= fProjects.values().iterator(); iter.hasNext();) { | |
628 | List<CleanUpTarget> projectTargets= iter.next(); | |
629 | result+= projectTargets.size(); | |
630 | } | |
631 | return result; | |
632 | } | |
633 | ||
634 | public void addCleanUp(ICleanUp fix) { | |
635 | fCleanUps.add(fix); | |
636 | } | |
637 | ||
638 | public void clearCleanUps() { | |
639 | fCleanUps.clear(); | |
640 | } | |
641 | ||
642 | public boolean hasCleanUps() { | |
643 | return !fCleanUps.isEmpty(); | |
644 | } | |
645 | ||
646 | public ICleanUp[] getCleanUps() { | |
647 | return fCleanUps.toArray(new ICleanUp[fCleanUps.size()]); | |
648 | } | |
649 | ||
650 | public IJavaProject[] getProjects() { | |
651 | return fProjects.keySet().toArray(new IJavaProject[fProjects.keySet().size()]); | |
652 | } | |
653 | ||
654 | public void setLeaveFilesDirty(boolean leaveFilesDirty) { | |
655 | fLeaveFilesDirty= leaveFilesDirty; | |
656 | } | |
657 | ||
658 | /* (non-Javadoc) | |
659 | * @see org.eclipse.ltk.core.refactoring.Refactoring#getName() | |
660 | */ | |
661 | @Override | |
662 | public String getName() { | |
663 | return fName; | |
664 | } | |
665 | ||
666 | /* (non-Javadoc) | |
667 | * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) | |
668 | */ | |
669 | @Override | |
670 | public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
671 | if (pm != null) { | |
672 | pm.beginTask("", 1); //$NON-NLS-1$ | |
673 | pm.worked(1); | |
674 | pm.done(); | |
675 | } | |
676 | return new RefactoringStatus(); | |
677 | } | |
678 | ||
679 | /* (non-Javadoc) | |
680 | * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor) | |
681 | */ | |
682 | @Override | |
683 | public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
684 | if (pm != null) { | |
685 | pm.beginTask("", 1); //$NON-NLS-1$ | |
686 | pm.worked(1); | |
687 | pm.done(); | |
688 | } | |
689 | return fChange; | |
690 | } | |
691 | ||
692 | /* (non-Javadoc) | |
693 | * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor) | |
694 | */ | |
695 | @Override | |
696 | public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
697 | ||
698 | if (pm == null) | |
699 | pm= new NullProgressMonitor(); | |
700 | ||
701 | if (fProjects.size() == 0 || fCleanUps.size() == 0) { | |
702 | pm.beginTask("", 1); //$NON-NLS-1$ | |
703 | pm.worked(1); | |
704 | pm.done(); | |
705 | fChange= new NullChange(); | |
706 | ||
707 | return new RefactoringStatus(); | |
708 | } | |
709 | ||
710 | int cuCount= getCleanUpTargetsSize(); | |
711 | ||
712 | RefactoringStatus result= new RefactoringStatus(); | |
713 | ||
714 | ICleanUp[] cleanUps= getCleanUps(); | |
715 | pm.beginTask("", cuCount * 2 * fCleanUps.size() + 4 * cleanUps.length); //$NON-NLS-1$ | |
716 | try { | |
717 | DynamicValidationStateChange change= new DynamicValidationStateChange(getName()); | |
718 | change.setSchedulingRule(getSchedulingRule()); | |
719 | for (Iterator<Entry<IJavaProject, List<CleanUpTarget>>> projectIter= fProjects.entrySet().iterator(); projectIter.hasNext();) { | |
720 | Entry<IJavaProject, List<CleanUpTarget>> entry= projectIter.next(); | |
721 | IJavaProject project= entry.getKey(); | |
722 | List<CleanUpTarget> targetsList= entry.getValue(); | |
723 | CleanUpTarget[] targets= targetsList.toArray(new CleanUpTarget[targetsList.size()]); | |
724 | ||
725 | if (fUseOptionsFromProfile) { | |
726 | result.merge(setOptionsFromProfile(project, cleanUps)); | |
727 | if (result.hasFatalError()) | |
728 | return result; | |
729 | } | |
730 | ||
731 | result.merge(checkPreConditions(project, targets, new SubProgressMonitor(pm, 3 * cleanUps.length))); | |
732 | if (result.hasFatalError()) | |
733 | return result; | |
734 | ||
735 | Change[] changes= cleanUpProject(project, targets, cleanUps, pm); | |
736 | ||
737 | result.merge(checkPostConditions(new SubProgressMonitor(pm, cleanUps.length))); | |
738 | if (result.hasFatalError()) | |
739 | return result; | |
740 | ||
741 | for (int i= 0; i < changes.length; i++) { | |
742 | change.add(changes[i]); | |
743 | } | |
744 | } | |
745 | List<IResource> files= change.generated_4320575570476407810(this); | |
746 | result.merge(Checks.validateModifiesFiles(files.toArray(new IFile[files.size()]), getValidationContext())); | |
747 | } finally { | |
748 | pm.done(); | |
749 | } | |
750 | ||
751 | return result; | |
752 | } | |
753 | ||
754 | public void findFilesToBeModified(CompositeChange change, List<IResource> result) throws JavaModelException { | |
755 | Change[] children= change.getChildren(); | |
756 | for (int i= 0; i < children.length; i++) { | |
757 | Change child= children[i]; | |
758 | if (child instanceof CompositeChange) { | |
759 | findFilesToBeModified((CompositeChange)child, result); | |
760 | } else if (child instanceof MultiStateCompilationUnitChange) { | |
761 | result.add(((MultiStateCompilationUnitChange)child).getCompilationUnit().getCorrespondingResource()); | |
762 | } else if (child instanceof CompilationUnitChange) { | |
763 | result.add(((CompilationUnitChange)child).getCompilationUnit().getCorrespondingResource()); | |
764 | } | |
765 | } | |
766 | } | |
767 | ||
768 | private Change[] cleanUpProject(IJavaProject project, CleanUpTarget[] targets, ICleanUp[] cleanUps, IProgressMonitor monitor) throws CoreException { | |
769 | CleanUpFixpointIterator iter= new CleanUpFixpointIterator(targets, cleanUps); | |
770 | ||
771 | SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 2 * targets.length * cleanUps.length); | |
772 | subMonitor.beginTask("", targets.length); //$NON-NLS-1$ | |
773 | return iter.generated_3192539793063366456(project, subMonitor); | |
774 | } | |
775 | ||
776 | private RefactoringStatus setOptionsFromProfile(IJavaProject javaProject, ICleanUp[] cleanUps) { | |
777 | Map<String, String> options= CleanUpPreferenceUtil.loadOptions(new ProjectScope(javaProject.getProject())); | |
778 | if (options == null) | |
779 | return RefactoringStatus.createFatalErrorStatus(Messages.format(FixMessages.CleanUpRefactoring_could_not_retrive_profile, BasicElementLabels.getResourceName(javaProject.getProject()))); | |
780 | ||
781 | CleanUpOptions cleanUpOptions= new MapCleanUpOptions(options); | |
782 | for (int i= 0; i < cleanUps.length; i++) | |
783 | cleanUps[i].setOptions(cleanUpOptions); | |
784 | ||
785 | return new RefactoringStatus(); | |
786 | } | |
787 | ||
788 | private RefactoringStatus checkPreConditions(IJavaProject javaProject, CleanUpTarget[] targets, IProgressMonitor monitor) throws CoreException { | |
789 | RefactoringStatus result= new RefactoringStatus(); | |
790 | ||
791 | ICompilationUnit[] compilationUnits= new ICompilationUnit[targets.length]; | |
792 | for (int i= 0; i < targets.length; i++) { | |
793 | compilationUnits[i]= targets[i].getCompilationUnit(); | |
794 | } | |
795 | ||
796 | ICleanUp[] cleanUps= getCleanUps(); | |
797 | monitor.beginTask("", compilationUnits.length * cleanUps.length); //$NON-NLS-1$ | |
798 | monitor.subTask(Messages.format(FixMessages.CleanUpRefactoring_Initialize_message, BasicElementLabels.getResourceName(javaProject.getProject()))); | |
799 | try { | |
800 | for (int j= 0; j < cleanUps.length; j++) { | |
801 | result.merge(cleanUps[j].checkPreConditions(javaProject, compilationUnits, new SubProgressMonitor(monitor, compilationUnits.length))); | |
802 | if (result.hasFatalError()) | |
803 | return result; | |
804 | } | |
805 | } finally { | |
806 | monitor.done(); | |
807 | } | |
808 | ||
809 | return result; | |
810 | } | |
811 | ||
812 | private RefactoringStatus checkPostConditions(SubProgressMonitor monitor) throws CoreException { | |
813 | RefactoringStatus result= new RefactoringStatus(); | |
814 | ||
815 | ICleanUp[] cleanUps= getCleanUps(); | |
816 | monitor.beginTask("", cleanUps.length); //$NON-NLS-1$ | |
817 | monitor.subTask(FixMessages.CleanUpRefactoring_checkingPostConditions_message); | |
818 | try { | |
819 | for (int j= 0; j < cleanUps.length; j++) { | |
820 | result.merge(cleanUps[j].checkPostConditions(new SubProgressMonitor(monitor, 1))); | |
821 | } | |
822 | } finally { | |
823 | monitor.done(); | |
824 | } | |
825 | return result; | |
826 | } | |
827 | ||
828 | private static String getChangeName(ICompilationUnit compilationUnit) { | |
829 | StringBuffer buf= new StringBuffer(); | |
830 | JavaElementLabels.getCompilationUnitLabel(compilationUnit, JavaElementLabels.ALL_DEFAULT, buf); | |
831 | buf.append(JavaElementLabels.CONCAT_STRING); | |
832 | ||
833 | StringBuffer buf2= new StringBuffer(); | |
834 | JavaElementLabels.getPackageFragmentLabel((IPackageFragment)compilationUnit.getParent(), JavaElementLabels.P_QUALIFIED, buf2); | |
835 | buf.append(buf2.toString().replace('.', '/')); | |
836 | ||
837 | return buf.toString(); | |
838 | } | |
839 | ||
840 | public static CleanUpChange calculateChange(CleanUpContext context, ICleanUp[] cleanUps, List<ICleanUp> undoneCleanUps, HashSet<ICleanUp> slowCleanUps) throws CoreException { | |
841 | if (cleanUps.length == 0) | |
842 | return null; | |
843 | ||
844 | CleanUpChange solution= null; | |
845 | int i= 0; | |
846 | do { | |
847 | ICleanUp cleanUp= cleanUps[i]; | |
848 | ICleanUpFix fix; | |
849 | if (slowCleanUps != null) { | |
850 | long timeBefore= System.currentTimeMillis(); | |
851 | fix= cleanUp.createFix(context); | |
852 | if (System.currentTimeMillis() - timeBefore > SLOW_CLEAN_UP_THRESHOLD) | |
853 | slowCleanUps.add(cleanUp); | |
854 | } else { | |
855 | fix= cleanUp.createFix(context); | |
856 | } | |
857 | if (fix != null) { | |
858 | CompilationUnitChange current= fix.createChange(null); | |
859 | TextEdit currentEdit= current.getEdit(); | |
860 | ||
861 | if (solution != null) { | |
862 | if (TextEditUtil.overlaps(currentEdit, solution.getEdit())) { | |
863 | undoneCleanUps.add(cleanUp); | |
864 | } else { | |
865 | CleanUpChange merge= new CleanUpChange(FixMessages.CleanUpRefactoring_clean_up_multi_chang_name, context.getCompilationUnit()); | |
866 | merge.setEdit(TextEditUtil.merge(currentEdit, solution.getEdit())); | |
867 | ||
868 | copyChangeGroups(merge, solution); | |
869 | copyChangeGroups(merge, current); | |
870 | ||
871 | solution= merge; | |
872 | } | |
873 | } else { | |
874 | solution= new CleanUpChange(current.getName(), context.getCompilationUnit()); | |
875 | solution.setEdit(currentEdit); | |
876 | ||
877 | copyChangeGroups(solution, current); | |
878 | } | |
879 | } | |
880 | i++; | |
881 | } while (i < cleanUps.length && (context.getAST() == null || !cleanUps[i].getRequirements().requiresFreshAST())); | |
882 | ||
883 | for (; i < cleanUps.length; i++) { | |
884 | undoneCleanUps.add(cleanUps[i]); | |
885 | } | |
886 | return solution; | |
887 | } | |
888 | ||
889 | private static void copyChangeGroups(CompilationUnitChange target, CompilationUnitChange source) { | |
890 | TextEditBasedChangeGroup[] changeGroups= source.getChangeGroups(); | |
891 | for (int i= 0; i < changeGroups.length; i++) { | |
892 | TextEditGroup textEditGroup= changeGroups[i].getTextEditGroup(); | |
893 | TextEditGroup newGroup; | |
894 | if (textEditGroup instanceof CategorizedTextEditGroup) { | |
895 | String label= textEditGroup.getName(); | |
896 | newGroup= new CategorizedTextEditGroup(label, new GroupCategorySet(new GroupCategory(label, label, label))); | |
897 | } else { | |
898 | newGroup= new TextEditGroup(textEditGroup.getName()); | |
899 | } | |
900 | TextEdit[] textEdits= textEditGroup.getTextEdits(); | |
901 | for (int j= 0; j < textEdits.length; j++) { | |
902 | newGroup.addTextEdit(textEdits[j]); | |
903 | } | |
904 | target.addTextEditGroup(newGroup); | |
905 | } | |
906 | } | |
907 | ||
908 | /* (non-Javadoc) | |
909 | * @see org.eclipse.ltk.core.refactoring.Refactoring#getRefactoringTickProvider() | |
910 | */ | |
911 | @Override | |
912 | protected RefactoringTickProvider doGetRefactoringTickProvider() { | |
913 | return CLEAN_UP_REFACTORING_TICK_PROVIDER; | |
914 | } | |
915 | ||
916 | /** | |
917 | * {@inheritDoc} | |
918 | */ | |
919 | public ISchedulingRule getSchedulingRule() { | |
920 | return ResourcesPlugin.getWorkspace().getRoot(); | |
921 | } | |
922 | ||
923 | public void generated_6419108774172304623(CleanUpConfigurationPage cleanupconfigurationpage) { | |
924 | int cleanUpTargetsSize= getCleanUpTargetsSize(); | |
925 | IJavaProject[] projects= getProjects(); | |
926 | if (cleanUpTargetsSize == 1) { | |
927 | cleanupconfigurationpage.setMessage(MultiFixMessages.CleanUpRefactoringWizard_CleaningUp11_Title); | |
928 | } else if (projects.length == 1) { | |
929 | cleanupconfigurationpage.setMessage(Messages.format(MultiFixMessages.CleanUpRefactoringWizard_CleaningUpN1_Title, new Integer(cleanUpTargetsSize))); | |
930 | } else { | |
931 | cleanupconfigurationpage.setMessage(Messages.format(MultiFixMessages.CleanUpRefactoringWizard_CleaningUpNN_Title, new Object[] {new Integer(cleanUpTargetsSize), new Integer(projects.length)})); | |
932 | } | |
933 | } | |
934 | ||
935 | public void generated_680054145197122767(CleanUpConfigurationPage cleanupconfigurationpage) { | |
936 | CleanUpOptions options= null; | |
937 | if (cleanupconfigurationpage.fUseCustomField.isSelected()) { | |
938 | setUseOptionsFromProfile(false); | |
939 | options= new MapCleanUpOptions(cleanupconfigurationpage.fCustomSettings); | |
940 | } else { | |
941 | setUseOptionsFromProfile(true); | |
942 | } | |
943 | ||
944 | clearCleanUps(); | |
945 | ICleanUp[] cleanups= JavaPlugin.getDefault().getCleanUpRegistry().createCleanUps(); | |
946 | for (int i= 0; i < cleanups.length; i++) { | |
947 | if (options != null) | |
948 | cleanups[i].setOptions(options); | |
949 | addCleanUp(cleanups[i]); | |
950 | } | |
951 | } | |
952 | ||
953 | public void generated_5919516677790640796(FixCorrectionProposal fixcorrectionproposal) { | |
954 | addCompilationUnit(fixcorrectionproposal.getCompilationUnit()); | |
955 | addCleanUp(fixcorrectionproposal.fCleanUp); | |
956 | setLeaveFilesDirty(true); | |
957 | ||
958 | int stopSeverity= RefactoringCore.getConditionCheckingFailedSeverity(); | |
959 | Shell shell= JavaPlugin.getActiveWorkbenchShell(); | |
960 | IRunnableContext context= PlatformUI.getWorkbench().getActiveWorkbenchWindow(); | |
961 | RefactoringExecutionHelper executer= new RefactoringExecutionHelper(this, stopSeverity, RefactoringSaveHelper.SAVE_NOTHING, shell, context); | |
962 | try { | |
963 | executer.perform(true, true); | |
964 | } catch (InterruptedException e) { | |
965 | } catch (InvocationTargetException e) { | |
966 | JavaPlugin.log(e); | |
967 | } | |
968 | return; | |
969 | } | |
970 | ||
971 | public RefactoringExecutionHelper generated_8947968545019694324(MultiFixTarget[] targets, final IProgressMonitor monitor, FixCorrectionProposal fixcorrectionproposal) { | |
972 | for (int i= 0; i < targets.length; i++) { | |
973 | addCleanUpTarget(targets[i]); | |
974 | } | |
975 | ||
976 | addCleanUp(fixcorrectionproposal.fCleanUp); | |
977 | ||
978 | IRunnableContext context= new IRunnableContext() { | |
979 | public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { | |
980 | runnable.run(monitor == null ? new NullProgressMonitor() : monitor); | |
981 | } | |
982 | }; | |
983 | ||
984 | Shell shell= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); | |
985 | RefactoringExecutionHelper helper= new RefactoringExecutionHelper(this, IStatus.INFO, RefactoringSaveHelper.SAVE_REFACTORING, shell, context); | |
986 | return helper; | |
987 | } | |
988 | ||
989 | public static ASTParser createCleanUpASTParser() { | |
990 | ASTParser result= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL); | |
991 | ||
992 | result.setResolveBindings(true); | |
993 | result.setStatementsRecovery(ASTProvider.SHARED_AST_STATEMENT_RECOVERY); | |
994 | result.setBindingsRecovery(ASTProvider.SHARED_BINDING_RECOVERY); | |
995 | ||
996 | return result; | |
997 | } | |
998 | ||
999 | } |