Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-06-22 16:25:36 +04:00
9 changed files with 139 additions and 75 deletions
+3
View File
@@ -51,6 +51,9 @@
<key>CFBundleHelpBookFolder</key>
<string>@@help_id@@.help</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSArchitecturePriority</key>
<array>
<string>x86_64</string>
@@ -199,11 +199,11 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
final String errorMessage = exception.getMessage();
if(valueLabel.endsWith(errorMessage)) {
descriptorText.append(valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES);
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
}
else {
descriptorText.append(valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
}
}
@@ -212,7 +212,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
descriptorText.append(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES);
}
else {
descriptorText.append(valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
}
}
}
@@ -225,6 +225,42 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
return descriptorText;
}
private static void appendValueTextWithEscapesRendering(SimpleColoredText descriptorText, String valueText, final SimpleTextAttributes attribs) {
final SimpleTextAttributes boldAttribs = attribs.derive(SimpleTextAttributes.STYLE_BOLD, null, null, null);
final StringBuilder buf = new StringBuilder();
boolean slashFound = false;
for (int idx= 0; idx < valueText.length(); idx++) {
final char ch = valueText.charAt(idx);
if (slashFound) {
slashFound = false;
if (ch == '\\' || ch == '\"' || ch == 'b'|| ch == 't'|| ch == 'n'|| ch == 'f'|| ch == 'r' ) {
if (buf.length() > 0) {
descriptorText.append(buf.toString(), attribs);
buf.setLength(0);
}
if (ch != '\\' && ch != '\"') {
descriptorText.append("\\", boldAttribs);
}
descriptorText.append(String.valueOf(ch), boldAttribs);
}
else {
buf.append('\\').append(ch);
}
}
else {
if (ch == '\\') {
slashFound = true;
}
else {
buf.append(ch);
}
}
}
if (buf.length() > 0) {
descriptorText.append(buf.toString(), attribs);
}
}
private static String[] breakString(String source, String substr) {
if (substr != null && substr.length() > 0) {
int index = Math.max(source.indexOf(substr), 0);
@@ -277,7 +277,6 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
final DocumentReference[] refs = new DocumentReference[]{DocumentReferenceManager.getInstance().create(file)};
if (myCurrentMerger.hasChangesOf(refs[0])) return;
System.out.println("adding action for " + file);
myCurrentMerger.addAction(new BasicUndoableAction() {
@Override
public void undo() throws UnexpectedUndoException {
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2012 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.
@@ -72,18 +72,16 @@ public class ManualArrayCopyInspection extends BaseInspection {
this.decrement = decrement;
}
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"manual.array.copy.replace.quickfix");
return InspectionGadgetsBundle.message("manual.array.copy.replace.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement forElement = descriptor.getPsiElement();
final PsiForStatement forStatement =
(PsiForStatement)forElement.getParent();
final PsiForStatement forStatement = (PsiForStatement)forElement.getParent();
final String newExpression = buildSystemArrayCopyText(forStatement);
if (newExpression == null) {
return;
@@ -92,20 +90,15 @@ public class ManualArrayCopyInspection extends BaseInspection {
}
@Nullable
private String buildSystemArrayCopyText(PsiForStatement forStatement)
throws IncorrectOperationException {
private String buildSystemArrayCopyText(PsiForStatement forStatement) throws IncorrectOperationException {
final PsiExpression condition = forStatement.getCondition();
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)ParenthesesUtils.stripParentheses(
condition);
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)ParenthesesUtils.stripParentheses(condition);
if (binaryExpression == null) {
return null;
}
final IElementType tokenType =
binaryExpression.getOperationTokenType();
final IElementType tokenType = binaryExpression.getOperationTokenType();
final PsiExpression limit;
if (decrement ^ JavaTokenType.LT.equals(tokenType) ||
JavaTokenType.LE.equals(tokenType)) {
if (decrement ^ JavaTokenType.LT.equals(tokenType) || JavaTokenType.LE.equals(tokenType)) {
limit = binaryExpression.getROperand();
}
else {
@@ -114,18 +107,15 @@ public class ManualArrayCopyInspection extends BaseInspection {
if (limit == null) {
return null;
}
final PsiStatement initialization =
forStatement.getInitialization();
final PsiStatement initialization = forStatement.getInitialization();
if (initialization == null) {
return null;
}
if (!(initialization instanceof PsiDeclarationStatement)) {
return null;
}
final PsiDeclarationStatement declaration =
(PsiDeclarationStatement)initialization;
final PsiElement[] declaredElements =
declaration.getDeclaredElements();
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization;
final PsiElement[] declaredElements = declaration.getDeclaredElements();
if (declaredElements.length != 1) {
return null;
}
@@ -137,33 +127,28 @@ public class ManualArrayCopyInspection extends BaseInspection {
final String lengthText;
final PsiExpression initializer = variable.getInitializer();
if (decrement) {
lengthText = buildLengthText(initializer, limit, false);
lengthText = buildLengthText(initializer, limit, JavaTokenType.LE.equals(tokenType) || JavaTokenType.GE.equals(tokenType));
}
else {
lengthText = buildLengthText(limit, initializer,
JavaTokenType.LE.equals(tokenType) ||
JavaTokenType.GE.equals(tokenType));
lengthText = buildLengthText(limit, initializer, JavaTokenType.LE.equals(tokenType) || JavaTokenType.GE.equals(tokenType));
}
if (lengthText == null) {
return null;
}
final PsiArrayAccessExpression lhs =
getLhsArrayAccessExpression(forStatement);
final PsiArrayAccessExpression lhs = getLhsArrayAccessExpression(forStatement);
if (lhs == null) {
return null;
}
final PsiExpression lArray = lhs.getArrayExpression();
final String toArrayText = lArray.getText();
final PsiArrayAccessExpression rhs =
getRhsArrayAccessExpression(forStatement);
final PsiArrayAccessExpression rhs = getRhsArrayAccessExpression(forStatement);
if (rhs == null) {
return null;
}
final PsiExpression rArray = rhs.getArrayExpression();
final String fromArrayText = rArray.getText();
final PsiExpression rhsIndexExpression = rhs.getIndexExpression();
final PsiExpression strippedRhsIndexExpression =
ParenthesesUtils.stripParentheses(rhsIndexExpression);
final PsiExpression strippedRhsIndexExpression = ParenthesesUtils.stripParentheses(rhsIndexExpression);
final PsiExpression limitExpression;
if (decrement) {
limitExpression = limit;
@@ -171,19 +156,12 @@ public class ManualArrayCopyInspection extends BaseInspection {
else {
limitExpression = initializer;
}
final String fromOffsetText =
buildOffsetText(strippedRhsIndexExpression, variable,
limitExpression, decrement &&
(JavaTokenType.LT.equals(tokenType) ||
JavaTokenType.GT.equals(tokenType)));
final String fromOffsetText = buildOffsetText(strippedRhsIndexExpression, variable, limitExpression, decrement &&
(JavaTokenType.LT.equals(tokenType) || JavaTokenType.GT.equals(tokenType)));
final PsiExpression lhsIndexExpression = lhs.getIndexExpression();
final PsiExpression strippedLhsIndexExpression =
ParenthesesUtils.stripParentheses(lhsIndexExpression);
final String toOffsetText =
buildOffsetText(strippedLhsIndexExpression, variable,
limitExpression, decrement &&
(JavaTokenType.LT.equals(tokenType) ||
JavaTokenType.GT.equals(tokenType)));
final PsiExpression strippedLhsIndexExpression = ParenthesesUtils.stripParentheses(lhsIndexExpression);
final String toOffsetText = buildOffsetText(strippedLhsIndexExpression, variable,
limitExpression, decrement && (JavaTokenType.LT.equals(tokenType) || JavaTokenType.GT.equals(tokenType)));
@NonNls final StringBuilder buffer = new StringBuilder(60);
buffer.append("System.arraycopy(");
buffer.append(fromArrayText);
@@ -199,6 +177,7 @@ public class ManualArrayCopyInspection extends BaseInspection {
return buffer.toString();
}
@Nullable
private static PsiArrayAccessExpression getLhsArrayAccessExpression(
PsiForStatement forStatement) {
PsiStatement body = forStatement.getBody();
@@ -240,6 +219,7 @@ public class ManualArrayCopyInspection extends BaseInspection {
return (PsiArrayAccessExpression)deparenthesizedExpression;
}
@Nullable
private static PsiArrayAccessExpression getRhsArrayAccessExpression(
PsiForStatement forStatement) {
PsiStatement body = forStatement.getBody();
@@ -297,9 +277,7 @@ public class ManualArrayCopyInspection extends BaseInspection {
@NonNls
@Nullable
private static String buildLengthText(PsiExpression max,
PsiExpression min,
boolean plusOne) {
private static String buildLengthText(PsiExpression max, PsiExpression min, boolean plusOne) {
max = ParenthesesUtils.stripParentheses(max);
if (max == null) {
return null;
@@ -308,10 +286,9 @@ public class ManualArrayCopyInspection extends BaseInspection {
if (min == null) {
return buildExpressionText(max, plusOne, false);
}
final Object constant =
ExpressionUtils.computeConstantExpression(min);
if (constant instanceof Number) {
final Number minNumber = (Number)constant;
final Object minConstant = ExpressionUtils.computeConstantExpression(min);
if (minConstant instanceof Number) {
final Number minNumber = (Number)minConstant;
final int minValue;
if (plusOne) {
minValue = minNumber.intValue() - 1;
@@ -319,14 +296,20 @@ public class ManualArrayCopyInspection extends BaseInspection {
else {
minValue = minNumber.intValue();
}
final String maxText =
buildExpressionText(max, false, false);
if (minValue == 0) {
return buildExpressionText(max, false, false);
}
if (max instanceof PsiLiteralExpression) {
final Object maxConstant = ExpressionUtils.computeConstantExpression(max);
if (maxConstant instanceof Number) {
final Number number = (Number)maxConstant;
return String.valueOf(number.intValue() - minValue);
}
}
final String maxText = buildExpressionText(max, false, false);
if (minValue > 0) {
return maxText + '-' + minValue;
}
else if (minValue == 0) {
return maxText;
}
else {
return maxText + '+' + -minValue;
}
@@ -343,39 +326,31 @@ public class ManualArrayCopyInspection extends BaseInspection {
return maxText + '-' + minText;
}
private static String buildExpressionText(PsiExpression expression,
boolean plusOne,
boolean parenthesize) {
private static String buildExpressionText(PsiExpression expression, boolean plusOne, boolean parenthesize) {
if (!plusOne) {
final int precedence =
ParenthesesUtils.getPrecedence(expression);
final int precedence = ParenthesesUtils.getPrecedence(expression);
if (precedence > ParenthesesUtils.ADDITIVE_PRECEDENCE) {
return '(' + expression.getText() + ')';
}
else {
if (parenthesize && precedence >=
ParenthesesUtils.ADDITIVE_PRECEDENCE) {
if (parenthesize && precedence >= ParenthesesUtils.ADDITIVE_PRECEDENCE) {
return '(' + expression.getText() + ')';
}
return expression.getText();
}
}
if (expression instanceof PsiBinaryExpression) {
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)expression;
final IElementType tokenType =
binaryExpression.getOperationTokenType();
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
final IElementType tokenType = binaryExpression.getOperationTokenType();
if (tokenType == JavaTokenType.MINUS) {
final PsiExpression rhs =
binaryExpression.getROperand();
final PsiExpression rhs = binaryExpression.getROperand();
if (ExpressionUtils.isOne(rhs)) {
return binaryExpression.getLOperand().getText();
}
}
}
else if (expression instanceof PsiLiteralExpression) {
final PsiLiteralExpression literalExpression =
(PsiLiteralExpression)expression;
final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expression;
final Object value = literalExpression.getValue();
if (value instanceof Integer) {
final Integer integer = (Integer)value;
@@ -0,0 +1,7 @@
package com.siyeh.igfixes.performance.replace_with_system_arraycopy;
class Decrement {
void foo(int[] a, int[] b) {
System.arraycopy(a, 0, b, 0, 2);
}
}
@@ -0,0 +1,9 @@
package com.siyeh.igfixes.performance.replace_with_system_arraycopy;
class Decrement {
void foo(int[] a, int[] b) {
<caret>for (int i = 1; i >= 0; i--) {
b[i] = a[i];
}
}
}
@@ -0,0 +1,7 @@
package com.siyeh.igfixes.performance.replace_with_system_arraycopy;
class Simple {
void foo(String[] source, Object[] target) {
System.arraycopy(source, 0, target, 0, 5);
}
}
@@ -0,0 +1,9 @@
package com.siyeh.igfixes.performance.replace_with_system_arraycopy;
class Simple {
void foo(String[] source, Object[] target) {
<caret>for (int k = 0; k < 5; k++) { // can be converted to System.arraycopy()
target[k] = source[k];
}
}
}
@@ -0,0 +1,19 @@
package com.siyeh.ig.fixes.performance;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.IGQuickFixesTestCase;
import com.siyeh.ig.performance.ManualArrayCopyInspection;
public class ManualArrayCopyFixTest extends IGQuickFixesTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.enableInspections(new ManualArrayCopyInspection());
myRelativePath = "performance/replace_with_system_arraycopy";
myDefaultHint = InspectionGadgetsBundle.message("manual.array.copy.replace.quickfix");
}
public void testSimple() { doTest(); }
public void testDecrement() { doTest(); }
}