From d728fd73faff458ad35cd9cbf0d185b3c3c380f4 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 4 Mar 2014 13:46:06 +0400 Subject: [PATCH] IDEA-121518 Cannot edit files in IDEA after project opening: initial folding in opening thread, assertions relaxed --- .../testData/fileEditorManager/src/Bar.java | 5 ++ .../impl/JavaFileEditorManagerTest.java | 54 +++++++++++++++++++ .../daemon/impl/DaemonListeners.java | 20 +++---- .../folding/impl/CodeFoldingManagerImpl.java | 37 ++++++------- .../folding/impl/DocumentFoldingInfo.java | 10 ++-- .../openapi/editor/impl/FoldingModelImpl.java | 2 - .../fileEditor/FileEditorManagerTest.java | 44 ++++----------- .../fileEditor/FileEditorManagerTestCase.java | 40 ++++++++++++++ 8 files changed, 138 insertions(+), 74 deletions(-) create mode 100644 java/java-tests/testData/fileEditorManager/src/Bar.java create mode 100644 java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java diff --git a/java/java-tests/testData/fileEditorManager/src/Bar.java b/java/java-tests/testData/fileEditorManager/src/Bar.java new file mode 100644 index 000000000000..4843c680a616 --- /dev/null +++ b/java/java-tests/testData/fileEditorManager/src/Bar.java @@ -0,0 +1,5 @@ +public class Bar { + public String doIt() { + return ""; + } +} diff --git a/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java new file mode 100644 index 000000000000..2a985b873ee3 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.openapi.fileEditor.FileEditorManagerTestCase; +import com.intellij.testFramework.PlatformTestUtil; +import org.jdom.JDOMException; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +/** + * @author Dmitry Avdeev + */ +public class JavaFileEditorManagerTest extends FileEditorManagerTestCase { + + public void testAsyncOpening() throws JDOMException, ExecutionException, InterruptedException, IOException { + openFiles("\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " "); + } + + @Override + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/fileEditorManager"; + } +} 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 d20e48149b1c..51e1686104dc 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 @@ -184,17 +184,17 @@ public class DaemonListeners implements Disposable { !worthBothering(editor.getDocument(), editor.getProject())) { return; //no need to stop daemon if something happened in the console } - - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - if (!editor.getComponent().isShowing() && !application.isUnitTestMode() || - myProject.isDisposed()) { - return; + if (!application.isUnitTestMode()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!editor.getComponent().isShowing() || myProject.isDisposed()) { + return; + } + myDaemonCodeAnalyzer.hideLastIntentionHint(); } - myDaemonCodeAnalyzer.hideLastIntentionHint(); - } - }, ModalityState.current()); + }, ModalityState.current()); + } } }, this); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java index 026564d7d2a0..4e831d920d2e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java @@ -39,7 +39,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.ui.LightweightHint; import com.intellij.util.containers.WeakList; -import com.intellij.util.ui.UIUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -217,32 +216,26 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec PsiDocumentManager.getInstance(myProject).commitDocument(document); - Runnable operation = new Runnable() { + Runnable runnable = updateFoldRegions(editor, true, true); + if (runnable != null) { + runnable.run(); + } + if (myProject.isDisposed() || editor.isDisposed()) return; + foldingModel.runBatchFoldingOperation(new Runnable() { @Override public void run() { - Runnable runnable = updateFoldRegions(editor, true, true); - if (runnable != null) { - runnable.run(); + DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document); + Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject); + for (Editor otherEditor : editors) { + if (otherEditor == editor) continue; + documentFoldingInfo.loadFromEditor(otherEditor); + break; } - if (myProject.isDisposed() || editor.isDisposed()) return; - foldingModel.runBatchFoldingOperation(new Runnable() { - @Override - public void run() { - DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document); - Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject); - for (Editor otherEditor : editors) { - if (otherEditor == editor) continue; - documentFoldingInfo.loadFromEditor(otherEditor); - break; - } - documentFoldingInfo.setToEditor(editor); + documentFoldingInfo.setToEditor(editor); - documentFoldingInfo.clear(); - } - }); + documentFoldingInfo.clear(); } - }; - UIUtil.invokeLaterIfNeeded(operation); + }); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java index 0e420b04de2d..9294f108eb75 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java @@ -21,6 +21,7 @@ import com.intellij.lang.folding.FoldingBuilder; import com.intellij.lang.folding.FoldingDescriptor; import com.intellij.lang.folding.LanguageFolding; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -38,7 +39,6 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import java.util.*; class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { @@ -64,7 +64,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { } void loadFromEditor(@NotNull Editor editor) { - assertDispatchThread(); + assertDispatchThread(editor); LOG.assertTrue(!editor.isDisposed()); clear(); @@ -95,12 +95,12 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { } } - private static void assertDispatchThread() { - assert SwingUtilities.isEventDispatchThread() : Thread.currentThread(); + private static void assertDispatchThread(@NotNull Editor editor) { + ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent()); } void setToEditor(@NotNull final Editor editor) { - assertDispatchThread(); + assertDispatchThread(editor); final PsiManager psiManager = PsiManager.getInstance(myProject); if (psiManager.isDisposed()) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index 1bbf9aae650c..8349aac12497 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -45,7 +45,6 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.awt.*; import java.util.Arrays; import java.util.List; @@ -201,7 +200,6 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList } private void runBatchFoldingOperation(final Runnable operation, final boolean dontCollapseCaret, final boolean moveCaret) { - LOG.assertTrue(SwingUtilities.isEventDispatchThread(), Thread.currentThread().toString()); assertIsDispatchThreadForEditor(); boolean oldDontCollapseCaret = myDoNotCollapseCaret; myDoNotCollapseCaret |= dontCollapseCaret; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java index cf53f977c813..09debec55b6b 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java @@ -17,29 +17,20 @@ package com.intellij.openapi.fileEditor; import com.intellij.ide.ui.UISettings; import com.intellij.mock.Mock; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import org.jdom.Document; import org.jdom.Element; -import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.PathMacroUtil; import javax.swing.*; import java.io.File; -import java.io.IOException; import java.util.Arrays; import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; /** * @author Dmitry Avdeev @@ -77,17 +68,18 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase { openFiles(" \n" + " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + " \n" + " \n" + " \n" + - " \n" + " \n"); FileEditor[] selectedEditors = myManager.getSelectedEditors(); assertEquals(1, selectedEditors.length); @@ -157,24 +149,6 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase { assertEquals(Arrays.asList(fileNames), names); } - private void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException { - Document document = JDOMUtil.loadDocument(s); - Element rootElement = document.getRootElement(); - ExpandMacroToPathMap map = new ExpandMacroToPathMap(); - map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath()); - map.substitute(rootElement, true, true); - - myManager.readExternal(rootElement); - - Future future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - myManager.getMainSplitters().openFiles(); - } - }); - future.get(); - } - @Override protected String getTestDataPath() { return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/fileEditorManager"; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java index aa528681114b..28d5def0a218 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java @@ -1,13 +1,27 @@ package com.intellij.openapi.fileEditor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.components.impl.ComponentManagerImpl; import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import com.intellij.ui.docking.DockManager; +import com.intellij.util.ui.UIUtil; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jetbrains.jps.model.serialization.PathMacroUtil; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * @author Dmitry Avdeev @@ -40,4 +54,30 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight protected VirtualFile getFile(String path) { return LocalFileSystem.getInstance().refreshAndFindFileByPath(getTestDataPath() + path); } + + protected void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException { + Document document = JDOMUtil.loadDocument(s); + Element rootElement = document.getRootElement(); + ExpandMacroToPathMap map = new ExpandMacroToPathMap(); + map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath()); + map.substitute(rootElement, true, true); + + myManager.readExternal(rootElement); + + Future future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + myManager.getMainSplitters().openFiles(); + } + }); + while (true) { + try { + future.get(100, TimeUnit.MILLISECONDS); + return; + } + catch (TimeoutException e) { + UIUtil.dispatchAllInvocationEvents(); + } + } + } }