From b9fb6c38ae524b68a3fcbd15c5f456756b3a9730 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 13 Jan 2010 14:58:59 +0300 Subject: [PATCH] IDEADEV-42010 --- .../intellij/codeInsight/CodeInsightTestCase.java | 22 ++++++++++++--- .../codeInsight/daemon/DaemonAnalyzerTestCase.java | 33 ++++++++++++++++++---- .../codeInsight/daemon/impl/DaemonListeners.java | 26 ++++++++++++++--- 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index c1aa5428a1..f8b6fcf274 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -21,7 +21,9 @@ import com.intellij.injected.editor.EditorWindow; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; @@ -29,6 +31,8 @@ import com.intellij.openapi.editor.actionSystem.TypedAction; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.roots.ContentEntry; @@ -112,7 +116,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase { return configureByFiles(projectFile, vFiles); } - protected VirtualFile configureByFile(String filePath, String projectRoot) throws Exception { + protected VirtualFile configureByFile(@NonNls String filePath, String projectRoot) throws Exception { String fullPath = getTestDataPath() + filePath; final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); @@ -586,11 +590,21 @@ public abstract class CodeInsightTestCase extends PsiTestCase { } } + protected void undo() { + UndoManager undoManager = UndoManager.getInstance(myProject); + TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(getEditor()); + undoManager.undo(textEditor); + } + protected void backspace() { - EditorActionManager actionManager = EditorActionManager.getInstance(); - EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + public void run() { + EditorActionManager actionManager = EditorActionManager.getInstance(); + EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); - actionHandler.execute(getEditor(), DataManager.getInstance().getDataContext()); + actionHandler.execute(getEditor(), DataManager.getInstance().getDataContext()); + } + }, "backspace", getEditor().getDocument()); } protected void ctrlShiftF7() { diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java index 9d8a94281c..ea6a40a455 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java @@ -143,6 +143,8 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase { ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runStartupActivities(); ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runPostStartupActivities(); DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false); + + myRunCommandForTest = wrapInCommand(); } protected void tearDown() throws Exception { @@ -307,17 +309,36 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase { public @interface CanChangeDocumentDuringHighlighting {} private boolean canChangeDocumentDuringHighlighting() { + return annotatedWith(CanChangeDocumentDuringHighlighting.class); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD, ElementType.TYPE}) + public @interface DoNotWrapInCommand {} + + private boolean wrapInCommand() { + return !annotatedWith(DoNotWrapInCommand.class); + } + + private boolean annotatedWith(Class annotationClass) { String methodName = "test" + getTestName(false); + Class aClass = getClass(); + if (aClass.getAnnotation(annotationClass) != null) return true; Method method = null; - try { - Class aClass = getClass(); - if (aClass.getAnnotation(CanChangeDocumentDuringHighlighting.class) != null) return true; - method = aClass.getDeclaredMethod(methodName); + while (aClass != null) { + try { + method = aClass.getDeclaredMethod(methodName); + break; + } + catch (NoSuchMethodException e) { + aClass = aClass.getSuperclass(); + } } - catch (NoSuchMethodException e) { + if (method == null) { fail(methodName); } - CanChangeDocumentDuringHighlighting annotation = method.getAnnotation(CanChangeDocumentDuringHighlighting.class); + + Object annotation = method.getAnnotation(annotationClass); return annotation != null; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index 012cc01c59..46fc190dba 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -29,6 +29,7 @@ import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.command.CommandAdapter; import com.intellij.openapi.command.CommandEvent; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.impl.UndoManagerImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.DocCommandGroupId; @@ -269,16 +270,33 @@ public class DaemonListeners implements Disposable { if (file instanceof PsiCodeFragment) return true; Project project = file.getProject(); if (!ModuleUtil.projectContainsFile(project, virtualFile, false)) return false; - if (!FileDocumentManager.getInstance().isFileModified(virtualFile)) return false; + Result vcs = vcsThinksItChanged(virtualFile, project); + if (vcs == Result.CHANGED) return true; + if (vcs == Result.UNCHANGED) return false; + + return canUndo(virtualFile); + } + + private boolean canUndo(VirtualFile virtualFile) { + for (FileEditor editor : FileEditorManager.getInstance(myProject).getEditors(virtualFile)) { + if (UndoManagerImpl.getInstance(myProject).isUndoAvailable(editor)) return true; + } + return false; + } + + private static enum Result { + CHANGED, UNCHANGED, NOT_SURE + } + private Result vcsThinksItChanged(VirtualFile virtualFile, Project project) { FilePath path = new FilePathImpl(virtualFile); boolean vcsIsThinking = !VcsDirtyScopeManager.getInstance(myProject).whatFilesDirty(Arrays.asList(path)).isEmpty(); - if (vcsIsThinking) return false; + if (vcsIsThinking) return Result.UNCHANGED; // do not modify file which is in the process of updating AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(virtualFile); - if (activeVcs == null) return true; + if (activeVcs == null) return Result.NOT_SURE; FileStatus status = FileStatusManager.getInstance(project).getStatus(virtualFile); - return status == FileStatus.MODIFIED || status == FileStatus.ADDED; + return status == FileStatus.MODIFIED || status == FileStatus.ADDED ? Result.CHANGED : Result.UNCHANGED; } private class MyApplicationListener extends ApplicationAdapter { -- 2.11.4.GIT