Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2016-04-19 18:04:47 +02:00
9 changed files with 102 additions and 58 deletions
@@ -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.
@@ -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<List<GutterMark>> 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<List<GutterMark>> 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<List<GutterMark>>() {
@Override
public boolean execute(List<GutterMark> 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<GutterMark> getGutterRenderers(int line) {
if (myLineToGutterRenderers == null) {
buildGutterRenderersCache();
}
return myLineToGutterRenderers.get(line);
}
private void processGutterRenderers(@NotNull TIntObjectProcedure<List<GutterMark>> 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<GutterMark> renderers = myLineToGutterRenderers.get(line);
List<GutterMark> 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<Point> t = new Ref<>(e.getPoint());
int line = EditorUtil.yPositionToLogicalLine(myEditor, e);
List<GutterMark> row = myLineToGutterRenderers.get(line);
List<GutterMark> row = getGutterRenderers(line);
Balloon.Position ballPosition = Balloon.Position.atRight;
if (row != null) {
final TreeMap<Integer, GutterMark> xPos = new TreeMap<>();
@@ -1697,22 +1720,17 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
@Nullable
public Point getCenterPoint(final GutterIconRenderer renderer) {
final Ref<Point> 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<GutterMark> renderers = myLineToGutterRenderers.get(line);
List<GutterMark> renderers = getGutterRenderers(line);
if (renderers == null) {
return null;
}
@@ -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();
@@ -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.
@@ -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();
@@ -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=''<code>#ref</code>'' has too many branches ({0}) #loc
if.statement.with.too.many.branches.problem.descriptor=<code>#ref</code> 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=<code>#ref</code> can be simplified to ''{0}'' #loc
simplifiable.if.statement.problem.descriptor=<code>#ref</code> statement can be replaced with ''{0}'' #loc
switch.statement.density.min.option=Minimum density of branches: %
switch.statement.density.problem.descriptor=''<code>#ref</code>'' has too low of a branch density ({0}%) #loc
switch.statement.density.problem.descriptor=<code>#ref</code> 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=''<code>#ref</code>'' has too few branches ({0}), and should probably be replaced with an ''if'' statement #loc
switch.statement.with.too.few.branches.problem.descriptor=<code>#ref</code> 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=<code>#ref</code> is unnecessary as the last statement in a 'void' method #loc
@@ -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<PsiEnumConstant> missingEnumElements = new ArrayList<PsiEnumConstant>(fields.length);
final List<PsiEnumConstant> 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);
@@ -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(); }
@@ -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.<p/>
Variables, method parameters and return values marked as <code>@Nullable</code> or <code>@NotNull</code> are treated as nullable (or not-null, respectively)
and used during the analysis to check nullability contracts, e.g. report possible <code>NullPointerException</code> errors.<p/>
and used during the analysis to check nullability contracts, e.g. report <code>NullPointerException</code> (NPE) errors that might be produced.<p/>
More complex contracts can be defined using <code>@Contract</code> annotation, for example:<p/>
<code>@Contract("_, null -> null")</code> &mdash; method returns null if its second argument is null<br/>