diff options
author | Nathan Ridge | 2013-07-23 05:28:30 +0000 |
---|---|---|
committer | Sergey Prigogin | 2013-07-25 00:47:38 +0000 |
commit | 156990d03eb770a1bff9b4b5104351276f27cb8b (patch) | |
tree | 29cb6479b392a8cf2a4c67248fc4e2853f7be9a1 | |
parent | e84409b1f0e54e2905cde561e48d9884e29b03c8 (diff) | |
download | org.eclipse.cdt-156990d03eb770a1bff9b4b5104351276f27cb8b.tar.gz org.eclipse.cdt-156990d03eb770a1bff9b4b5104351276f27cb8b.tar.xz org.eclipse.cdt-156990d03eb770a1bff9b4b5104351276f27cb8b.zip |
Bug 352267 - Assignment in condition checker matches the whole
expression
Change-Id: I7aea1c5d404a8d374020e34c997e6e890fcdb3d6
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/14764
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
3 files changed, 76 insertions, 12 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixAssignmentInCondition.java b/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixAssignmentInCondition.java index 422713fc7e5..b7d1f2c2a9a 100644 --- a/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixAssignmentInCondition.java +++ b/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixAssignmentInCondition.java @@ -1,41 +1,70 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Andrew Gvozdev + * Copyright (c) 2009, 2013 Andrew Gvozdev and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Andrew Gvozdev - initial API and implementation + * Andrew Gvozdev - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.codan.internal.checkers.ui.quickfix; import org.eclipse.cdt.codan.internal.checkers.ui.CheckersUiActivator; import org.eclipse.cdt.codan.internal.checkers.ui.Messages; -import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution; +import org.eclipse.cdt.codan.ui.AbstractAstRewriteQuickFix; +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.FindReplaceDocumentAdapter; -import org.eclipse.jface.text.IDocument; /** * quick fix for assignment in condition */ -public class QuickFixAssignmentInCondition extends AbstractCodanCMarkerResolution { +public class QuickFixAssignmentInCondition extends AbstractAstRewriteQuickFix { @Override public String getLabel() { return Messages.QuickFixAssignmentInCondition_Message; } @Override - public void apply(IMarker marker, IDocument document) { - int pos = getOffset(marker, document); + public void modifyAST(IIndex index, IMarker marker) { try { - FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(document); - dad.find(pos, "=", /* forwardSearch *///$NON-NLS-1$ - true, /* caseSensitive */false, - /* wholeWord */false, /* regExSearch */false); - dad.replace("==", /* regExReplace */false); //$NON-NLS-1$ + IASTTranslationUnit ast = getTranslationUnitViaEditor(marker).getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS); + int markerStart = marker.getAttribute(IMarker.CHAR_START, -1); + int markerEnd = marker.getAttribute(IMarker.CHAR_END, -1); + if (markerStart == -1 || markerEnd == -1 || markerStart >= markerEnd) + return; + IASTNodeSelector nodeSelector = ast.getNodeSelector(null); + IASTNode containedNode = nodeSelector.findEnclosingNode(markerStart, markerEnd - markerStart); + if (containedNode instanceof IASTBinaryExpression) { + IASTBinaryExpression expr = (IASTBinaryExpression) containedNode; + IASTNodeLocation[] leftSubexprLocations = expr.getOperand1().getNodeLocations(); + if (leftSubexprLocations.length != 1) // don't handle expressions in macro expansions + return; + IASTNodeLocation leftSubexprLocation = leftSubexprLocations[0]; + int leftSubexprEnd = leftSubexprLocation.getNodeOffset() + leftSubexprLocation.getNodeLength(); + + // Assignment operator will be following the end of the left subexpression. + FindReplaceDocumentAdapter adapter = new FindReplaceDocumentAdapter(getDocument()); + adapter.find(leftSubexprEnd, + "=", ///$NON-NLS-1$ + true, /* forwardSearch */ + false, /* caseSensitive */ + false, /* wholeWord */ + false); /* regExSearch */ + adapter.replace("==", false /* regExReplace */); ///$NON-NLS-1$ + } + } catch (CoreException e) { + CheckersUiActivator.log(e); } catch (BadLocationException e) { CheckersUiActivator.log(e); } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java index 7f700eaea05..560042a5be1 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.codan.core.internal.checkers.StatementHasNoEffectCheckerT import org.eclipse.cdt.codan.core.internal.checkers.SuggestedParenthesisCheckerTest; import org.eclipse.cdt.codan.core.internal.checkers.SuspiciousSemicolonCheckerTest; import org.eclipse.cdt.codan.core.internal.checkers.UnusedSymbolInFileScopeCheckerTest; +import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.AssignmentInConditionQuickFixTest; import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CaseBreakQuickFixTest; import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CatchByReferenceQuickFixTest; import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CreateLocalVariableQuickFixTest; @@ -76,6 +77,7 @@ public class AutomatedIntegrationSuite extends TestSuite { suite.addTestSuite(SuggestedParenthesisQuickFixTest.class); suite.addTestSuite(CatchByReferenceQuickFixTest.class); suite.addTestSuite(CaseBreakQuickFixTest.class); + suite.addTestSuite(AssignmentInConditionQuickFixTest.class); return suite; } } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java new file mode 100644 index 00000000000..3dfb63106ae --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.checkers.ui.quickfix; + +import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution; + +@SuppressWarnings("nls") +public class AssignmentInConditionQuickFixTest extends QuickFixTestCase { + @SuppressWarnings("restriction") + @Override + protected AbstractCodanCMarkerResolution createQuickFix() { + return new QuickFixAssignmentInCondition(); + } + + // void func() { + // int a, b; + // if (a == 1 && b = 2) { + // } + // } + public void testComparisonAndAssignment_bug352267() throws Exception { + loadcode(getAboveComment()); + String result = runQuickFixOneFile(); + assertContainedIn("b == 2", result); + } +} |