refactor to expose indenter class

Summary: public
just a refactoring

Reviewed By: cristianoc

Differential Revision: D2600856

fb-gh-sync-id: 264658c
master
Jules Villard 9 years ago committed by facebook-github-bot-7
parent 80057ea523
commit 43cb5ae7e0

@ -24,9 +24,6 @@ import sys
import utils import utils
import inferlib import inferlib
BASE_INDENT = 2
# how many lines of context around each report
SOURCE_CONTEXT = 2
HTML_REPORT_DIR = 'report.html' HTML_REPORT_DIR = 'report.html'
TRACES_REPORT_DIR = 'traces' TRACES_REPORT_DIR = 'traces'
SOURCE_REMOTE_GITHUB_URL_TEMPLATE = ('https://github.com/{project}/blob/' SOURCE_REMOTE_GITHUB_URL_TEMPLATE = ('https://github.com/{project}/blob/'
@ -91,48 +88,11 @@ class Tracer(object):
def __init__(self, args, level=sys.maxsize): def __init__(self, args, level=sys.maxsize):
self.args = args self.args = args
self.max_level = level self.max_level = level
self.indenter = utils.Indenter()
self.text = ''
self.indent = []
def indent_get(self):
indent = ''
for i in self.indent:
indent += i
return indent
def indent_push(self, n=1):
self.indent.append(n * BASE_INDENT * ' ')
def indent_pop(self):
return self.indent.pop()
def add(self, s):
self.text += self.indent_get() + s
def newline(self):
self.text += '\n'
def build_node_tags(self, node): def build_node_tags(self, node):
pass pass
def build_source_context(self, source_name, report_line):
start_line = max(1, report_line - SOURCE_CONTEXT)
# could go beyond last line, checked in the loop
end_line = report_line + SOURCE_CONTEXT
n_length = len(str(end_line))
line_number = 1
with open(source_name) as source_file:
for line in source_file:
if start_line <= line_number <= end_line:
num = str(line_number).zfill(n_length)
caret = ' '
if line_number == report_line:
caret = '> '
self.add(num + ' ' + caret + line)
line_number += 1
def build_node(self, node): def build_node(self, node):
if node['level'] > self.max_level: if node['level'] > self.max_level:
return return
@ -140,15 +100,17 @@ class Tracer(object):
report_line = node['line_number'] report_line = node['line_number']
fname = node['filename'] fname = node['filename']
self.add('%s:%d: %s\n' % (fname, self.indenter.newline()
report_line, self.indenter.add('%s:%d: %s' % (fname,
node['description'])) report_line,
node['description']))
self.indenter.newline()
if not self.args.no_source: if not self.args.no_source:
self.indent_push(node['level']) self.indenter.indent_push(node['level'])
self.build_source_context(fname, report_line) self.indenter.add(utils.build_source_context(fname, report_line))
self.indent_pop() self.indenter.indent_pop()
self.newline() self.indenter.newline()
def build_trace(self, trace): def build_trace(self, trace):
total_nodes = len(trace) total_nodes = len(trace)
@ -159,8 +121,9 @@ class Tracer(object):
if hidden_nodes > 0: if hidden_nodes > 0:
hidden_str = ' (%d steps too deeply nested)' % hidden_nodes hidden_str = ' (%d steps too deeply nested)' % hidden_nodes
all_str = '' all_str = ''
self.add('Showing %s%d steps of the trace%s\n\n' self.indenter.add('Showing %s%d steps of the trace%s\n\n'
% (all_str, shown_nodes, hidden_str)) % (all_str, shown_nodes, hidden_str))
self.indenter.newline()
for node in trace: for node in trace:
self.build_node(node) self.build_node(node)
@ -170,7 +133,7 @@ class Tracer(object):
self.build_trace(traces['trace']) self.build_trace(traces['trace'])
def __str__(self): def __str__(self):
return self.text return str(self.indenter)
class Selector(object): class Selector(object):

@ -57,6 +57,10 @@ BUCK_INFER_OUT = 'infer'
FORMAT = '[%(levelname)s] %(message)s' FORMAT = '[%(levelname)s] %(message)s'
DEBUG_FORMAT = '[%(levelname)s:%(filename)s:%(lineno)03d] %(message)s' DEBUG_FORMAT = '[%(levelname)s:%(filename)s:%(lineno)03d] %(message)s'
BASE_INDENT = 2
# how many lines of context around each report
SOURCE_CONTEXT = 2
# Monkey patching subprocess (I'm so sorry!). # Monkey patching subprocess (I'm so sorry!).
if "check_output" not in dir(subprocess): if "check_output" not in dir(subprocess):
@ -363,4 +367,55 @@ class AbsolutePathAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None): def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, os.path.abspath(values)) setattr(namespace, self.dest, os.path.abspath(values))
class Indenter(str):
def __init__(self):
super(Indenter, self).__init__()
self.text = ''
self.indent = []
def indent_get(self):
indent = ''
for i in self.indent:
indent += i
return indent
def indent_push(self, n=1):
self.indent.append(n * BASE_INDENT * ' ')
def indent_pop(self):
return self.indent.pop()
def newline(self):
self.text += '\n'
def add(self, x):
lines = x.splitlines()
indent = self.indent_get()
lines = [indent + l for l in lines]
self.text += '\n'.join(lines)
def __str__(self):
return self.text
def build_source_context(source_name, report_line):
start_line = max(1, report_line - SOURCE_CONTEXT)
# could go beyond last line, checked in the loop
end_line = report_line + SOURCE_CONTEXT
n_length = len(str(end_line))
line_number = 1
s = ''
with open(source_name) as source_file:
for line in source_file:
if start_line <= line_number <= end_line:
num = str(line_number).zfill(n_length)
caret = ' '
if line_number == report_line:
caret = '> '
s += num + '. ' + caret + line
line_number += 1
return s
# vim: set sw=4 ts=4 et: # vim: set sw=4 ts=4 et:

Loading…
Cancel
Save