Look for empty loop/conditional body with only a single semicolon. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(filename, clean_lines, linenum, error)
| 4000 | |
| 4001 | |
| 4002 | def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
| 4003 | """Look for empty loop/conditional body with only a single semicolon. |
| 4004 | |
| 4005 | Args: |
| 4006 | filename: The name of the current file. |
| 4007 | clean_lines: A CleansedLines instance containing the file. |
| 4008 | linenum: The number of the line to check. |
| 4009 | error: The function to call with any errors found. |
| 4010 | """ |
| 4011 | |
| 4012 | # Search for loop keywords at the beginning of the line. Because only |
| 4013 | # whitespaces are allowed before the keywords, this will also ignore most |
| 4014 | # do-while-loops, since those lines should start with closing brace. |
| 4015 | # |
| 4016 | # We also check "if" blocks here, since an empty conditional block |
| 4017 | # is likely an error. |
| 4018 | line = clean_lines.elided[linenum] |
| 4019 | matched = Match(r'\s*(for|while|if)\s*\(', line) |
| 4020 | if matched: |
| 4021 | # Find the end of the conditional expression. |
| 4022 | (end_line, end_linenum, end_pos) = CloseExpression( |
| 4023 | clean_lines, linenum, line.find('(')) |
| 4024 | |
| 4025 | # Output warning if what follows the condition expression is a semicolon. |
| 4026 | # No warning for all other cases, including whitespace or newline, since we |
| 4027 | # have a separate check for semicolons preceded by whitespace. |
| 4028 | if end_pos >= 0 and Match(r';', end_line[end_pos:]): |
| 4029 | if matched.group(1) == 'if': |
| 4030 | error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, |
| 4031 | 'Empty conditional bodies should use {}') |
| 4032 | else: |
| 4033 | error(filename, end_linenum, 'whitespace/empty_loop_body', 5, |
| 4034 | 'Empty loop bodies should use {} or continue') |
| 4035 | |
| 4036 | # Check for if statements that have completely empty bodies (no comments) |
| 4037 | # and no else clauses. |
| 4038 | if end_pos >= 0 and matched.group(1) == 'if': |
| 4039 | # Find the position of the opening { for the if statement. |
| 4040 | # Return without logging an error if it has no brackets. |
| 4041 | opening_linenum = end_linenum |
| 4042 | opening_line_fragment = end_line[end_pos:] |
| 4043 | # Loop until EOF or find anything that's not whitespace or opening {. |
| 4044 | while not Search(r'^\s*\{', opening_line_fragment): |
| 4045 | if Search(r'^(?!\s*$)', opening_line_fragment): |
| 4046 | # Conditional has no brackets. |
| 4047 | return |
| 4048 | opening_linenum += 1 |
| 4049 | if opening_linenum == len(clean_lines.elided): |
| 4050 | # Couldn't find conditional's opening { or any code before EOF. |
| 4051 | return |
| 4052 | opening_line_fragment = clean_lines.elided[opening_linenum] |
| 4053 | # Set opening_line (opening_line_fragment may not be entire opening line). |
| 4054 | opening_line = clean_lines.elided[opening_linenum] |
| 4055 | |
| 4056 | # Find the position of the closing }. |
| 4057 | opening_pos = opening_line_fragment.find('{') |
| 4058 | if opening_linenum == end_linenum: |
| 4059 | # We need to make opening_pos relative to the start of the entire line. |
no test coverage detected
searching dependent graphs…