diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java index 8d8971214f75..96d90b24c256 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java @@ -139,7 +139,7 @@ public class SimplifyBooleanExpressionFix extends LocalQuickFixOnPsiElement { PsiElement parent = orig.getParent(); if (parent == null) return; if (statement instanceof PsiBlockStatement && parent instanceof PsiCodeBlock && - !VariableSearchUtils.containsConflictingDeclarations((PsiCodeBlock)parent, (PsiCodeBlock)parent)) { + !VariableSearchUtils.containsConflictingDeclarations(((PsiBlockStatement)statement).getCodeBlock(), (PsiCodeBlock)parent)) { // See IDEADEV-24277 // Code block can only be inlined into another (parent) code block. // Code blocks, which are if or loop statement branches should not be inlined. diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index adda15ddc1c8..38dfa6eca8da 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -66,7 +66,7 @@ import com.intellij.util.ui.UIUtil; import gnu.trove.TIntArrayList; import gnu.trove.TIntFunction; import gnu.trove.TIntObjectHashMap; -import gnu.trove.TObjectProcedure; +import gnu.trove.TIntObjectProcedure; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -128,6 +128,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private final EditorImpl myEditor; private final FoldingAnchorsOverlayStrategy myAnchorsDisplayStrategy; + @Nullable private TIntObjectHashMap> myLineToGutterRenderers; private int myIconsAreaWidth = 0; private int myLineNumberAreaWidth = 0; private int myAdditionalLineNumberAreaWidth = 0; @@ -683,6 +684,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse int prevHash = sizeHash(); if (!onLayout) { + clearLineToGutterRenderersCache(); calcLineNumberAreaWidth(); calcLineMarkerAreaWidth(canShrink); calcAnnotationsSize(); @@ -748,23 +750,15 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } - private TIntObjectHashMap> myLineToGutterRenderers; + public void clearLineToGutterRenderersCache() { + myLineToGutterRenderers = null; + } - private void calcLineMarkerAreaWidth(boolean canShrink) { + private void buildGutterRenderersCache() { myLineToGutterRenderers = new TIntObjectHashMap<>(); - myLeftFreePaintersAreaShown = myForceLeftFreePaintersAreaShown; - myRightFreePaintersAreaShown = myForceRightFreePaintersAreaShown; - processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() { @Override public void process(@NotNull RangeHighlighter highlighter) { - LineMarkerRenderer lineMarkerRenderer = highlighter.getLineMarkerRenderer(); - if (lineMarkerRenderer != null) { - LineMarkerRendererEx.Position position = getLineMarkerPosition(lineMarkerRenderer); - if (position == LineMarkerRendererEx.Position.LEFT && isLineMarkerVisible(highlighter)) myLeftFreePaintersAreaShown = true; - if (position == LineMarkerRendererEx.Position.RIGHT && isLineMarkerVisible(highlighter)) myRightFreePaintersAreaShown = true; - } - GutterMark renderer = highlighter.getGutterIconRenderer(); if (renderer == null) { return; @@ -785,6 +779,23 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } }); + } + + private void calcLineMarkerAreaWidth(boolean canShrink) { + myLeftFreePaintersAreaShown = myForceLeftFreePaintersAreaShown; + myRightFreePaintersAreaShown = myForceRightFreePaintersAreaShown; + + processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() { + @Override + public void process(@NotNull RangeHighlighter highlighter) { + LineMarkerRenderer lineMarkerRenderer = highlighter.getLineMarkerRenderer(); + if (lineMarkerRenderer != null) { + LineMarkerRendererEx.Position position = getLineMarkerPosition(lineMarkerRenderer); + if (position == LineMarkerRendererEx.Position.LEFT && isLineMarkerVisible(highlighter)) myLeftFreePaintersAreaShown = true; + if (position == LineMarkerRendererEx.Position.RIGHT && isLineMarkerVisible(highlighter)) myRightFreePaintersAreaShown = true; + } + } + }); if (canShrink) { myIconsAreaWidth = myEditor.getLineHeight(); @@ -792,21 +803,18 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse myIconsAreaWidth = Math.max(myIconsAreaWidth, myEditor.getLineHeight()); } - myLineToGutterRenderers.forEachValue(new TObjectProcedure>() { - @Override - public boolean execute(List renderers) { - int width = 1; - for (int i = 0; i < renderers.size(); i++) { - GutterMark renderer = renderers.get(i); - if (!checkDumbAware(renderer)) continue; - width += scaleIcon(renderer.getIcon()).getIconWidth(); - if (i > 0) width += GAP_BETWEEN_ICONS; - } - if (myIconsAreaWidth < width) { - myIconsAreaWidth = width + 1; - } - return true; + processGutterRenderers((line, renderers) -> { + int width = 1; + for (int i = 0; i < renderers.size(); i++) { + GutterMark renderer = renderers.get(i); + if (!checkDumbAware(renderer)) continue; + width += scaleIcon(renderer.getIcon()).getIconWidth(); + if (i > 0) width += GAP_BETWEEN_ICONS; } + if (myIconsAreaWidth < width) { + myIconsAreaWidth = width + 1; + } + return true; }); if (isDumbMode()) { @@ -817,6 +825,21 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } + @Nullable + private List getGutterRenderers(int line) { + if (myLineToGutterRenderers == null) { + buildGutterRenderersCache(); + } + return myLineToGutterRenderers.get(line); + } + + private void processGutterRenderers(@NotNull TIntObjectProcedure> processor) { + if (myLineToGutterRenderers == null) { + buildGutterRenderersCache(); + } + myLineToGutterRenderers.forEachEntry(processor); + } + private boolean isHighlighterVisible(RangeHighlighter highlighter) { int startOffset = highlighter instanceof RangeHighlighterEx ? ((RangeHighlighterEx)highlighter).getAffectedAreaStartOffset() : @@ -850,7 +873,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private void paintIcons(final int firstVisibleLine, final int lastVisibleLine, final Graphics2D g) { for (int line = firstVisibleLine; line <= lastVisibleLine; line++) { - List renderers = myLineToGutterRenderers.get(line); + List renderers = getGutterRenderers(line); if (renderers != null) { paintIconRow(line, renderers, g); } @@ -1442,7 +1465,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse if (toolTip != null && !toolTip.isEmpty()) { final Ref t = new Ref<>(e.getPoint()); int line = EditorUtil.yPositionToLogicalLine(myEditor, e); - List row = myLineToGutterRenderers.get(line); + List row = getGutterRenderers(line); Balloon.Position ballPosition = Balloon.Position.atRight; if (row != null) { final TreeMap xPos = new TreeMap<>(); @@ -1697,22 +1720,17 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse @Nullable public Point getCenterPoint(final GutterIconRenderer renderer) { final Ref result = Ref.create(); - for (int line : myLineToGutterRenderers.keys()) { - processIconsRow(line, myLineToGutterRenderers.get(line), new LineGutterIconRendererProcessor() { - @Override - public void process(int x, int y, GutterMark r) { - if (result.isNull() && r.equals(renderer)) { - Icon icon = scaleIcon(r.getIcon()); - result.set(new Point(x + icon.getIconWidth() / 2, y + icon.getIconHeight() / 2)); - } + processGutterRenderers((line, renderers) -> { + processIconsRow(line, renderers, (x, y, r) -> { + if (result.isNull() && r.equals(renderer)) { + Icon icon = scaleIcon(r.getIcon()); + result.set(new Point(x + icon.getIconWidth() / 2, y + icon.getIconHeight() / 2)); } }, true); - if (!result.isNull()) { - return result.get(); - } - } - return null; + return result.isNull(); + }); + return result.get(); } @Override @@ -1840,7 +1858,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private GutterMark getGutterRenderer(final Point p) { int line = convertPointToLineNumber(p); if (line == -1) return null; - List renderers = myLineToGutterRenderers.get(line); + List renderers = getGutterRenderers(line); if (renderers == null) { return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 1c611d0ac866..1c41c4cf2770 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -1947,10 +1947,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi boolean painted = false; if (myDocument.getTextLength() > 0) { - int startDocLine = myDocument.getLineNumber(e.getOffset()); - int endDocLine = myDocument.getLineNumber(e.getOffset() + e.getNewLength()); - if (e.getOldLength() > e.getNewLength() || startDocLine != endDocLine || StringUtil.indexOf(e.getOldFragment(), '\n') != -1) { - updateGutterSize(); + if (startLine != endLine || StringUtil.indexOf(e.getOldFragment(), '\n') != -1) { + myGutterComponent.clearLineToGutterRenderersCache(); } if (countLineFeeds(e.getOldFragment()) != countLineFeeds(e.getNewFragment())) { @@ -2036,7 +2034,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi dim = mySizeAdjustmentStrategy.adjust(dim, myPreferredSize, this); myPreferredSize = dim; - myGutterComponent.updateSize(); + updateGutterSize(); myEditorComponent.setSize(dim); myEditorComponent.fireResized(); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index 39ae76b84947..1c050c8112b6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -209,7 +209,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica LOG.info("Dumb mode not permitted in modal environment; see DumbService.allowStartingDumbModeInside documentation", trace); } else if (permission == DumbModePermission.MAY_START_MODAL) { - LOG.info("Starting modal dumb mode, caused by the following trace", trace); + LOG.debug("Starting modal dumb mode, caused by the following trace", trace); } // always change dumb status inside write action. diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java index 0df772a82089..3fc61807a3a6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java @@ -88,7 +88,16 @@ public class VcsHistoryUtil { final byte[] content1 = loadRevisionContent(revision1); final byte[] content2 = loadRevisionContent(revision2); - String title = DiffRequestFactoryImpl.getContentTitle(path); + FilePath path1 = getRevisionPath(revision1); + FilePath path2 = getRevisionPath(revision2); + + String title; + if (path1 != null && path2 != null) { + title = DiffRequestFactoryImpl.getTitle(path1, path2, " -> "); + } + else { + title = DiffRequestFactoryImpl.getContentTitle(path); + } DiffContent diffContent1 = createContent(project, content1, revision1, path); DiffContent diffContent2 = createContent(project, content2, revision2, path); @@ -113,6 +122,14 @@ public class VcsHistoryUtil { return null; } + @Nullable + private static FilePath getRevisionPath(@NotNull VcsFileRevision revision) { + if (revision instanceof VcsFileRevisionEx) { + return ((VcsFileRevisionEx)revision).getPath(); + } + return null; + } + @NotNull public static byte[] loadRevisionContent(@NotNull VcsFileRevision revision) throws VcsException, IOException { byte[] content = revision.getContent(); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 3cb40faa79c7..d14b775a6227 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1287,7 +1287,7 @@ string.equals.empty.string.quickfix=Replace with 'length()==0' string.equals.empty.string.isempty.quickfix=Replace with 'isEmpty()' tail.recursion.replace.quickfix=Replace tail recursion with iteration if.statement.with.too.many.branches.max.option=Maximum number of branches: -if.statement.with.too.many.branches.problem.descriptor=''#ref'' has too many branches ({0}) #loc +if.statement.with.too.many.branches.problem.descriptor=#ref has too many branches ({0}) #loc negated.conditional.ignore.option=Ignore '!= null' comparisons negated.conditional.invert.quickfix=Invert condition negated.if.else.ignore.negated.null.option=Ignore '!= null' comparisons @@ -1298,9 +1298,9 @@ pointless.boolean.expression.ignore.option=Ignore named constants in determining simplifiable.conditional.expression.problem.descriptor=#ref can be simplified to ''{0}'' #loc simplifiable.if.statement.problem.descriptor=#ref statement can be replaced with ''{0}'' #loc switch.statement.density.min.option=Minimum density of branches: % -switch.statement.density.problem.descriptor=''#ref'' has too low of a branch density ({0}%) #loc +switch.statement.density.problem.descriptor=#ref has too low of a branch density ({0}%) #loc switch.statement.with.too.few.branches.min.option=Minimum number of branches: -switch.statement.with.too.few.branches.problem.descriptor=''#ref'' has too few branches ({0}), and should probably be replaced with an ''if'' statement #loc +switch.statement.with.too.few.branches.problem.descriptor=#ref has too few branches ({0}), and should probably be replaced with an ''if'' statement #loc switch.statement.without.default.ignore.option=Ignore if all cases of an enumerated type are covered unnecessary.label.remove.quickfix=Remove label unnecessary.return.problem.descriptor=#ref is unnecessary as the last statement in a 'void' method #loc diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java index 9f2078cac24f..fac06bb8dc6a 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2016 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,6 +16,7 @@ package com.siyeh.ipp.enumswitch; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.ig.PsiReplacementUtil; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; @@ -29,11 +30,13 @@ import java.util.Map; public class CreateEnumSwitchBranchesIntention extends Intention { + @Override @NotNull protected PsiElementPredicate getElementPredicate() { return new EnumSwitchPredicate(); } + @Override public void processIntention(@NotNull PsiElement element) { if (element instanceof PsiWhiteSpace) { element = element.getPrevSibling(); @@ -54,7 +57,7 @@ public class CreateEnumSwitchBranchesIntention extends Intention { return; } final PsiField[] fields = enumClass.getFields(); - final List missingEnumElements = new ArrayList(fields.length); + final List missingEnumElements = new ArrayList<>(fields.length); for (final PsiField field : fields) { if (!(field instanceof PsiEnumConstant)) { continue; @@ -114,6 +117,13 @@ public class CreateEnumSwitchBranchesIntention extends Intention { } private static void addSwitchLabelStatementBefore(PsiEnumConstant missingEnumElement, PsiElement anchor) { + if (anchor instanceof PsiSwitchLabelStatement) { + PsiElement sibling = PsiTreeUtil.skipSiblingsBackward(anchor, PsiWhiteSpace.class); + while (sibling instanceof PsiSwitchLabelStatement) { + anchor = sibling; + sibling = PsiTreeUtil.skipSiblingsBackward(anchor, PsiWhiteSpace.class); + } + } final PsiElement parent = anchor.getParent(); final PsiElementFactory factory = JavaPsiFacade.getElementFactory(anchor.getProject()); final PsiStatement caseStatement = factory.createStatementFromText("case " + missingEnumElement.getName() + ":", anchor); diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java index 0cee31ba1abd..9a7d0f79688b 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -25,6 +25,7 @@ public class EnumSwitchBranchesIntentionTest extends IPPTestCase { public void testWithoutBraces() { doTest(); } public void testBeforeDefault() { doTest(); } + public void testBeforeFallthrough() { doTest(); } public void testMultiple() { doTest(); } public void testNoActionAfterBraces() { assertIntentionNotAvailable(); } diff --git a/resources-en/src/inspectionDescriptions/ConstantConditions.html b/resources-en/src/inspectionDescriptions/ConstantConditions.html index 1e2dd7644de7..1a0040fe202e 100644 --- a/resources-en/src/inspectionDescriptions/ConstantConditions.html +++ b/resources-en/src/inspectionDescriptions/ConstantConditions.html @@ -4,7 +4,7 @@ This inspection analyzes method control and data flow to report possible conditi expressions whose value is statically proven to be constant, and situations that can lead to nullability contract violations.

Variables, method parameters and return values marked as @Nullable or @NotNull are treated as nullable (or not-null, respectively) -and used during the analysis to check nullability contracts, e.g. report possible NullPointerException errors.

+and used during the analysis to check nullability contracts, e.g. report NullPointerException (NPE) errors that might be produced.

More complex contracts can be defined using @Contract annotation, for example:

@Contract("_, null -> null") — method returns null if its second argument is null