diff --git a/src/com/google/javascript/jscomp/ReferenceCollectingCallback.java b/src/com/google/javascript/jscomp/ReferenceCollectingCallback.java index a970e68ea50..3877d4207f3 100644 --- a/src/com/google/javascript/jscomp/ReferenceCollectingCallback.java +++ b/src/com/google/javascript/jscomp/ReferenceCollectingCallback.java @@ -530,8 +530,8 @@ boolean isAssignedOnceInLifetime() { } /** - * @return The one and only assignment. Returns if there are 0 or 2+ - * assignments. + * @return The one and only assignment. Returns null if the number of assignments is not + * exactly one. */ private Reference getOneAndOnlyAssignment() { Reference assignment = null; @@ -715,9 +715,7 @@ boolean isInitializingDeclaration() { * return the assigned value, otherwise null. */ Node getAssignedValue() { - Node parent = getParent(); - return (parent.isFunction()) - ? parent : NodeUtil.getAssignedValue(nameNode); + return NodeUtil.getRValueOfLValue(nameNode); } BasicBlock getBasicBlock() { @@ -747,6 +745,11 @@ boolean isSimpleAssignmentToName() { && parent.getFirstChild() == nameNode; } + /** + * Returns whether the name node for this reference is an lvalue. + * TODO(tbreisacher): This method disagrees with NodeUtil#isLValue for + * "var x;" and "let x;". Consider updating it to match. + */ boolean isLvalue() { Node parent = getParent(); int parentType = parent.getType(); diff --git a/src/com/google/javascript/jscomp/VariableReferenceCheck.java b/src/com/google/javascript/jscomp/VariableReferenceCheck.java index 1352565939d..3897aa02f95 100644 --- a/src/com/google/javascript/jscomp/VariableReferenceCheck.java +++ b/src/com/google/javascript/jscomp/VariableReferenceCheck.java @@ -276,6 +276,10 @@ private void checkVar(Var v, List references) { && !lhsOfForInLoop) { unusedAssignment = reference; } + if ((reference.getParent().isDec() || reference.getParent().isInc()) + && NodeUtil.isExpressionResultUsed(reference.getNode())) { + isRead = true; + } } else { isRead = true; } diff --git a/test/com/google/javascript/jscomp/VariableReferenceCheckTest.java b/test/com/google/javascript/jscomp/VariableReferenceCheckTest.java index 3b91f39e641..b170c659132 100644 --- a/test/com/google/javascript/jscomp/VariableReferenceCheckTest.java +++ b/test/com/google/javascript/jscomp/VariableReferenceCheckTest.java @@ -204,7 +204,7 @@ public void testUnusedLocalLet() { assertUnusedEs6("function f() { let a; a = 2; }"); } - public void xtestUnusedLocalConst() { + public void testUnusedLocalConst() { enableUnusedLocalAssignmentCheck = true; assertUnusedEs6("function f() { const a = 2; }"); } @@ -224,6 +224,14 @@ public void testUnusedAssignedInInnerFunction() { assertUnused("function f() { var x = 1; function g() { x = 2; } }"); } + public void testIncrementDecrementResultUsed() { + enableUnusedLocalAssignmentCheck = true; + assertNoWarning("function f() { var x = 5; while (x-- > 0) {} }"); + assertNoWarning("function f() { var x = -5; while (x++ < 0) {} }"); + assertNoWarning("function f() { var x = 5; while (--x > 0) {} }"); + assertNoWarning("function f() { var x = -5; while (++x < 0) {} }"); + } + public void testUsedInInnerFunction() { enableUnusedLocalAssignmentCheck = true; assertNoWarning("function f() { var x = 1; function g() { use(x); } }");