extends ClassVisitor {
if ((access & Opcodes.ACC_ABSTRACT) != 0) {
flags |= ModifierFlags.ABSTRACT_MASK;
}
- else if (isInterface) {
+ else if (isInterface && (access & Opcodes.ACC_STATIC) == 0) {
flags |= ModifierFlags.DEFENDER_MASK;
}
if ((access & Opcodes.ACC_STRICT) != 0) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index a27dfe5adb83..f78a5165345b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -25,7 +25,6 @@ import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -60,7 +59,6 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
processor = new MethodResolverProcessor(anonymous, argumentList, place, place.getContainingFile());
aClass = anonymous.getBaseClassType().resolve();
if (aClass == null) return JavaResolveResult.EMPTY_ARRAY;
- substitutor = substitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(aClass, anonymous, substitutor));
}
else {
processor = new MethodResolverProcessor(aClass, argumentList, place, place.getContainingFile());
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritanceOfStaticMethodFromDefault.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritanceOfStaticMethodFromDefault.java
new file mode 100644
index 000000000000..918c88ff50c7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritanceOfStaticMethodFromDefault.java
@@ -0,0 +1,7 @@
+interface A {
+ default void foo(){}
+}
+
+interface B extends A {
+ static void foo(){}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.html b/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.html
new file mode 100644
index 000000000000..44d2a12be7af
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.html
@@ -0,0 +1,2 @@
+ class Foo
+extends Object
foobar
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.java b/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.java
new file mode 100644
index 000000000000..a3c0fcacca6d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/noSpaceAfterTagName.java
@@ -0,0 +1,2 @@
+/** foo{@literal@tag}bar */
+class Foo {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/Function.txt b/java/java-tests/testData/psi/cls/mirror/Function.txt
new file mode 100644
index 000000000000..24bb6e9ff0ac
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/Function.txt
@@ -0,0 +1,16 @@
+
+ // IntelliJ API Decompiler stub source generated from a class file
+ // Implementation of methods is not available
+
+package java.util.function;
+
+@java.lang.FunctionalInterface
+public interface Function {
+ R apply(T t);
+
+ default java.util.function.Function compose(java.util.function.Function super V,? extends T> function) { /* compiled code */ }
+
+ default java.util.function.Function andThen(java.util.function.Function super R,? extends V> function) { /* compiled code */ }
+
+ static java.util.function.Function identity() { /* compiled code */ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy
index 379068e37eeb..a5b84c0c1559 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy
@@ -14,11 +14,16 @@
* limitations under the License.
*/
package com.intellij.codeInsight
-
import com.intellij.openapi.module.JavaModuleType
+import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModificationUtil
+import com.intellij.openapi.roots.ModuleSourceOrderEntry
+import com.intellij.openapi.roots.OrderEntry
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
+import com.intellij.util.Consumer
+import com.intellij.util.containers.ContainerUtil
+
/**
* @author peter
*/
@@ -95,4 +100,51 @@ class Class3 {
ModuleRootModificationUtil.addDependency(myModule, mod1)
ModuleRootModificationUtil.addDependency(myModule, mod2)
}
+
+ public void testOverridingJdkExceptions() {
+ def dep = PsiTestUtil.addModule(project, JavaModuleType.moduleType, "dep", myFixture.tempDirFixture.findOrCreateDir("dep"))
+ ModuleRootModificationUtil.setModuleSdk(dep, ModuleRootManager.getInstance(myModule).sdk)
+ ModuleRootModificationUtil.updateModel(myModule, { model ->
+ model.addModuleOrderEntry(dep)
+
+ List entries = model.orderEntries as List
+ def srcEntry = ContainerUtil.findInstance(entries, ModuleSourceOrderEntry)
+ assert srcEntry
+
+ model.rearrangeOrderEntries(([srcEntry] + (entries - srcEntry)) as OrderEntry[])
+ } as Consumer)
+
+ myFixture.addFileToProject "java/lang/IllegalArgumentException.java", '''
+package java.lang;
+
+public class IllegalArgumentException extends Exception { }
+'''
+
+ myFixture.addFileToProject 'dep/foo/Foo.java', '''
+package foo;
+
+public class Foo {
+ public static void libraryMethod() throws IllegalArgumentException {}
+}
+'''
+
+ myFixture.configureFromExistingVirtualFile(myFixture.addFileToProject('Bar.java', '''
+class Bar {
+
+void caught() {
+ try {
+ foo.Foo.libraryMethod();
+ } catch (IllegalArgumentException e) {}
+}
+
+void uncaught() {
+ foo.Foo.libraryMethod();
+}
+
+}
+
+''').virtualFile)
+ myFixture.checkHighlighting()
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index e6cceffbab96..f308271a953a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -52,6 +52,10 @@ public class Interface8MethodsHighlightingTest extends LightCodeInsightFixtureTe
doTest(true, false);
}
+ public void testInheritanceOfStaticMethodFromDefault() throws Exception {
+ doTest();
+ }
+
public void testStaticMethodAccessibleBothThroughStaticImportAndInheritance() throws Exception {
myFixture.addClass("package p; public interface Foo {" +
" static void foo() {}" +
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index 21160772691b..d93cd3005f0e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -159,6 +159,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
assertNotNull(docInfo);
assertEquals(exampleHtmlFileText(getTestName(true)), replaceEnvironmentDependentContent(docInfo));
}
+
+ public void testNoSpaceAfterTagName() throws Exception {
+ verifyJavaDoc(getTestClass());
+ }
private static String exampleHtmlFileText(String name) throws IOException {
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + name + ".html");
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index df5cb1d2ff49..7d4c62b27d82 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -82,6 +82,13 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
doTest(clsPath, txtPath);
}
+ public void testStaticMethodInInterface() {
+ String testDir = JavaTestUtil.getJavaTestDataPath();
+ String clsPath = testDir + "/../../mockJDK-1.8/jre/lib/rt.jar!/java/util/function/Function.class";
+ String txtPath = testDir + "/psi/cls/mirror/Function.txt";
+ doTest(clsPath, txtPath);
+ }
+
public void testStrayInnersFiltering() throws IOException {
String path = JavaTestUtil.getJavaTestDataPath() + "/../../mockJDK-1.8/jre/lib/rt.jar!/java/lang/Class.class";
VirtualFile file = StandardFileSystems.jar().findFileByPath(path);
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java
index 1cd16c1f7fc0..862c44006476 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java
@@ -89,8 +89,9 @@ public abstract class VirtualFileSystem {
* This method is useful when the file was created externally and you need to find {@link VirtualFile}
* corresponding to it.
*
- * This method should be only called within write-action.
- * See {@link Application#runWriteAction}.
+ * If this method is invoked not from Swing event dispatch thread, then it must not happen inside a read action. The reason is that
+ * then the method call won't return until proper VFS events are fired, which happens on Swing thread and in write action. So invoking
+ * this method in a read action would result in a deadlock.
*
* @param path the path
* @return {@link VirtualFile} if the file was found, null otherwise
diff --git a/platform/diff-api/src/com/intellij/diff/FrameDiffTool.java b/platform/diff-api/src/com/intellij/diff/FrameDiffTool.java
index 446a33a25204..86f354889cc2 100644
--- a/platform/diff-api/src/com/intellij/diff/FrameDiffTool.java
+++ b/platform/diff-api/src/com/intellij/diff/FrameDiffTool.java
@@ -40,6 +40,10 @@ public interface FrameDiffTool extends DiffTool {
@NotNull
@CalledInAwt
ToolbarComponents init();
+
+ @Override
+ @CalledInAwt
+ void dispose();
}
class ToolbarComponents {
diff --git a/platform/diff-api/src/com/intellij/diff/requests/MessageDiffRequest.java b/platform/diff-api/src/com/intellij/diff/requests/MessageDiffRequest.java
index 8e4c9f1a10c7..0d3dde3a195e 100644
--- a/platform/diff-api/src/com/intellij/diff/requests/MessageDiffRequest.java
+++ b/platform/diff-api/src/com/intellij/diff/requests/MessageDiffRequest.java
@@ -49,4 +49,8 @@ public abstract class MessageDiffRequest extends DiffRequest {
public void setMessage(@NotNull String message) {
myMessage = message;
}
+
+ @Override
+ public final void onAssigned(boolean isAssigned) {
+ }
}
diff --git a/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java
index 63aabc7bf446..1a9a42dbd0b4 100644
--- a/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java
+++ b/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java
@@ -138,7 +138,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
@CalledInAwt
protected void onDispose() {
super.onDispose();
- Disposer.dispose(myQueue);
+ myQueue.abort();
myRequestCache.clear();
}
diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestPanelImpl.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestPanelImpl.java
index 964c09bcf399..8677e343d868 100644
--- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestPanelImpl.java
+++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestPanelImpl.java
@@ -35,7 +35,6 @@ public class DiffRequestPanelImpl implements DiffRequestPanel {
public DiffRequestPanelImpl(@Nullable Project project, @Nullable Window window) {
myProcessor = new MyCacheDiffRequestChainProcessor(project, window);
- myProcessor.init();
myPanel = new JPanel(new BorderLayout()) {
@Override
diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java
index 74674c4f83ab..f939641e63fb 100644
--- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java
+++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java
@@ -93,7 +93,7 @@ public abstract class DiffRequestProcessor implements Disposable {
@NotNull private DiffRequest myActiveRequest;
- @NotNull private ViewerState myState;
+ @Nullable private ViewerState myState;
public DiffRequestProcessor(@Nullable Project project) {
this(project, new UserDataHolderBase());
@@ -106,14 +106,14 @@ public abstract class DiffRequestProcessor implements Disposable {
public DiffRequestProcessor(@Nullable Project project, @NotNull UserDataHolder context) {
myProject = project;
- myAvailableTools = DiffManagerEx.getInstance().getDiffTools();
- myToolOrder = new LinkedList();
-
myContext = new MyDiffContext(context);
myActiveRequest = NoDiffRequest.INSTANCE;
mySettings = DiffSettingsHolder.getInstance().getSettings(myContext.getUserData(DiffUserDataKeysEx.PLACE));
+ myAvailableTools = DiffManagerEx.getInstance().getDiffTools();
+ myToolOrder = new LinkedList(getToolOrderFromSettings(myAvailableTools));
+
// UI
myPanel = new JPanel(new BorderLayout());
@@ -139,6 +139,8 @@ public abstract class DiffRequestProcessor implements Disposable {
if (bottomPanel != null) myMainPanel.add(bottomPanel, BorderLayout.SOUTH);
if (bottomPanel instanceof Disposable) Disposer.register(this, (Disposable)bottomPanel);
+ myState = new EmptyState();
+ myContentPanel.setContent(DiffUtil.createMessagePanel(NoDiffRequest.INSTANCE.getMessage()));
myOpenInEditorAction = new OpenInEditorAction(new Runnable() {
@Override
@@ -148,14 +150,6 @@ public abstract class DiffRequestProcessor implements Disposable {
});
}
- public void init() {
- myToolOrder.addAll(getToolOrderFromSettings(myAvailableTools));
-
- myActiveRequest.onAssigned(true);
- myState = new ErrorState((MessageDiffRequest)myActiveRequest);
- myState.init();
- }
-
//
// Update
//
@@ -966,8 +960,10 @@ public abstract class DiffRequestProcessor implements Disposable {
//
private interface ViewerState {
+ @CalledInAwt
void init();
+ @CalledInAwt
void destroy();
@Nullable
@@ -980,6 +976,34 @@ public abstract class DiffRequestProcessor implements Disposable {
DiffTool getActiveTool();
}
+ private static class EmptyState implements ViewerState {
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Object getData(@NonNls String dataId) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public DiffTool getActiveTool() {
+ return ErrorDiffTool.INSTANCE;
+ }
+ }
+
private class ErrorState implements ViewerState {
@Nullable private final DiffTool myDiffTool;
@NotNull private final MessageDiffRequest myRequest;
@@ -998,6 +1022,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void init() {
myContentPanel.setContent(myViewer.getComponent());
@@ -1008,6 +1033,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
}
@@ -1041,6 +1067,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void init() {
myContentPanel.setContent(myViewer.getComponent());
setTitle(myActiveRequest.getTitle());
@@ -1058,6 +1085,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
}
@@ -1097,6 +1125,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void init() {
myContentPanel.setContent(myWrapperViewer.getComponent());
setTitle(myActiveRequest.getTitle());
@@ -1130,6 +1159,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
+ @CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
Disposer.dispose(myWrapperViewer);
diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffWindowBase.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffWindowBase.java
index 8d9cff475107..309385201233 100644
--- a/platform/diff-impl/src/com/intellij/diff/impl/DiffWindowBase.java
+++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffWindowBase.java
@@ -64,7 +64,6 @@ public abstract class DiffWindowBase {
}
})
.build();
- myProcessor.init();
myWrapper.setImage(ImageLoader.loadFromResource("/diff/Diff.png"));
Disposer.register(myWrapper, myProcessor);
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java
index 9079242200e0..5b6fec5aaec2 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java
@@ -55,6 +55,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -118,20 +119,17 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
}
@Override
- protected void onInit() {
- super.onInit();
- processContextHints();
- }
-
- @Override
+ @CalledInAwt
public void onDispose() {
- updateContextHints();
destroyEditorListeners();
destroyEditors();
super.onDispose();
}
- private void processContextHints() {
+ @Override
+ @CalledInAwt
+ protected void processContextHints() {
+ super.processContextHints();
if (myEditor1 == null) {
myCurrentSide = Side.RIGHT;
}
@@ -144,7 +142,10 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
}
}
- private void updateContextHints() {
+ @Override
+ @CalledInAwt
+ protected void updateContextHints() {
+ super.updateContextHints();
if (myEditor1 != null && myEditor2 != null) {
myContext.putUserData(DiffUserDataKeys.PREFERRED_FOCUS_SIDE, myCurrentSide);
}
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java
index 652904780f43..b40ca61e9af3 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java
@@ -146,30 +146,34 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
}
@Override
+ @CalledInAwt
protected void onInit() {
super.onInit();
- processContextHints();
installTypingSupport();
myPanel.setLoadingContent(); // We need loading panel only for initial rediff()
}
@Override
+ @CalledInAwt
protected void onDispose() {
- updateContextHints();
- EditorFactory.getInstance().releaseEditor(myEditor);
super.onDispose();
+ EditorFactory.getInstance().releaseEditor(myEditor);
}
+ @Override
@CalledInAwt
protected void processContextHints() {
+ super.processContextHints();
Side side = DiffUtil.getUserData(myRequest, myContext, DiffUserDataKeys.MASTER_SIDE);
if (side != null && side.select(myActualContent1, myActualContent2) != null) myMasterSide = side;
myInitialScrollHelper.processContext(myRequest);
}
+ @Override
@CalledInAwt
protected void updateContextHints() {
+ super.updateContextHints();
myInitialScrollHelper.updateContext(myRequest);
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
}
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java
index 4f007437da89..4072c5bf5200 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java
@@ -92,6 +92,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Override
+ @CalledInAwt
protected void onInit() {
super.onInit();
myContentPanel.setPainter(new MyDividerPainter());
@@ -99,10 +100,11 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Override
- protected void onDisposeAwt() {
+ @CalledInAwt
+ protected void onDispose() {
myModifierProvider.destroy();
destroyChangedBlocks();
- super.onDisposeAwt();
+ super.onDispose();
}
@NotNull
@@ -159,16 +161,18 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Override
+ @CalledInAwt
protected void processContextHints() {
super.processContextHints();
myInitialScrollHelper.processContext(myRequest);
}
@Override
+ @CalledInAwt
protected void updateContextHints() {
+ super.updateContextHints();
if (myFoldingModel != null) myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
myInitialScrollHelper.updateContext(myRequest);
- super.updateContextHints();
}
//
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java
index 8632c27973c0..2e23d720f70a 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java
@@ -86,6 +86,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
@Override
+ @CalledInAwt
protected void onInit() {
super.onInit();
myContentPanel.setPainter(new MyDividerPainter(Side.LEFT), Side.LEFT);
@@ -94,9 +95,10 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
@Override
- protected void onDisposeAwt() {
+ @CalledInAwt
+ protected void onDispose() {
destroyChangedBlocks();
- super.onDisposeAwt();
+ super.onDispose();
}
@NotNull
@@ -136,12 +138,14 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
@Override
+ @CalledInAwt
protected void processContextHints() {
super.processContextHints();
myInitialScrollHelper.processContext(myRequest);
}
@Override
+ @CalledInAwt
protected void updateContextHints() {
super.updateContextHints();
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
@@ -259,6 +263,8 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
myInvalidDiffChanges.clear();
+ myFoldingModel.destroy();
+
myContentPanel.repaintDividers();
myStatusPanel.update();
}
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java b/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java
index 5f41070aa91f..e519314f7079 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java
@@ -31,13 +31,13 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.util.Alarm;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.*;
import javax.swing.*;
import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
public abstract class DiffViewerBase implements DiffViewer, DataProvider {
protected static final Logger LOG = Logger.getInstance(DiffViewerBase.class);
@@ -47,7 +47,8 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull protected final ContentDiffRequest myRequest;
@NotNull private final DiffTaskQueue myTaskExecutor = new DiffTaskQueue();
- @NotNull private final AtomicBoolean myDisposed = new AtomicBoolean(false);
+ @NotNull private final Alarm myTaskAlarm = new Alarm();
+ private volatile boolean myDisposed;
public DiffViewerBase(@NotNull DiffContext context, @NotNull ContentDiffRequest request) {
myProject = context.getProject();
@@ -57,6 +58,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull
public final FrameDiffTool.ToolbarComponents init() {
+ processContextHints();
onInit();
FrameDiffTool.ToolbarComponents components = new FrameDiffTool.ToolbarComponents();
@@ -69,24 +71,41 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
}
@Override
+ @CalledInAwt
public final void dispose() {
- if (!myDisposed.compareAndSet(false, true)) return;
+ if (myDisposed) return;
- onDispose();
-
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ Runnable doDispose = new Runnable() {
@Override
public void run() {
- onDisposeAwt();
+ if (myDisposed) return;
+ myDisposed = true;
+
+ abortRediff();
+ updateContextHints();
+
+ onDispose();
}
- });
+ };
+
+ if (!ApplicationManager.getApplication().isDispatchThread()) LOG.warn(new Throwable("dispose() not from EDT"));
+ UIUtil.invokeLaterIfNeeded(doDispose);
+ }
+
+ @CalledInAwt
+ protected void processContextHints() {
+ }
+
+ @CalledInAwt
+ protected void updateContextHints() {
}
@CalledInAwt
public final void scheduleRediff() {
- if (myDisposed.get()) return;
+ if (isDisposed()) return;
- myTaskExecutor.abortAndSchedule(new Runnable() {
+ abortRediff();
+ myTaskAlarm.addRequest(new Runnable() {
@Override
public void run() {
rediff();
@@ -97,6 +116,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
public final void abortRediff() {
myTaskExecutor.abort();
+ myTaskAlarm.cancelAllRequests();
}
@CalledInAwt
@@ -106,7 +126,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
public final void rediff(boolean trySync) {
- if (myDisposed.get()) return;
+ if (isDisposed()) return;
onBeforeRediff();
@@ -148,7 +168,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
}
public boolean isDisposed() {
- return myDisposed.get();
+ return myDisposed;
}
//
@@ -191,12 +211,9 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull
protected abstract Runnable performRediff(@NotNull ProgressIndicator indicator);
- protected void onDispose() {
- Disposer.dispose(myTaskExecutor);
- }
-
@CalledInAwt
- protected void onDisposeAwt() {
+ protected void onDispose() {
+ Disposer.dispose(myTaskAlarm);
}
@Nullable
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java
index a1f81110d4d1..86eb56b42e7c 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java
@@ -111,29 +111,24 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
}
@Override
- protected void onInit() {
- super.onInit();
- processContextHints();
- }
-
- @Override
+ @CalledInAwt
protected void onDispose() {
- updateContextHints();
super.onDispose();
+ destroyEditors();
}
@Override
- protected void onDisposeAwt() {
- destroyEditors();
- super.onDisposeAwt();
- }
-
+ @CalledInAwt
protected void processContextHints() {
+ super.processContextHints();
ThreeSide side = myContext.getUserData(DiffUserDataKeys.PREFERRED_FOCUS_THREESIDE);
if (side != null) myCurrentSide = side;
}
+ @Override
+ @CalledInAwt
protected void updateContextHints() {
+ super.updateContextHints();
myContext.putUserData(DiffUserDataKeys.PREFERRED_FOCUS_THREESIDE, myCurrentSide);
}
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/twoside/TwosideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/twoside/TwosideTextDiffViewer.java
index 0a767ff45e5e..c7109814f010 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/twoside/TwosideTextDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/twoside/TwosideTextDiffViewer.java
@@ -114,24 +114,16 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
}
@Override
- protected void onInit() {
- super.onInit();
- processContextHints();
- }
-
- @Override
+ @CalledInAwt
protected void onDispose() {
- updateContextHints();
super.onDispose();
+ destroyEditors();
}
@Override
- protected void onDisposeAwt() {
- destroyEditors();
- super.onDisposeAwt();
- }
-
+ @CalledInAwt
protected void processContextHints() {
+ super.processContextHints();
if (myEditor1 == null) {
myCurrentSide = Side.RIGHT;
}
@@ -144,7 +136,10 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
}
}
+ @Override
+ @CalledInAwt
protected void updateContextHints() {
+ super.updateContextHints();
if (myEditor1 != null && myEditor2 != null) {
myContext.putUserData(DiffUserDataKeys.PREFERRED_FOCUS_SIDE, myCurrentSide);
}
diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java b/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java
index 40b6b6733967..4c4283136d29 100644
--- a/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java
+++ b/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java
@@ -15,64 +15,19 @@
*/
package com.intellij.diff.util;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.util.Alarm;
import com.intellij.util.Function;
-import org.jetbrains.annotations.*;
+import org.jetbrains.annotations.CalledInAwt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class DiffTaskQueue implements Disposable {
- @NotNull private final Object LOCK = new Object();
- @NotNull private final Alarm myAlarm = new Alarm();
-
- private boolean myDisposed;
- @NotNull private final AtomicReference myProgressIndicator = new AtomicReference();
-
- @CalledInAny
- public void dispose() {
- // if EDT is awaiting for background progress in executeAndTryWait - it holds LOCK.
- // so we want to try cancel indicator before getting the lock.
- cancelProgress();
- synchronized (LOCK) {
- if (myDisposed) return;
- myDisposed = true;
- cancelProgress();
- Disposer.dispose(myAlarm);
- }
- }
+public class DiffTaskQueue {
+ @Nullable private ProgressIndicator myProgressIndicator;
@CalledInAwt
public void abort() {
- synchronized (LOCK) {
- cancelProgress();
- myAlarm.cancelAllRequests();
- }
- }
-
- private void cancelProgress() {
- ProgressIndicator indicator = myProgressIndicator.getAndSet(null);
- if (indicator != null) indicator.cancel();
- }
-
- @CalledInAwt
- public void abortAndSchedule(@NotNull final Runnable task, int millis) {
- synchronized (LOCK) {
- if (myDisposed) return;
- abort();
-
- myAlarm.addRequest(new Runnable() {
- @Override
- public void run() {
- synchronized (LOCK) {
- if (myDisposed) return;
- }
- task.run();
- }
- }, millis);
- }
+ if (myProgressIndicator != null) myProgressIndicator.cancel();
+ myProgressIndicator = null;
}
@CalledInAwt
@@ -87,11 +42,7 @@ public class DiffTaskQueue implements Disposable {
@Nullable final Runnable onSlowAction,
final int waitMillis,
final boolean forceEDT) {
- synchronized (LOCK) {
- if (myDisposed) return;
- abort();
-
- myProgressIndicator.set(BackgroundTaskUtil.executeAndTryWait(backgroundTask, onSlowAction, waitMillis, forceEDT));
- }
+ abort();
+ myProgressIndicator = BackgroundTaskUtil.executeAndTryWait(backgroundTask, onSlowAction, waitMillis, forceEDT);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
index 6f13af4fed19..2bd2f27fd53a 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
@@ -16,6 +16,7 @@
package com.intellij.ide.util;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.DefaultTreeExpander;
import com.intellij.ide.IdeBundle;
@@ -27,6 +28,8 @@ import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.StructureViewComposite;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
+import com.intellij.ide.structureView.newStructureView.TreeActionWrapper;
+import com.intellij.ide.structureView.newStructureView.TreeActionsOwner;
import com.intellij.ide.structureView.newStructureView.TreeModelWrapper;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.NodeRenderer;
@@ -46,8 +49,7 @@ import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.JBPopup;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -77,8 +79,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -91,7 +91,7 @@ import java.util.List;
/**
* @author Konstantin Bulenkov
*/
-public class FileStructurePopup implements Disposable {
+public class FileStructurePopup implements Disposable, TreeActionsOwner {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.FileStructurePopup");
private final Project myProject;
private final StructureViewModel myTreeModel;
@@ -101,7 +101,6 @@ public class FileStructurePopup implements Disposable {
private JBPopup myPopup;
@NonNls private static final String narrowDownPropertyKey = "FileStructurePopup.narrowDown";
- private boolean myShouldNarrowDown = true;
private final FileStructureTree myTree;
private final FilteringTreeBuilder myAbstractTreeBuilder;
private String myTitle;
@@ -119,6 +118,7 @@ public class FileStructurePopup implements Disposable {
private final TreeExpander myTreeExpander;
@NotNull private final FileEditor myFileEditor;
private final StructureView myStructureViewDelegate;
+ private boolean myCanClose = true;
public FileStructurePopup(@NotNull Project project,
@@ -259,7 +259,7 @@ public class FileStructurePopup implements Disposable {
@Override
public Boolean compute() {
DimensionService.getInstance().setLocation(getDimensionServiceKey(), myPopup.getLocationOnScreen(), myProject);
- return true;
+ return myCanClose;
}
})
.createPopup();
@@ -498,6 +498,10 @@ public class FileStructurePopup implements Disposable {
}
+ private static boolean isShouldNarrowDown() {
+ return PropertiesComponent.getInstance().getBoolean(narrowDownPropertyKey, true);
+ }
+
@NonNls
protected static String getDimensionServiceKey() {
return "StructurePopup";
@@ -584,12 +588,17 @@ public class FileStructurePopup implements Disposable {
for (FileStructureNodeProvider provider : fileStructureNodeProviders) {
addCheckbox(comboPanel, provider);
}
+ final JPanel topPanel = new JPanel(new BorderLayout());
+ topPanel.add(comboPanel);
+
+ topPanel.add(createSettingsButton(), BorderLayout.EAST);
+
myPreferredWidth = Math.max(comboPanel.getPreferredSize().width, JBUI.scale(350));
- panel.add(comboPanel, BorderLayout.NORTH);
+ panel.add(topPanel, BorderLayout.NORTH);
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myAbstractTreeBuilder.getTree());
scrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.BOTTOM));
panel.add(scrollPane, BorderLayout.CENTER);
- panel.add(createSouthPanel(), BorderLayout.SOUTH);
+ //panel.add(createSouthPanel(), BorderLayout.SOUTH);
DataManager.registerDataProvider(panel, new DataProvider() {
@Override
public Object getData(@NonNls String dataId) {
@@ -634,6 +643,84 @@ public class FileStructurePopup implements Disposable {
return panel;
}
+ @NotNull
+ protected JComponent createSettingsButton() {
+ final JLabel label = new JLabel(AllIcons.General.SecondaryGroup);
+ new ClickListener() {
+ @Override
+ public boolean onClick(@NotNull MouseEvent event, int clickCount) {
+ DefaultActionGroup group = new DefaultActionGroup();
+ //addSorters(group);
+ //addGroupers(group);
+ //addFilters(group);
+
+ group.add(new ToggleAction(IdeBundle.message("checkbox.narrow.down.on.typing")) {
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return isShouldNarrowDown();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ PropertiesComponent.getInstance().setValue(narrowDownPropertyKey, Boolean.toString(state));
+ if (mySpeedSearch.isPopupActive() && !StringUtil.isEmpty(mySpeedSearch.getEnteredPrefix())) {
+ myAbstractTreeBuilder.queueUpdate();
+ }
+ }
+ });
+
+ final DataManager dataManager = DataManager.getInstance();
+ assert dataManager != null;
+ final ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup(null, group,
+ dataManager.getDataContext(label),
+ JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
+ false);
+ popup.addListener(
+ new JBPopupListener() {
+ @Override
+ public void beforeShown(LightweightWindowEvent event) {
+
+ }
+
+ @Override
+ public void onClosed(LightweightWindowEvent event) {
+ myCanClose = true;
+ }
+ });
+ myCanClose = false;
+ popup.showUnderneathOf(label);
+ return true;
+ }
+ }.installOn(label);
+ return label;
+ }
+
+ protected void addFilters(DefaultActionGroup group) {
+ Filter[] filters = myTreeModel.getFilters();
+ for (Filter filter : filters) {
+ group.add(new TreeActionWrapper(filter, this));
+ }
+ }
+
+ protected void addGroupers(DefaultActionGroup group) {
+ Grouper[] groupers = myTreeModel.getGroupers();
+ for (Grouper grouper : groupers) {
+ group.add(new TreeActionWrapper(grouper, this));
+ }
+ }
+
+ protected void addSorters(DefaultActionGroup group) {
+ Sorter[] sorters = myTreeModel.getSorters();
+ for (final Sorter sorter : sorters) {
+ if (sorter.isVisible()) {
+ group.add(new TreeActionWrapper(sorter, this));
+ }
+ }
+ if (sorters.length > 0) {
+ group.addSeparator();
+ }
+ }
+
@Nullable
private AbstractTreeNode getSelectedNode() {
final TreePath path = myTree.getSelectionPath();
@@ -687,28 +774,6 @@ public class FileStructurePopup implements Disposable {
return succeeded.get();
}
- private JComponent createSouthPanel() {
- final JCheckBox checkBox = new JCheckBox(IdeBundle.message("checkbox.narrow.down.on.typing"));
- checkBox.setSelected(PropertiesComponent.getInstance().getBoolean(narrowDownPropertyKey, true));
- checkBox.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- myShouldNarrowDown = checkBox.isSelected();
- PropertiesComponent.getInstance().setValue(narrowDownPropertyKey, Boolean.toString(myShouldNarrowDown));
-
- if (mySpeedSearch.isPopupActive() && !StringUtil.isEmpty(mySpeedSearch.getEnteredPrefix())) {
- myAbstractTreeBuilder.queueUpdate();
- }
- }
- });
-
- checkBox.setFocusable(false);
- UIUtil.applyStyle(UIUtil.ComponentStyle.MINI, checkBox);
- final JPanel panel = new JPanel(new BorderLayout());
- panel.add(checkBox, BorderLayout.WEST);
- return panel;
- }
-
private void addCheckbox(final JPanel panel, final TreeAction action) {
String text = action instanceof FileStructureFilter ? ((FileStructureFilter)action).getCheckBoxText() :
action instanceof FileStructureNodeProvider ? ((FileStructureNodeProvider)action).getCheckBoxText() : null;
@@ -881,6 +946,16 @@ public class FileStructurePopup implements Disposable {
return null;
}
+ @Override
+ public void setActionActive(String name, boolean state) {
+
+ }
+
+ @Override
+ public boolean isActionActive(String name) {
+ return false;
+ }
+
private class FileStructurePopupFilter implements ElementFilter {
private String myLastFilter = null;
private final Set