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
.*;
116 import java
.io
.IOException
;
117 import java
.io
.OutputStream
;
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()) {
182 FileUtil
.copy(fromFile
, destFile
);
185 final VirtualFile file
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(destFile
);
186 Assert
.assertNotNull(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
);
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);
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
) {
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())) {
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()) {
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
);
372 InspectionTestUtil
.runTool(tool
, scope
, globalContext
, inspectionManager
);
373 InspectionTestUtil
.compareToolResults(tool
, false, new File(getTestDataPath(), testDir
).getPath());
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());
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();
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();
406 public List
<IntentionAction
> getAvailableIntentions() {
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();
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
{
448 configureByFiles(filesBefore
);
449 final LookupElement
[] items
= complete(CompletionType
.BASIC
);
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
{
466 final List
<String
> result
= getCompletionVariants(fileBefore
);
467 UsefulTestCase
.assertSameElements(result
, expectedItems
);
470 public List
<String
> getCompletionVariants(final String
... filesBefore
) throws Exception
{
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();
479 public List
<String
> getLookupElementStrings() {
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
{
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
{
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
) {
522 new WriteCommandAction(getProject()) {
523 protected void run(Result result
) throws Exception
{
524 EditorActionManager actionManager
= EditorActionManager
.getInstance();
525 final DataContext dataContext
= DataManager
.getInstance().getDataContext();
527 performEditorAction(IdeActions
.ACTION_EDITOR_BACKSPACE
);
531 if (LookupManager
.getActiveLookup(getEditor()) != null) {
532 performEditorAction(IdeActions
.ACTION_CHOOSE_LOOKUP_ITEM
);
536 performEditorAction(IdeActions
.ACTION_EDITOR_ENTER
);
540 if (LookupManager
.getInstance(getProject()).getActiveLookup() != null) {
541 performEditorAction(IdeActions
.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE
);
546 actionManager
.getTypedAction().actionPerformed(getEditor(), c
, dataContext
);
551 public void performEditorAction(final String actionId
) {
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
{
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
{
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();
599 public GutterIconRenderer
findGutter(final String filePath
) throws Exception
{
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
);
620 }.execute().throwException();
625 public Collection
<GutterIconRenderer
> findAllGutters(final String filePath
) throws Exception
{
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
{
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
) {
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() {
687 public LookupElement
[] complete(final CompletionType type
) {
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
);
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()));
717 return getLookupElements();
721 protected Editor
getCompletionEditor() {
722 return InjectedLanguageUtil
.getEditorForInjectedLanguageNoCommit(myEditor
, myFile
);
726 public LookupElement
[] completeBasic() {
727 return complete(CompletionType
.BASIC
);
731 public LookupElement
[] getLookupElements() {
732 LookupImpl lookup
= (LookupImpl
)LookupManager
.getActiveLookup(myEditor
);
733 if (lookup
== null) {
734 return myEmptyLookup ? LookupElement
.EMPTY_ARRAY
: null;
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 checkResult(text
, false);
746 public void checkResult(String text
, boolean stripTrailingSpaces
) throws IOException
{
747 PsiDocumentManager
.getInstance(getProject()).commitAllDocuments();
748 EditorUtil
.fillVirtualSpaceUntilCaret(myEditor
);
749 checkResult("TEXT", stripTrailingSpaces
, SelectionAndCaretMarkupLoader
.fromText(text
, getProject()), myFile
.getText());
752 public void checkResultByFile(final String expectedFile
) throws Exception
{
753 checkResultByFile(expectedFile
, false);
756 public void checkResultByFile(final String expectedFile
, final boolean ignoreTrailingWhitespaces
) throws Exception
{
758 new WriteCommandAction
.Simple(myProjectFixture
.getProject()) {
760 protected void run() throws Exception
{
761 checkResultByFile(expectedFile
, myFile
, ignoreTrailingWhitespaces
);
763 }.execute().throwException();
766 public void checkResultByFile(final String filePath
, final String expectedFile
, final boolean ignoreTrailingWhitespaces
) throws Exception
{
769 new WriteCommandAction
.Simple(myProjectFixture
.getProject()) {
771 protected void run() throws Exception
{
772 final VirtualFile copy
= findFileInTempDir(filePath
.replace(File
.separatorChar
, '/'));
773 final PsiFile psiFile
= myPsiManager
.findFile(copy
);
774 assert psiFile
!= null;
775 checkResultByFile(expectedFile
, psiFile
, ignoreTrailingWhitespaces
);
777 }.execute().throwException();
780 public void setUp() throws Exception
{
783 myProjectFixture
.setUp();
784 myTempDirFixture
.setUp();
785 myPsiManager
= (PsiManagerImpl
)PsiManager
.getInstance(getProject());
786 configureInspections(myInspections
== null ?
new LocalInspectionTool
[0] : myInspections
);
787 DaemonCodeAnalyzerSettings
.getInstance().setImportHintEnabled(false);
790 private void enableInspectionTool(InspectionProfileEntry tool
){
791 final String shortName
= tool
.getShortName();
792 final HighlightDisplayKey key
= HighlightDisplayKey
.find(shortName
);
794 String id
= tool
instanceof LocalInspectionTool ?
((LocalInspectionTool
)tool
).getID() : shortName
;
795 HighlightDisplayKey
.register(shortName
, tool
.getDisplayName(), id
);
797 myAvailableTools
.put(shortName
, tool
);
798 myAvailableLocalTools
.put(shortName
, tool
instanceof LocalInspectionTool ?
799 new LocalInspectionToolWrapper((LocalInspectionTool
)tool
) :
800 (InspectionTool
)tool
);
803 private void configureInspections(final InspectionProfileEntry
[] tools
) {
804 for (InspectionProfileEntry tool
: tools
) {
805 enableInspectionTool(tool
);
808 final InspectionProfileImpl profile
= new InspectionProfileImpl(PROFILE
) {
810 public ModifiableModel
getModifiableModel() {
816 public InspectionProfileEntry
[] getInspectionTools(PsiElement element
) {
817 final Collection
<InspectionTool
> tools
= myAvailableLocalTools
.values();
818 return tools
.toArray(new InspectionTool
[tools
.size()]);
822 public List
<ToolsImpl
> getAllEnabledInspectionTools() {
823 List
<ToolsImpl
> result
= new ArrayList
<ToolsImpl
>();
824 for (InspectionProfileEntry entry
: getInspectionTools(null)) {
825 result
.add(new ToolsImpl(entry
, entry
.getDefaultLevel(), true));
830 public boolean isToolEnabled(HighlightDisplayKey key
, PsiElement element
) {
831 return key
!= null && key
.toString() != null && myAvailableTools
.containsKey(key
.toString());
834 public HighlightDisplayLevel
getErrorLevel(@NotNull HighlightDisplayKey key
, PsiElement element
) {
835 final InspectionProfileEntry entry
= myAvailableTools
.get(key
.toString());
836 return entry
!= null ? entry
.getDefaultLevel() : HighlightDisplayLevel
.WARNING
;
839 public InspectionTool
getInspectionTool(@NotNull String shortName
, @NotNull PsiElement element
) {
840 return myAvailableLocalTools
.get(shortName
);
843 final InspectionProfileManager inspectionProfileManager
= InspectionProfileManager
.getInstance();
844 inspectionProfileManager
.addProfile(profile
);
845 Disposer
.register(getProject(), new Disposable() {
846 public void dispose() {
847 inspectionProfileManager
.deleteProfile(PROFILE
);
850 inspectionProfileManager
.setRootProfile(profile
.getName());
851 InspectionProjectProfileManager
.getInstance(getProject()).updateProfile(profile
);
852 InspectionProjectProfileManager
.getInstance(getProject()).setProjectProfile(profile
.getName());
855 public void tearDown() throws Exception
{
856 if (SwingUtilities
.isEventDispatchThread()) {
857 LookupManager
.getInstance(getProject()).hideActiveLookup();
860 ApplicationManager
.getApplication().invokeAndWait(new Runnable() {
862 LookupManager
.getInstance(getProject()).hideActiveLookup();
864 }, ModalityState
.NON_MODAL
);
867 FileEditorManager editorManager
= FileEditorManager
.getInstance(getProject());
868 VirtualFile
[] openFiles
= editorManager
.getOpenFiles();
869 for (VirtualFile openFile
: openFiles
) {
870 editorManager
.closeFile(openFile
);
873 myProjectFixture
.tearDown();
874 myTempDirFixture
.tearDown();
879 private int configureByFilesInner(@NonNls String
... filePaths
) throws IOException
{
883 for (int i
= filePaths
.length
- 1; i
> 0; i
--) {
884 configureByFileInner(filePaths
[i
]);
886 return configureByFileInner(filePaths
[0]);
889 public void configureByFile(final String file
) throws IOException
{
891 new WriteCommandAction
.Simple(getProject()) {
892 protected void run() throws Exception
{
893 configureByFilesInner(file
);
898 public void configureByFiles(@NonNls final String
... files
) throws Exception
{
899 new WriteCommandAction
.Simple(getProject()) {
900 protected void run() throws Exception
{
901 configureByFilesInner(files
);
906 public PsiFile
configureByText(final FileType fileType
, @NonNls final String text
) throws IOException
{
908 final String extension
= fileType
.getDefaultExtension();
909 final FileTypeManager fileTypeManager
= FileTypeManager
.getInstance();
910 if (fileTypeManager
.getFileTypeByExtension(extension
) != fileType
) {
911 new WriteCommandAction(getProject()) {
912 protected void run(Result result
) throws Exception
{
913 fileTypeManager
.associateExtension(fileType
, extension
);
917 final VirtualFile vFile
;
918 if (myTempDirFixture
instanceof LightTempDirTestFixtureImpl
) {
919 final VirtualFile root
= LightPlatformTestCase
.getSourceRoot();
920 root
.refresh(false, false);
921 vFile
= root
.findOrCreateChildData(this, "aaa." + extension
);
924 final File tempFile
= File
.createTempFile("aaa", "." + extension
, new File(getTempDirPath()));
925 vFile
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(tempFile
);
927 VfsUtil
.saveText(vFile
, text
);
928 configureInner(vFile
, SelectionAndCaretMarkupLoader
.fromFile(vFile
, getProject()));
932 public PsiFile
configureByText(String fileName
, @NonNls String text
) throws IOException
{
933 return configureByText(FileTypeManager
.getInstance().getFileTypeByFileName(fileName
), text
);
936 public Document
getDocument(final PsiFile file
) {
938 return PsiDocumentManager
.getInstance(getProject()).getDocument(file
);
941 public void setFileContext(@Nullable final PsiElement context
) {
942 myFileContext
= context
;
943 setContext(myFile
, context
);
949 * @return caret offset or -1 if caret marker does not present
950 * @throws IOException
952 private int configureByFileInner(@NonNls String filePath
) throws IOException
{
954 final VirtualFile file
= copyFileToProject(filePath
);
955 return configureByFileInner(file
);
958 public int configureFromTempProjectFile(final String filePath
) throws IOException
{
959 return configureByFileInner(findFileInTempDir(filePath
));
962 public void configureFromExistingVirtualFile(VirtualFile f
) throws IOException
{
963 configureByFileInner(f
);
966 private int configureByFileInner(final VirtualFile copy
) throws IOException
{
967 return configureInner(copy
, SelectionAndCaretMarkupLoader
.fromFile(copy
, getProject()));
970 private int configureInner(@NotNull final VirtualFile copy
, final SelectionAndCaretMarkupLoader loader
) {
973 final OutputStream outputStream
= copy
.getOutputStream(null, 0, 0);
974 outputStream
.write(loader
.newFileText
.getBytes());
975 outputStream
.close();
977 catch (IOException e
) {
978 throw new RuntimeException(e
);
980 myFile
= myPsiManager
.findFile(copy
);
981 setContext(myFile
, myFileContext
);
982 myEditor
= createEditor(copy
);
983 assert myEditor
!= null : "Editor couldn't be created for file: " + copy
.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
985 if (loader
.caretMarker
!= null) {
986 offset
= loader
.caretMarker
.getStartOffset();
987 myEditor
.getCaretModel().moveToOffset(offset
);
989 if (loader
.selStartMarker
!= null && loader
.selEndMarker
!= null) {
990 myEditor
.getSelectionModel().setSelection(loader
.selStartMarker
.getStartOffset(), loader
.selEndMarker
.getStartOffset());
993 Module module
= getModule();
994 if (module
!= null) {
995 for (Facet facet
: FacetManager
.getInstance(module
).getAllFacets()) {
996 module
.getMessageBus().syncPublisher(FacetManager
.FACETS_TOPIC
).facetConfigurationChanged(facet
);
1003 private static void setContext(final PsiFile file
, final PsiElement context
) {
1004 if (file
!= null && context
!= null) {
1005 file
.putUserData(FileContextUtil
.INJECTED_IN_ELEMENT
, new IdentitySmartPointer
<PsiElement
>(context
));
1009 public VirtualFile
findFileInTempDir(final String filePath
) {
1010 if (myTempDirFixture
instanceof LightTempDirTestFixtureImpl
) {
1011 return myTempDirFixture
.getFile(filePath
);
1013 String fullPath
= getTempDirPath() + "/" + filePath
;
1015 final VirtualFile copy
= LocalFileSystem
.getInstance().refreshAndFindFileByPath(fullPath
.replace(File
.separatorChar
, '/'));
1016 assert copy
!= null : "file " + fullPath
+ " not found";
1021 private Editor
createEditor(VirtualFile file
) {
1022 final Project project
= getProject();
1023 final FileEditorManager instance
= FileEditorManager
.getInstance(project
);
1024 if (file
.getFileType().isBinary()) {
1027 return instance
.openTextEditor(new OpenFileDescriptor(project
, file
, 0), false);
1030 private void collectAndCheckHighlightings(boolean checkWarnings
, boolean checkInfos
, boolean checkWeakWarnings
, Ref
<Long
> duration
)
1032 ExpectedHighlightingData data
= new ExpectedHighlightingData(myEditor
.getDocument(), checkWarnings
, checkWeakWarnings
, checkInfos
, myFile
);
1034 collectAndCheckHighlightings(data
, duration
);
1037 private void collectAndCheckHighlightings(final ExpectedHighlightingData data
, final Ref
<Long
> duration
) {
1038 final Project project
= getProject();
1039 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
1041 ((PsiFileImpl
)myFile
).calcTreeElement(); //to load text
1043 //to initialize caches
1044 myPsiManager
.getCacheManager().getFilesWithWord(XXX
, UsageSearchContext
.IN_COMMENTS
, GlobalSearchScope
.allScope(project
), true);
1046 ((PsiManagerImpl
)PsiManager
.getInstance(project
)).setAssertOnFileLoadingFilter(myJavaFilesFilter
);
1048 final long start
= System
.currentTimeMillis();
1049 // ProfilingUtil.startCPUProfiling();
1050 List
<HighlightInfo
> infos
= doHighlighting();
1051 removeDuplicatedRangesForInjected(infos
);
1052 final long elapsed
= System
.currentTimeMillis() - start
;
1053 duration
.set(duration
.isNull()? elapsed
: duration
.get().longValue() + elapsed
);
1054 // ProfilingUtil.captureCPUSnapshot("testing");
1056 ((PsiManagerImpl
)PsiManager
.getInstance(project
)).setAssertOnFileLoadingFilter(VirtualFileFilter
.NONE
);
1058 data
.checkResult(infos
, myEditor
.getDocument().getText());
1061 private static void removeDuplicatedRangesForInjected(List
<HighlightInfo
> infos
) {
1062 Collections
.sort(infos
, new Comparator
<HighlightInfo
>() {
1063 public int compare(HighlightInfo o1
, HighlightInfo o2
) {
1064 final int i
= o2
.startOffset
- o1
.startOffset
;
1065 return i
!= 0 ? i
: o1
.getSeverity().myVal
- o2
.getSeverity().myVal
;
1068 HighlightInfo prevInfo
= null;
1069 for (Iterator
<HighlightInfo
> it
= infos
.iterator(); it
.hasNext();) {
1070 final HighlightInfo info
= it
.next();
1071 if (prevInfo
!= null &&
1072 info
.getSeverity() == HighlightSeverity
.INFORMATION
&&
1073 info
.description
== null &&
1074 info
.startOffset
== prevInfo
.startOffset
&&
1075 info
.endOffset
== prevInfo
.endOffset
) {
1078 prevInfo
= info
.getSeverity() == HighlightInfoType
.INJECTED_FRAGMENT_SEVERITY ? info
: null;
1083 public List
<HighlightInfo
> doHighlighting() {
1084 final Project project
= myProjectFixture
.getProject();
1085 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
1088 ApplicationManager
.getApplication().runReadAction(new Computable
<List
<HighlightInfo
>>() {
1089 public List
<HighlightInfo
> compute() {
1090 return instantiateAndRun(getFile(), getEditor(), ArrayUtil
.EMPTY_INT_ARRAY
, false);
1096 public static List
<HighlightInfo
> instantiateAndRun(PsiFile file
, Editor editor
, int[] toIgnore
, boolean allowDirt
) {
1097 Project project
= file
.getProject();
1098 ensureIndexesUpToDate(project
);
1099 DaemonCodeAnalyzerImpl codeAnalyzer
= (DaemonCodeAnalyzerImpl
)DaemonCodeAnalyzer
.getInstance(project
);
1100 FileStatusMap fileStatusMap
= codeAnalyzer
.getFileStatusMap();
1101 for (int ignoreId
: toIgnore
) {
1102 fileStatusMap
.markFileUpToDate(editor
.getDocument(), file
, ignoreId
);
1104 fileStatusMap
.allowDirt(allowDirt
);
1106 TextEditorBackgroundHighlighter highlighter
= (TextEditorBackgroundHighlighter
)TextEditorProvider
.getInstance().getTextEditor(editor
).getBackgroundHighlighter();
1107 final List
<TextEditorHighlightingPass
> passes
= highlighter
.getPasses(toIgnore
);
1108 final ProgressIndicator progress
= new DaemonProgressIndicator();
1109 ProgressManager
.getInstance().runProcess(new Runnable() {
1111 for (TextEditorHighlightingPass pass
: passes
) {
1112 pass
.collectInformation(progress
);
1113 pass
.applyInformationToEditor();
1117 List
<HighlightInfo
> infos
= DaemonCodeAnalyzerImpl
.getHighlights(editor
.getDocument(), project
);
1118 return infos
== null ? Collections
.<HighlightInfo
>emptyList() : new ArrayList
<HighlightInfo
>(infos
);
1121 fileStatusMap
.allowDirt(true);
1122 codeAnalyzer
.clearPasses();
1126 private static void ensureIndexesUpToDate(Project project
) {
1127 FileBasedIndex
.getInstance().ensureUpToDate(StubUpdatingIndex
.INDEX_ID
, project
, null);
1128 FileBasedIndex
.getInstance().ensureUpToDate(TodoIndex
.NAME
, project
, null);
1129 assertTrue(!DumbServiceImpl
.getInstance(project
).isDumb());
1132 public String
getTestDataPath() {
1133 return myTestDataPath
;
1136 public Project
getProject() {
1137 return myProjectFixture
.getProject();
1140 public Module
getModule() {
1141 return myProjectFixture
.getModule();
1144 public Editor
getEditor() {
1148 public PsiFile
getFile() {
1152 public static List
<IntentionAction
> getAvailableIntentions(final Editor editor
, final PsiFile file
) {
1153 return ApplicationManager
.getApplication().runReadAction(new Computable
<List
<IntentionAction
>>() {
1154 public List
<IntentionAction
> compute() {
1155 return doGetAvailableIntentions(editor
, file
);
1160 private static List
<IntentionAction
> doGetAvailableIntentions(Editor editor
, PsiFile file
) {
1161 ShowIntentionsPass
.IntentionsInfo intentions
= new ShowIntentionsPass
.IntentionsInfo();
1162 ShowIntentionsPass
.getActionsToShow(editor
, file
, intentions
, -1);
1163 List
<HighlightInfo
.IntentionActionDescriptor
> descriptors
= new ArrayList
<HighlightInfo
.IntentionActionDescriptor
>();
1164 descriptors
.addAll(intentions
.intentionsToShow
);
1165 descriptors
.addAll(intentions
.errorFixesToShow
);
1166 descriptors
.addAll(intentions
.inspectionFixesToShow
);
1167 descriptors
.addAll(intentions
.guttersToShow
);
1169 PsiElement element
= file
.findElementAt(editor
.getCaretModel().getOffset());
1170 List
<IntentionAction
> result
= new ArrayList
<IntentionAction
>();
1172 List
<HighlightInfo
> infos
= DaemonCodeAnalyzerImpl
.getFileLevelHighlights(file
.getProject(), file
);
1173 for (HighlightInfo info
: infos
) {
1174 for (Pair
<HighlightInfo
.IntentionActionDescriptor
, TextRange
> pair
: info
.quickFixActionRanges
) {
1175 HighlightInfo
.IntentionActionDescriptor actionInGroup
= pair
.first
;
1176 if (actionInGroup
.getAction().isAvailable(file
.getProject(), editor
, file
)) {
1177 descriptors
.add(actionInGroup
);
1182 // add all intention options for simplicity
1183 for (HighlightInfo
.IntentionActionDescriptor descriptor
: descriptors
) {
1184 result
.add(descriptor
.getAction());
1185 List
<IntentionAction
> options
= descriptor
.getOptions(element
);
1186 if (options
!= null) {
1187 for (IntentionAction option
: options
) {
1188 if (option
.isAvailable(file
.getProject(), editor
, file
)) {
1197 public void allowTreeAccessForFile(final VirtualFile file
) {
1198 myJavaFilesFilter
.allowTreeAccessForFile(file
);
1201 public void allowTreeAccessForAllFiles() {
1202 myJavaFilesFilter
.allowTreeAccessForAllFiles();
1205 static class SelectionAndCaretMarkupLoader
{
1206 final String newFileText
;
1207 final RangeMarker caretMarker
;
1208 final RangeMarker selStartMarker
;
1209 final RangeMarker selEndMarker
;
1211 static SelectionAndCaretMarkupLoader
fromFile(String path
, Project project
) throws IOException
{
1212 return new SelectionAndCaretMarkupLoader(StringUtil
.convertLineSeparators(new String(FileUtil
.loadFileText(new File(path
)))), project
);
1214 static SelectionAndCaretMarkupLoader
fromFile(VirtualFile file
, Project project
) throws IOException
{
1215 return new SelectionAndCaretMarkupLoader(StringUtil
.convertLineSeparators(VfsUtil
.loadText(file
)), project
);
1218 static SelectionAndCaretMarkupLoader
fromText(String text
, Project project
) {
1219 return new SelectionAndCaretMarkupLoader(text
, project
);
1222 private SelectionAndCaretMarkupLoader(String fileText
, Project project
) {
1223 final Document document
= EditorFactory
.getInstance().createDocument(fileText
);
1225 int caretIndex
= fileText
.indexOf(CARET_MARKER
);
1226 int selStartIndex
= fileText
.indexOf(SELECTION_START_MARKER
);
1227 int selEndIndex
= fileText
.indexOf(SELECTION_END_MARKER
);
1229 caretMarker
= caretIndex
>= 0 ? document
.createRangeMarker(caretIndex
, caretIndex
) : null;
1230 selStartMarker
= selStartIndex
>= 0 ? document
.createRangeMarker(selStartIndex
, selStartIndex
) : null;
1231 selEndMarker
= selEndIndex
>= 0 ? document
.createRangeMarker(selEndIndex
, selEndIndex
) : null;
1233 new WriteCommandAction(project
) {
1234 protected void run(Result result
) throws Exception
{
1235 if (caretMarker
!= null) {
1236 document
.deleteString(caretMarker
.getStartOffset(), caretMarker
.getStartOffset() + CARET_MARKER
.length());
1238 if (selStartMarker
!= null) {
1239 document
.deleteString(selStartMarker
.getStartOffset(), selStartMarker
.getStartOffset() + SELECTION_START_MARKER
.length());
1241 if (selEndMarker
!= null) {
1242 document
.deleteString(selEndMarker
.getStartOffset(), selEndMarker
.getStartOffset() + SELECTION_END_MARKER
.length());
1247 newFileText
= document
.getText();
1251 private void checkResultByFile(@NonNls String expectedFile
,
1252 @NotNull PsiFile originalFile
,
1253 boolean stripTrailingSpaces
) throws IOException
{
1254 if (!stripTrailingSpaces
) {
1255 EditorUtil
.fillVirtualSpaceUntilCaret(myEditor
);
1257 PsiDocumentManager
.getInstance(getProject()).commitAllDocuments();
1258 checkResult(expectedFile
, stripTrailingSpaces
, SelectionAndCaretMarkupLoader
.fromFile(getTestDataPath() + "/" + expectedFile
, getProject()), originalFile
.getText());
1261 private void checkResult(final String expectedFile
,
1262 final boolean stripTrailingSpaces
,
1263 final SelectionAndCaretMarkupLoader loader
,
1264 String actualText
) {
1265 assertInitialized();
1266 Project project
= myProjectFixture
.getProject();
1268 project
.getComponent(PostprocessReformattingAspect
.class).doPostponedFormatting();
1269 if (stripTrailingSpaces
) {
1270 actualText
= stripTrailingSpaces(actualText
);
1273 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
1275 String newFileText1
= loader
.newFileText
;
1276 if (stripTrailingSpaces
) {
1277 newFileText1
= stripTrailingSpaces(newFileText1
);
1280 actualText
= StringUtil
.convertLineSeparators(actualText
);
1282 //noinspection HardCodedStringLiteral
1283 Assert
.assertEquals("Text mismatch in file " + expectedFile
, newFileText1
, actualText
);
1285 if (loader
.caretMarker
!= null) {
1286 int caretLine
= StringUtil
.offsetToLineNumber(loader
.newFileText
, loader
.caretMarker
.getStartOffset());
1287 int caretCol
= loader
.caretMarker
.getStartOffset() - StringUtil
.lineColToOffset(loader
.newFileText
, caretLine
, 0);
1289 Assert
.assertEquals("caretLine", caretLine
+ 1, myEditor
.getCaretModel().getLogicalPosition().line
+ 1);
1290 Assert
.assertEquals("caretColumn", caretCol
+ 1, myEditor
.getCaretModel().getLogicalPosition().column
+ 1);
1293 if (loader
.selStartMarker
!= null && loader
.selEndMarker
!= null) {
1294 int selStartLine
= StringUtil
.offsetToLineNumber(loader
.newFileText
, loader
.selStartMarker
.getStartOffset());
1295 int selStartCol
= loader
.selStartMarker
.getStartOffset() - StringUtil
.lineColToOffset(loader
.newFileText
, selStartLine
, 0);
1297 int selEndLine
= StringUtil
.offsetToLineNumber(loader
.newFileText
, loader
.selEndMarker
.getEndOffset());
1298 int selEndCol
= loader
.selEndMarker
.getEndOffset() - StringUtil
.lineColToOffset(loader
.newFileText
, selEndLine
, 0);
1300 Assert
.assertEquals("selectionStartLine", selStartLine
+ 1,
1301 StringUtil
.offsetToLineNumber(loader
.newFileText
, myEditor
.getSelectionModel().getSelectionStart()) + 1);
1303 Assert
.assertEquals("selectionStartCol", selStartCol
+ 1, myEditor
.getSelectionModel().getSelectionStart() -
1304 StringUtil
.lineColToOffset(loader
.newFileText
, selStartLine
, 0) + 1);
1306 Assert
.assertEquals("selectionEndLine", selEndLine
+ 1,
1307 StringUtil
.offsetToLineNumber(loader
.newFileText
, myEditor
.getSelectionModel().getSelectionEnd()) + 1);
1309 Assert
.assertEquals("selectionEndCol", selEndCol
+ 1,
1310 myEditor
.getSelectionModel().getSelectionEnd() - StringUtil
.lineColToOffset(loader
.newFileText
, selEndLine
, 0) +
1313 else if (myEditor
!= null) {
1314 Assert
.assertTrue("has no selection", !myEditor
.getSelectionModel().hasSelection());
1318 private static String
stripTrailingSpaces(String actualText
) {
1319 final Document document
= EditorFactory
.getInstance().createDocument(actualText
);
1320 ((DocumentEx
)document
).stripTrailingSpaces(false);
1321 actualText
= document
.getText();