@@ 4142-4243 (lines=102) @@ | ||
4139 | "You don't need a ; after a }") |
|
4140 | ||
4141 | ||
4142 | def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
|
4143 | """Look for empty loop/conditional body with only a single semicolon. |
|
4144 | ||
4145 | Args: |
|
4146 | filename: The name of the current file. |
|
4147 | clean_lines: A CleansedLines instance containing the file. |
|
4148 | linenum: The number of the line to check. |
|
4149 | error: The function to call with any errors found. |
|
4150 | """ |
|
4151 | ||
4152 | # Search for loop keywords at the beginning of the line. Because only |
|
4153 | # whitespaces are allowed before the keywords, this will also ignore most |
|
4154 | # do-while-loops, since those lines should start with closing brace. |
|
4155 | # |
|
4156 | # We also check "if" blocks here, since an empty conditional block |
|
4157 | # is likely an error. |
|
4158 | line = clean_lines.elided[linenum] |
|
4159 | matched = Match(r'\s*(for|while|if)\s*\(', line) |
|
4160 | if matched: |
|
4161 | # Find the end of the conditional expression. |
|
4162 | (end_line, end_linenum, end_pos) = CloseExpression( |
|
4163 | clean_lines, linenum, line.find('(')) |
|
4164 | ||
4165 | # Output warning if what follows the condition expression is a semicolon. |
|
4166 | # No warning for all other cases, including whitespace or newline, since we |
|
4167 | # have a separate check for semicolons preceded by whitespace. |
|
4168 | if end_pos >= 0 and Match(r';', end_line[end_pos:]): |
|
4169 | if matched.group(1) == 'if': |
|
4170 | error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, |
|
4171 | 'Empty conditional bodies should use {}') |
|
4172 | else: |
|
4173 | error(filename, end_linenum, 'whitespace/empty_loop_body', 5, |
|
4174 | 'Empty loop bodies should use {} or continue') |
|
4175 | ||
4176 | # Check for if statements that have completely empty bodies (no comments) |
|
4177 | # and no else clauses. |
|
4178 | if end_pos >= 0 and matched.group(1) == 'if': |
|
4179 | # Find the position of the opening { for the if statement. |
|
4180 | # Return without logging an error if it has no brackets. |
|
4181 | opening_linenum = end_linenum |
|
4182 | opening_line_fragment = end_line[end_pos:] |
|
4183 | # Loop until EOF or find anything that's not whitespace or opening {. |
|
4184 | while not Search(r'^\s*\{', opening_line_fragment): |
|
4185 | if Search(r'^(?!\s*$)', opening_line_fragment): |
|
4186 | # Conditional has no brackets. |
|
4187 | return |
|
4188 | opening_linenum += 1 |
|
4189 | if opening_linenum == len(clean_lines.elided): |
|
4190 | # Couldn't find conditional's opening { or any code before EOF. |
|
4191 | return |
|
4192 | opening_line_fragment = clean_lines.elided[opening_linenum] |
|
4193 | # Set opening_line (opening_line_fragment may not be entire opening line). |
|
4194 | opening_line = clean_lines.elided[opening_linenum] |
|
4195 | ||
4196 | # Find the position of the closing }. |
|
4197 | opening_pos = opening_line_fragment.find('{') |
|
4198 | if opening_linenum == end_linenum: |
|
4199 | # We need to make opening_pos relative to the start of the entire line. |
|
4200 | opening_pos += end_pos |
|
4201 | (closing_line, closing_linenum, closing_pos) = CloseExpression( |
|
4202 | clean_lines, opening_linenum, opening_pos) |
|
4203 | if closing_pos < 0: |
|
4204 | return |
|
4205 | ||
4206 | # Now construct the body of the conditional. This consists of the portion |
|
4207 | # of the opening line after the {, all lines until the closing line, |
|
4208 | # and the portion of the closing line before the }. |
|
4209 | if (clean_lines.raw_lines[opening_linenum] != |
|
4210 | CleanseComments(clean_lines.raw_lines[opening_linenum])): |
|
4211 | # Opening line ends with a comment, so conditional isn't empty. |
|
4212 | return |
|
4213 | if closing_linenum > opening_linenum: |
|
4214 | # Opening line after the {. Ignore comments here since we checked above. |
|
4215 | bodylist = list(opening_line[opening_pos+1:]) |
|
4216 | # All lines until closing line, excluding closing line, with comments. |
|
4217 | bodylist.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum]) |
|
4218 | # Closing line before the }. Won't (and can't) have comments. |
|
4219 | bodylist.append(clean_lines.elided[closing_linenum][:closing_pos-1]) |
|
4220 | body = '\n'.join(bodylist) |
|
4221 | else: |
|
4222 | # If statement has brackets and fits on a single line. |
|
4223 | body = opening_line[opening_pos+1:closing_pos-1] |
|
4224 | ||
4225 | # Check if the body is empty |
|
4226 | if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body): |
|
4227 | return |
|
4228 | # The body is empty. Now make sure there's not an else clause. |
|
4229 | current_linenum = closing_linenum |
|
4230 | current_line_fragment = closing_line[closing_pos:] |
|
4231 | # Loop until EOF or find anything that's not whitespace or else clause. |
|
4232 | while Search(r'^\s*$|^(?=\s*else)', current_line_fragment): |
|
4233 | if Search(r'^(?=\s*else)', current_line_fragment): |
|
4234 | # Found an else clause, so don't log an error. |
|
4235 | return |
|
4236 | current_linenum += 1 |
|
4237 | if current_linenum == len(clean_lines.elided): |
|
4238 | break |
|
4239 | current_line_fragment = clean_lines.elided[current_linenum] |
|
4240 | ||
4241 | # The body is empty and there's no else clause until EOF or other code. |
|
4242 | error(filename, end_linenum, 'whitespace/empty_if_body', 4, |
|
4243 | ('If statement had no body and no else clause')) |
|
4244 | ||
4245 | ||
4246 | def FindCheckMacro(line): |
@@ 4142-4243 (lines=102) @@ | ||
4139 | "You don't need a ; after a }") |
|
4140 | ||
4141 | ||
4142 | def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
|
4143 | """Look for empty loop/conditional body with only a single semicolon. |
|
4144 | ||
4145 | Args: |
|
4146 | filename: The name of the current file. |
|
4147 | clean_lines: A CleansedLines instance containing the file. |
|
4148 | linenum: The number of the line to check. |
|
4149 | error: The function to call with any errors found. |
|
4150 | """ |
|
4151 | ||
4152 | # Search for loop keywords at the beginning of the line. Because only |
|
4153 | # whitespaces are allowed before the keywords, this will also ignore most |
|
4154 | # do-while-loops, since those lines should start with closing brace. |
|
4155 | # |
|
4156 | # We also check "if" blocks here, since an empty conditional block |
|
4157 | # is likely an error. |
|
4158 | line = clean_lines.elided[linenum] |
|
4159 | matched = Match(r'\s*(for|while|if)\s*\(', line) |
|
4160 | if matched: |
|
4161 | # Find the end of the conditional expression. |
|
4162 | (end_line, end_linenum, end_pos) = CloseExpression( |
|
4163 | clean_lines, linenum, line.find('(')) |
|
4164 | ||
4165 | # Output warning if what follows the condition expression is a semicolon. |
|
4166 | # No warning for all other cases, including whitespace or newline, since we |
|
4167 | # have a separate check for semicolons preceded by whitespace. |
|
4168 | if end_pos >= 0 and Match(r';', end_line[end_pos:]): |
|
4169 | if matched.group(1) == 'if': |
|
4170 | error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, |
|
4171 | 'Empty conditional bodies should use {}') |
|
4172 | else: |
|
4173 | error(filename, end_linenum, 'whitespace/empty_loop_body', 5, |
|
4174 | 'Empty loop bodies should use {} or continue') |
|
4175 | ||
4176 | # Check for if statements that have completely empty bodies (no comments) |
|
4177 | # and no else clauses. |
|
4178 | if end_pos >= 0 and matched.group(1) == 'if': |
|
4179 | # Find the position of the opening { for the if statement. |
|
4180 | # Return without logging an error if it has no brackets. |
|
4181 | opening_linenum = end_linenum |
|
4182 | opening_line_fragment = end_line[end_pos:] |
|
4183 | # Loop until EOF or find anything that's not whitespace or opening {. |
|
4184 | while not Search(r'^\s*\{', opening_line_fragment): |
|
4185 | if Search(r'^(?!\s*$)', opening_line_fragment): |
|
4186 | # Conditional has no brackets. |
|
4187 | return |
|
4188 | opening_linenum += 1 |
|
4189 | if opening_linenum == len(clean_lines.elided): |
|
4190 | # Couldn't find conditional's opening { or any code before EOF. |
|
4191 | return |
|
4192 | opening_line_fragment = clean_lines.elided[opening_linenum] |
|
4193 | # Set opening_line (opening_line_fragment may not be entire opening line). |
|
4194 | opening_line = clean_lines.elided[opening_linenum] |
|
4195 | ||
4196 | # Find the position of the closing }. |
|
4197 | opening_pos = opening_line_fragment.find('{') |
|
4198 | if opening_linenum == end_linenum: |
|
4199 | # We need to make opening_pos relative to the start of the entire line. |
|
4200 | opening_pos += end_pos |
|
4201 | (closing_line, closing_linenum, closing_pos) = CloseExpression( |
|
4202 | clean_lines, opening_linenum, opening_pos) |
|
4203 | if closing_pos < 0: |
|
4204 | return |
|
4205 | ||
4206 | # Now construct the body of the conditional. This consists of the portion |
|
4207 | # of the opening line after the {, all lines until the closing line, |
|
4208 | # and the portion of the closing line before the }. |
|
4209 | if (clean_lines.raw_lines[opening_linenum] != |
|
4210 | CleanseComments(clean_lines.raw_lines[opening_linenum])): |
|
4211 | # Opening line ends with a comment, so conditional isn't empty. |
|
4212 | return |
|
4213 | if closing_linenum > opening_linenum: |
|
4214 | # Opening line after the {. Ignore comments here since we checked above. |
|
4215 | bodylist = list(opening_line[opening_pos+1:]) |
|
4216 | # All lines until closing line, excluding closing line, with comments. |
|
4217 | bodylist.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum]) |
|
4218 | # Closing line before the }. Won't (and can't) have comments. |
|
4219 | bodylist.append(clean_lines.elided[closing_linenum][:closing_pos-1]) |
|
4220 | body = '\n'.join(bodylist) |
|
4221 | else: |
|
4222 | # If statement has brackets and fits on a single line. |
|
4223 | body = opening_line[opening_pos+1:closing_pos-1] |
|
4224 | ||
4225 | # Check if the body is empty |
|
4226 | if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body): |
|
4227 | return |
|
4228 | # The body is empty. Now make sure there's not an else clause. |
|
4229 | current_linenum = closing_linenum |
|
4230 | current_line_fragment = closing_line[closing_pos:] |
|
4231 | # Loop until EOF or find anything that's not whitespace or else clause. |
|
4232 | while Search(r'^\s*$|^(?=\s*else)', current_line_fragment): |
|
4233 | if Search(r'^(?=\s*else)', current_line_fragment): |
|
4234 | # Found an else clause, so don't log an error. |
|
4235 | return |
|
4236 | current_linenum += 1 |
|
4237 | if current_linenum == len(clean_lines.elided): |
|
4238 | break |
|
4239 | current_line_fragment = clean_lines.elided[current_linenum] |
|
4240 | ||
4241 | # The body is empty and there's no else clause until EOF or other code. |
|
4242 | error(filename, end_linenum, 'whitespace/empty_if_body', 4, |
|
4243 | ('If statement had no body and no else clause')) |
|
4244 | ||
4245 | ||
4246 | def FindCheckMacro(line): |