| @@ 2370-2436 (lines=67) @@ | ||
| 2367 | _BlockInfo.__init__(self, linenum, True) |
|
| 2368 | ||
| 2369 | ||
| 2370 | class _ClassInfo(_BlockInfo): |
|
| 2371 | """Stores information about a class.""" |
|
| 2372 | ||
| 2373 | def __init__(self, name, class_or_struct, clean_lines, linenum): |
|
| 2374 | _BlockInfo.__init__(self, linenum, False) |
|
| 2375 | self.name = name |
|
| 2376 | self.is_derived = False |
|
| 2377 | self.check_namespace_indentation = True |
|
| 2378 | if class_or_struct == 'struct': |
|
| 2379 | self.access = 'public' |
|
| 2380 | self.is_struct = True |
|
| 2381 | else: |
|
| 2382 | self.access = 'private' |
|
| 2383 | self.is_struct = False |
|
| 2384 | ||
| 2385 | # Remember initial indentation level for this class. Using raw_lines here |
|
| 2386 | # instead of elided to account for leading comments. |
|
| 2387 | self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) |
|
| 2388 | ||
| 2389 | # Try to find the end of the class. This will be confused by things like: |
|
| 2390 | # class A { |
|
| 2391 | # } *x = { ... |
|
| 2392 | # |
|
| 2393 | # But it's still good enough for CheckSectionSpacing. |
|
| 2394 | self.last_line = 0 |
|
| 2395 | depth = 0 |
|
| 2396 | for i in range(linenum, clean_lines.NumLines()): |
|
| 2397 | line = clean_lines.elided[i] |
|
| 2398 | depth += line.count('{') - line.count('}') |
|
| 2399 | if not depth: |
|
| 2400 | self.last_line = i |
|
| 2401 | break |
|
| 2402 | ||
| 2403 | def CheckBegin(self, filename, clean_lines, linenum, error): |
|
| 2404 | # Look for a bare ':' |
|
| 2405 | if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): |
|
| 2406 | self.is_derived = True |
|
| 2407 | ||
| 2408 | def CheckEnd(self, filename, clean_lines, linenum, error): |
|
| 2409 | # If there is a DISALLOW macro, it should appear near the end of |
|
| 2410 | # the class. |
|
| 2411 | seen_last_thing_in_class = False |
|
| 2412 | for i in xrange(linenum - 1, self.starting_linenum, -1): |
|
| 2413 | match = Search( |
|
| 2414 | r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + |
|
| 2415 | self.name + r'\)', |
|
| 2416 | clean_lines.elided[i]) |
|
| 2417 | if match: |
|
| 2418 | if seen_last_thing_in_class: |
|
| 2419 | error(filename, i, 'readability/constructors', 3, |
|
| 2420 | match.group(1) + ' should be the last thing in the class') |
|
| 2421 | break |
|
| 2422 | ||
| 2423 | if not Match(r'^\s*$', clean_lines.elided[i]): |
|
| 2424 | seen_last_thing_in_class = True |
|
| 2425 | ||
| 2426 | # Check that closing brace is aligned with beginning of the class. |
|
| 2427 | # Only do this if the closing brace is indented by only whitespaces. |
|
| 2428 | # This means we will not check single-line class definitions. |
|
| 2429 | indent = Match(r'^( *)\}', clean_lines.elided[linenum]) |
|
| 2430 | if indent and len(indent.group(1)) != self.class_indent: |
|
| 2431 | if self.is_struct: |
|
| 2432 | parent = 'struct ' + self.name |
|
| 2433 | else: |
|
| 2434 | parent = 'class ' + self.name |
|
| 2435 | error(filename, linenum, 'whitespace/indent', 3, |
|
| 2436 | 'Closing brace should be aligned with beginning of %s' % parent) |
|
| 2437 | ||
| 2438 | ||
| 2439 | class _NamespaceInfo(_BlockInfo): |
|
| @@ 2370-2436 (lines=67) @@ | ||
| 2367 | _BlockInfo.__init__(self, linenum, True) |
|
| 2368 | ||
| 2369 | ||
| 2370 | class _ClassInfo(_BlockInfo): |
|
| 2371 | """Stores information about a class.""" |
|
| 2372 | ||
| 2373 | def __init__(self, name, class_or_struct, clean_lines, linenum): |
|
| 2374 | _BlockInfo.__init__(self, linenum, False) |
|
| 2375 | self.name = name |
|
| 2376 | self.is_derived = False |
|
| 2377 | self.check_namespace_indentation = True |
|
| 2378 | if class_or_struct == 'struct': |
|
| 2379 | self.access = 'public' |
|
| 2380 | self.is_struct = True |
|
| 2381 | else: |
|
| 2382 | self.access = 'private' |
|
| 2383 | self.is_struct = False |
|
| 2384 | ||
| 2385 | # Remember initial indentation level for this class. Using raw_lines here |
|
| 2386 | # instead of elided to account for leading comments. |
|
| 2387 | self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) |
|
| 2388 | ||
| 2389 | # Try to find the end of the class. This will be confused by things like: |
|
| 2390 | # class A { |
|
| 2391 | # } *x = { ... |
|
| 2392 | # |
|
| 2393 | # But it's still good enough for CheckSectionSpacing. |
|
| 2394 | self.last_line = 0 |
|
| 2395 | depth = 0 |
|
| 2396 | for i in range(linenum, clean_lines.NumLines()): |
|
| 2397 | line = clean_lines.elided[i] |
|
| 2398 | depth += line.count('{') - line.count('}') |
|
| 2399 | if not depth: |
|
| 2400 | self.last_line = i |
|
| 2401 | break |
|
| 2402 | ||
| 2403 | def CheckBegin(self, filename, clean_lines, linenum, error): |
|
| 2404 | # Look for a bare ':' |
|
| 2405 | if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): |
|
| 2406 | self.is_derived = True |
|
| 2407 | ||
| 2408 | def CheckEnd(self, filename, clean_lines, linenum, error): |
|
| 2409 | # If there is a DISALLOW macro, it should appear near the end of |
|
| 2410 | # the class. |
|
| 2411 | seen_last_thing_in_class = False |
|
| 2412 | for i in xrange(linenum - 1, self.starting_linenum, -1): |
|
| 2413 | match = Search( |
|
| 2414 | r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + |
|
| 2415 | self.name + r'\)', |
|
| 2416 | clean_lines.elided[i]) |
|
| 2417 | if match: |
|
| 2418 | if seen_last_thing_in_class: |
|
| 2419 | error(filename, i, 'readability/constructors', 3, |
|
| 2420 | match.group(1) + ' should be the last thing in the class') |
|
| 2421 | break |
|
| 2422 | ||
| 2423 | if not Match(r'^\s*$', clean_lines.elided[i]): |
|
| 2424 | seen_last_thing_in_class = True |
|
| 2425 | ||
| 2426 | # Check that closing brace is aligned with beginning of the class. |
|
| 2427 | # Only do this if the closing brace is indented by only whitespaces. |
|
| 2428 | # This means we will not check single-line class definitions. |
|
| 2429 | indent = Match(r'^( *)\}', clean_lines.elided[linenum]) |
|
| 2430 | if indent and len(indent.group(1)) != self.class_indent: |
|
| 2431 | if self.is_struct: |
|
| 2432 | parent = 'struct ' + self.name |
|
| 2433 | else: |
|
| 2434 | parent = 'class ' + self.name |
|
| 2435 | error(filename, linenum, 'whitespace/indent', 3, |
|
| 2436 | 'Closing brace should be aligned with beginning of %s' % parent) |
|
| 2437 | ||
| 2438 | ||
| 2439 | class _NamespaceInfo(_BlockInfo): |
|