removed old jam, rewrote seam jam components mode, added rename refactorings
[fedora-idea.git] / codeInsight / tests / com / intellij / codeInsight / daemon / DaemonAnalyzerTestCase.java
blobfeee43f556ead0c2d9eb827301442bd1290142bf
1 package com.intellij.codeInsight.daemon;
3 import com.intellij.codeHighlighting.HighlightDisplayLevel;
4 import com.intellij.codeHighlighting.Pass;
5 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
6 import com.intellij.codeInsight.CodeInsightTestCase;
7 import com.intellij.codeInsight.daemon.impl.*;
8 import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
9 import com.intellij.codeInsight.intention.IntentionAction;
10 import com.intellij.codeInspection.InspectionProfileEntry;
11 import com.intellij.codeInspection.InspectionToolProvider;
12 import com.intellij.codeInspection.LocalInspectionTool;
13 import com.intellij.codeInspection.ModifiableModel;
14 import com.intellij.codeInspection.ex.InspectionProfileImpl;
15 import com.intellij.codeInspection.ex.InspectionTool;
16 import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
17 import com.intellij.codeInspection.ex.ToolsImpl;
18 import com.intellij.ide.startup.StartupManagerEx;
19 import com.intellij.ide.startup.impl.StartupManagerImpl;
20 import com.intellij.lang.annotation.HighlightSeverity;
21 import com.intellij.openapi.Disposable;
22 import com.intellij.openapi.editor.Document;
23 import com.intellij.openapi.editor.Editor;
24 import com.intellij.openapi.fileTypes.FileType;
25 import com.intellij.openapi.fileTypes.FileTypeManager;
26 import com.intellij.openapi.fileTypes.StdFileTypes;
27 import com.intellij.openapi.module.Module;
28 import com.intellij.openapi.progress.ProgressIndicator;
29 import com.intellij.openapi.roots.ModuleRootManager;
30 import com.intellij.openapi.startup.StartupManager;
31 import com.intellij.openapi.util.Disposer;
32 import com.intellij.openapi.util.Pair;
33 import com.intellij.openapi.util.TextRange;
34 import com.intellij.openapi.util.io.FileUtil;
35 import com.intellij.openapi.vfs.LocalFileSystem;
36 import com.intellij.openapi.vfs.VfsUtil;
37 import com.intellij.openapi.vfs.VirtualFile;
38 import com.intellij.openapi.vfs.VirtualFileFilter;
39 import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
40 import com.intellij.profile.codeInspection.InspectionProfileManager;
41 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
42 import com.intellij.psi.*;
43 import com.intellij.psi.impl.JavaPsiFacadeEx;
44 import com.intellij.psi.impl.source.tree.TreeElement;
45 import com.intellij.psi.impl.source.tree.TreeUtil;
46 import com.intellij.psi.search.GlobalSearchScope;
47 import com.intellij.psi.search.UsageSearchContext;
48 import com.intellij.testFramework.ExpectedHighlightingData;
49 import com.intellij.util.IncorrectOperationException;
50 import gnu.trove.THashMap;
51 import gnu.trove.THashSet;
52 import gnu.trove.TIntArrayList;
53 import org.jetbrains.annotations.NonNls;
54 import org.jetbrains.annotations.NotNull;
56 import java.io.File;
57 import java.io.IOException;
58 import java.util.*;
60 public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
61 private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
62 private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
63 private boolean toInitializeDaemon;
64 protected final Set<VirtualFile> myAddedClasses = new THashSet<VirtualFile>();
66 protected void setUp() throws Exception {
67 super.setUp();
68 ((VirtualFilePointerManagerImpl)VirtualFilePointerManagerImpl.getInstance()).cleanupForNextTest();
70 final LocalInspectionTool[] tools = configureLocalInspectionTools();
71 for (LocalInspectionTool tool : tools) {
72 enableInspectionTool(tool);
75 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
76 @NotNull
77 public ModifiableModel getModifiableModel() {
78 mySource = this;
79 return this;
82 @NotNull
83 public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
84 final Collection<LocalInspectionToolWrapper> tools = myAvailableLocalTools.values();
85 return tools.toArray(new LocalInspectionToolWrapper[tools.size()]);
88 @Override
89 public List<ToolsImpl> getAllEnabledInspectionTools() {
90 List<ToolsImpl> result = new ArrayList<ToolsImpl>();
91 for (InspectionProfileEntry entry : getInspectionTools(null)) {
92 result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
94 return result;
97 public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
98 return key != null && myAvailableTools.containsKey(key.toString());
101 public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
102 final LocalInspectionTool localInspectionTool = key == null ? null : myAvailableTools.get(key.toString());
103 return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
106 public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
107 return myAvailableLocalTools.get(shortName);
110 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
111 inspectionProfileManager.addProfile(profile);
112 inspectionProfileManager.setRootProfile(PROFILE);
113 Disposer.register(getProject(), new Disposable() {
114 public void dispose() {
115 inspectionProfileManager.deleteProfile(PROFILE);
118 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
119 InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
120 DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
121 toInitializeDaemon = !daemonCodeAnalyzer.isInitialized();
122 if (toInitializeDaemon) {
123 daemonCodeAnalyzer.projectOpened();
125 ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runStartupActivities();
126 ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runPostStartupActivities();
129 protected void tearDown() throws Exception {
130 ((StartupManagerImpl)StartupManager.getInstance(getProject())).checkCleared();
131 if (toInitializeDaemon) {
132 DaemonCodeAnalyzer.getInstance(getProject()).projectClosed();
134 super.tearDown();
135 ((VirtualFilePointerManagerImpl)VirtualFilePointerManagerImpl.getInstance()).assertPointersDisposed();
138 protected void enableInspectionTool(LocalInspectionTool tool){
139 final String shortName = tool.getShortName();
140 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
141 if (key == null){
142 HighlightDisplayKey.register(shortName, tool.getDisplayName(), tool.getID());
144 myAvailableTools.put(shortName, tool);
145 myAvailableLocalTools.put(shortName, new LocalInspectionToolWrapper(tool));
148 protected void enableInspectionToolsFromProvider(InspectionToolProvider toolProvider){
149 try {
150 for(Class c:toolProvider.getInspectionClasses()) {
151 enableInspectionTool((LocalInspectionTool)c.newInstance());
154 catch (Exception e) {
155 throw new RuntimeException(e);
159 protected void disableInspectionTool(String shortName){
160 myAvailableTools.remove(shortName);
161 myAvailableLocalTools.remove(shortName);
164 protected LocalInspectionTool[] configureLocalInspectionTools() {
165 return new LocalInspectionTool[0];
168 protected static LocalInspectionTool[] createLocalInspectionTools(final InspectionToolProvider... provider) {
169 final ArrayList<LocalInspectionTool> result = new ArrayList<LocalInspectionTool>();
170 for (InspectionToolProvider toolProvider : provider) {
171 for (Class aClass : toolProvider.getInspectionClasses()) {
172 final Object tool;
173 try {
174 tool = aClass.newInstance();
175 assertTrue(tool instanceof LocalInspectionTool);
176 result.add((LocalInspectionTool)tool);
178 catch (Exception e) {
179 LOG.error(e);
183 return result.toArray(new LocalInspectionTool[result.size()]);
186 protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
187 configureByFile(filePath);
188 doDoTest(checkWarnings, checkInfos, checkWeakWarnings);
191 protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
192 doTest(filePath, checkWarnings, checkInfos, false);
195 protected void doTest(@NonNls String filePath, @NonNls String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception {
196 configureByFile(filePath, projectRoot);
197 doDoTest(checkWarnings, checkInfos);
200 protected void doTest(VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
201 doTest(new VirtualFile[] { vFile }, checkWarnings, checkInfos );
204 protected void doTest(VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
205 configureByFiles(null, vFile);
206 doDoTest(checkWarnings, checkInfos);
209 protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos) {
210 return doDoTest(checkWarnings, checkInfos, false);
213 protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) {
215 return checkHighlighting(new ExpectedHighlightingData(myEditor.getDocument(),checkWarnings, checkWeakWarnings, checkInfos, myFile));
218 protected Collection<HighlightInfo> checkHighlighting(final ExpectedHighlightingData data) {
219 PsiDocumentManager.getInstance(myProject).commitAllDocuments();
221 //to load text
222 TreeUtil.clearCaches((TreeElement)myFile.getNode());
224 //to initialize caches
225 myPsiManager.getCacheManager().getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(myProject), true);
226 VirtualFileFilter javaFilesFilter = new VirtualFileFilter() {
227 public boolean accept(VirtualFile file) {
228 if (myAddedClasses.contains(file)) return false;
230 FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
231 return (fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS) && !file.getName().equals("package-info.java");
234 final JavaPsiFacadeEx facade = getJavaFacade();
235 if (facade != null) {
236 facade.setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work
239 Collection<HighlightInfo> infos = doHighlighting();
241 if (facade != null) {
242 facade.setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
245 String text = myEditor.getDocument().getText();
246 data.checkLineMarkers(DaemonCodeAnalyzerImpl.getLineMarkers(getDocument(getFile()), getProject()), text);
247 data.checkResult(infos, text);
248 return infos;
251 public void allowTreeAccessForFile(final VirtualFile file) {
252 myAddedClasses.add(file);
255 protected Collection<HighlightInfo> highlightErrors() {
256 return filter(doHighlighting(), HighlightSeverity.ERROR);
259 protected List<HighlightInfo> doHighlighting() {
260 PsiDocumentManager.getInstance(myProject).commitAllDocuments();
262 TIntArrayList toIgnore = new TIntArrayList();
263 if (!doTestLineMarkers()) {
264 toIgnore.add(Pass.UPDATE_OVERRIDEN_MARKERS);
265 toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
266 toIgnore.add(Pass.LINE_MARKERS);
268 ProgressIndicator progress = new DaemonProgressIndicator();
269 List<TextEditorHighlightingPass> passes = TextEditorHighlightingPassRegistrarEx.getInstanceEx(getProject()).instantiatePasses(getFile(), getEditor(), toIgnore.toNativeArray());
271 for(Iterator<TextEditorHighlightingPass> i = passes.iterator();i.hasNext();) {
272 final TextEditorHighlightingPass pass = i.next();
274 if ((!(pass instanceof ExternalToolPass) && forceExternalValidation()) ||
275 (pass instanceof ExternalToolPass && !forceExternalValidation() && !doExternalValidation())
277 i.remove();
281 for (TextEditorHighlightingPass pass : passes) {
282 pass.collectInformation(progress);
284 for (TextEditorHighlightingPass pass : passes) {
285 pass.applyInformationToEditor();
288 if (doTestLineMarkers()) {
289 Document document = getDocument(getFile());
290 assertTrue(((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).getFileStatusMap().allDirtyScopesAreNull(document));
293 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(getEditor().getDocument(), getProject());
294 return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
297 public static List<HighlightInfo> filter(final List<HighlightInfo> infos, HighlightSeverity minSeverity) {
298 ArrayList<HighlightInfo> result = new ArrayList<HighlightInfo>();
299 for (final HighlightInfo info : infos) {
300 if (info.getSeverity().compareTo(minSeverity) >= 0) result.add(info);
302 return result;
305 protected boolean doTestLineMarkers() {
306 return false;
309 protected boolean doExternalValidation() {
310 return true;
313 protected boolean forceExternalValidation() {
314 return false;
317 protected static void findAndInvokeIntentionAction(final Collection<HighlightInfo> infos, String intentionActionName, final Editor editor,
318 final PsiFile file) throws IncorrectOperationException {
319 IntentionAction intentionAction = findIntentionAction(infos, intentionActionName, editor, file);
321 assertNotNull(intentionAction);
322 intentionAction.invoke(file.getProject(), editor, file);
325 protected static IntentionAction findIntentionAction(final Collection<HighlightInfo> infos, final String intentionActionName, final Editor editor,
326 final PsiFile file) {
327 List<IntentionAction> actions = LightQuickFixTestCase.getAvailableActions(editor, file);
328 IntentionAction intentionAction = LightQuickFixTestCase.findActionWithText(actions, intentionActionName);
330 if (intentionAction == null) {
331 final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
333 for (HighlightInfo info :infos) {
334 if (info.quickFixActionRanges != null) {
335 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
336 IntentionAction action = pair.first.getAction();
337 if (action.isAvailable(file.getProject(), editor, file)) availableActions.add(action);
342 intentionAction = LightQuickFixTestCase.findActionWithText(
343 availableActions,
344 intentionActionName
347 return intentionAction;
350 public void checkHighlighting(Editor editor, boolean checkWarnings, boolean checkInfos) {
351 setActiveEditor(editor);
352 doDoTest(checkWarnings, checkInfos);
355 public PsiClass createClass(String text) throws IOException {
356 return createClass(myModule, text);
359 protected PsiClass createClass(final Module module, final String text) throws IOException {
360 final String qname = ((PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", text)).getClasses()[0].getQualifiedName();
361 final VirtualFile[] files = ModuleRootManager.getInstance(module).getSourceRoots();
362 File dir;
363 if (files.length > 0) {
364 dir = VfsUtil.virtualToIoFile(files[0]);
366 else {
367 dir = createTempDir("unitTest");
368 VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
369 addSourceContentToRoots(module, vDir);
372 File file = new File(dir, qname.replace('.', '/') + ".java");
373 FileUtil.createIfDoesntExist(file);
374 VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(file.getCanonicalPath().replace(File.separatorChar, '/'));
375 VfsUtil.saveText(vFile, text);
376 return ((PsiJavaFile)myPsiManager.findFile(vFile)).getClasses()[0];