in build-support/iwyu/fix_includes.py [0:0]
def _GetToplevelReorderSpans(file_lines):
"""Returns a sorted list of all reorder_spans not inside an #ifdef/namespace.
This routine looks at all the reorder_spans in file_lines, ignores
reorder spans inside #ifdefs and namespaces -- except for the 'header
guard' ifdef that encapsulates an entire .h file -- and returns the
rest in sorted order.
Arguments:
file_lines: an array of LineInfo objects with .type and
.reorder_span filled in.
Returns:
A list of [start_line, end_line) reorder_spans.
"""
in_ifdef = [False] * len(file_lines) # lines inside an #if
ifdef_depth = 0
for line_number in range(len(file_lines)):
line_info = file_lines[line_number]
if line_info.deleted:
continue
if line_info.type == _IF_RE: # does not cover the header-guard ifdef
ifdef_depth += 1
elif line_info.type == _ENDIF_RE:
ifdef_depth -= 1
if ifdef_depth > 0:
in_ifdef[line_number] = True
# Figuring out whether a } ends a namespace or some other languague
# construct is hard, so as soon as we see any 'contentful' line
# inside a namespace, we assume the entire rest of the file is in
# the namespace.
in_namespace = [False] * len(file_lines)
namespace_depth = 0
for line_number in range(len(file_lines)):
line_info = file_lines[line_number]
if line_info.deleted:
continue
if line_info.type == _NAMESPACE_START_RE:
# The 'max' is because the namespace-re may be a macro.
namespace_depth += max(line_info.line.count('{'), 1)
elif line_info.type == _NAMESPACE_END_RE:
namespace_depth -= max(line_info.line.count('}'), 1)
if namespace_depth > 0:
in_namespace[line_number] = True
if line_info.type is None:
for i in range(line_number, len(file_lines)): # rest of file
in_namespace[i] = True
break
reorder_spans = [fl.reorder_span for fl in file_lines if fl.reorder_span]
reorder_spans = sorted(set(reorder_spans))
good_reorder_spans = []
for reorder_span in reorder_spans:
for line_number in range(*reorder_span):
if in_ifdef[line_number] or in_namespace[line_number]:
break
else: # for/else
good_reorder_spans.append(reorder_span) # never in ifdef or namespace
return good_reorder_spans