From b5108ffcd7ae36f6e55e8a2b33328ce6ebabb7e1 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Wed, 11 May 2011 11:09:04 +0400 Subject: [PATCH] IDEA-68757 Wrong warning on assignment to variable in for expression --- ...tOfIncrementOrDecrementUsedInspection.java | 32 ++++++++++++++++--- .../groovy/lang/GroovyHighlightingTest.java | 5 +++ .../highlighting/ResultOfIncUsed.groovy | 12 +++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 plugins/groovy/testdata/highlighting/ResultOfIncUsed.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyResultOfIncrementOrDecrementUsedInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyResultOfIncrementOrDecrementUsedInspection.java index bbd586181020..713ad4a106af 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyResultOfIncrementOrDecrementUsedInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyResultOfIncrementOrDecrementUsedInspection.java @@ -17,14 +17,21 @@ package org.jetbrains.plugins.groovy.codeInspection.confusing; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; +import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyResultOfIncrementOrDecrementUsedInspection extends BaseInspection { @@ -54,14 +61,29 @@ public class GroovyResultOfIncrementOrDecrementUsedInspection extends BaseInspec public void visitUnaryExpression(GrUnaryExpression grUnaryExpression) { super.visitUnaryExpression(grUnaryExpression); - final PsiElement parent = grUnaryExpression.getParent(); - if (parent instanceof GrCodeBlock) { - return; - } + final IElementType tokenType = grUnaryExpression.getOperationTokenType(); if (!GroovyTokenTypes.mINC.equals(tokenType) && !GroovyTokenTypes.mDEC.equals(tokenType)) { return; } + + final PsiElement parent = PsiTreeUtil.skipParentsOfType(grUnaryExpression, GrParenthesizedExpression.class); + PsiElement skipped = PsiUtil.skipParentheses(grUnaryExpression, true); + assert skipped != null; + + if (ControlFlowUtils.collectReturns(ControlFlowUtils.findControlFlowOwner(parent)).contains(skipped)) { + registerError(grUnaryExpression); + return; + } + + if (parent instanceof GrStatementOwner || parent instanceof GrControlStatement) { + return; + } + + if (parent instanceof GrTraditionalForClause) { + if (PsiTreeUtil.isAncestor(((GrTraditionalForClause)parent).getUpdate(), skipped, false)) return; + } + registerError(grUnaryExpression); } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index 277dc14a0570..6e01beb56b3a 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -24,6 +24,7 @@ import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyAccessibilityInspe import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyLabeledStatementInspection; import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyRangeTypeCheckInspection; import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyResultOfObjectAllocationIgnoredInspection; +import org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyResultOfIncrementOrDecrementUsedInspection; import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection; import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection; import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection; @@ -410,4 +411,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testAnotherCurrying(){ doTest(new GroovyAssignabilityCheckInspection()); } + + public void testResultOfIncUsed() { + doTest(new GroovyResultOfIncrementOrDecrementUsedInspection()); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ResultOfIncUsed.groovy b/plugins/groovy/testdata/highlighting/ResultOfIncUsed.groovy new file mode 100644 index 000000000000..9f4a783c528a --- /dev/null +++ b/plugins/groovy/testdata/highlighting/ResultOfIncUsed.groovy @@ -0,0 +1,12 @@ +for (int i=0;i<10; i++) { + def x = i++ +} + +def x= 0 + +if (true) x++ +print x + +def foo(d) { + d++ //used in return +} \ No newline at end of file