Permalink
Browse files

check for variable reuse in nested for loops

  • Loading branch information...
shamer committed Jun 5, 2015
1 parent b98629d commit 7b9c2943a4af93ecb5306a3cff6cb11b711bbe2f
@@ -37,6 +37,7 @@ class Rule(object):
VARIABLE_ARG_MARKER = 'variable_arg_marker'
UNUSED_PRIVATE_MEMBERS = 'unused_private_members'
UNUSED_LOCAL_VARIABLES = 'unused_local_variables'
REUSED_LOOP_VARIABLE = 'reused_loop_variable'
# Rule to raise all known errors.
ALL = 'all'
@@ -49,7 +50,8 @@ class Rule(object):
NO_BRACES_AROUND_INHERIT_DOC,
BRACES_AROUND_TYPE,
OPTIONAL_TYPE_MARKER,
VARIABLE_ARG_MARKER])
VARIABLE_ARG_MARKER,
REUSED_LOOP_VARIABLE])
flags.DEFINE_boolean('strict', False,
View
@@ -139,6 +139,8 @@ def ByName(name):
REMOVE_COMMENT_BEFORE_SUBMIT = 1254
# End of list of ActionScript specific errors.
REUSED_LOOP_VARIABLE = 5000
NEW_ERRORS = frozenset([
# Errors added after 2.0.2:
WRONG_INDENTATION,
@@ -61,6 +61,7 @@
'jsdoc.js',
'limited_doc_checks.js',
'minimal.js',
'nested_loops.js',
'other.js',
'provide_blank.js',
'provide_extra.js',
@@ -80,6 +80,9 @@ def CheckToken(self, token, state):
if error_check.ShouldCheck(Rule.UNUSED_LOCAL_VARIABLES):
self._CheckUnusedLocalVariables(token, state)
if error_check.ShouldCheck(Rule.REUSED_LOOP_VARIABLE):
self._CheckReusedLoopVariable(token, state)
if error_check.ShouldCheck(Rule.UNUSED_PRIVATE_MEMBERS):
# Find all assignments to private members.
if token.type == Type.SIMPLE_LVALUE:
@@ -597,6 +600,60 @@ def _MarkLocalVariableUsed(self, identifier):
del unused_local_variables[identifier]
break
def _CheckReusedLoopVariable(self, token, state):
"""Checks for reused variables in for loops.
Args:
token: The token to check.
state: The state tracker.
"""
def forLoopVarIdentifier(start_token):
""" returns the identifier for the var declaration, None if it is not present. """
var_token = tokenutil.CustomSearch(
start_token,
lambda t: t.IsKeyword('var'),
end_func=lambda t: t.type == Type.SEMICOLON,
distance=None)
if var_token:
ident_token = tokenutil.CustomSearch(
var_token,
lambda t: t.type == Type.SIMPLE_LVALUE,
end_func=lambda t: t.type == Type.SEMICOLON,
distance=None)
if ident_token:
var_ident = ident_token.string
return var_ident
return None
if token.IsKeyword('for'):
var_ident = forLoopVarIdentifier(token)
block_token = tokenutil.CustomSearch(
token,
lambda t: t.type == Type.START_BLOCK,
end_func=lambda t: t.type == Type.END_BLOCK,
distance=None)
block_counter = 1
# check nested for loops for their variable declarations
if block_token:
next_token = block_token.next
while block_counter:
if next_token.IsKeyword('for'):
inner_var_ident = forLoopVarIdentifier(next_token)
if inner_var_ident and inner_var_ident == var_ident:
reused_loop_ident_msg = 'Reused loop variable %s' % (var_ident, )
self._HandleError(
errors.REUSED_LOOP_VARIABLE,
reused_loop_ident_msg,
token, position=Position.AtBeginning())
elif next_token.type == Type.START_BLOCK:
block_counter += 1
elif next_token.type == Type.END_BLOCK:
block_counter -= 1
next_token = next_token.next
def _ReportMissingProvides(self, missing_provides, token, need_blank_line):
"""Reports missing provide statements to the error handler.
@@ -0,0 +1,27 @@
// Reuse of i
for (var i = 0; i < 10; i++) {
for (var i = 3; i < 5; i++) {
}
}
// Reuse of j
for (var j = 10; j < 50; j++) {
for (var q = 0; q < 20; q++) {
for (var j = 7; j < 10; j++) {
}
}
}
// Reuse of r
for (var q = 10; q < 50; q++) {
for (var r = 0; r < 20; r++) {
for (var r = 7; r < 10; r++) {
}
}
}

0 comments on commit 7b9c294

Please sign in to comment.