42174f8acfe4d6fe6d075237ca4bb6e685cefe92
[fedora-idea.git] / platform / testFramework / src / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
blob42174f8acfe4d6fe6d075237ca4bb6e685cefe92
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.intellij.testFramework.fixtures.impl;
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;
114 import javax.swing.*;
115 import java.io.File;
116 import java.io.IOException;
117 import java.io.OutputStream;
118 import java.util.*;
121 * @author Dmitry Avdeev
123 @SuppressWarnings({"TestMethodWithIncorrectSignature"})
124 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
126 @NonNls private static final String PROFILE = "Configurable";
128 private PsiManagerImpl myPsiManager;
129 private PsiFile myFile;
130 private Editor myEditor;
131 private String myTestDataPath;
132 private boolean myEmptyLookup;
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>();
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();
144 public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
145 myProjectFixture = projectFixture;
146 myTempDirFixture = tempDirTestFixture;
149 public void setTestDataPath(String dataPath) {
150 myTestDataPath = dataPath;
153 public String getTempDirPath() {
154 return myTempDirFixture.getTempDirPath();
157 public TempDirTestFixture getTempDirFixture() {
158 return myTempDirFixture;
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);
167 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
168 VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
169 if (fromVFile == null) {
170 fromVFile = myTempDirFixture.getFile(sourceFilePath);
172 assert fromVFile != null: "can't find testdata file " + sourceFilePath;
173 return myTempDirFixture.copyFile(fromVFile, targetPath);
175 final File destFile = new File(getTempDirPath() + "/" + targetPath);
176 if (!destFile.exists()) {
178 if (fromFile.isDirectory()) {
179 destFile.mkdirs();
181 else {
182 FileUtil.copy(fromFile, destFile);
185 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
186 Assert.assertNotNull(file);
187 return file;
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);
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;
206 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
207 return copyFileToProject(sourceFilePath, sourceFilePath);
210 public void enableInspections(InspectionProfileEntry... inspections) {
211 myInspections = inspections;
212 if (isInitialized()) {
213 configureInspections(myInspections);
217 private boolean isInitialized() {
218 return myPsiManager != null;
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);
228 catch (Exception e) {
229 throw new RuntimeException("Cannot instantiate " + clazz);
232 enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
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;
248 myInspections = tools.toArray(new InspectionProfileEntry[tools.size()]);
249 configureInspections(myInspections);
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 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
258 tools.add(inspection);
260 catch (Exception e) {
261 throw new RuntimeException("Cannot instantiate " + clazz);
265 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
266 configureInspections(myInspections);
269 public long testHighlighting(final boolean checkWarnings,
270 final boolean checkInfos,
271 final boolean checkWeakWarnings,
272 final String... filePaths) throws Exception {
273 final Ref<Long> duration = new Ref<Long>();
274 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
276 protected void run() throws Exception {
277 if (filePaths.length > 0) {
278 configureByFilesInner(filePaths);
280 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
282 }.execute().throwException();
283 return duration.get().longValue();
286 public long testHighlightingAllFiles(final boolean checkWarnings,
287 final boolean checkInfos,
288 final boolean checkWeakWarnings,
289 @NonNls final String... filePaths) throws Exception {
290 final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
291 for (String path : filePaths) {
292 files.add(copyFileToProject(path));
294 return testHighlightingAllFiles(checkWarnings, checkInfos, checkWeakWarnings, VfsUtil.toVirtualFileArray(files));
297 public long testHighlightingAllFiles(final boolean checkWarnings,
298 final boolean checkInfos,
299 final boolean checkWeakWarnings,
300 @NonNls final VirtualFile... files) throws Exception {
301 final Ref<Long> duration = new Ref<Long>();
302 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
304 protected void run() throws Exception {
305 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration, files);
307 }.execute().throwException();
308 return duration.get().longValue();
311 private void collectAndCheckHighlightings(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final Ref<Long> duration,
312 final VirtualFile[] files) {
313 final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas = ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
314 public Trinity<PsiFile, Editor, ExpectedHighlightingData> fun(final VirtualFile file) {
315 final PsiFile psiFile = myPsiManager.findFile(file);
316 assertNotNull(psiFile);
317 final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
318 assertNotNull(document);
319 return Trinity.create(psiFile, createEditor(file), new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile));
322 for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
323 myEditor = trinity.second;
324 myFile = trinity.first;
325 collectAndCheckHighlightings(trinity.third, duration);
329 public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Exception {
330 final Ref<Long> duration = new Ref<Long>();
331 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
332 protected void run() throws Exception {
333 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
335 }.execute().throwException();
336 return duration.get().longValue();
339 public long checkHighlighting() throws Exception {
340 return checkHighlighting(true, true, true);
343 public long testHighlighting(final String... filePaths) throws Exception {
344 return testHighlighting(true, true, true, filePaths);
347 public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Exception {
348 final Ref<Long> duration = new Ref<Long>();
349 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
350 protected void run() throws Exception {
351 openFileInEditor(file);
352 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
354 }.execute().throwException();
355 return duration.get().longValue();
358 public void openFileInEditor(@NotNull final VirtualFile file) {
359 myFile = myPsiManager.findFile(file);
360 myEditor = createEditor(file);
363 public void testInspection(String testDir, InspectionTool tool) throws Exception {
364 VirtualFile sourceDir = copyDirectoryToProject(new File(testDir, "src").getPath(), "src");
365 AnalysisScope scope = new AnalysisScope(getPsiManager().findDirectory(sourceDir));
367 InspectionManagerEx inspectionManager = (InspectionManagerEx) InspectionManager.getInstance(getProject());
368 final GlobalInspectionContextImpl globalContext = inspectionManager.createNewGlobalContext(!(myProjectFixture instanceof LightIdeaTestFixture));
369 globalContext.setCurrentScope(scope);
370 scope.invalidate();
372 InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
373 InspectionTestUtil.compareToolResults(tool, false, new File(getTestDataPath(), testDir).getPath());
376 @Nullable
377 public PsiReference getReferenceAtCaretPosition(final String... filePaths) throws Exception {
378 new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
379 protected void run(final Result<PsiReference> result) throws Exception {
380 configureByFilesInner(filePaths);
382 }.execute().throwException();
383 return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
386 @NotNull
387 public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) throws Exception {
388 final PsiReference reference = getReferenceAtCaretPosition(filePaths);
389 assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
390 return reference;
393 @NotNull
394 public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Exception {
396 final Project project = myProjectFixture.getProject();
397 return new WriteCommandAction<List<IntentionAction>>(project) {
398 protected void run(final Result<List<IntentionAction>> result) throws Exception {
399 configureByFilesInner(filePaths);
400 result.setResult(getAvailableIntentions());
402 }.execute().getResultObject();
405 @NotNull
406 public List<IntentionAction> getAvailableIntentions() {
407 doHighlighting();
408 return getAvailableIntentions(myEditor, myFile);
411 public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) throws Exception {
412 final List<IntentionAction> availableIntentions = getAvailableIntentions();
413 return ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
414 public boolean value(final IntentionAction intentionAction) {
415 return intentionAction.getText().startsWith(hint);
420 public IntentionAction findSingleIntention(@NotNull final String hint) throws Exception {
421 final List<IntentionAction> list = filterAvailableIntentions(hint);
422 if (list.size() != 1) {
423 Assert.fail(StringUtil.join(getAvailableIntentions(), new Function<IntentionAction, String>() {
424 public String fun(final IntentionAction intentionAction) {
425 return intentionAction.getText();
427 }, ", "));
429 return UsefulTestCase.assertOneElement(list);
432 public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) throws Exception {
433 List<IntentionAction> intentions = getAvailableIntentions(filePaths);
434 return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
437 public void launchAction(@NotNull final IntentionAction action) throws Exception {
438 new WriteCommandAction(myProjectFixture.getProject()) {
439 protected void run(final Result result) throws Exception {
440 ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
442 }.execute().throwException();
446 public void testCompletion(final String[] filesBefore, final String fileAfter) throws Exception {
447 assertInitialized();
448 configureByFiles(filesBefore);
449 final LookupElement[] items = complete(CompletionType.BASIC);
450 if (items != null) {
451 System.out.println("items = " + Arrays.toString(items));
453 checkResultByFile(fileAfter);
456 protected void assertInitialized() {
457 Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
460 public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) throws Exception {
461 testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
464 public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Exception {
465 assertInitialized();
466 final List<String> result = getCompletionVariants(fileBefore);
467 UsefulTestCase.assertSameElements(result, expectedItems);
470 public List<String> getCompletionVariants(final String... filesBefore) throws Exception {
471 assertInitialized();
472 configureByFiles(filesBefore);
473 final LookupElement[] items = complete(CompletionType.BASIC);
474 Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
475 return getLookupElementStrings();
478 @Nullable
479 public List<String> getLookupElementStrings() {
480 assertInitialized();
481 final LookupElement[] elements = getLookupElements();
482 if (elements == null) return null;
484 return ContainerUtil.map(elements, new Function<LookupElement, String>() {
485 public String fun(final LookupElement lookupItem) {
486 return lookupItem.getLookupString();
491 public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) throws Exception {
492 assertInitialized();
493 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
494 testRename(fileAfter, newName);
497 public void testRename(final String fileAfter, final String newName) throws Exception {
498 renameElementAtCaret(newName);
499 checkResultByFile(fileAfter);
502 public void renameElementAtCaret(final String newName) throws Exception {
503 assertInitialized();
504 final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
505 TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
506 assert element != null : "element not found in file " + myFile.getName() + " at caret position, offset " +
507 myEditor.getCaretModel().getOffset();
508 renameElement(element, newName);
511 public void renameElement(final PsiElement element, final String newName) throws Exception {
512 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
513 protected void run() throws Exception {
514 final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
515 new RenameProcessor(myProjectFixture.getProject(), substitution, newName, false, false).run();
517 }.execute().throwException();
520 public void type(final char c) {
521 assertInitialized();
522 new WriteCommandAction(getProject()) {
523 protected void run(Result result) throws Exception {
524 EditorActionManager actionManager = EditorActionManager.getInstance();
525 final DataContext dataContext = DataManager.getInstance().getDataContext();
526 if (c == '\b') {
527 performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
528 return;
530 if (c == '\n') {
531 if (LookupManager.getActiveLookup(getEditor()) != null) {
532 performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM);
533 return;
536 performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
537 return;
539 if (c == '\t') {
540 if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
541 performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE);
542 return;
546 actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
548 }.execute();
551 public void performEditorAction(final String actionId) {
552 assertInitialized();
553 final DataContext dataContext = DataManager.getInstance().getDataContext();
554 EditorActionManager actionManager = EditorActionManager.getInstance();
555 actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
558 public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) throws Exception {
559 assertInitialized();
560 configureByFiles(fileNames);
561 final PsiElement targetElement = TargetElementUtilBase
562 .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
563 assert targetElement != null : "Cannot find referenced element";
564 return findUsages(targetElement);
567 public Collection<UsageInfo> findUsages(@NotNull final PsiElement targetElement) {
568 final Project project = getProject();
569 final FindUsagesHandler handler = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
571 final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
572 final FindUsagesOptions options = new FindUsagesOptions(project, null);
573 options.isUsages = true;
574 assert handler != null : "Cannot find handler for: " + targetElement;
575 final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
576 for (PsiElement psiElement : psiElements) {
577 handler.processElementUsages(psiElement, processor, options);
579 return processor.getResults();
582 public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) throws Exception {
583 assertInitialized();
584 final Project project = myProjectFixture.getProject();
585 new WriteCommandAction.Simple(project) {
586 protected void run() throws Exception {
587 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
588 final VirtualFile file = findFileInTempDir(to);
589 assert file.isDirectory() : to + " is not a directory";
590 final PsiDirectory directory = myPsiManager.findDirectory(file);
591 new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
592 false, false, null, null).run();
594 }.execute().throwException();
598 @Nullable
599 public GutterIconRenderer findGutter(final String filePath) throws Exception {
600 assertInitialized();
601 final Project project = myProjectFixture.getProject();
602 final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
603 new WriteCommandAction.Simple(project) {
605 protected void run() throws Exception {
606 final int offset = configureByFilesInner(filePath);
608 final Collection<HighlightInfo> infos = doHighlighting();
609 for (HighlightInfo info :infos) {
610 if (info.endOffset >= offset && info.startOffset <= offset) {
611 final GutterIconRenderer renderer = info.getGutterIconRenderer();
612 if (renderer != null) {
613 result.set(renderer);
614 return;
620 }.execute().throwException();
621 return result.get();
624 @NotNull
625 public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Exception {
626 assertInitialized();
627 final Project project = myProjectFixture.getProject();
628 final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
629 new WriteCommandAction.Simple(project) {
631 protected void run() throws Exception {
632 configureByFilesInner(filePath);
634 for (HighlightInfo info : doHighlighting()) {
635 addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset);
638 for (final RangeHighlighter highlighter : myEditor.getDocument().getMarkupModel(project).getAllHighlighters()) {
639 addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset());
643 private void addGutterIconRenderer(final GutterIconRenderer renderer, final int offset) {
644 if (renderer == null) return;
646 List<GutterIconRenderer> renderers = result.get(offset);
647 if (renderers == null) {
648 result.put(offset, renderers = new SmartList<GutterIconRenderer>());
650 renderers.add(renderer);
653 }.execute().throwException();
654 return ContainerUtil.concat(result.values());
658 public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) throws IOException {
659 assertInitialized();
660 return addFileToProject(getTempDirPath(), relativePath, fileText);
663 protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) throws IOException {
664 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
665 final VirtualFile file = myTempDirFixture.createFile(relativePath, fileText);
666 return PsiManager.getInstance(getProject()).findFile(file);
669 return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(rootPath, relativePath, fileText);
672 public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
673 assertInitialized();
674 final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
675 extensionPoint.registerExtension(extension);
676 disposeOnTearDown(new Disposable() {
677 public void dispose() {
678 extensionPoint.unregisterExtension(extension);
683 public PsiManager getPsiManager() {
684 return myPsiManager;
687 public LookupElement[] complete(final CompletionType type) {
688 assertInitialized();
689 myEmptyLookup = false;
690 new WriteCommandAction(getProject()) {
691 protected void run(Result result) throws Exception {
692 final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
693 protected PsiFile createFileCopy(final PsiFile file) {
694 final PsiFile copy = super.createFileCopy(file);
695 if (myFileContext != null) {
696 final PsiElement contextCopy = myFileContext.copy();
697 final PsiFile containingFile = contextCopy.getContainingFile();
698 if (containingFile instanceof PsiFileImpl) {
699 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
701 setContext(copy, contextCopy);
703 return copy;
706 @Override
707 protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
708 final LookupElement[] items) {
709 myEmptyLookup = items.length == 0;
710 super.completionFinished(offset1, offset2, context, indicator, items);
713 Editor editor = getCompletionEditor();
714 handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
716 }.execute();
717 return getLookupElements();
720 @Nullable
721 protected Editor getCompletionEditor() {
722 return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
725 @Nullable
726 public LookupElement[] completeBasic() {
727 return complete(CompletionType.BASIC);
730 @Nullable
731 public LookupElement[] getLookupElements() {
732 LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
733 if (lookup == null) {
734 return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
736 else {
737 final List<LookupElement> list = lookup.getItems();
738 return list.toArray(new LookupElement[list.size()]);
742 public void checkResult(final String text) throws IOException {
743 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
744 EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
745 checkResult("TEXT", false, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
748 public void checkResultByFile(final String expectedFile) throws Exception {
749 checkResultByFile(expectedFile, false);
752 public void checkResultByFile(final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
753 assertInitialized();
754 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
756 protected void run() throws Exception {
757 checkResultByFile(expectedFile, myFile, ignoreTrailingWhitespaces);
759 }.execute().throwException();
762 public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
763 assertInitialized();
765 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
767 protected void run() throws Exception {
768 final VirtualFile copy = findFileInTempDir(filePath.replace(File.separatorChar, '/'));
769 final PsiFile psiFile = myPsiManager.findFile(copy);
770 assert psiFile != null;
771 checkResultByFile(expectedFile, psiFile, ignoreTrailingWhitespaces);
773 }.execute().throwException();
776 public void setUp() throws Exception {
777 super.setUp();
779 myProjectFixture.setUp();
780 myTempDirFixture.setUp();
781 myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
782 configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
783 DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
786 private void enableInspectionTool(InspectionProfileEntry tool){
787 final String shortName = tool.getShortName();
788 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
789 if (key == null){
790 String id = tool instanceof LocalInspectionTool ? ((LocalInspectionTool)tool).getID() : shortName;
791 HighlightDisplayKey.register(shortName, tool.getDisplayName(), id);
793 myAvailableTools.put(shortName, tool);
794 myAvailableLocalTools.put(shortName, tool instanceof LocalInspectionTool ?
795 new LocalInspectionToolWrapper((LocalInspectionTool)tool) :
796 (InspectionTool)tool);
799 private void configureInspections(final InspectionProfileEntry[] tools) {
800 for (InspectionProfileEntry tool : tools) {
801 enableInspectionTool(tool);
804 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
805 @NotNull
806 public ModifiableModel getModifiableModel() {
807 mySource = this;
808 return this;
811 @NotNull
812 public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
813 final Collection<InspectionTool> tools = myAvailableLocalTools.values();
814 return tools.toArray(new InspectionTool[tools.size()]);
817 @Override
818 public List<ToolsImpl> getAllEnabledInspectionTools() {
819 List<ToolsImpl> result = new ArrayList<ToolsImpl>();
820 for (InspectionProfileEntry entry : getInspectionTools(null)) {
821 result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
823 return result;
826 public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
827 return key != null && key.toString() != null && myAvailableTools.containsKey(key.toString());
830 public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
831 final InspectionProfileEntry entry = myAvailableTools.get(key.toString());
832 return entry != null ? entry.getDefaultLevel() : HighlightDisplayLevel.WARNING;
835 public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
836 return myAvailableLocalTools.get(shortName);
839 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
840 inspectionProfileManager.addProfile(profile);
841 Disposer.register(getProject(), new Disposable() {
842 public void dispose() {
843 inspectionProfileManager.deleteProfile(PROFILE);
846 inspectionProfileManager.setRootProfile(profile.getName());
847 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
848 InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
851 public void tearDown() throws Exception {
852 if (SwingUtilities.isEventDispatchThread()) {
853 LookupManager.getInstance(getProject()).hideActiveLookup();
855 else {
856 ApplicationManager.getApplication().invokeAndWait(new Runnable() {
857 public void run() {
858 LookupManager.getInstance(getProject()).hideActiveLookup();
860 }, ModalityState.NON_MODAL);
863 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
864 VirtualFile[] openFiles = editorManager.getOpenFiles();
865 for (VirtualFile openFile : openFiles) {
866 editorManager.closeFile(openFile);
869 myProjectFixture.tearDown();
870 myTempDirFixture.tearDown();
872 super.tearDown();
875 private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
876 assertInitialized();
877 myFile = null;
878 myEditor = null;
879 for (int i = filePaths.length - 1; i > 0; i--) {
880 configureByFileInner(filePaths[i]);
882 return configureByFileInner(filePaths[0]);
885 public void configureByFile(final String file) throws IOException {
886 assertInitialized();
887 new WriteCommandAction.Simple(getProject()) {
888 protected void run() throws Exception {
889 configureByFilesInner(file);
891 }.execute();
894 public void configureByFiles(@NonNls final String... files) throws Exception {
895 new WriteCommandAction.Simple(getProject()) {
896 protected void run() throws Exception {
897 configureByFilesInner(files);
899 }.execute();
902 public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws IOException {
903 assertInitialized();
904 final String extension = fileType.getDefaultExtension();
905 final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
906 if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
907 new WriteCommandAction(getProject()) {
908 protected void run(Result result) throws Exception {
909 fileTypeManager.associateExtension(fileType, extension);
911 }.execute();
913 final VirtualFile vFile;
914 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
915 final VirtualFile root = LightPlatformTestCase.getSourceRoot();
916 root.refresh(false, false);
917 vFile = root.findOrCreateChildData(this, "aaa." + extension);
919 else{
920 final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
921 vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
923 VfsUtil.saveText(vFile, text);
924 configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
925 return myFile;
928 public PsiFile configureByText(String fileName, @NonNls String text) throws IOException {
929 return configureByText(FileTypeManager.getInstance().getFileTypeByFileName(fileName), text);
932 public Document getDocument(final PsiFile file) {
933 assertInitialized();
934 return PsiDocumentManager.getInstance(getProject()).getDocument(file);
937 public void setFileContext(@Nullable final PsiElement context) {
938 myFileContext = context;
939 setContext(myFile, context);
944 * @param filePath
945 * @return caret offset or -1 if caret marker does not present
946 * @throws IOException
948 private int configureByFileInner(@NonNls String filePath) throws IOException {
949 assertInitialized();
950 final VirtualFile file = copyFileToProject(filePath);
951 return configureByFileInner(file);
954 public int configureFromTempProjectFile(final String filePath) throws IOException {
955 return configureByFileInner(findFileInTempDir(filePath));
958 public void configureFromExistingVirtualFile(VirtualFile f) throws IOException {
959 configureByFileInner(f);
962 private int configureByFileInner(final VirtualFile copy) throws IOException {
963 return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
966 private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
967 assertInitialized();
968 try {
969 final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
970 outputStream.write(loader.newFileText.getBytes());
971 outputStream.close();
973 catch (IOException e) {
974 throw new RuntimeException(e);
976 myFile = myPsiManager.findFile(copy);
977 setContext(myFile, myFileContext);
978 myEditor = createEditor(copy);
979 assert myEditor != null : "Editor couldn't be created for file: " + copy.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
980 int offset = -1;
981 if (loader.caretMarker != null) {
982 offset = loader.caretMarker.getStartOffset();
983 myEditor.getCaretModel().moveToOffset(offset);
985 if (loader.selStartMarker != null && loader.selEndMarker != null) {
986 myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
989 Module module = getModule();
990 if (module != null) {
991 for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
992 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
996 return offset;
999 private static void setContext(final PsiFile file, final PsiElement context) {
1000 if (file != null && context != null) {
1001 file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new IdentitySmartPointer<PsiElement>(context));
1005 public VirtualFile findFileInTempDir(final String filePath) {
1006 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1007 return myTempDirFixture.getFile(filePath);
1009 String fullPath = getTempDirPath() + "/" + filePath;
1011 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
1012 assert copy != null : "file " + fullPath + " not found";
1013 return copy;
1016 @Nullable
1017 private Editor createEditor(VirtualFile file) {
1018 final Project project = getProject();
1019 final FileEditorManager instance = FileEditorManager.getInstance(project);
1020 if (file.getFileType().isBinary()) {
1021 return null;
1023 return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
1026 private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
1027 throws Exception {
1028 ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
1030 collectAndCheckHighlightings(data, duration);
1033 private void collectAndCheckHighlightings(final ExpectedHighlightingData data, final Ref<Long> duration) {
1034 final Project project = getProject();
1035 PsiDocumentManager.getInstance(project).commitAllDocuments();
1037 ((PsiFileImpl)myFile).calcTreeElement(); //to load text
1039 //to initialize caches
1040 myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
1042 ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter);
1044 final long start = System.currentTimeMillis();
1045 // ProfilingUtil.startCPUProfiling();
1046 List<HighlightInfo> infos = doHighlighting();
1047 removeDuplicatedRangesForInjected(infos);
1048 final long elapsed = System.currentTimeMillis() - start;
1049 duration.set(duration.isNull()? elapsed : duration.get().longValue() + elapsed);
1050 // ProfilingUtil.captureCPUSnapshot("testing");
1052 ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
1054 data.checkResult(infos, myEditor.getDocument().getText());
1057 private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
1058 Collections.sort(infos, new Comparator<HighlightInfo>() {
1059 public int compare(HighlightInfo o1, HighlightInfo o2) {
1060 final int i = o2.startOffset - o1.startOffset;
1061 return i != 0 ? i : o1.getSeverity().myVal - o2.getSeverity().myVal;
1064 HighlightInfo prevInfo = null;
1065 for (Iterator<HighlightInfo> it = infos.iterator(); it.hasNext();) {
1066 final HighlightInfo info = it.next();
1067 if (prevInfo != null &&
1068 info.getSeverity() == HighlightSeverity.INFORMATION &&
1069 info.description == null &&
1070 info.startOffset == prevInfo.startOffset &&
1071 info.endOffset == prevInfo.endOffset) {
1072 it.remove();
1074 prevInfo = info.getSeverity() == HighlightInfoType.INJECTED_FRAGMENT_SEVERITY ? info : null;
1078 @NotNull
1079 public List<HighlightInfo> doHighlighting() {
1080 final Project project = myProjectFixture.getProject();
1081 PsiDocumentManager.getInstance(project).commitAllDocuments();
1083 return
1084 ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
1085 public List<HighlightInfo> compute() {
1086 return instantiateAndRun(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY, false);
1091 @NotNull
1092 public static List<HighlightInfo> instantiateAndRun(PsiFile file, Editor editor, int[] toIgnore, boolean allowDirt) {
1093 Project project = file.getProject();
1094 ensureIndexesUpToDate(project);
1095 DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
1096 FileStatusMap fileStatusMap = codeAnalyzer.getFileStatusMap();
1097 for (int ignoreId : toIgnore) {
1098 fileStatusMap.markFileUpToDate(editor.getDocument(), file, ignoreId);
1100 fileStatusMap.allowDirt(allowDirt);
1101 try {
1102 TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter)TextEditorProvider.getInstance().getTextEditor(editor).getBackgroundHighlighter();
1103 final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
1104 final ProgressIndicator progress = new DaemonProgressIndicator();
1105 ProgressManager.getInstance().runProcess(new Runnable() {
1106 public void run() {
1107 for (TextEditorHighlightingPass pass : passes) {
1108 pass.collectInformation(progress);
1109 pass.applyInformationToEditor();
1112 }, progress);
1113 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), project);
1114 return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
1116 finally {
1117 fileStatusMap.allowDirt(true);
1118 codeAnalyzer.clearPasses();
1122 private static void ensureIndexesUpToDate(Project project) {
1123 FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
1124 FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
1125 assertTrue(!DumbServiceImpl.getInstance(project).isDumb());
1128 public String getTestDataPath() {
1129 return myTestDataPath;
1132 public Project getProject() {
1133 return myProjectFixture.getProject();
1136 public Module getModule() {
1137 return myProjectFixture.getModule();
1140 public Editor getEditor() {
1141 return myEditor;
1144 public PsiFile getFile() {
1145 return myFile;
1148 public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
1149 return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
1150 public List<IntentionAction> compute() {
1151 return doGetAvailableIntentions(editor, file);
1156 private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
1157 ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
1158 ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
1159 List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
1160 descriptors.addAll(intentions.intentionsToShow);
1161 descriptors.addAll(intentions.errorFixesToShow);
1162 descriptors.addAll(intentions.inspectionFixesToShow);
1163 descriptors.addAll(intentions.guttersToShow);
1165 PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1166 List<IntentionAction> result = new ArrayList<IntentionAction>();
1168 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(file.getProject(), file);
1169 for (HighlightInfo info : infos) {
1170 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1171 HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1172 if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1173 descriptors.add(actionInGroup);
1178 // add all intention options for simplicity
1179 for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1180 result.add(descriptor.getAction());
1181 List<IntentionAction> options = descriptor.getOptions(element);
1182 if (options != null) {
1183 for (IntentionAction option : options) {
1184 if (option.isAvailable(file.getProject(), editor, file)) {
1185 result.add(option);
1190 return result;
1193 public void allowTreeAccessForFile(final VirtualFile file) {
1194 myJavaFilesFilter.allowTreeAccessForFile(file);
1197 public void allowTreeAccessForAllFiles() {
1198 myJavaFilesFilter.allowTreeAccessForAllFiles();
1201 static class SelectionAndCaretMarkupLoader {
1202 final String newFileText;
1203 final RangeMarker caretMarker;
1204 final RangeMarker selStartMarker;
1205 final RangeMarker selEndMarker;
1207 static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1208 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1210 static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
1211 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(VfsUtil.loadText(file)), project);
1214 static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1215 return new SelectionAndCaretMarkupLoader(text, project);
1218 private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1219 final Document document = EditorFactory.getInstance().createDocument(fileText);
1221 int caretIndex = fileText.indexOf(CARET_MARKER);
1222 int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1223 int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1225 caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1226 selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1227 selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1229 new WriteCommandAction(project) {
1230 protected void run(Result result) throws Exception {
1231 if (caretMarker != null) {
1232 document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1234 if (selStartMarker != null) {
1235 document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1237 if (selEndMarker != null) {
1238 document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1241 }.execute();
1243 newFileText = document.getText();
1247 private void checkResultByFile(@NonNls String expectedFile,
1248 @NotNull PsiFile originalFile,
1249 boolean stripTrailingSpaces) throws IOException {
1250 if (!stripTrailingSpaces) {
1251 EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
1253 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1254 checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1257 private void checkResult(final String expectedFile,
1258 final boolean stripTrailingSpaces,
1259 final SelectionAndCaretMarkupLoader loader,
1260 String actualText) {
1261 assertInitialized();
1262 Project project = myProjectFixture.getProject();
1264 project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1265 if (stripTrailingSpaces) {
1266 actualText = stripTrailingSpaces(actualText);
1269 PsiDocumentManager.getInstance(project).commitAllDocuments();
1271 String newFileText1 = loader.newFileText;
1272 if (stripTrailingSpaces) {
1273 newFileText1 = stripTrailingSpaces(newFileText1);
1276 actualText = StringUtil.convertLineSeparators(actualText);
1278 //noinspection HardCodedStringLiteral
1279 Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1281 if (loader.caretMarker != null) {
1282 int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1283 int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1285 Assert.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1286 Assert.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1289 if (loader.selStartMarker != null && loader.selEndMarker != null) {
1290 int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1291 int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1293 int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1294 int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1296 Assert.assertEquals("selectionStartLine", selStartLine + 1,
1297 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1299 Assert.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1300 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1302 Assert.assertEquals("selectionEndLine", selEndLine + 1,
1303 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1305 Assert.assertEquals("selectionEndCol", selEndCol + 1,
1306 myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1309 else if (myEditor != null) {
1310 Assert.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());
1314 private static String stripTrailingSpaces(String actualText) {
1315 final Document document = EditorFactory.getInstance().createDocument(actualText);
1316 ((DocumentEx)document).stripTrailingSpaces(false);
1317 actualText = document.getText();
1318 return actualText;