@@ 3312-3437 (lines=126) @@ | ||
3309 | pass |
|
3310 | ||
3311 | ||
3312 | def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): |
|
3313 | """Checks for the correctness of various spacing issues in the code. |
|
3314 | ||
3315 | Things we check for: spaces around operators, spaces after |
|
3316 | if/for/while/switch, no spaces around parens in function calls, two |
|
3317 | spaces between code and comment, don't start a block with a blank |
|
3318 | line, don't end a function with a blank line, don't add a blank line |
|
3319 | after public/protected/private, don't have too many blank lines in a row. |
|
3320 | ||
3321 | Args: |
|
3322 | filename: The name of the current file. |
|
3323 | clean_lines: A CleansedLines instance containing the file. |
|
3324 | linenum: The number of the line to check. |
|
3325 | nesting_state: A NestingState instance which maintains information about |
|
3326 | the current stack of nested blocks being parsed. |
|
3327 | error: The function to call with any errors found. |
|
3328 | """ |
|
3329 | ||
3330 | # Don't use "elided" lines here, otherwise we can't check commented lines. |
|
3331 | # Don't want to use "raw" either, because we don't want to check inside C++11 |
|
3332 | # raw strings, |
|
3333 | raw = clean_lines.lines_without_raw_strings |
|
3334 | line = raw[linenum] |
|
3335 | ||
3336 | # Before nixing comments, check if the line is blank for no good |
|
3337 | # reason. This includes the first line after a block is opened, and |
|
3338 | # blank lines at the end of a function (ie, right before a line like '}' |
|
3339 | # |
|
3340 | # Skip all the blank line checks if we are immediately inside a |
|
3341 | # namespace body. In other words, don't issue blank line warnings |
|
3342 | # for this block: |
|
3343 | # namespace { |
|
3344 | # |
|
3345 | # } |
|
3346 | # |
|
3347 | # A warning about missing end of namespace comments will be issued instead. |
|
3348 | # |
|
3349 | # Also skip blank line checks for 'extern "C"' blocks, which are formatted |
|
3350 | # like namespaces. |
|
3351 | if (IsBlankLine(line) and |
|
3352 | not nesting_state.InNamespaceBody() and |
|
3353 | not nesting_state.InExternC()): |
|
3354 | elided = clean_lines.elided |
|
3355 | prev_line = elided[linenum - 1] |
|
3356 | prevbrace = prev_line.rfind('{') |
|
3357 | # TODO(unknown): Don't complain if line before blank line, and line after, |
|
3358 | # both start with alnums and are indented the same amount. |
|
3359 | # This ignores whitespace at the start of a namespace block |
|
3360 | # because those are not usually indented. |
|
3361 | if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: |
|
3362 | # OK, we have a blank line at the start of a code block. Before we |
|
3363 | # complain, we check if it is an exception to the rule: The previous |
|
3364 | # non-empty line has the parameters of a function header that are indented |
|
3365 | # 4 spaces (because they did not fit in a 80 column line when placed on |
|
3366 | # the same line as the function name). We also check for the case where |
|
3367 | # the previous line is indented 6 spaces, which may happen when the |
|
3368 | # initializers of a constructor do not fit into a 80 column line. |
|
3369 | exception = False |
|
3370 | if Match(r' {6}\w', prev_line): # Initializer list? |
|
3371 | # We are looking for the opening column of initializer list, which |
|
3372 | # should be indented 4 spaces to cause 6 space indentation afterwards. |
|
3373 | search_position = linenum-2 |
|
3374 | while (search_position >= 0 |
|
3375 | and Match(r' {6}\w', elided[search_position])): |
|
3376 | search_position -= 1 |
|
3377 | exception = (search_position >= 0 |
|
3378 | and elided[search_position][:5] == ' :') |
|
3379 | else: |
|
3380 | # Search for the function arguments or an initializer list. We use a |
|
3381 | # simple heuristic here: If the line is indented 4 spaces; and we have a |
|
3382 | # closing paren, without the opening paren, followed by an opening brace |
|
3383 | # or colon (for initializer lists) we assume that it is the last line of |
|
3384 | # a function header. If we have a colon indented 4 spaces, it is an |
|
3385 | # initializer list. |
|
3386 | exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', |
|
3387 | prev_line) |
|
3388 | or Match(r' {4}:', prev_line)) |
|
3389 | ||
3390 | if not exception: |
|
3391 | error(filename, linenum, 'whitespace/blank_line', 2, |
|
3392 | 'Redundant blank line at the start of a code block ' |
|
3393 | 'should be deleted.') |
|
3394 | # Ignore blank lines at the end of a block in a long if-else |
|
3395 | # chain, like this: |
|
3396 | # if (condition1) { |
|
3397 | # // Something followed by a blank line |
|
3398 | # |
|
3399 | # } else if (condition2) { |
|
3400 | # // Something else |
|
3401 | # } |
|
3402 | if linenum + 1 < clean_lines.NumLines(): |
|
3403 | next_line = raw[linenum + 1] |
|
3404 | if (next_line |
|
3405 | and Match(r'\s*}', next_line) |
|
3406 | and next_line.find('} else ') == -1): |
|
3407 | error(filename, linenum, 'whitespace/blank_line', 3, |
|
3408 | 'Redundant blank line at the end of a code block ' |
|
3409 | 'should be deleted.') |
|
3410 | ||
3411 | matched = Match(r'\s*(public|protected|private):', prev_line) |
|
3412 | if matched: |
|
3413 | error(filename, linenum, 'whitespace/blank_line', 3, |
|
3414 | 'Do not leave a blank line after "%s:"' % matched.group(1)) |
|
3415 | ||
3416 | # Next, check comments |
|
3417 | next_line_start = 0 |
|
3418 | if linenum + 1 < clean_lines.NumLines(): |
|
3419 | next_line = raw[linenum + 1] |
|
3420 | next_line_start = len(next_line) - len(next_line.lstrip()) |
|
3421 | CheckComment(line, filename, linenum, next_line_start, error) |
|
3422 | ||
3423 | # get rid of comments and strings |
|
3424 | line = clean_lines.elided[linenum] |
|
3425 | ||
3426 | # You shouldn't have spaces before your brackets, except maybe after |
|
3427 | # 'delete []' or 'return []() {};' |
|
3428 | if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line): |
|
3429 | error(filename, linenum, 'whitespace/braces', 5, |
|
3430 | 'Extra space before [') |
|
3431 | ||
3432 | # In range-based for, we wanted spaces before and after the colon, but |
|
3433 | # not around "::" tokens that might appear. |
|
3434 | if (Search(r'for *\(.*[^:]:[^: ]', line) or |
|
3435 | Search(r'for *\(.*[^: ]:[^:]', line)): |
|
3436 | error(filename, linenum, 'whitespace/forcolon', 2, |
|
3437 | 'Missing space around colon in range-based for loop') |
|
3438 | ||
3439 | ||
3440 | def CheckOperatorSpacing(filename, clean_lines, linenum, error): |
@@ 3312-3437 (lines=126) @@ | ||
3309 | pass |
|
3310 | ||
3311 | ||
3312 | def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): |
|
3313 | """Checks for the correctness of various spacing issues in the code. |
|
3314 | ||
3315 | Things we check for: spaces around operators, spaces after |
|
3316 | if/for/while/switch, no spaces around parens in function calls, two |
|
3317 | spaces between code and comment, don't start a block with a blank |
|
3318 | line, don't end a function with a blank line, don't add a blank line |
|
3319 | after public/protected/private, don't have too many blank lines in a row. |
|
3320 | ||
3321 | Args: |
|
3322 | filename: The name of the current file. |
|
3323 | clean_lines: A CleansedLines instance containing the file. |
|
3324 | linenum: The number of the line to check. |
|
3325 | nesting_state: A NestingState instance which maintains information about |
|
3326 | the current stack of nested blocks being parsed. |
|
3327 | error: The function to call with any errors found. |
|
3328 | """ |
|
3329 | ||
3330 | # Don't use "elided" lines here, otherwise we can't check commented lines. |
|
3331 | # Don't want to use "raw" either, because we don't want to check inside C++11 |
|
3332 | # raw strings, |
|
3333 | raw = clean_lines.lines_without_raw_strings |
|
3334 | line = raw[linenum] |
|
3335 | ||
3336 | # Before nixing comments, check if the line is blank for no good |
|
3337 | # reason. This includes the first line after a block is opened, and |
|
3338 | # blank lines at the end of a function (ie, right before a line like '}' |
|
3339 | # |
|
3340 | # Skip all the blank line checks if we are immediately inside a |
|
3341 | # namespace body. In other words, don't issue blank line warnings |
|
3342 | # for this block: |
|
3343 | # namespace { |
|
3344 | # |
|
3345 | # } |
|
3346 | # |
|
3347 | # A warning about missing end of namespace comments will be issued instead. |
|
3348 | # |
|
3349 | # Also skip blank line checks for 'extern "C"' blocks, which are formatted |
|
3350 | # like namespaces. |
|
3351 | if (IsBlankLine(line) and |
|
3352 | not nesting_state.InNamespaceBody() and |
|
3353 | not nesting_state.InExternC()): |
|
3354 | elided = clean_lines.elided |
|
3355 | prev_line = elided[linenum - 1] |
|
3356 | prevbrace = prev_line.rfind('{') |
|
3357 | # TODO(unknown): Don't complain if line before blank line, and line after, |
|
3358 | # both start with alnums and are indented the same amount. |
|
3359 | # This ignores whitespace at the start of a namespace block |
|
3360 | # because those are not usually indented. |
|
3361 | if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: |
|
3362 | # OK, we have a blank line at the start of a code block. Before we |
|
3363 | # complain, we check if it is an exception to the rule: The previous |
|
3364 | # non-empty line has the parameters of a function header that are indented |
|
3365 | # 4 spaces (because they did not fit in a 80 column line when placed on |
|
3366 | # the same line as the function name). We also check for the case where |
|
3367 | # the previous line is indented 6 spaces, which may happen when the |
|
3368 | # initializers of a constructor do not fit into a 80 column line. |
|
3369 | exception = False |
|
3370 | if Match(r' {6}\w', prev_line): # Initializer list? |
|
3371 | # We are looking for the opening column of initializer list, which |
|
3372 | # should be indented 4 spaces to cause 6 space indentation afterwards. |
|
3373 | search_position = linenum-2 |
|
3374 | while (search_position >= 0 |
|
3375 | and Match(r' {6}\w', elided[search_position])): |
|
3376 | search_position -= 1 |
|
3377 | exception = (search_position >= 0 |
|
3378 | and elided[search_position][:5] == ' :') |
|
3379 | else: |
|
3380 | # Search for the function arguments or an initializer list. We use a |
|
3381 | # simple heuristic here: If the line is indented 4 spaces; and we have a |
|
3382 | # closing paren, without the opening paren, followed by an opening brace |
|
3383 | # or colon (for initializer lists) we assume that it is the last line of |
|
3384 | # a function header. If we have a colon indented 4 spaces, it is an |
|
3385 | # initializer list. |
|
3386 | exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', |
|
3387 | prev_line) |
|
3388 | or Match(r' {4}:', prev_line)) |
|
3389 | ||
3390 | if not exception: |
|
3391 | error(filename, linenum, 'whitespace/blank_line', 2, |
|
3392 | 'Redundant blank line at the start of a code block ' |
|
3393 | 'should be deleted.') |
|
3394 | # Ignore blank lines at the end of a block in a long if-else |
|
3395 | # chain, like this: |
|
3396 | # if (condition1) { |
|
3397 | # // Something followed by a blank line |
|
3398 | # |
|
3399 | # } else if (condition2) { |
|
3400 | # // Something else |
|
3401 | # } |
|
3402 | if linenum + 1 < clean_lines.NumLines(): |
|
3403 | next_line = raw[linenum + 1] |
|
3404 | if (next_line |
|
3405 | and Match(r'\s*}', next_line) |
|
3406 | and next_line.find('} else ') == -1): |
|
3407 | error(filename, linenum, 'whitespace/blank_line', 3, |
|
3408 | 'Redundant blank line at the end of a code block ' |
|
3409 | 'should be deleted.') |
|
3410 | ||
3411 | matched = Match(r'\s*(public|protected|private):', prev_line) |
|
3412 | if matched: |
|
3413 | error(filename, linenum, 'whitespace/blank_line', 3, |
|
3414 | 'Do not leave a blank line after "%s:"' % matched.group(1)) |
|
3415 | ||
3416 | # Next, check comments |
|
3417 | next_line_start = 0 |
|
3418 | if linenum + 1 < clean_lines.NumLines(): |
|
3419 | next_line = raw[linenum + 1] |
|
3420 | next_line_start = len(next_line) - len(next_line.lstrip()) |
|
3421 | CheckComment(line, filename, linenum, next_line_start, error) |
|
3422 | ||
3423 | # get rid of comments and strings |
|
3424 | line = clean_lines.elided[linenum] |
|
3425 | ||
3426 | # You shouldn't have spaces before your brackets, except maybe after |
|
3427 | # 'delete []' or 'return []() {};' |
|
3428 | if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line): |
|
3429 | error(filename, linenum, 'whitespace/braces', 5, |
|
3430 | 'Extra space before [') |
|
3431 | ||
3432 | # In range-based for, we wanted spaces before and after the colon, but |
|
3433 | # not around "::" tokens that might appear. |
|
3434 | if (Search(r'for *\(.*[^:]:[^: ]', line) or |
|
3435 | Search(r'for *\(.*[^: ]:[^:]', line)): |
|
3436 | error(filename, linenum, 'whitespace/forcolon', 2, |
|
3437 | 'Missing space around colon in range-based for loop') |
|
3438 | ||
3439 | ||
3440 | def CheckOperatorSpacing(filename, clean_lines, linenum, error): |