Stores information about a namespace.
| 2334 | |
| 2335 | |
| 2336 | class _NamespaceInfo(_BlockInfo): |
| 2337 | """Stores information about a namespace.""" |
| 2338 | |
| 2339 | def __init__(self, name, linenum): |
| 2340 | _BlockInfo.__init__(self, linenum, False) |
| 2341 | self.name = name or '' |
| 2342 | self.check_namespace_indentation = True |
| 2343 | |
| 2344 | def CheckEnd(self, filename, clean_lines, linenum, error): |
| 2345 | """Check end of namespace comments.""" |
| 2346 | line = clean_lines.raw_lines[linenum] |
| 2347 | |
| 2348 | # Check how many lines is enclosed in this namespace. Don't issue |
| 2349 | # warning for missing namespace comments if there aren't enough |
| 2350 | # lines. However, do apply checks if there is already an end of |
| 2351 | # namespace comment and it's incorrect. |
| 2352 | # |
| 2353 | # TODO(unknown): We always want to check end of namespace comments |
| 2354 | # if a namespace is large, but sometimes we also want to apply the |
| 2355 | # check if a short namespace contained nontrivial things (something |
| 2356 | # other than forward declarations). There is currently no logic on |
| 2357 | # deciding what these nontrivial things are, so this check is |
| 2358 | # triggered by namespace size only, which works most of the time. |
| 2359 | if (linenum - self.starting_linenum < 10 |
| 2360 | and not Match(r'^\s*};*\s*(//|/\*).*\bnamespace\b', line)): |
| 2361 | return |
| 2362 | |
| 2363 | # Look for matching comment at end of namespace. |
| 2364 | # |
| 2365 | # Note that we accept C style "/* */" comments for terminating |
| 2366 | # namespaces, so that code that terminate namespaces inside |
| 2367 | # preprocessor macros can be cpplint clean. |
| 2368 | # |
| 2369 | # We also accept stuff like "// end of namespace <name>." with the |
| 2370 | # period at the end. |
| 2371 | # |
| 2372 | # Besides these, we don't accept anything else, otherwise we might |
| 2373 | # get false negatives when existing comment is a substring of the |
| 2374 | # expected namespace. |
| 2375 | if self.name: |
| 2376 | # Named namespace |
| 2377 | if not Match((r'^\s*};*\s*(//|/\*).*\bnamespace\s+' + |
| 2378 | re.escape(self.name) + r'[\*/\.\\\s]* {$'), |
| 2379 | line): |
| 2380 | error(filename, linenum, 'readability/namespace', 5, |
| 2381 | 'Namespace should be terminated with "// namespace %s {"' % |
| 2382 | self.name) |
| 2383 | else: |
| 2384 | # Anonymous namespace |
| 2385 | if not Match(r'^\s*};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]* {$', line): |
| 2386 | # If "// namespace anonymous" or "// anonymous namespace (more text)", |
| 2387 | # mention "// anonymous namespace" as an acceptable form |
| 2388 | if Match(r'^\s*}.*\b(namespace anonymous|anonymous namespace)\b', line): |
| 2389 | error(filename, linenum, 'readability/namespace', 5, |
| 2390 | 'Anonymous namespace should be terminated with "// namespace"' |
| 2391 | ' or "// anonymous namespace"') |
| 2392 | else: |
| 2393 | error(filename, linenum, 'readability/namespace', 5, |