tolerate non local inspection tools returned from InspectionToolPRovider when configu...
[idea/community.git] / platform / testFramework / src / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.testFramework.fixtures.impl;
18
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.codeHighlighting.HighlightDisplayLevel;
21 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
22 import com.intellij.codeInsight.CodeInsightActionHandler;
23 import com.intellij.codeInsight.TargetElementUtilBase;
24 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
25 import com.intellij.codeInsight.completion.CompletionContext;
26 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
27 import com.intellij.codeInsight.completion.CompletionType;
28 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
29 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
30 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
31 import com.intellij.codeInsight.daemon.impl.*;
32 import com.intellij.codeInsight.intention.IntentionAction;
33 import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
34 import com.intellij.codeInsight.lookup.LookupElement;
35 import com.intellij.codeInsight.lookup.LookupManager;
36 import com.intellij.codeInsight.lookup.impl.LookupImpl;
37 import com.intellij.codeInspection.*;
38 import com.intellij.codeInspection.ex.*;
39 import com.intellij.facet.Facet;
40 import com.intellij.facet.FacetManager;
41 import com.intellij.find.FindManager;
42 import com.intellij.find.findUsages.FindUsagesHandler;
43 import com.intellij.find.findUsages.FindUsagesOptions;
44 import com.intellij.find.impl.FindManagerImpl;
45 import com.intellij.ide.DataManager;
46 import com.intellij.lang.annotation.HighlightSeverity;
47 import com.intellij.openapi.Disposable;
48 import com.intellij.openapi.actionSystem.DataContext;
49 import com.intellij.openapi.actionSystem.IdeActions;
50 import com.intellij.openapi.application.ApplicationManager;
51 import com.intellij.openapi.application.ModalityState;
52 import com.intellij.openapi.application.Result;
53 import com.intellij.openapi.command.WriteCommandAction;
54 import com.intellij.openapi.editor.Document;
55 import com.intellij.openapi.editor.Editor;
56 import com.intellij.openapi.editor.EditorFactory;
57 import com.intellij.openapi.editor.RangeMarker;
58 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
59 import com.intellij.openapi.editor.ex.DocumentEx;
60 import com.intellij.openapi.editor.ex.util.EditorUtil;
61 import com.intellij.openapi.editor.markup.GutterIconRenderer;
62 import com.intellij.openapi.editor.markup.RangeHighlighter;
63 import com.intellij.openapi.extensions.ExtensionPoint;
64 import com.intellij.openapi.extensions.ExtensionPointName;
65 import com.intellij.openapi.extensions.ExtensionsArea;
66 import com.intellij.openapi.fileEditor.FileEditorManager;
67 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
68 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
69 import com.intellij.openapi.fileTypes.FileType;
70 import com.intellij.openapi.fileTypes.FileTypeManager;
71 import com.intellij.openapi.module.Module;
72 import com.intellij.openapi.progress.ProgressIndicator;
73 import com.intellij.openapi.progress.ProgressManager;
74 import com.intellij.openapi.project.DumbServiceImpl;
75 import com.intellij.openapi.project.Project;
76 import com.intellij.openapi.util.*;
77 import com.intellij.openapi.util.io.FileUtil;
78 import com.intellij.openapi.util.text.StringUtil;
79 import com.intellij.openapi.vfs.LocalFileSystem;
80 import com.intellij.openapi.vfs.VfsUtil;
81 import com.intellij.openapi.vfs.VirtualFile;
82 import com.intellij.openapi.vfs.VirtualFileFilter;
83 import com.intellij.profile.codeInspection.InspectionProfileManager;
84 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
85 import com.intellij.psi.*;
86 import com.intellij.psi.impl.PsiManagerImpl;
87 import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
88 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
89 import com.intellij.psi.impl.source.PsiFileImpl;
90 import com.intellij.psi.impl.source.resolve.FileContextUtil;
91 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
92 import com.intellij.psi.search.GlobalSearchScope;
93 import com.intellij.psi.search.UsageSearchContext;
94 import com.intellij.psi.stubs.StubUpdatingIndex;
95 import com.intellij.psi.util.PsiUtilBase;
96 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
97 import com.intellij.refactoring.rename.RenameProcessor;
98 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
99 import com.intellij.testFramework.*;
100 import com.intellij.testFramework.fixtures.*;
101 import com.intellij.usageView.UsageInfo;
102 import com.intellij.util.ArrayUtil;
103 import com.intellij.util.CommonProcessors;
104 import com.intellij.util.Function;
105 import com.intellij.util.SmartList;
106 import com.intellij.util.containers.ContainerUtil;
107 import com.intellij.util.indexing.FileBasedIndex;
108 import gnu.trove.THashMap;
109 import junit.framework.Assert;
110 import org.jetbrains.annotations.NonNls;
111 import org.jetbrains.annotations.NotNull;
112 import org.jetbrains.annotations.Nullable;
113
114 import javax.swing.*;
115 import java.io.File;
116 import java.io.IOException;
117 import java.io.OutputStream;
118 import java.util.*;
119
120 /**
121  * @author Dmitry Avdeev
122  */
123 @SuppressWarnings({"TestMethodWithIncorrectSignature"})
124 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
125
126   @NonNls private static final String PROFILE = "Configurable";
127
128   private PsiManagerImpl myPsiManager;
129   private PsiFile myFile;
130   private Editor myEditor;
131   private String myTestDataPath;
132   private boolean myEmptyLookup;
133
134   private InspectionProfileEntry[] myInspections;
135   private final Map<String, InspectionProfileEntry> myAvailableTools = new THashMap<String, InspectionProfileEntry>();
136   private final Map<String, InspectionTool> myAvailableLocalTools = new THashMap<String, InspectionTool>();
137
138   private final TempDirTestFixture myTempDirFixture;
139   protected final IdeaProjectTestFixture myProjectFixture;
140   @NonNls private static final String XXX = "XXX";
141   private PsiElement myFileContext;
142   private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
143
144   public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
145     myProjectFixture = projectFixture;
146     myTempDirFixture = tempDirTestFixture;
147   }
148
149   public void setTestDataPath(String dataPath) {
150     myTestDataPath = dataPath;
151   }
152
153   public String getTempDirPath() {
154     return myTempDirFixture.getTempDirPath();
155   }
156
157   public TempDirTestFixture getTempDirFixture() {
158     return myTempDirFixture;
159   }
160
161   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
162     File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
163     if (!fromFile.exists()) {
164       fromFile = new File(sourceFilePath);
165     }
166
167     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
168       VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
169       if (fromVFile == null) {
170         fromVFile = myTempDirFixture.getFile(sourceFilePath);
171       }
172       assert fromVFile != null: "can't find testdata file " + sourceFilePath;
173       return myTempDirFixture.copyFile(fromVFile, targetPath);
174     }
175     final File destFile = new File(getTempDirPath() + "/" + targetPath);
176     if (!destFile.exists()) {
177
178       if (fromFile.isDirectory()) {
179         destFile.mkdirs();
180       }
181       else {
182         FileUtil.copy(fromFile, destFile);
183       }
184     }
185     final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
186     Assert.assertNotNull(file);
187     return file;
188   }
189
190   public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
191     assert getTestDataPath() != null: "test data path not specified";
192     final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
193     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
194       return myTempDirFixture.copyAll(fromFile.getPath(), targetPath);
195     }
196     else {
197       final File destFile = new File(getTempDirPath() + "/" + targetPath);
198       FileUtil.copyDir(fromFile, destFile);
199       final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
200       Assert.assertNotNull(file);
201       file.refresh(false, true);
202       return file;
203     }
204   }
205
206   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
207     return copyFileToProject(sourceFilePath, sourceFilePath);
208   }
209
210   public void enableInspections(InspectionProfileEntry... inspections) {
211     myInspections = inspections;
212     if (isInitialized()) {
213       configureInspections(myInspections);
214     }
215   }
216
217   private boolean isInitialized() {
218     return myPsiManager != null;
219   }
220
221   public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
222     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
223     for (Class clazz: inspections) {
224       try {
225         LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
226         tools.add(inspection);
227       }
228       catch (Exception e) {
229         throw new RuntimeException("Cannot instantiate " + clazz);
230       }
231     }
232     enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
233   }
234
235   public void disableInspections(InspectionProfileEntry... inspections) {
236     myAvailableTools.clear();
237     myAvailableLocalTools.clear();
238     final ArrayList<InspectionProfileEntry> tools = new ArrayList<InspectionProfileEntry>(Arrays.asList(myInspections));
239     for (Iterator<InspectionProfileEntry> i = tools.iterator(); i.hasNext();) {
240       final InspectionProfileEntry tool = i.next();
241       for (InspectionProfileEntry toRemove: inspections) {
242         if (tool.getShortName().equals(toRemove.getShortName())) {
243           i.remove();
244           break;
245         }
246       }
247     }
248     myInspections = tools.toArray(new InspectionProfileEntry[tools.size()]);
249     configureInspections(myInspections);
250   }
251
252   public void enableInspections(InspectionToolProvider... providers) {
253     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
254     for (InspectionToolProvider provider: providers) {
255       for (Class clazz: provider.getInspectionClasses()) {
256         try {
257           Object o = clazz.getConstructor().newInstance();
258           if (o instanceof LocalInspectionTool) {
259             LocalInspectionTool inspection = (LocalInspectionTool)o;
260             tools.add(inspection);
261           }
262         }
263         catch (Exception e) {
264           throw new RuntimeException("Cannot instantiate " + clazz, e);
265         }
266       }
267     }
268     myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
269     configureInspections(myInspections);
270   }
271
272   public long testHighlighting(final boolean checkWarnings,
273                                final boolean checkInfos,
274                                final boolean checkWeakWarnings,
275                                final String... filePaths) throws Exception {
276     final Ref<Long> duration = new Ref<Long>();
277     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
278
279       protected void run() throws Exception {
280         if (filePaths.length > 0) {
281           configureByFilesInner(filePaths);
282         }
283         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
284       }
285     }.execute().throwException();
286     return duration.get().longValue();
287   }
288
289   public long testHighlightingAllFiles(final boolean checkWarnings,
290                                        final boolean checkInfos,
291                                        final boolean checkWeakWarnings,
292                                        @NonNls final String... filePaths) throws Exception {
293     final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
294     for (String path : filePaths) {
295       files.add(copyFileToProject(path));
296     }
297     return testHighlightingAllFiles(checkWarnings, checkInfos, checkWeakWarnings, VfsUtil.toVirtualFileArray(files));
298   }
299
300   public long testHighlightingAllFiles(final boolean checkWarnings,
301                                final boolean checkInfos,
302                                final boolean checkWeakWarnings,
303                                @NonNls final VirtualFile... files) throws Exception {
304     final Ref<Long> duration = new Ref<Long>();
305     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
306
307       protected void run() throws Exception {
308         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration, files);
309       }
310     }.execute().throwException();
311     return duration.get().longValue();
312   }
313
314   private void collectAndCheckHighlightings(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final Ref<Long> duration,
315                                             final VirtualFile[] files) {
316     final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas = ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
317       public Trinity<PsiFile, Editor, ExpectedHighlightingData> fun(final VirtualFile file) {
318         final PsiFile psiFile = myPsiManager.findFile(file);
319         assertNotNull(psiFile);
320         final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
321         assertNotNull(document);
322         return Trinity.create(psiFile, createEditor(file), new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile));
323       }
324     });
325     for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
326       myEditor = trinity.second;
327       myFile = trinity.first;
328       collectAndCheckHighlightings(trinity.third, duration);
329     }
330   }
331
332   public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Exception {
333     final Ref<Long> duration = new Ref<Long>();
334     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
335       protected void run() throws Exception {
336         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
337       }
338     }.execute().throwException();
339     return duration.get().longValue();
340   }
341
342   public long checkHighlighting() throws Exception {
343     return checkHighlighting(true, true, true);
344   }
345
346   public long testHighlighting(final String... filePaths) throws Exception {
347     return testHighlighting(true, true, true, filePaths);
348   }
349
350   public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Exception {
351     final Ref<Long> duration = new Ref<Long>();
352     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
353       protected void run() throws Exception {
354         openFileInEditor(file);
355         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
356       }
357     }.execute().throwException();
358     return duration.get().longValue();
359   }
360
361   public void openFileInEditor(@NotNull final VirtualFile file) {
362     myFile = myPsiManager.findFile(file);
363     myEditor = createEditor(file);
364   }
365
366   public void testInspection(String testDir, InspectionTool tool) throws Exception {
367     VirtualFile sourceDir = copyDirectoryToProject(new File(testDir, "src").getPath(), "src");
368     AnalysisScope scope = new AnalysisScope(getPsiManager().findDirectory(sourceDir));
369
370     InspectionManagerEx inspectionManager = (InspectionManagerEx) InspectionManager.getInstance(getProject());
371     final GlobalInspectionContextImpl globalContext = inspectionManager.createNewGlobalContext(!(myProjectFixture instanceof LightIdeaTestFixture));
372     globalContext.setCurrentScope(scope);
373     scope.invalidate();
374
375     InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
376     InspectionTestUtil.compareToolResults(tool, false, new File(getTestDataPath(), testDir).getPath());
377   }
378
379   @Nullable
380   public PsiReference getReferenceAtCaretPosition(final String... filePaths) throws Exception {
381     new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
382       protected void run(final Result<PsiReference> result) throws Exception {
383         configureByFilesInner(filePaths);
384       }
385     }.execute().throwException();
386     return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
387   }
388
389   @NotNull
390   public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) throws Exception {
391     final PsiReference reference = getReferenceAtCaretPosition(filePaths);
392     assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
393     return reference;
394   }
395
396   @NotNull
397   public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Exception {
398
399     return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
400       protected void run(final Result<List<IntentionAction>> result) throws Exception {
401         configureByFilesInner(filePaths);
402         result.setResult(getAvailableIntentions());
403       }
404     }.execute().getResultObject();
405   }
406
407   @NotNull
408   public List<IntentionAction> getAllQuickFixes(@NonNls final String... filePaths) {
409     return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
410       protected void run(final Result<List<IntentionAction>> result) throws Exception {
411         configureByFilesInner(filePaths);
412         List<HighlightInfo> infos = doHighlighting();
413         ArrayList<IntentionAction> actions = new ArrayList<IntentionAction>();
414         for (HighlightInfo info : infos) {
415           for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
416             actions.add(pair.getFirst().getAction());
417           }
418         }
419         result.setResult(actions);
420       }
421     }.execute().getResultObject();
422   }
423
424   @NotNull
425   public List<IntentionAction> getAvailableIntentions() {
426     doHighlighting();
427     return getAvailableIntentions(myEditor, myFile);
428   }
429
430   public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) throws Exception {
431     final List<IntentionAction> availableIntentions = getAvailableIntentions();
432     return ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
433       public boolean value(final IntentionAction intentionAction) {
434         return intentionAction.getText().startsWith(hint);
435       }
436     });
437   }
438
439   public IntentionAction findSingleIntention(@NotNull final String hint) throws Exception {
440     final List<IntentionAction> list = filterAvailableIntentions(hint);
441     if (list.size() != 1) {
442       Assert.fail(StringUtil.join(getAvailableIntentions(), new Function<IntentionAction, String>() {
443         public String fun(final IntentionAction intentionAction) {
444           return intentionAction.getText();
445         }
446       }, ", "));
447     }
448     return UsefulTestCase.assertOneElement(list);
449   }
450
451   public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) throws Exception {
452     List<IntentionAction> intentions = getAvailableIntentions(filePaths);
453     return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
454   }
455
456   public void launchAction(@NotNull final IntentionAction action) throws Exception {
457     new WriteCommandAction(myProjectFixture.getProject()) {
458       protected void run(final Result result) throws Exception {
459         ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
460       }
461     }.execute().throwException();
462
463   }
464
465   public void testCompletion(final String[] filesBefore, final String fileAfter) throws Exception {
466     assertInitialized();
467     configureByFiles(filesBefore);
468     final LookupElement[] items = complete(CompletionType.BASIC);
469     if (items != null) {
470       System.out.println("items = " + Arrays.toString(items));
471     }
472     checkResultByFile(fileAfter);
473   }
474
475   protected void assertInitialized() {
476     Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
477   }
478
479   public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) throws Exception {
480     testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
481   }
482
483   public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Exception {
484     assertInitialized();
485     final List<String> result = getCompletionVariants(fileBefore);
486     UsefulTestCase.assertSameElements(result, expectedItems);
487   }
488
489   public List<String> getCompletionVariants(final String... filesBefore) throws Exception {
490     assertInitialized();
491     configureByFiles(filesBefore);
492     final LookupElement[] items = complete(CompletionType.BASIC);
493     Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
494     return getLookupElementStrings();
495   }
496
497   @Nullable
498   public List<String> getLookupElementStrings() {
499     assertInitialized();
500     final LookupElement[] elements = getLookupElements();
501     if (elements == null) return null;
502
503     return ContainerUtil.map(elements, new Function<LookupElement, String>() {
504       public String fun(final LookupElement lookupItem) {
505         return lookupItem.getLookupString();
506       }
507     });
508   }
509
510   public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) throws Exception {
511     assertInitialized();
512     configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
513     testRename(fileAfter, newName);
514   }
515
516   public void testRename(final String fileAfter, final String newName) throws Exception {
517     renameElementAtCaret(newName);
518     checkResultByFile(fileAfter);
519   }
520
521   public void renameElementAtCaret(final String newName) throws Exception {
522     assertInitialized();
523     final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
524                                                                                         TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
525     assert element != null : "element not found in file " + myFile.getName() + " at caret position, offset " +
526                              myEditor.getCaretModel().getOffset();
527     renameElement(element, newName);
528   }
529
530   public void renameElement(final PsiElement element, final String newName) throws Exception {
531     final boolean searchInComments = false;
532     final boolean searchTextOccurrences = false;
533     renameElement(element, newName, searchInComments, searchTextOccurrences);
534   }
535
536   public void renameElement(final PsiElement element,
537                              final String newName,
538                              final boolean searchInComments,
539                              final boolean searchTextOccurrences) throws Exception {
540     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
541       protected void run() throws Exception {
542         final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
543         new RenameProcessor(myProjectFixture.getProject(), substitution, newName, searchInComments, searchTextOccurrences).run();
544      }
545     }.execute().throwException();
546   }
547
548   public void type(final char c) {
549     assertInitialized();
550     new WriteCommandAction(getProject()) {
551       protected void run(Result result) throws Exception {
552         EditorActionManager actionManager = EditorActionManager.getInstance();
553         final DataContext dataContext = DataManager.getInstance().getDataContext();
554         if (c == '\b') {
555           performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
556           return;
557         }
558         if (c == '\n') {
559           if (LookupManager.getActiveLookup(getEditor()) != null) {
560             performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM);
561             return;
562           }
563
564           performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
565           return;
566         }
567         if (c == '\t') {
568           if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
569             performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE);
570             return;
571           }
572         }
573
574         actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
575       }
576     }.execute();
577   }
578
579   public void performEditorAction(final String actionId) {
580     assertInitialized();
581     final DataContext dataContext = DataManager.getInstance().getDataContext();
582     EditorActionManager actionManager = EditorActionManager.getInstance();
583     actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
584   }
585
586   public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) throws Exception {
587     assertInitialized();
588     configureByFiles(fileNames);
589     final PsiElement targetElement = TargetElementUtilBase
590       .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
591     assert targetElement != null : "Cannot find referenced element";
592     return findUsages(targetElement);
593   }
594
595   public Collection<UsageInfo> findUsages(@NotNull final PsiElement targetElement) {
596     final Project project = getProject();
597     final FindUsagesHandler handler = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
598
599     final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
600     final FindUsagesOptions options = new FindUsagesOptions(project, null);
601     options.isUsages = true;
602     assert handler != null : "Cannot find handler for: " + targetElement;
603     final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
604     for (PsiElement psiElement : psiElements) {
605       handler.processElementUsages(psiElement, processor, options);
606     }
607     return processor.getResults();
608   }
609
610   public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) throws Exception {
611     assertInitialized();
612     final Project project = myProjectFixture.getProject();
613     new WriteCommandAction.Simple(project) {
614       protected void run() throws Exception {
615         configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
616         final VirtualFile file = findFileInTempDir(to);
617         assert file.isDirectory() : to + " is not a directory";
618         final PsiDirectory directory = myPsiManager.findDirectory(file);
619         new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
620                                             false, false, null, null).run();
621       }
622     }.execute().throwException();
623
624   }
625
626   @Nullable
627   public GutterIconRenderer findGutter(final String filePath) throws Exception {
628     assertInitialized();
629     final Project project = myProjectFixture.getProject();
630     final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
631     new WriteCommandAction.Simple(project) {
632
633       protected void run() throws Exception {
634         final int offset = configureByFilesInner(filePath);
635
636         final Collection<HighlightInfo> infos = doHighlighting();
637         for (HighlightInfo info :infos) {
638           if (info.endOffset >= offset && info.startOffset <= offset) {
639             final GutterIconRenderer renderer = info.getGutterIconRenderer();
640             if (renderer != null) {
641               result.set(renderer);
642               return;
643             }
644           }
645         }
646
647       }
648     }.execute().throwException();
649     return result.get();
650   }
651
652   @NotNull
653   public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Exception {
654     assertInitialized();
655     final Project project = myProjectFixture.getProject();
656     final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
657     new WriteCommandAction.Simple(project) {
658
659       protected void run() throws Exception {
660         configureByFilesInner(filePath);
661
662         for (HighlightInfo info : doHighlighting()) {
663           addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset);
664         }
665
666         for (final RangeHighlighter highlighter : myEditor.getDocument().getMarkupModel(project).getAllHighlighters()) {
667           addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset());
668         }
669       }
670
671       private void addGutterIconRenderer(final GutterIconRenderer renderer, final int offset) {
672         if (renderer == null) return;
673
674         List<GutterIconRenderer> renderers = result.get(offset);
675         if (renderers == null) {
676           result.put(offset, renderers = new SmartList<GutterIconRenderer>());
677         }
678         renderers.add(renderer);
679       }
680
681     }.execute().throwException();
682     return ContainerUtil.concat(result.values());
683   }
684
685
686   public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) throws IOException {
687     assertInitialized();
688     return addFileToProject(getTempDirPath(), relativePath, fileText);
689   }
690
691   protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) throws IOException {
692     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
693       final VirtualFile file = myTempDirFixture.createFile(relativePath, fileText);
694       return PsiManager.getInstance(getProject()).findFile(file);
695     }
696
697     return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(rootPath, relativePath, fileText);
698   }
699
700   public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
701     assertInitialized();
702     final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
703     extensionPoint.registerExtension(extension);
704     disposeOnTearDown(new Disposable() {
705       public void dispose() {
706         extensionPoint.unregisterExtension(extension);
707       }
708     });
709   }
710
711   public PsiManager getPsiManager() {
712     return myPsiManager;
713   }
714
715   public LookupElement[] complete(final CompletionType type) {
716     assertInitialized();
717     myEmptyLookup = false;
718     new WriteCommandAction(getProject()) {
719       protected void run(Result result) throws Exception {
720         final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
721           protected PsiFile createFileCopy(final PsiFile file) {
722             final PsiFile copy = super.createFileCopy(file);
723             if (myFileContext != null) {
724               final PsiElement contextCopy = myFileContext.copy();
725               final PsiFile containingFile = contextCopy.getContainingFile();
726               if (containingFile instanceof PsiFileImpl) {
727                 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
728               }
729               setContext(copy, contextCopy);
730             }
731             return copy;
732           }
733
734           @Override
735           protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
736                                             final LookupElement[] items) {
737             myEmptyLookup = items.length == 0;
738             super.completionFinished(offset1, offset2, context, indicator, items);
739           }
740         };
741         Editor editor = getCompletionEditor();
742         handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
743       }
744     }.execute();
745     return getLookupElements();
746   }
747
748   @Nullable
749   protected Editor getCompletionEditor() {
750     return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
751   }
752
753   @Nullable
754   public LookupElement[] completeBasic() {
755     return complete(CompletionType.BASIC);
756   }
757
758   @Nullable
759   public LookupElement[] getLookupElements() {
760     LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
761     if (lookup == null) {
762       return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
763     }
764     else {
765       final List<LookupElement> list = lookup.getItems();
766       return list.toArray(new LookupElement[list.size()]);
767     }
768   }
769
770   public void checkResult(final String text) throws IOException {
771     checkResult(text, false);
772   }
773
774   public void checkResult(String text, boolean stripTrailingSpaces) throws IOException {
775     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
776     EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
777     checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
778   }
779
780   public void checkResultByFile(final String expectedFile) throws Exception {
781     checkResultByFile(expectedFile, false);
782   }
783
784   public void checkResultByFile(final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
785     assertInitialized();
786     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
787
788       protected void run() throws Exception {
789         checkResultByFile(expectedFile, myFile, ignoreTrailingWhitespaces);
790       }
791     }.execute().throwException();
792   }
793
794   public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
795     assertInitialized();
796
797     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
798
799       protected void run() throws Exception {
800         final VirtualFile copy = findFileInTempDir(filePath.replace(File.separatorChar, '/'));
801         final PsiFile psiFile = myPsiManager.findFile(copy);
802         assert psiFile != null;
803         checkResultByFile(expectedFile, psiFile, ignoreTrailingWhitespaces);
804       }
805     }.execute().throwException();
806   }
807
808   public void setUp() throws Exception {
809     super.setUp();
810
811     myProjectFixture.setUp();
812     myTempDirFixture.setUp();
813     myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
814     configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
815     DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
816   }
817
818   private void enableInspectionTool(InspectionProfileEntry tool){
819     final String shortName = tool.getShortName();
820     final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
821     if (key == null){
822       String id = tool instanceof LocalInspectionTool ? ((LocalInspectionTool)tool).getID() : shortName;
823       HighlightDisplayKey.register(shortName, tool.getDisplayName(), id);
824     }
825     myAvailableTools.put(shortName, tool);
826     myAvailableLocalTools.put(shortName, tool instanceof LocalInspectionTool ?
827                                          new LocalInspectionToolWrapper((LocalInspectionTool)tool) :
828                                          (InspectionTool)tool);
829   }
830
831   private void configureInspections(final InspectionProfileEntry[] tools) {
832     for (InspectionProfileEntry tool : tools) {
833       enableInspectionTool(tool);
834     }
835
836     final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
837       @NotNull
838       public ModifiableModel getModifiableModel() {
839         mySource = this;
840         return this;
841       }
842
843       @NotNull
844       public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
845         final Collection<InspectionTool> tools = myAvailableLocalTools.values();
846         return tools.toArray(new InspectionTool[tools.size()]);
847       }
848
849       @Override
850       public List<ToolsImpl> getAllEnabledInspectionTools() {
851         List<ToolsImpl> result = new ArrayList<ToolsImpl>();
852         for (InspectionProfileEntry entry : getInspectionTools(null)) {
853           result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
854         }
855         return result;
856       }
857
858       public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
859         return key != null && key.toString() != null && myAvailableTools.containsKey(key.toString());
860       }
861
862       public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
863         final InspectionProfileEntry entry = myAvailableTools.get(key.toString());
864         return entry != null ? entry.getDefaultLevel() : HighlightDisplayLevel.WARNING;
865       }
866
867       public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
868         return myAvailableLocalTools.get(shortName);
869       }
870     };
871     final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
872     inspectionProfileManager.addProfile(profile);
873     Disposer.register(getProject(), new Disposable() {
874       public void dispose() {
875         inspectionProfileManager.deleteProfile(PROFILE);
876       }
877     });
878     inspectionProfileManager.setRootProfile(profile.getName());
879     InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
880     InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
881   }
882
883   public void tearDown() throws Exception {
884     if (SwingUtilities.isEventDispatchThread()) {
885       LookupManager.getInstance(getProject()).hideActiveLookup();
886     }
887     else {
888       ApplicationManager.getApplication().invokeAndWait(new Runnable() {
889         public void run() {
890           LookupManager.getInstance(getProject()).hideActiveLookup();
891         }
892       }, ModalityState.NON_MODAL);
893     }
894
895     FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
896     VirtualFile[] openFiles = editorManager.getOpenFiles();
897     for (VirtualFile openFile : openFiles) {
898       editorManager.closeFile(openFile);
899     }
900
901     myProjectFixture.tearDown();
902     myTempDirFixture.tearDown();
903
904     super.tearDown();
905   }
906
907   private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
908     assertInitialized();
909     myFile = null;
910     myEditor = null;
911     for (int i = filePaths.length - 1; i > 0; i--) {
912       configureByFileInner(filePaths[i]);
913     }
914     return configureByFileInner(filePaths[0]);
915   }
916
917   public void configureByFile(final String file) throws IOException {
918     assertInitialized();
919     new WriteCommandAction.Simple(getProject()) {
920       protected void run() throws Exception {
921         configureByFilesInner(file);
922       }
923     }.execute();
924   }
925
926   public void configureByFiles(@NonNls final String... files) throws Exception {
927     new WriteCommandAction.Simple(getProject()) {
928       protected void run() throws Exception {
929         configureByFilesInner(files);
930       }
931     }.execute();
932   }
933
934   public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws IOException {
935     assertInitialized();
936     final String extension = fileType.getDefaultExtension();
937     final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
938     if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
939       new WriteCommandAction(getProject()) {
940         protected void run(Result result) throws Exception {
941           fileTypeManager.associateExtension(fileType, extension);
942         }
943       }.execute();
944     }
945     final VirtualFile vFile;
946     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
947       final VirtualFile root = LightPlatformTestCase.getSourceRoot();
948       root.refresh(false, false);
949       vFile = root.findOrCreateChildData(this, "aaa." + extension);
950     }
951     else{
952       final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
953       vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
954     }
955     VfsUtil.saveText(vFile, text);
956     configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
957     return myFile;
958   }
959
960   public PsiFile configureByText(String fileName, @NonNls String text) throws IOException {
961     return configureByText(FileTypeManager.getInstance().getFileTypeByFileName(fileName), text);
962   }
963
964   public Document getDocument(final PsiFile file) {
965     assertInitialized();
966     return PsiDocumentManager.getInstance(getProject()).getDocument(file);
967   }
968
969   public void setFileContext(@Nullable final PsiElement context) {
970     myFileContext = context;
971     setContext(myFile, context);
972   }
973
974   /**
975    *
976    * @param filePath
977    * @return caret offset or -1 if caret marker does not present
978    * @throws IOException
979    */
980   private int configureByFileInner(@NonNls String filePath) throws IOException {
981     assertInitialized();
982     final VirtualFile file = copyFileToProject(filePath);
983     return configureByFileInner(file);
984   }
985
986   public int configureFromTempProjectFile(final String filePath) throws IOException {
987     return configureByFileInner(findFileInTempDir(filePath));
988   }
989
990   public void configureFromExistingVirtualFile(VirtualFile f) throws IOException {
991     configureByFileInner(f);
992   }
993
994   private int configureByFileInner(final VirtualFile copy) throws IOException {
995     return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
996   }
997
998   private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
999     assertInitialized();
1000     try {
1001       final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
1002       outputStream.write(loader.newFileText.getBytes());
1003       outputStream.close();
1004     }
1005     catch (IOException e) {
1006       throw new RuntimeException(e);
1007     }
1008     myFile = myPsiManager.findFile(copy);
1009     setContext(myFile, myFileContext);
1010     myEditor = createEditor(copy);
1011     assert myEditor != null : "Editor couldn't be created for file: " + copy.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
1012     int offset = -1;
1013     if (loader.caretMarker != null) {
1014       offset = loader.caretMarker.getStartOffset();
1015       myEditor.getCaretModel().moveToOffset(offset);
1016     }
1017     if (loader.selStartMarker != null && loader.selEndMarker != null) {
1018       myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
1019     }
1020
1021     Module module = getModule();
1022     if (module != null) {
1023       for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
1024         module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
1025       }
1026     }
1027
1028     return offset;
1029   }
1030
1031   private static void setContext(final PsiFile file, final PsiElement context) {
1032     if (file != null && context != null) {
1033       file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new IdentitySmartPointer<PsiElement>(context));
1034     }
1035   }
1036
1037   public VirtualFile findFileInTempDir(final String filePath) {
1038     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1039       return myTempDirFixture.getFile(filePath);
1040     }
1041     String fullPath = getTempDirPath() + "/" + filePath;
1042
1043     final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
1044     assert copy != null : "file " + fullPath + " not found";
1045     return copy;
1046   }
1047
1048   @Nullable
1049   private Editor createEditor(VirtualFile file) {
1050     final Project project = getProject();
1051     final FileEditorManager instance = FileEditorManager.getInstance(project);
1052     if (file.getFileType().isBinary()) {
1053       return null;
1054     }
1055     return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
1056   }
1057
1058   private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
1059     throws Exception {
1060     ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
1061
1062     collectAndCheckHighlightings(data, duration);
1063   }
1064
1065   private void collectAndCheckHighlightings(final ExpectedHighlightingData data, final Ref<Long> duration) {
1066     final Project project = getProject();
1067     PsiDocumentManager.getInstance(project).commitAllDocuments();
1068
1069     ((PsiFileImpl)myFile).calcTreeElement(); //to load text
1070
1071     //to initialize caches
1072     myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
1073
1074     ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter);
1075
1076     final long start = System.currentTimeMillis();
1077 //    ProfilingUtil.startCPUProfiling();
1078     List<HighlightInfo> infos = doHighlighting();
1079     removeDuplicatedRangesForInjected(infos);
1080     final long elapsed = System.currentTimeMillis() - start;
1081     duration.set(duration.isNull()? elapsed : duration.get().longValue() + elapsed);
1082 //    ProfilingUtil.captureCPUSnapshot("testing");
1083
1084     ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
1085
1086     data.checkResult(infos, myEditor.getDocument().getText());
1087   }
1088
1089   private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
1090     Collections.sort(infos, new Comparator<HighlightInfo>() {
1091       public int compare(HighlightInfo o1, HighlightInfo o2) {
1092         final int i = o2.startOffset - o1.startOffset;
1093         return i != 0 ? i : o1.getSeverity().myVal - o2.getSeverity().myVal;
1094       }
1095     });
1096     HighlightInfo prevInfo = null;
1097     for (Iterator<HighlightInfo> it = infos.iterator(); it.hasNext();) {
1098       final HighlightInfo info = it.next();
1099       if (prevInfo != null &&
1100           info.getSeverity() == HighlightSeverity.INFORMATION &&
1101           info.description == null &&
1102           info.startOffset == prevInfo.startOffset &&
1103           info.endOffset == prevInfo.endOffset) {
1104         it.remove();
1105       }
1106       prevInfo = info.getSeverity() == HighlightInfoType.INJECTED_FRAGMENT_SEVERITY ? info : null;
1107     }
1108   }
1109
1110   @NotNull
1111   public List<HighlightInfo> doHighlighting() {
1112     final Project project = myProjectFixture.getProject();
1113     PsiDocumentManager.getInstance(project).commitAllDocuments();
1114
1115     return
1116     ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
1117       public List<HighlightInfo> compute() {
1118         return instantiateAndRun(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY, false);
1119       }
1120     });
1121   }
1122
1123   @NotNull
1124   public static List<HighlightInfo> instantiateAndRun(PsiFile file, Editor editor, int[] toIgnore, boolean allowDirt) {
1125     Project project = file.getProject();
1126     ensureIndexesUpToDate(project);
1127     DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
1128     FileStatusMap fileStatusMap = codeAnalyzer.getFileStatusMap();
1129     for (int ignoreId : toIgnore) {
1130       fileStatusMap.markFileUpToDate(editor.getDocument(), file, ignoreId);
1131     }
1132     fileStatusMap.allowDirt(allowDirt);
1133     try {
1134       TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter)TextEditorProvider.getInstance().getTextEditor(editor).getBackgroundHighlighter();
1135       final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
1136       final ProgressIndicator progress = new DaemonProgressIndicator();
1137       ProgressManager.getInstance().runProcess(new Runnable() {
1138         public void run() {
1139           for (TextEditorHighlightingPass pass : passes) {
1140             pass.collectInformation(progress);
1141             pass.applyInformationToEditor();
1142           }
1143         }
1144       }, progress);
1145       List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), project);
1146       return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
1147     }
1148     finally {
1149       fileStatusMap.allowDirt(true);
1150       codeAnalyzer.clearPasses();
1151     }
1152   }
1153
1154   private static void ensureIndexesUpToDate(Project project) {
1155     FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
1156     FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
1157     assertTrue(!DumbServiceImpl.getInstance(project).isDumb());
1158   }
1159
1160   public String getTestDataPath() {
1161     return myTestDataPath;
1162   }
1163
1164   public Project getProject() {
1165     return myProjectFixture.getProject();
1166   }
1167
1168   public Module getModule() {
1169     return myProjectFixture.getModule();
1170   }
1171
1172   public Editor getEditor() {
1173     return myEditor;
1174   }
1175
1176   public PsiFile getFile() {
1177     return myFile;
1178   }
1179
1180   public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
1181     return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
1182       public List<IntentionAction> compute() {
1183         return doGetAvailableIntentions(editor, file);
1184       }
1185     });
1186   }
1187
1188   private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
1189     ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
1190     ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
1191     List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
1192     descriptors.addAll(intentions.intentionsToShow);
1193     descriptors.addAll(intentions.errorFixesToShow);
1194     descriptors.addAll(intentions.inspectionFixesToShow);
1195     descriptors.addAll(intentions.guttersToShow);
1196
1197     PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1198     List<IntentionAction> result = new ArrayList<IntentionAction>();
1199
1200     List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(file.getProject(), file);
1201     for (HighlightInfo info : infos) {
1202       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1203         HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1204         if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1205           descriptors.add(actionInGroup);
1206         }
1207       }
1208     }
1209
1210     // add all intention options for simplicity
1211     for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1212       result.add(descriptor.getAction());
1213       List<IntentionAction> options = descriptor.getOptions(element);
1214       if (options != null) {
1215         for (IntentionAction option : options) {
1216           if (option.isAvailable(file.getProject(), editor, file)) {
1217             result.add(option);
1218           }
1219         }
1220       }
1221     }
1222     return result;
1223   }
1224
1225   public void allowTreeAccessForFile(final VirtualFile file) {
1226     myJavaFilesFilter.allowTreeAccessForFile(file);
1227   }
1228
1229   public void allowTreeAccessForAllFiles() {
1230     myJavaFilesFilter.allowTreeAccessForAllFiles();
1231   }
1232
1233   static class SelectionAndCaretMarkupLoader {
1234     final String newFileText;
1235     final RangeMarker caretMarker;
1236     final RangeMarker selStartMarker;
1237     final RangeMarker selEndMarker;
1238
1239     static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1240       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1241     }
1242     static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
1243       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(VfsUtil.loadText(file)), project);
1244     }
1245
1246     static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1247       return new SelectionAndCaretMarkupLoader(text, project);
1248     }
1249
1250     private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1251       final Document document = EditorFactory.getInstance().createDocument(fileText);
1252
1253       int caretIndex = fileText.indexOf(CARET_MARKER);
1254       int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1255       int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1256
1257       caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1258       selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1259       selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1260
1261       new WriteCommandAction(project) {
1262         protected void run(Result result) throws Exception {
1263           if (caretMarker != null) {
1264             document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1265           }
1266           if (selStartMarker != null) {
1267             document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1268           }
1269           if (selEndMarker != null) {
1270             document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1271           }
1272         }
1273       }.execute();
1274
1275       newFileText = document.getText();
1276     }
1277
1278   }
1279   private void checkResultByFile(@NonNls String expectedFile,
1280                                  @NotNull PsiFile originalFile,
1281                                  boolean stripTrailingSpaces) throws IOException {
1282     if (!stripTrailingSpaces) {
1283       EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
1284     }
1285     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1286     checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1287   }
1288
1289   private void checkResult(final String expectedFile,
1290                            final boolean stripTrailingSpaces,
1291                            final SelectionAndCaretMarkupLoader loader,
1292                            String actualText) {
1293     assertInitialized();
1294     Project project = myProjectFixture.getProject();
1295
1296     project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1297     if (stripTrailingSpaces) {
1298       actualText = stripTrailingSpaces(actualText);
1299     }
1300
1301     PsiDocumentManager.getInstance(project).commitAllDocuments();
1302
1303     String newFileText1 = loader.newFileText;
1304     if (stripTrailingSpaces) {
1305       newFileText1 = stripTrailingSpaces(newFileText1);
1306     }
1307
1308     actualText = StringUtil.convertLineSeparators(actualText);
1309
1310     //noinspection HardCodedStringLiteral
1311     Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1312
1313     if (loader.caretMarker != null) {
1314       int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1315       int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1316
1317       Assert.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1318       Assert.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1319     }
1320
1321     if (loader.selStartMarker != null && loader.selEndMarker != null) {
1322       int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1323       int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1324
1325       int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1326       int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1327
1328       Assert.assertEquals("selectionStartLine", selStartLine + 1,
1329                           StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1330
1331       Assert.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1332                                                                 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1333
1334       Assert.assertEquals("selectionEndLine", selEndLine + 1,
1335                           StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1336
1337       Assert.assertEquals("selectionEndCol", selEndCol + 1,
1338                           myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1339                           1);
1340     }
1341     else if (myEditor != null) {
1342       Assert.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());
1343     }
1344   }
1345
1346   private static String stripTrailingSpaces(String actualText) {
1347     final Document document = EditorFactory.getInstance().createDocument(actualText);
1348     ((DocumentEx)document).stripTrailingSpaces(false);
1349     actualText = document.getText();
1350     return actualText;
1351   }
1352
1353 }