From f53bb941155bc8546492bc2a1bcd39013a9a7490 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 20 May 2015 14:36:33 +0300 Subject: [PATCH 01/27] IDEA-132852 Debugger: values in editor are still shown after disconnect - fix for closing toolwindow --- .../xdebugger/impl/frame/XVariablesView.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java index b75002919dce..4b5a5f8bca3e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java @@ -68,12 +68,22 @@ public class XVariablesView extends XVariablesViewBase { } @Override - protected void clear() { - XDebuggerTree tree = getTree(); + public void dispose() { + clearInlineData(getTree()); + super.dispose(); + } + + private static void clearInlineData(XDebuggerTree tree) { tree.getProject().putUserData(DEBUG_VARIABLES, null); tree.getProject().putUserData(DEBUG_VARIABLES_TIMESTAMPS, null); - tree.setSourcePosition(null); tree.updateEditor(); + } + + @Override + protected void clear() { + XDebuggerTree tree = getTree(); + tree.setSourcePosition(null); + clearInlineData(tree); XDebuggerTreeNode node; XDebugSession session = getSession(getPanel()); From 2fc7821d064eadc87de92024e0584511e89416d2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 20 May 2015 12:03:04 +0200 Subject: [PATCH 02/27] forbid native in interfaces (IDEA-140491) --- .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 4 ++++ .../lambda/interfaceMethods/ModifierNativeInInterface.java | 5 +++++ .../daemon/lambda/Interface8MethodsHighlightingTest.java | 1 + 3 files changed, 10 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ModifierNativeInInterface.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 32bc89d5518b..78f4713426ce 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -941,6 +941,10 @@ public class HighlightUtil extends HighlightUtilBase { isAllowed &= modifierOwnerParent instanceof PsiClass && !((PsiClass)modifierOwnerParent).isInterface(); } + if (containingClass != null && containingClass.isInterface()) { + isAllowed &= !PsiModifier.NATIVE.equals(modifier); + } + if (containingClass != null && containingClass.isAnnotationType()) { isAllowed &= !PsiModifier.STATIC.equals(modifier); isAllowed &= !PsiModifier.DEFAULT.equals(modifier); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ModifierNativeInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ModifierNativeInInterface.java new file mode 100644 index 000000000000..aa3b062834f7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ModifierNativeInInterface.java @@ -0,0 +1,5 @@ +interface A { + default native void m(){} + static native void m1(){} + native void m2(); +} \ No newline at end of file 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 f308271a953a..83770afac62b 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 @@ -36,6 +36,7 @@ public class Interface8MethodsHighlightingTest extends LightCodeInsightFixtureTe public void testStaticMethodCalls() { doTest(false, false); } public void testStaticMethodCallsAndOverloadResolution() { doTest(false, false); } public void testDefaultMethodOverrideEquivalentObject() { doTest(false, false); } + public void testModifierNativeInInterface() { doTest(false, false); } public void testStaticMethods() { doTest(false, false); } public void testFinalStaticDefaultMethods() { doTest(false, false); } public void testIDEA122720() { doTest(false, false); } From 1d5ff33cbe74b473f6c9f2421a67c7bd72ad98a2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 20 May 2015 12:53:16 +0200 Subject: [PATCH 03/27] extend check for enclosing instance for java 8 default methods in interfaces (IDEA-140492) --- .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 6 ++++++ ...TypeNameInterfaceSuperMethodReferenceApplicability.java | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 78f4713426ce..b6dacbe717fb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -1522,6 +1522,12 @@ public class HighlightUtil extends HighlightUtilBase { .descriptionAndTooltip(JavaErrorMessages.message("bad.qualifier.in.super.method.reference", format(aClass), formatClass(superClass))).create(); } } + + if (expr instanceof PsiSuperExpression && !classT.isInheritor(aClass, false)) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(qualifier) + .descriptionAndTooltip(JavaErrorMessages.message("no.enclosing.instance.in.scope", format(aClass))).create(); + } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeNameInterfaceSuperMethodReferenceApplicability.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeNameInterfaceSuperMethodReferenceApplicability.java index 28f175aae9e4..23bdff178cca 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeNameInterfaceSuperMethodReferenceApplicability.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeNameInterfaceSuperMethodReferenceApplicability.java @@ -38,5 +38,12 @@ class Test { } }; } + + interface D extends J { + default void m() { + D.super.toString(); + J.super.toString(); + } + } } From 870c89b50eb40dbbd9485a95725cd5b6e15c5ce6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 20 May 2015 13:45:38 +0200 Subject: [PATCH 04/27] exclude non-content files from analysis --- .../codeInspection/ex/GlobalInspectionContextImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 84329b36912b..ce5e9b6cbfae 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -50,7 +50,10 @@ import com.intellij.openapi.progress.*; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectCoreUtil; import com.intellij.openapi.project.ProjectUtilCore; +import com.intellij.openapi.roots.FileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; @@ -507,10 +510,12 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp @Override public void run() { try { + final FileIndex fileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); scope.accept(new Processor() { @Override public boolean process(final VirtualFile file) { progressIndicator.checkCanceled(); + if (ProjectCoreUtil.isProjectOrWorkspaceFile(file) || !fileIndex.isInContent(file)) return true; final PsiFile[] psiFile = new PsiFile[1]; Document document = ApplicationManager.getApplication().runReadAction(new Computable() { From b1dbec0ce003c3c54143705a84cac54326c972ea Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 13:06:03 +0300 Subject: [PATCH 05/27] vcs: cleanup --- .../com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java index 0c5811916e19..e15334571397 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java @@ -274,7 +274,7 @@ public abstract class ChangesTreeList extends JPanel implements TypeSafeDataP myChangeDecorator = changeDecorator; } - public void setDoubleClickHandler(final Runnable doubleClickHandler) { + public void setDoubleClickHandler(@NotNull final Runnable doubleClickHandler) { myDoubleClickHandler = doubleClickHandler; } From fdab7e091b71927872c0a71452bb2622625de9ee Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 14:07:25 +0300 Subject: [PATCH 06/27] diff: make toolbarPanel focusable even without toolbar * this is required to keep focus, that was granted before initial applyRequest() was called (and we builded toolbar) issue: diff opened from modal dialog was slow (doWhenFocusSettlesDown() delayed initial doApplyRequest() at ~0.5 sec) and the resulting focus owner was wrong introduced by c701599 * replace custom helper class with util one * validate() is called insite Wrapper now --- .../diff/impl/DiffRequestProcessor.java | 28 +++++-------- .../intellij/diff/impl/ModifiablePanel.java | 41 ------------------- .../idea/svn/difftool/SvnDiffViewer.java | 6 +-- .../SvnTreeConflictDiffRequestProvider.java | 4 +- 4 files changed, 15 insertions(+), 64 deletions(-) delete mode 100644 platform/diff-impl/src/com/intellij/diff/impl/ModifiablePanel.java 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 985f78421130..c4dee802b3da 100644 --- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java @@ -55,6 +55,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; +import com.intellij.ui.components.panels.Wrapper; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -87,9 +88,9 @@ public abstract class DiffRequestProcessor implements Disposable { @NotNull private final JPanel myPanel; @NotNull private final MyPanel myMainPanel; - @NotNull private final ModifiablePanel myContentPanel; - @NotNull private final ModifiablePanel myToolbarPanel; // TODO: allow to call 'updateToolbar' from Viewer ? - @NotNull private final ModifiablePanel myToolbarStatusPanel; + @NotNull private final Wrapper myContentPanel; + @NotNull private final Wrapper myToolbarPanel; // TODO: allow to call 'updateToolbar' from Viewer ? + @NotNull private final Wrapper myToolbarStatusPanel; @NotNull private DiffRequest myActiveRequest; @@ -118,9 +119,10 @@ public abstract class DiffRequestProcessor implements Disposable { myPanel = new JPanel(new BorderLayout()); myMainPanel = new MyPanel(); - myContentPanel = new ModifiablePanel(); - myToolbarPanel = new ModifiablePanel(); - myToolbarStatusPanel = new ModifiablePanel(); + myContentPanel = new Wrapper(); + myToolbarPanel = new Wrapper(); + myToolbarPanel.setFocusable(true); + myToolbarStatusPanel = new Wrapper(); myPanel.add(myMainPanel, BorderLayout.CENTER); @@ -469,7 +471,7 @@ public abstract class DiffRequestProcessor implements Disposable { @Nullable public JComponent getPreferredFocusedComponent() { JComponent component = myState.getPreferredFocusedComponent(); - return component != null ? component : myToolbarPanel.getContent(); + return component != null ? component : myToolbarPanel.getTargetComponent(); } @Nullable @@ -832,7 +834,7 @@ public abstract class DiffRequestProcessor implements Disposable { public Object getData(@NonNls String dataId) { Object data; - DataProvider contentProvider = DataManagerImpl.getDataProviderEx(myContentPanel.getContent()); + DataProvider contentProvider = DataManagerImpl.getDataProviderEx(myContentPanel.getTargetComponent()); if (contentProvider != null) { data = contentProvider.getData(dataId); if (data != null) return data; @@ -1016,8 +1018,6 @@ public abstract class DiffRequestProcessor implements Disposable { FrameDiffTool.ToolbarComponents init = myViewer.init(); buildToolbar(init.toolbarActions); - - myPanel.validate(); } @Override @@ -1060,16 +1060,12 @@ public abstract class DiffRequestProcessor implements Disposable { myContentPanel.setContent(myViewer.getComponent()); setTitle(myActiveRequest.getTitle()); - myPanel.validate(); - FrameDiffTool.ToolbarComponents toolbarComponents = myViewer.init(); buildToolbar(toolbarComponents.toolbarActions); buildActionPopup(toolbarComponents.popupActions); myToolbarStatusPanel.setContent(toolbarComponents.statusPanel); - - myPanel.validate(); } @Override @@ -1118,8 +1114,6 @@ public abstract class DiffRequestProcessor implements Disposable { myContentPanel.setContent(myWrapperViewer.getComponent()); setTitle(myActiveRequest.getTitle()); - myPanel.validate(); - FrameDiffTool.ToolbarComponents toolbarComponents1 = myViewer.init(); FrameDiffTool.ToolbarComponents toolbarComponents2 = myWrapperViewer.init(); @@ -1142,8 +1136,6 @@ public abstract class DiffRequestProcessor implements Disposable { myToolbarStatusPanel.setContent(toolbarComponents1.statusPanel); // TODO: combine both panels ? - - myPanel.validate(); } @Override diff --git a/platform/diff-impl/src/com/intellij/diff/impl/ModifiablePanel.java b/platform/diff-impl/src/com/intellij/diff/impl/ModifiablePanel.java deleted file mode 100644 index 3fff31d37435..000000000000 --- a/platform/diff-impl/src/com/intellij/diff/impl/ModifiablePanel.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2000-2015 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.diff.impl; - -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.*; - -public class ModifiablePanel extends JPanel { - @Nullable private JComponent myContent; - - public ModifiablePanel() { - super(new BorderLayout()); - } - - public void setContent(@Nullable JComponent content) { - myContent = content; - removeAll(); - if (content != null) add(content, BorderLayout.CENTER); - invalidate(); - } - - @Nullable - public JComponent getContent() { - return myContent; - } -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnDiffViewer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnDiffViewer.java index 1778255b66dd..ccce9564be54 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnDiffViewer.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnDiffViewer.java @@ -5,7 +5,6 @@ import com.intellij.diff.FrameDiffTool.DiffViewer; import com.intellij.diff.FrameDiffTool.ToolbarComponents; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.EmptyContent; -import com.intellij.diff.impl.ModifiablePanel; import com.intellij.diff.requests.DiffRequest; import com.intellij.diff.requests.ErrorDiffRequest; import com.intellij.diff.tools.ErrorDiffTool; @@ -23,6 +22,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.JBColor; +import com.intellij.ui.components.panels.Wrapper; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -60,7 +60,7 @@ public class SvnDiffViewer implements DiffViewer { @NotNull private final JPanel myPanel; @NotNull private final Splitter mySplitter; - @NotNull private final ModifiablePanel myNotificationPanel; + @NotNull private final Wrapper myNotificationPanel; @NotNull private final DiffViewer myContentViewer; @NotNull private final DiffViewer myPropertiesViewer; @@ -85,7 +85,7 @@ public class SvnDiffViewer implements DiffViewer { mySplitter.setProportion(mySettings.getSplitterProportion()); mySplitter.setFirstComponent(myContentViewer.getComponent()); - myNotificationPanel = new ModifiablePanel(); + myNotificationPanel = new Wrapper(); MyPropertyContext propertyContext = initPropertyContext(context); myPropertiesViewer = createPropertiesViewer(propertyRequest, propertyContext); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnTreeConflictDiffRequestProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnTreeConflictDiffRequestProvider.java index 35562e795f06..918985fcdb3c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnTreeConflictDiffRequestProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/difftool/SvnTreeConflictDiffRequestProvider.java @@ -8,11 +8,11 @@ import com.intellij.openapi.util.UserDataHolder; import com.intellij.diff.DiffContext; import com.intellij.diff.FrameDiffTool; import com.intellij.diff.chains.DiffRequestProducerException; -import com.intellij.diff.impl.ModifiablePanel; import com.intellij.diff.requests.DiffRequest; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer; import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProvider; +import com.intellij.ui.components.panels.Wrapper; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,7 +91,7 @@ public class SvnTreeConflictDiffRequestProvider implements ChangeDiffRequestProv private static class SvnTreeConflictDiffViewer implements FrameDiffTool.DiffViewer { @NotNull private final DiffContext myContext; @NotNull private final SvnTreeConflictDiffRequest myRequest; - @NotNull private final ModifiablePanel myPanel = new ModifiablePanel(); + @NotNull private final Wrapper myPanel = new Wrapper(); @NotNull private final BackgroundTaskQueue myQueue; @NotNull private final TreeConflictRefreshablePanel myDelegate; From 5dbcd913ca0486471123cd92ecdfa4aa4211189f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 20 May 2015 14:29:31 +0200 Subject: [PATCH 07/27] move common code to EditorOptionsTopHitProviderBase --- .../impl/ImagesOptionsTopHitProvider.java | 9 ++--- .../AutoImportOptionsTopHitProvider.java | 8 +---- .../CodeFoldingOptionsTopHitProvider.java | 13 +------ .../editor/EditorOptionsTopHitProvider.java | 13 +------ .../EditorOptionsTopHitProviderBase.java | 36 +++++++++++++++++++ .../EditorSmartKeysOptionsTopHitProvider.java | 8 +---- .../EditorTabsOptionsTopHitProvider.java | 13 +------ .../GuiDesignerOptionsTopHitProvider.java | 9 ++--- 8 files changed, 45 insertions(+), 64 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProviderBase.java diff --git a/images/src/org/intellij/images/options/impl/ImagesOptionsTopHitProvider.java b/images/src/org/intellij/images/options/impl/ImagesOptionsTopHitProvider.java index 39675fc62d31..32efe6f703ae 100644 --- a/images/src/org/intellij/images/options/impl/ImagesOptionsTopHitProvider.java +++ b/images/src/org/intellij/images/options/impl/ImagesOptionsTopHitProvider.java @@ -15,19 +15,14 @@ */ package org.intellij.images.options.impl; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; +import com.intellij.application.options.editor.EditorOptionsTopHitProviderBase; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class ImagesOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class ImagesOptionsTopHitProvider extends EditorOptionsTopHitProviderBase { @Override protected Configurable getConfigurable(Project project) { return new OptionsConfigurabe(); diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsTopHitProvider.java index 8778b9f27492..0b7d293b2297 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/AutoImportOptionsTopHitProvider.java @@ -15,19 +15,13 @@ */ package com.intellij.application.options.editor; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class AutoImportOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class AutoImportOptionsTopHitProvider extends EditorOptionsTopHitProviderBase { @Override protected Configurable getConfigurable(Project project) { return new AutoImportOptionsConfigurable(); diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingOptionsTopHitProvider.java index cedf5416d8a7..7cc91dab9b4f 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingOptionsTopHitProvider.java @@ -15,7 +15,6 @@ */ package com.intellij.application.options.editor; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; @@ -24,25 +23,15 @@ import javax.swing.*; /** * @author Sergey.Malenkov */ -public class CodeFoldingOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { +public class CodeFoldingOptionsTopHitProvider extends EditorOptionsTopHitProviderBase.NoPrefix { private int myCount; - @Override - public String getId() { - return "editor"; - } - @Override protected Configurable getConfigurable(Project project) { myCount = 0; return new CodeFoldingConfigurable(); } - @Override - protected String getName(Configurable configurable) { - return null; - } - @Override protected String getOptionName(JCheckBox checkbox) { String name = super.getOptionName(checkbox); diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProvider.java index 9828e92fc484..ab3432c5af07 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProvider.java @@ -15,26 +15,15 @@ */ package com.intellij.application.options.editor; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class EditorOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class EditorOptionsTopHitProvider extends EditorOptionsTopHitProviderBase.NoPrefix { @Override protected Configurable getConfigurable(Project project) { return new EditorOptions(); } - - @Override - protected String getName(Configurable configurable) { - return null; - } } diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProviderBase.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProviderBase.java new file mode 100644 index 000000000000..e09b2e0cf010 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsTopHitProviderBase.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2015 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.application.options.editor; + +import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; +import com.intellij.openapi.options.Configurable; + +/** + * @author Konstantin Bulenkov + */ +public abstract class EditorOptionsTopHitProviderBase extends ConfigurableOptionsTopHitProvider { + @Override + public String getId() { + return "editor"; + } + + public static abstract class NoPrefix extends EditorOptionsTopHitProviderBase { + @Override + protected String getName(Configurable configurable) { + return null; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysOptionsTopHitProvider.java index 28b185b10197..4be1dee5cb36 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysOptionsTopHitProvider.java @@ -15,19 +15,13 @@ */ package com.intellij.application.options.editor; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class EditorSmartKeysOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class EditorSmartKeysOptionsTopHitProvider extends EditorOptionsTopHitProviderBase { @Override protected Configurable getConfigurable(Project project) { return new EditorSmartKeysConfigurable(); diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsOptionsTopHitProvider.java index 805412fbf4a7..8ffb74604409 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsOptionsTopHitProvider.java @@ -15,26 +15,15 @@ */ package com.intellij.application.options.editor; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class EditorTabsOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class EditorTabsOptionsTopHitProvider extends EditorOptionsTopHitProviderBase.NoPrefix { @Override protected Configurable getConfigurable(Project project) { return new EditorTabsConfigurable(); } - - @Override - protected String getName(Configurable configurable) { - return null; - } } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/GuiDesignerOptionsTopHitProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/GuiDesignerOptionsTopHitProvider.java index 7413c94a96fb..cf220ea6ceef 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/GuiDesignerOptionsTopHitProvider.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/GuiDesignerOptionsTopHitProvider.java @@ -15,19 +15,14 @@ */ package com.intellij.uiDesigner; -import com.intellij.ide.ui.ConfigurableOptionsTopHitProvider; +import com.intellij.application.options.editor.EditorOptionsTopHitProviderBase; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; /** * @author Sergey.Malenkov */ -public class GuiDesignerOptionsTopHitProvider extends ConfigurableOptionsTopHitProvider { - @Override - public String getId() { - return "editor"; - } - +public class GuiDesignerOptionsTopHitProvider extends EditorOptionsTopHitProviderBase { @Override protected Configurable getConfigurable(Project project) { return new GuiDesignerConfigurable(project); From f68631cd1ded3c83eae6e2b270c6eb14fc2d60ab Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 18 May 2015 21:00:14 +0300 Subject: [PATCH 08/27] diff: remove unused methods --- .../diff/tools/fragmented/ChangedBlock.java | 8 -------- .../diff/tools/util/FoldingModelSupport.java | 13 ------------- .../intellij/diff/tools/util/LineFragmentCache.java | 8 -------- 3 files changed, 29 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/ChangedBlock.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/ChangedBlock.java index 6c94c2365c92..b58db4495d08 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/ChangedBlock.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/ChangedBlock.java @@ -82,14 +82,6 @@ public class ChangedBlock { return myLine2; } - public boolean hasInsertion() { - return myStartOffset2 != myEndOffset2; - } - - public boolean hasDeletion() { - return myStartOffset1 != myEndOffset1; - } - @NotNull public LineFragment getLineFragment() { return myLineFragment; diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java index 76e2baf88284..5f7c35df2be5 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java @@ -85,14 +85,6 @@ public class FoldingModelSupport { // Init // - @Deprecated - protected void install(@Nullable final Iterator changedLines, - @NotNull final UserDataHolder context, - final boolean defaultExpanded, - final int range) { - install(changedLines, context, new Settings(range, defaultExpanded)); - } - /* * Iterator returns ranges of changed lines: start1, end1, start2, end2, ... */ @@ -498,11 +490,6 @@ public class FoldingModelSupport { } } - @Deprecated - public void updateContext(@NotNull UserDataHolder context, boolean defaultState) { - updateContext(context, new Settings(0, defaultState)); - } - public void updateContext(@NotNull UserDataHolder context, @NotNull final Settings settings) { if (myFoldings.isEmpty()) return; // do not rewrite cache by initial state context.putUserData(CACHE_KEY, getFoldingCache(settings)); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/LineFragmentCache.java b/platform/diff-impl/src/com/intellij/diff/tools/util/LineFragmentCache.java index 9653f0fc77bf..f3eadad277d2 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/LineFragmentCache.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/LineFragmentCache.java @@ -47,14 +47,6 @@ public class LineFragmentCache { myFragments = new HashMap(3); } - public long getStamp1() { - return myModificationStamp1; - } - - public long getStamp2() { - return myModificationStamp2; - } - public boolean checkStamps(long stamp1, long stamp2) { return myModificationStamp1 == stamp1 && myModificationStamp2 == stamp2; } From 541e9b1cab3c31a03e42241f0e6c9eadab2bc7ba Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 18 May 2015 20:56:16 +0300 Subject: [PATCH 09/27] diff: remove useless return value --- .../com/intellij/diff/tools/util/SyncScrollSupport.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java b/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java index 5a97124251b8..e0447120699d 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java @@ -68,9 +68,9 @@ public class SyncScrollSupport { return myDuringSyncScroll; } - public boolean setDisabled(boolean value) { + public void setDisabled(boolean value) { if (myDisabled == value) LOG.warn(new Throwable("myDisabled == value: " + myDisabled + " - " + value)); - return myDisabled = value; + myDisabled = value; } @NotNull @@ -170,9 +170,9 @@ public class SyncScrollSupport { myHelper22 = create(editors.get(2), editors.get(1), myScrollable2, Side.RIGHT); } - public boolean setDisabled(boolean value) { + public void setDisabled(boolean value) { if (myDisabled == value) LOG.warn(new Throwable("myDisabled == value: " + myDisabled + " - " + value)); - return myDisabled = value; + myDisabled = value; } public void visibleAreaChanged(VisibleAreaEvent e) { From 6a60fe38e93fb680ac6683e849990cb0075d1947 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 15:38:00 +0300 Subject: [PATCH 10/27] diff: remove unused fields --- .../intellij/diff/tools/fragmented/OnesideDiffPanel.java | 8 +------- .../intellij/diff/tools/fragmented/OnesideDiffViewer.java | 2 +- .../src/com/intellij/diff/tools/util/SimpleDiffPanel.java | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffPanel.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffPanel.java index 493c4c494f97..396a8988786a 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffPanel.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffPanel.java @@ -37,25 +37,19 @@ public class OnesideDiffPanel extends DiffPanelBase { private static final String OPERATION_CANCELED_CONTENT = "OperationCanceledContent"; private static final String ERROR_CONTENT = "ErrorContent"; - @NotNull private final Editor myEditor; - - @NotNull private final JPanel myEditorPanel; @NotNull private final AsyncProcessIcon.Big myBusyIcon; public OnesideDiffPanel(@Nullable Project project, @NotNull OnesideContentPanel content, - @NotNull Editor editor, @NotNull DataProvider provider, @NotNull DiffContext context) { super(project, provider, context); - myEditor = editor; - myEditorPanel = content; myBusyIcon = new AsyncProcessIcon.Big("OnesideDiff"); JPanel centerPanel = new JPanel(new BorderLayout()); centerPanel.add(myNotificationsPanel, BorderLayout.NORTH); - centerPanel.add(myEditorPanel, BorderLayout.CENTER); + centerPanel.add(content, BorderLayout.CENTER); myContentPanel.add(centerPanel, GOOD_CONTENT); myContentPanel.add(myBusyIcon, LOADING_CONTENT); 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 b40ca61e9af3..73d94fe41088 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 @@ -135,7 +135,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase { List titles = DiffUtil.createTextTitles(myRequest, ContainerUtil.list(myEditor, myEditor)); OnesideContentPanel contentPanel = new OnesideContentPanel(titles, myEditor); - myPanel = new OnesideDiffPanel(myProject, contentPanel, myEditor, this, myContext); + myPanel = new OnesideDiffPanel(myProject, contentPanel, this, myContext); myFoldingModel = new MyFoldingModel(myEditor, this); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/SimpleDiffPanel.java b/platform/diff-impl/src/com/intellij/diff/tools/util/SimpleDiffPanel.java index fd498a4a070f..d723d0c83fca 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/SimpleDiffPanel.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/SimpleDiffPanel.java @@ -28,17 +28,14 @@ public class SimpleDiffPanel extends DiffPanelBase { private static final String GOOD_CONTENT = "GoodContent"; private static final String ERROR_CONTENT = "ErrorContent"; - @NotNull private final JComponent myEditorsPanel; - public SimpleDiffPanel(@NotNull JComponent editorPanel, @NotNull DataProvider dataProvider, @NotNull DiffContext context) { super(context.getProject(), dataProvider, context); - myEditorsPanel = editorPanel; JPanel centerPanel = new JPanel(new BorderLayout()); centerPanel.add(myNotificationsPanel, BorderLayout.NORTH); - centerPanel.add(myEditorsPanel, BorderLayout.CENTER); + centerPanel.add(editorPanel, BorderLayout.CENTER); myContentPanel.add(centerPanel, GOOD_CONTENT); myContentPanel.add(DiffUtil.createMessagePanel("Error"), ERROR_CONTENT); From f28a3e7e0fac97e24e039b3dc300bf98bf911c4e Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 18 May 2015 20:55:54 +0300 Subject: [PATCH 11/27] diff: try another initial scroll method on fail --- .../com/intellij/diff/tools/simple/SimpleDiffViewer.java | 9 +++------ .../diff/tools/simple/SimpleThreesideDiffViewer.java | 6 ++---- 2 files changed, 5 insertions(+), 10 deletions(-) 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 3e1a7786d1bf..b6f55de5ba64 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 @@ -1103,21 +1103,18 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer { @Override protected boolean doScrollToChange() { if (myScrollToChange == null) return false; - SimpleDiffViewer.this.doScrollToChange(myScrollToChange); - return true; + return SimpleDiffViewer.this.doScrollToChange(myScrollToChange); } @Override protected boolean doScrollToFirstChange() { - SimpleDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE); - return true; + return SimpleDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE); } @Override protected boolean doScrollToContext() { if (myNavigationContext == null) return false; - SimpleDiffViewer.this.doScrollToContext(myNavigationContext); - return true; + return SimpleDiffViewer.this.doScrollToContext(myNavigationContext); } } } 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 342052fd48b5..5bb3ad3fb2b9 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 @@ -672,14 +672,12 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer { @Override protected boolean doScrollToChange() { if (myScrollToChange == null) return false; - SimpleThreesideDiffViewer.this.doScrollToChange(myScrollToChange); - return true; + return SimpleThreesideDiffViewer.this.doScrollToChange(myScrollToChange); } @Override protected boolean doScrollToFirstChange() { - SimpleThreesideDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE); - return true; + return SimpleThreesideDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE); } } } From 1d1845c053056be9b26a662e1d50bd9041532f73 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 19 May 2015 22:23:59 +0200 Subject: [PATCH 12/27] make IG test light --- .../instanceof_chain/InstanceofChain.java | 6 ++--- .../abstraction/instanceof_chain/expected.xml | 23 ------------------- .../InstanceofChainInspectionTest.java | 17 ++++++++++---- 3 files changed, 15 insertions(+), 31 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java index cc1d5707f537..0d3ae444a5bc 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java @@ -2,7 +2,7 @@ package com.siyeh.igtest.abstraction.instanceof_chain; public class InstanceofChain { void arg(Object o) { - if (o instanceof String || o instanceof String || o instanceof String) { + if (o instanceof String || o instanceof String || o instanceof String) { } else if (o instanceof Integer) { @@ -12,7 +12,7 @@ public class InstanceofChain { } void m(boolean b, Object o) { - if (o instanceof String) { + if (o instanceof String) { } else if (o instanceof Boolean) { @@ -20,7 +20,7 @@ public class InstanceofChain { } void n(Object o) { - if (o instanceof Integer) {} + if (o instanceof Integer) {} if (o instanceof Byte) {} if (o instanceof Long) {} } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/expected.xml deleted file mode 100644 index f6524570189a..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/expected.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - InstanceofChain.java - 5 - Chain of 'instanceof' checks - Chain of 'instanceof' checks indicates abstraction failure #loc - - - - InstanceofChain.java - 23 - Chain of 'instanceof' checks - Chain of 'instanceof' checks indicates abstraction failure #loc - - - - InstanceofChain.java - 15 - Chain of 'instanceof' checks - Chain of 'instanceof' checks indicates abstraction failure #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/InstanceofChainInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/InstanceofChainInspectionTest.java index 5d2973ed9bf7..2145bcda4bed 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/InstanceofChainInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/InstanceofChainInspectionTest.java @@ -1,11 +1,18 @@ package com.siyeh.ig.abstraction; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class InstanceofChainInspectionTest extends IGInspectionTestCase { +public class InstanceofChainInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/abstraction/instanceof_chain", - new InstanceofChainInspection()); + public void testInstanceofChain() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new InstanceofChainInspection(); } } \ No newline at end of file From 3620f2a817640a502ce7db0d1962b986c3d26c9a Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 19 May 2015 22:38:37 +0200 Subject: [PATCH 13/27] make IG test light --- .../siyeh/igtest/bugs/DuplicateCondition.java | 27 -------------- .../DuplicateCondition.java | 30 +++++++++++++-- .../duplicate_condition/expected.xml | 37 ------------------- .../DuplicateConditionInspectionTest.java | 16 ++++++-- 4 files changed, 39 insertions(+), 71 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/DuplicateCondition.java delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/DuplicateCondition.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/DuplicateCondition.java deleted file mode 100644 index aad58b54108e..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/DuplicateCondition.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.siyeh.igtest.bugs; - -public class DuplicateCondition { - public void foo() - { - if(bar()||bar()) - { - System.out.println("1"); - }else if(bar()|| true) - { - System.out.println("2"); - } - } - - public boolean bar() - { - return true; - } - - void incompleteCode(String s) { - if (s.contains(A)) { - - } else if (s.contains(B)) { - - } - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java index ef047398e14f..148dc19c35fc 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java @@ -3,10 +3,34 @@ package com.siyeh.igtest.controlflow.duplicate_condition; public class DuplicateCondition { void x(boolean b) { - if (b || b || b ) { + if (b || b || b ) { - } else if (b) { + } else if (b) { - } else if (b) {} + } else if (b) {} + } + + public void foo() + { + if(bar()||bar()) + { + System.out.println("1"); + }else if(bar()|| true) + { + System.out.println("2"); + } + } + + public boolean bar() + { + return true; + } + + void incompleteCode(String s) { + if (s.contains(A)) { + + } else if (s.contains(B)) { + + } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/expected.xml deleted file mode 100644 index 47f1e352b5e6..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/expected.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - DuplicateCondition.java - 6 - Duplicate condition in 'if' statement - Duplicate condition <code>b</code> #loc - - - - DuplicateCondition.java - 6 - Duplicate condition in 'if' statement - Duplicate condition <code>b</code> #loc - - - - DuplicateCondition.java - 8 - Duplicate condition in 'if' statement - Duplicate condition <code>b</code> #loc - - - - DuplicateCondition.java - 6 - Duplicate condition in 'if' statement - Duplicate condition <code>b</code> #loc - - - - DuplicateCondition.java - 10 - Duplicate condition in 'if' statement - Duplicate condition <code>b</code> #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/DuplicateConditionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/DuplicateConditionInspectionTest.java index aaa379cf6ad1..60cd9abe92ce 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/DuplicateConditionInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/DuplicateConditionInspectionTest.java @@ -1,10 +1,18 @@ package com.siyeh.ig.controlflow; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class DuplicateConditionInspectionTest extends IGInspectionTestCase { +public class DuplicateConditionInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/controlflow/duplicate_condition", new DuplicateConditionInspection()); + public void testDuplicateCondition() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new DuplicateConditionInspection(); } } \ No newline at end of file From 8f50a325c39922e38ac551ea27818f864af45503 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 19 May 2015 23:14:33 +0200 Subject: [PATCH 14/27] IG: remove a little duplication by introducing a utility method --- .../ig/abstraction/InstanceofChainInspection.java | 12 ++++-------- .../controlflow/DuplicateConditionInspection.java | 12 ++++-------- .../IfStatementWithTooManyBranchesInspection.java | 13 ++++--------- .../src/com/siyeh/ig/psiutils/ControlFlowUtils.java | 10 ++++++++++ 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java index b7ae3d74125f..003fc6935233 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.ControlFlowUtils; import com.siyeh.ig.psiutils.LibraryUtil; import org.jetbrains.annotations.NotNull; @@ -65,13 +66,8 @@ public class InstanceofChainInspection extends BaseInspection { @Override public void visitIfStatement(@NotNull PsiIfStatement ifStatement) { super.visitIfStatement(ifStatement); - final PsiElement parent = ifStatement.getParent(); - if (parent instanceof PsiIfStatement) { - final PsiIfStatement parentStatement = (PsiIfStatement)parent; - final PsiStatement elseBranch = parentStatement.getElseBranch(); - if (ifStatement.equals(elseBranch)) { - return; - } + if (ControlFlowUtils.isElseIf(ifStatement)) { + return; } final PsiStatement previousStatement = PsiTreeUtil.getPrevSiblingOfType(ifStatement, PsiStatement.class); if (previousStatement instanceof PsiIfStatement) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DuplicateConditionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DuplicateConditionInspection.java index cc734b3fbd42..1d200879a6ee 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DuplicateConditionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DuplicateConditionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.psi.tree.IElementType; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.ControlFlowUtils; import com.siyeh.ig.psiutils.EquivalenceChecker; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,13 +70,8 @@ public class DuplicateConditionInspection extends BaseInspection { @Override public void visitIfStatement(@NotNull PsiIfStatement statement) { super.visitIfStatement(statement); - final PsiElement parent = statement.getParent(); - if (parent instanceof PsiIfStatement) { - final PsiIfStatement parentStatement = (PsiIfStatement)parent; - final PsiStatement elseBranch = parentStatement.getElseBranch(); - if (statement.equals(elseBranch)) { - return; - } + if (ControlFlowUtils.isElseIf(statement)) { + return; } final Set conditions = new HashSet(); collectConditionsForIfStatement(statement, conditions, 0); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithTooManyBranchesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithTooManyBranchesInspection.java index 2ff82f4cfc51..f90aabeb9034 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithTooManyBranchesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithTooManyBranchesInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,12 @@ package com.siyeh.ig.controlflow; import com.intellij.codeInspection.ui.SingleIntegerFieldOptionsPanel; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiIfStatement; import com.intellij.psi.PsiStatement; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.ControlFlowUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -73,13 +73,8 @@ public class IfStatementWithTooManyBranchesInspection @Override public void visitIfStatement(@NotNull PsiIfStatement statement) { super.visitIfStatement(statement); - final PsiElement parent = statement.getParent(); - if (parent instanceof PsiIfStatement) { - final PsiIfStatement parentStatement = (PsiIfStatement)parent; - final PsiStatement elseBranch = parentStatement.getElseBranch(); - if (statement.equals(elseBranch)) { - return; - } + if (ControlFlowUtils.isElseIf(statement)) { + return; } final int branchCount = calculateBranchCount(statement); if (branchCount <= m_limit) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java index 7917a8ef73d9..e79c60e23a49 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java @@ -25,6 +25,16 @@ public class ControlFlowUtils { private ControlFlowUtils() {} + public static boolean isElseIf(PsiIfStatement ifStatement) { + final PsiElement parent = ifStatement.getParent(); + if (!(parent instanceof PsiIfStatement)) { + return false; + } + final PsiIfStatement parentStatement = (PsiIfStatement)parent; + final PsiStatement elseBranch = parentStatement.getElseBranch(); + return ifStatement.equals(elseBranch); + } + public static boolean statementMayCompleteNormally(@Nullable PsiStatement statement) { if (statement == null) { return true; From 169f8329534baf90ad7ee5b7ece709a85a55b300 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 20 May 2015 15:04:56 +0200 Subject: [PATCH 15/27] IDEA-140400 (Chain of instanceof checks: Support class equality tests) --- .../siyeh/InspectionGadgetsBundle.properties | 1 + .../InstanceofChainInspection.java | 80 +++++++++++++------ .../com/siyeh/ig/psiutils/LibraryUtil.java | 13 ++- .../InstanceofChain.html | 5 +- .../instanceof_chain/InstanceofChain.java | 32 +++++++- 5 files changed, 100 insertions(+), 31 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 5dd040bb66b2..e806398948d8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -13,6 +13,7 @@ instance.variable.of.concrete.class.display.name=Type of instance field is concr instance.variable.of.concrete.class.problem.descriptor=Type of field ''{0}'' is concrete class #ref #loc chain.of.instanceof.checks.display.name=Chain of 'instanceof' checks chain.of.instanceof.checks.problem.descriptor=Chain of 'instanceof' checks indicates abstraction failure #loc +chain.of.class.equality.checks.problem.descriptor=Chain of class equality checks indicates abstraction failure #loc instanceof.concrete.class.display.name='instanceof' a concrete class instanceof.concrete.class.problem.descriptor='instanceof' concrete class #ref #loc instanceof.check.for.this.display.name='instanceof' check for 'this' diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java index 003fc6935233..b6c91cbdbaff 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/InstanceofChainInspection.java @@ -23,6 +23,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.ControlFlowUtils; import com.siyeh.ig.psiutils.LibraryUtil; +import com.siyeh.ig.psiutils.ParenthesesUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -47,6 +48,10 @@ public class InstanceofChainInspection extends BaseInspection { @Override @NotNull protected String buildErrorString(Object... infos) { + final Check check = (Check)infos[0]; + if (check == Check.CLASS_EQUALITY) { + return InspectionGadgetsBundle.message("chain.of.class.equality.checks.problem.descriptor"); + } return InspectionGadgetsBundle.message("chain.of.instanceof.checks.problem.descriptor"); } @@ -61,6 +66,10 @@ public class InstanceofChainInspection extends BaseInspection { return new InstanceofChainVisitor(); } + private enum Check { + CLASS_EQUALITY, INSTANCEOF, NEITHER + } + private class InstanceofChainVisitor extends BaseInspectionVisitor { @Override @@ -72,20 +81,26 @@ public class InstanceofChainInspection extends BaseInspection { final PsiStatement previousStatement = PsiTreeUtil.getPrevSiblingOfType(ifStatement, PsiStatement.class); if (previousStatement instanceof PsiIfStatement) { final PsiIfStatement previousIfStatement = (PsiIfStatement)previousStatement; - if (isInstanceofCheck(previousIfStatement.getCondition())) { + final PsiExpression condition = previousIfStatement.getCondition(); + if (chainCheck(condition, null) != Check.NEITHER) { return; } } int numChecks = 0; PsiIfStatement branch = ifStatement; + Check check = null; while (true) { final PsiExpression condition = branch.getCondition(); - if (!isInstanceofCheck(condition)) { + final Check chainCheck = chainCheck(condition, check); + if (chainCheck == Check.NEITHER) { if (numChecks > 1) { break; } return; } + else { + check = chainCheck; + } numChecks++; final PsiStatement elseBranch = branch.getElseBranch(); if (elseBranch instanceof PsiIfStatement) { @@ -105,32 +120,30 @@ public class InstanceofChainInspection extends BaseInspection { if (numChecks < 2) { return; } - registerStatementError(ifStatement); + registerStatementError(ifStatement, check); } - private boolean isInstanceofCheck(PsiExpression condition) { + private Check chainCheck(PsiExpression condition, Check check) { while (true) { if (condition == null) { - return false; + return Check.NEITHER; } - else if (condition instanceof PsiInstanceOfExpression) { - if (ignoreInstanceofOnLibraryClasses) { - final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)condition; - if (isInstanceofOnLibraryClass(instanceOfExpression)) { - return false; - } - } - return true; + else if (check != Check.CLASS_EQUALITY && isInstanceofExpression(condition)) { + return Check.INSTANCEOF; } else if (condition instanceof PsiPolyadicExpression) { + if (check != Check.INSTANCEOF && isClassEqualityExpression(condition)) { + return Check.CLASS_EQUALITY; + } final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)condition; final PsiExpression[] operands = polyadicExpression.getOperands(); for (PsiExpression operand : operands) { - if (!isInstanceofCheck(operand)) { - return false; + final Check chainCheck = chainCheck(operand, check); + if (chainCheck != Check.NEITHER) { + return chainCheck; } } - return true; + return Check.NEITHER; } else if (condition instanceof PsiParenthesizedExpression) { final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)condition; @@ -147,22 +160,39 @@ public class InstanceofChainInspection extends BaseInspection { condition = postfixExpression.getOperand(); continue; } - return false; + return Check.NEITHER; } } - private boolean isInstanceofOnLibraryClass(PsiInstanceOfExpression instanceOfExpression) { - final PsiTypeElement checkType = instanceOfExpression.getCheckType(); - if (checkType == null) { + private boolean isClassEqualityExpression(PsiExpression expression) { + if (!(expression instanceof PsiBinaryExpression)) { return false; } - final PsiType type = checkType.getType(); - if (!(type instanceof PsiClassType)) { + final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression; + if (binaryExpression.getOperationTokenType() != JavaTokenType.EQEQ) { return false; } - final PsiClassType classType = (PsiClassType)type; - final PsiClass aClass = classType.resolve(); - return LibraryUtil.classIsInLibrary(aClass); + return isClassObjectAccessExpression(binaryExpression.getLOperand()) || + isClassObjectAccessExpression(binaryExpression.getROperand()); + } + + private boolean isClassObjectAccessExpression(PsiExpression expression) { + expression = ParenthesesUtils.stripParentheses(expression); + if (!(expression instanceof PsiClassObjectAccessExpression)) { + return false; + } + final PsiClassObjectAccessExpression classObjectAccessExpression = (PsiClassObjectAccessExpression)expression; + final PsiTypeElement typeElement = classObjectAccessExpression.getOperand(); + return !ignoreInstanceofOnLibraryClasses || !LibraryUtil.isTypeInLibrary(typeElement.getType()); + } + + private boolean isInstanceofExpression(PsiExpression expression) { + if (!(expression instanceof PsiInstanceOfExpression)) { + return false; + } + final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)expression; + final PsiTypeElement typeElement = instanceOfExpression.getCheckType(); + return !ignoreInstanceofOnLibraryClasses || typeElement == null || !LibraryUtil.isTypeInLibrary(typeElement.getType()); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/LibraryUtil.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/LibraryUtil.java index 0d2c8183150f..fbe379694a37 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/LibraryUtil.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/LibraryUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,15 @@ import org.jetbrains.annotations.Nullable; public class LibraryUtil { - private LibraryUtil() { - super(); + private LibraryUtil() {} + + public static boolean isTypeInLibrary(@Nullable PsiType type) { + if (!(type instanceof PsiClassType)) { + return false; + } + final PsiClassType classType = (PsiClassType)type; + final PsiClass aClass = classType.resolve(); + return classIsInLibrary(aClass); } public static boolean classIsInLibrary(@Nullable PsiClass aClass) { diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html index 04a3ebd9054c..39717d0afcbf 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html @@ -1,7 +1,8 @@ -Reports any chains of if-else statements all of whose conditions are instanceof expressions -(or combinations of such expressions). Such constructions usually indicate a failure of object-oriented design, which +Reports any chains of if-else statements all of whose conditions are instanceof expressions +or class equality expressions (e.g. comparison with String.class). +Such constructions usually indicate a failure of object-oriented design, which dictates that such type-based dispatch should be done via polymorphic method calls rather than explicit chains of type tests. diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java index 0d3ae444a5bc..cb0223b94d69 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/instanceof_chain/InstanceofChain.java @@ -2,7 +2,7 @@ package com.siyeh.igtest.abstraction.instanceof_chain; public class InstanceofChain { void arg(Object o) { - if (o instanceof String || o instanceof String || o instanceof String) { + if (o != null || o instanceof String || o instanceof String || o instanceof String) { } else if (o instanceof Integer) { @@ -24,4 +24,34 @@ public class InstanceofChain { if (o instanceof Byte) {} if (o instanceof Long) {} } + + void f(Class objClass1, Class objClass2) { + if (objClass1 == String.class) { + if (objClass2 == Integer.class || objClass2 == Double.class) { + } else if (objClass2 == Boolean.class) { + } + } else if (objClass1 == Byte.class){ + if (objClass2 == Float.class){ + } + } + } + + void g(Object obj1, Object obj2) { + if (obj1.getClass() == String.class) { + if (obj2.getClass() == Integer.class || obj2.getClass() == Double.class) { + } else if (obj2.getClass() == Boolean.class) { + } + } else if (obj1.getClass() == Byte.class){ + if (obj2.getClass() == Float.class){ + } + } + } + + void h(Object o) { + if (o instanceof String) { + + } else if (o == null) { + + } + } } From 7faf488b58232a9caac3f376fa59d9e82c71f500 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 May 2015 16:08:25 +0300 Subject: [PATCH 16/27] more logging --- .../daemon/impl/FileStatusMap.java | 26 +++++++++---------- .../psi/impl/PsiTreeChangeEventImpl.java | 7 ++--- .../daemon/impl/DaemonCodeAnalyzerImpl.java | 9 ++++--- .../daemon/impl/PsiChangeHandler.java | 20 +++++++------- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java index e417dfb07f60..4bf905f017ee 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -53,18 +53,18 @@ public class FileStatusMap implements Disposable { private final Map myDocumentToStatusMap = new WeakHashMap(); // all dirty if absent private volatile boolean myAllowDirt = true; - public FileStatusMap(@NotNull Project project) { + FileStatusMap(@NotNull Project project) { myProject = project; } @Override public void dispose() { // clear dangling references to PsiFiles/Documents. SCR#10358 - markAllFilesDirty(); + markAllFilesDirty("FileStatusMap dispose"); } @Nullable("null means the file is clean") - public static TextRange getDirtyTextRange(@NotNull Editor editor, int passId) { + static TextRange getDirtyTextRange(@NotNull Editor editor, int passId) { Document document = editor.getDocument(); FileStatusMap me = DaemonCodeAnalyzerEx.getInstanceEx(editor.getProject()).getFileStatusMap(); @@ -87,7 +87,7 @@ public class FileStatusMap implements Disposable { } } - public boolean wasErrorFound(@NotNull Document document) { + boolean wasErrorFound(@NotNull Document document) { synchronized(myDocumentToStatusMap) { FileStatus status = myDocumentToStatusMap.get(document); return status != null && status.errorFound; @@ -164,9 +164,9 @@ public class FileStatusMap implements Disposable { } } - public void markAllFilesDirty() { + void markAllFilesDirty(@NotNull @NonNls Object reason) { assertAllowModifications(); - LOG.debug("********************************* Mark all dirty"); + LOG.debug("Mark all dirty: ", reason); synchronized (myDocumentToStatusMap) { myDocumentToStatusMap.clear(); } @@ -220,10 +220,10 @@ public class FileStatusMap implements Disposable { } } - public void markFileScopeDirtyDefensively(@NotNull PsiFile file) { + void markFileScopeDirtyDefensively(@NotNull PsiFile file, @NotNull @NonNls Object reason) { assertAllowModifications(); if (LOG.isDebugEnabled()) { - LOG.debug("********************************* Mark dirty file defensively: "+file.getName()); + LOG.debug("Mark dirty file defensively: "+file.getName()+": "+reason); } // mark whole file dirty in case no subsequent PSI events will come, but file requires rehighlighting nevertheless // e.g. in the case of quick typing/backspacing char @@ -236,10 +236,10 @@ public class FileStatusMap implements Disposable { } } - public void markFileScopeDirty(@NotNull Document document, @NotNull TextRange scope, int fileLength) { + void markFileScopeDirty(@NotNull Document document, @NotNull TextRange scope, int fileLength, @NotNull @NonNls Object reason) { assertAllowModifications(); if (LOG.isDebugEnabled()) { - LOG.debug("********************************* Mark dirty: "+scope); + LOG.debug("Mark scope dirty: "+scope+" : "+reason); } synchronized(myDocumentToStatusMap) { FileStatus status = myDocumentToStatusMap.get(document); @@ -270,7 +270,7 @@ public class FileStatusMap implements Disposable { return document.createRangeMarker(union); } - public boolean allDirtyScopesAreNull(@NotNull Document document) { + boolean allDirtyScopesAreNull(@NotNull Document document) { synchronized (myDocumentToStatusMap) { PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document); if (!ProblemHighlightFilter.shouldHighlightFile(file)) return true; @@ -342,7 +342,7 @@ public class FileStatusMap implements Disposable { @Override public T getUserData(@NotNull Key key) { - throw null; + throw new UnsupportedOperationException(); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java index 9c9bc6ca7d76..0805dc95d7c3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangeEventImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -42,7 +42,7 @@ public class PsiTreeChangeEventImpl extends PsiTreeChangeEvent{ private PsiEventType myCode; - public PsiTreeChangeEventImpl(PsiManager manager) { + public PsiTreeChangeEventImpl(@NotNull PsiManager manager) { super(manager); } @@ -124,8 +124,9 @@ public class PsiTreeChangeEventImpl extends PsiTreeChangeEvent{ isGenericChange = genericChange; } + @NotNull @Override public String toString() { - return "PsiTreeChangeEventImpl{myCode=" + myCode + (isGenericChange ? " (generic)" : "") + '}'; + return "PsiTreeChangeEventImpl{" + myCode + (isGenericChange ? " (generic)" : "") + '}'; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 8663b82128a9..346d1e1ad920 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -143,7 +143,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers myInitialized = true; myDisposed = false; - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty("DCAI init"); Disposer.register(this, new Disposable() { @Override public void dispose() { @@ -477,7 +477,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers @Override public void restart() { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty("Global restart"); stopProcess(true, "Global restart"); } @@ -485,8 +485,9 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers public void restart(@NotNull PsiFile file) { Document document = myPsiDocumentManager.getCachedDocument(file); if (document == null) return; - myFileStatusMap.markFileScopeDirty(document, new TextRange(0, document.getTextLength()), file.getTextLength()); - stopProcess(true, "Psi file restart"); + String reason = "Psi file restart: " + file.getName(); + myFileStatusMap.markFileScopeDirty(document, new TextRange(0, document.getTextLength()), file.getTextLength(), reason); + stopProcess(true, reason); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java index becc369f534b..b2acbad9c634 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -178,7 +178,7 @@ class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable { // mark file dirty just in case PsiFile psiFile = event.getFile(); if (psiFile != null) { - myFileStatusMap.markFileScopeDirtyDefensively(psiFile); + myFileStatusMap.markFileScopeDirtyDefensively(psiFile, event); } } @@ -186,15 +186,15 @@ class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable { public void propertyChanged(@NotNull PsiTreeChangeEvent event) { String propertyName = event.getPropertyName(); if (!propertyName.equals(PsiTreeChangeEvent.PROP_WRITABLE)) { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty(event); } } - private void queueElement(PsiElement child, final boolean whitespaceOptimizationAllowed, PsiTreeChangeEvent event) { + private void queueElement(@NotNull PsiElement child, final boolean whitespaceOptimizationAllowed, @NotNull PsiTreeChangeEvent event) { PsiFile file = event.getFile(); if (file == null) file = child.getContainingFile(); if (file == null) { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty(child); return; } @@ -216,30 +216,30 @@ class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable { file = child.getContainingFile(); } catch (PsiInvalidElementAccessException e) { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty(e); return; } if (file == null || file instanceof PsiCompiledElement) { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty(child); return; } int fileLength = file.getTextLength(); if (!file.getViewProvider().isPhysical()) { - myFileStatusMap.markFileScopeDirty(document, new TextRange(0, fileLength), fileLength); + myFileStatusMap.markFileScopeDirty(document, new TextRange(0, fileLength), fileLength, "Non-physical file update: "+file); return; } PsiElement element = whitespaceOptimizationAllowed && UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document) ? child : child.getParent(); while (true) { if (element == null || element instanceof PsiFile || element instanceof PsiDirectory) { - myFileStatusMap.markAllFilesDirty(); + myFileStatusMap.markAllFilesDirty("Top element: "+element); return; } final PsiElement scope = getChangeHighlightingScope(element); if (scope != null) { - myFileStatusMap.markFileScopeDirty(document, scope.getTextRange(), fileLength); + myFileStatusMap.markFileScopeDirty(document, scope.getTextRange(), fileLength, "Scope: "+scope); return; } From ca41b48336a9a6bd88f3db1ba077bbf71714579b Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 20 May 2015 16:18:13 +0300 Subject: [PATCH 17/27] IDEA-140418 "Switch Boot JDK" dialog has display problems on Windows; NPE at SwitchBootJdkAction$SwitchBootJdkDialog$1.customize --- .../src/com/intellij/openapi/util/SwitchBootJdkAction.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index 86650918fa15..2550d354749c 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -17,6 +17,7 @@ package com.intellij.openapi.util; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; @@ -51,6 +52,11 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { + Presentation presentation = e.getPresentation(); + if (!SystemInfo.isMac) { + presentation.setEnabledAndVisible(false); + return; + } e.getPresentation().setText("Switch Boot JDK"); } From 04a1ba93ee23fc1b99870fb055f9422c6bd18912 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 May 2015 14:10:19 +0200 Subject: [PATCH 18/27] IDEA-140517 Clearly indicate re-indexing reason --- .../openapi/roots/impl/ProjectRootManagerComponent.java | 1 + .../src/com/intellij/util/indexing/FileBasedIndexImpl.java | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java index 3c85e97a3a69..34bc35c19b30 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java @@ -285,6 +285,7 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { if (!myStartupActivityPerformed) return; if (myDoLogCachesUpdate) LOG.info(new Throwable("sync roots")); + else LOG.info("project roots have changed"); DumbServiceImpl dumbService = DumbServiceImpl.getInstance(myProject); if (FileBasedIndex.getInstance() instanceof FileBasedIndexImpl) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index a68926b084fc..c6bb7c5048c4 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -227,7 +227,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { LOG.info(e); } } - scheduleIndexRebuild(); + scheduleIndexRebuild("File type change"); } }); @@ -1248,7 +1248,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { doClearIndex(indexId); if (!cleanupOnly) { - scheduleIndexRebuild(); + scheduleIndexRebuild("checkRebuild"); } } catch (StorageException e) { @@ -1286,7 +1286,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - private static void scheduleIndexRebuild() { + private static void scheduleIndexRebuild(String reason) { + LOG.info("scheduleIndexRebuild, reason: " + reason); for (Project project : ProjectManager.getInstance().getOpenProjects()) { DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, false)); } From fd62fed99444729e35e62210f68d66bed445eb3b Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 May 2015 14:18:52 +0200 Subject: [PATCH 19/27] dfa: don't suggest to convert lvalue to ternary expression (IDEA-140519) --- .../codeInspection/ReplaceWithTernaryOperatorFix.java | 3 ++- .../replaceWithTernaryOperator/beforeLValue.java | 9 +++++++++ .../codeInspection/DataFlowInspectionTestSuite.java | 6 ++---- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeLValue.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java index 212662fc7fdb..583cf36744b4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java @@ -22,6 +22,7 @@ import com.intellij.pom.Navigatable; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; /** @@ -95,7 +96,7 @@ public class ReplaceWithTernaryOperatorFix implements LocalQuickFix { return false; } - return !(expression.getParent() instanceof PsiExpressionStatement); + return !(expression.getParent() instanceof PsiExpressionStatement) && !PsiUtil.isAccessedForWriting(expression); } private static String suggestDefaultValue(@NotNull PsiExpression expression) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeLValue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeLValue.java new file mode 100644 index 000000000000..394fda7f580f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeLValue.java @@ -0,0 +1,9 @@ +// "Replace with 'a != null ?:'" "false" +class A{ + void test(){ + A a = null; + a.field = 2; + } + + int field; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java index adb0d9f35c50..0178b38bd58a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java @@ -17,10 +17,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.completion.NormalCompletionDfaTest; import com.intellij.codeInsight.completion.SmartTypeCompletionDfaTest; -import com.intellij.codeInsight.daemon.quickFix.AddAssertStatementFixTest; -import com.intellij.codeInsight.daemon.quickFix.ReplaceFromOfNullableFixTest; -import com.intellij.codeInsight.daemon.quickFix.ReplaceWithOfNullableFixTest; -import com.intellij.codeInsight.daemon.quickFix.SurroundWithIfFixTest; +import com.intellij.codeInsight.daemon.quickFix.*; import com.intellij.slicer.SliceBackwardTest; import com.intellij.slicer.SliceTreeTest; import junit.framework.Test; @@ -51,6 +48,7 @@ public class DataFlowInspectionTestSuite { suite.addTestSuite(AddAssertStatementFixTest.class); suite.addTestSuite(SurroundWithIfFixTest.class); + suite.addTestSuite(ReplaceWithTernaryOperatorTest.class); suite.addTestSuite(ReplaceWithOfNullableFixTest.class); suite.addTestSuite(ReplaceFromOfNullableFixTest.class); return suite; From 882e11a5c4bd52b550be8864e660c309230b684f Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 May 2015 14:29:41 +0200 Subject: [PATCH 20/27] IDEA-140449 Space in Go to Class no longer works --- .../src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index f69a4e8e9f43..c1a4af74f289 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -814,7 +814,7 @@ public abstract class ChooseByNameBase { } @NotNull public String getTrimmedText() { - return StringUtil.notNullize(myTextField.getText()).trim(); + return StringUtil.trimLeading(StringUtil.notNullize(myTextField.getText())); } public void setFixLostTyping(boolean fixLostTyping) { From 5684569b0cd9a47fb3cf699d54bac3a18f34d1e1 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Wed, 20 May 2015 16:21:20 +0300 Subject: [PATCH 21/27] Fix for upsource - it uses its own class loaders which are not IS-A PluginClassLoader --- .../src/net/sf/cglib/proxy/AdvancedEnhancer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java index a2f21c3d0018..410c7b47c2a1 100644 --- a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java +++ b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java @@ -366,6 +366,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator protected ClassLoader getDefaultClassLoader() { int maxIndex = -1; ClassLoader bestLoader = null; + ClassLoader nonPluginLoader = null; if (interfaces != null && interfaces.length > 0) { for (final Class anInterface : interfaces) { final ClassLoader loader = anInterface.getClassLoader(); @@ -376,6 +377,9 @@ public class AdvancedEnhancer extends AbstractClassGenerator bestLoader = loader; } } + else if (nonPluginLoader == null) { + nonPluginLoader = loader; + } } } ClassLoader superLoader = null; @@ -387,7 +391,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator } } if (bestLoader != null) return bestLoader; - return superLoader; + return superLoader == null ? nonPluginLoader : superLoader; } private static Signature rename(Signature sig, int index) { From c367d6f4e15f0a98bb988ff73bcdc532b7d5c84e Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 20 May 2015 15:28:48 +0300 Subject: [PATCH 22/27] use walking visitor to prevent SOE on big html files --- .../src/com/intellij/xml/util/XmlRefCountHolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java b/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java index ecb407e19d33..e24e55ce0173 100644 --- a/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java +++ b/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java @@ -160,7 +160,7 @@ public class XmlRefCountHolder { return myUsedNamespaces.contains(ns); } - private static class IdGatheringRecursiveVisitor extends XmlRecursiveElementVisitor { + private static class IdGatheringRecursiveVisitor extends XmlRecursiveElementWalkingVisitor { private final XmlRefCountHolder myHolder; private IdGatheringRecursiveVisitor(@NotNull XmlRefCountHolder holder) { From 28ff0b4a1e4b67494dae5b81ed4b95a523e45817 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 16:25:28 +0300 Subject: [PATCH 23/27] diff: oneside viewer - hide chevrone operations on state invalidation * they will do nothing anyway --- .../tools/fragmented/OnesideDiffChange.java | 1 + .../tools/fragmented/OnesideDiffViewer.java | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java index cdb30e3cad4e..692beef63da3 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java @@ -235,6 +235,7 @@ public class OnesideDiffChange { @Nullable public GutterIconRenderer createRenderer() { + if (myViewer.isStateIsOutOfDate()) return null; if (!myViewer.isEditable(mySide.other(), true)) return null; boolean bothEditable = myViewer.isEditable(mySide, true); 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 73d94fe41088..eb1487cd6f31 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 @@ -383,6 +383,22 @@ public class OnesideDiffViewer extends TextDiffViewerBase { updateEditorCanBeTyped(); } + @CalledInAwt + protected void markSuppressEditorTyping() { + mySuppressEditorTyping = true; + updateEditorCanBeTyped(); + } + + @CalledInAwt + protected void markStateIsOutOfDate() { + myStateIsOutOfDate = true; + if (myChangedBlockData != null) { + for (OnesideDiffChange diffChange : myChangedBlockData.getDiffChanges()) { + diffChange.updateGutterActions(); + } + } + } + @Nullable private EditorHighlighter buildHighlighter(@Nullable Project project, @NotNull DocumentContent content1, @@ -611,8 +627,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase { if (twosideStartLine == -1 || twosideEndLine == -1) { // this should never happen logDebugInfo(e, onesideStartPosition, onesideEndPosition, twosideStartLine, twosideEndLine); - mySuppressEditorTyping = true; - updateEditorCanBeTyped(); + markSuppressEditorTyping(); return; } @@ -630,7 +645,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase { finally { // TODO: we can avoid marking state out-of-date in some simple cases (like in SimpleDiffViewer) // but this will greatly increase complexity, so let's wait if it's actually required by users - myStateIsOutOfDate = true; + markStateIsOutOfDate(); myFoldingModel.onDocumentChanged(e); scheduleRediff(); @@ -673,9 +688,8 @@ public class OnesideDiffViewer extends TextDiffViewerBase { protected void onDocumentChange(@NotNull DocumentEvent e) { if (myDuringTwosideDocumentModification) return; - myStateIsOutOfDate = true; - mySuppressEditorTyping = true; - updateEditorCanBeTyped(); + markStateIsOutOfDate(); + markSuppressEditorTyping(); myFoldingModel.onDocumentChanged(e); scheduleRediff(); From 99b64a006417a618baa8300ac97e43e7720f8e86 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 16:50:25 +0300 Subject: [PATCH 24/27] diff: oneside viewer - do not rebuild diff in EDT on clicking chevrone button we're inside WriteAction - so all rediff activities will be made in EDT (because pooled thread can't get ReadAction) --- .../com/intellij/diff/tools/fragmented/OnesideDiffChange.java | 3 +++ .../com/intellij/diff/tools/fragmented/OnesideDiffViewer.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java index 692beef63da3..d0a3d5706dc0 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffChange.java @@ -289,6 +289,9 @@ public class OnesideDiffChange { myViewer.applyChange(OnesideDiffChange.this, sourceSide); } }); + // applyChange() will schedule rediff, but we want to try to do it in sync + // and we can't do it inside write action + myViewer.rediff(); } }; } 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 eb1487cd6f31..44388a9bf6e2 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 @@ -715,7 +715,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase { // no need to mark myStateIsOutOfDate - it will be made by DocumentListener // TODO: we can apply change manually, without marking state out-of-date. But we'll have to schedule rediff anyway. - rediff(); + scheduleRediff(); } // From c8b501e31da207f747672db762e5acb510c96a9b Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 20 May 2015 16:54:13 +0300 Subject: [PATCH 25/27] diff: abort scheduled tasks on rediff viewer.scheduleRediff(); viewer.rediff(); shouldn't cause performing calculations twice --- .../src/com/intellij/diff/tools/util/base/DiffViewerBase.java | 1 + 1 file changed, 1 insertion(+) 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 e519314f7079..c897e28e9a06 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 @@ -127,6 +127,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { @CalledInAwt public final void rediff(boolean trySync) { if (isDisposed()) return; + abortRediff(); onBeforeRediff(); From 5587104390fab759ba4a4b28db85132a296cdec4 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 20 May 2015 16:56:41 +0300 Subject: [PATCH 26/27] IDEA-140424 "Switch Boot JDK" dialog: do not show "JDK bundled with IDE" if there is no JDK bundled --- .../com/intellij/openapi/util/SwitchBootJdkAction.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index 2550d354749c..de3338aebaaf 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -49,11 +49,12 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { @NonNls private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.SwitchBootJdkAction"); @NonNls private static final String productJdkConfigFileName = ApplicationNamesInfo.getInstance().getScriptName() + ".jdk"; @NonNls private static final File productJdkConfigFile = new File(PathManager.getConfigPath(), productJdkConfigFileName); + @NonNls private static final File customJdkFile = new File(PathManager.getHomePath() + File.separator + "jre" + File.separator + "jdk"); @Override public void update(AnActionEvent e) { Presentation presentation = e.getPresentation(); - if (!SystemInfo.isMac) { + if (!SystemInfo.isMac || !customJdkFile.exists()) { presentation.setEnabledAndVisible(false); return; } @@ -224,7 +225,10 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { ArrayList jdkPathsList = new ArrayList(); if (!SystemInfo.isMac) return jdkPathsList; - jdkPathsList.add(new JdkBundleDescriptor(new File(PathManager.getHomePath() + File.separator + "jre" + File.separator + "jdk" ), "JDK bundled with IDE")); + + if (customJdkFile.exists()) { + jdkPathsList.add(new JdkBundleDescriptor(customJdkFile, "JDK bundled with IDE")); + } jdkPathsList.addAll(jdkBundlesFromLocation(STANDARD_JDK_6_LOCATION_ON_MAC_OS_X, "1.6.0")); jdkPathsList.addAll(jdkBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, "jdk1.8.0_(\\d*).jdk")); From 5bed082ed136432043817bfee7ba8686c0a3097e Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 20 May 2015 17:04:27 +0300 Subject: [PATCH 27/27] IDEA-140480 "Switch IDE Boot JDK" dialog: "Specify Boot JDK Path" text could be changed to something like "Select Boot JDK" --- .../src/com/intellij/openapi/util/SwitchBootJdkAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index de3338aebaaf..52d50ee38f9d 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -197,7 +197,7 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { @Nullable @Override protected JComponent createNorthPanel() { - return new JBLabel("Specify Boot JDK path"); + return new JBLabel("Select Boot JDK"); } @Nullable