Created
April 14, 2014 13:38
-
-
Save ibizaman/10648726 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from baron.rendering_dictionnary import rendering_dictionnary as d | |
| from baron.dumper import dumps | |
| import json | |
| class Position: | |
| def __init__(self, line, column): | |
| self.line = line | |
| self.column = column | |
| def advance_columns(self, columns): | |
| self.column += columns | |
| def advance_line(self): | |
| self.advance_lines(1) | |
| def advance_lines(self, lines): | |
| self.line += 1 | |
| self.column = 1 | |
| def path_to_location(tree, line, column): | |
| current = Position(1,1) | |
| target = Position(line, column) | |
| found = path_to_location_walk(tree, current, target) | |
| if not found: | |
| return None | |
| else: | |
| return json.dumps(found) | |
| def path_to_location_walk(node, current, target): | |
| if isinstance(node, list): | |
| for pos, child in enumerate(node): | |
| found = path_to_location_walk(child, current, target) | |
| if found is not None: | |
| found["path"] = [pos] + found["path"] | |
| return found | |
| elif isinstance(node, dict): | |
| if node['type'] == "endl": | |
| current.advance_line() | |
| for render_pos, key_type, render_key, value in render(node): | |
| if key_type == 'list': | |
| found = path_to_location_walk(node[render_key], current, target) | |
| else: | |
| found = path_to_location_walk(value, current, target) | |
| if found is not None: | |
| if render_key is not None: | |
| found["path"] = [render_key] + found["path"] | |
| if found["type"] is None: | |
| found["type"] = node["type"] | |
| found["position_in_rendering_list"] = render_pos | |
| return found | |
| else: | |
| advance_by = len(node) | |
| if is_on_targetted_node(target, current, advance_by): | |
| return {"path":[], "type":None, "position_in_rendering_list":None} | |
| current.advance_columns(advance_by) | |
| return None | |
| def is_on_targetted_node(target, current, length): | |
| return target.line == current.line \ | |
| and target.column >= current.column \ | |
| and target.column < current.column + length | |
| def render(node): | |
| for pos, (key_type, render_key) in enumerate(d[node['type']](node)): | |
| if key_type == 'list': | |
| value = '' | |
| elif key_type == 'key': | |
| value = node[render_key] | |
| elif key_type == 'constant': | |
| value = render_key | |
| render_key = None | |
| elif key_type == 'formatting': | |
| value = dumps(node[render_key]) | |
| yield (pos+1, key_type, render_key, value) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #rendering_dictionnary = { | |
| # "ternary_operator": [ | |
| # ("key", "first" ), | |
| # ("list", "first_formatting" ), | |
| # ("constant", "if" ), | |
| # ("list", "second_formatting"), | |
| # ("key", "value" ), | |
| # ("list", "third_formatting" ), | |
| # ("constant", "else" ), | |
| # ("list", "fourth_formatting"), | |
| # ("key", "second" ) | |
| # ], | |
| # "assignment": [ | |
| # ("key", "target" ), | |
| # ("list", "first_formatting" ), | |
| # ("key", "operator" ), | |
| # ("constant", "=" ), | |
| # ("list", "second_formatting"), | |
| # ("key", "value" ) | |
| # ], | |
| # "funcdef": [ | |
| # ("list", "decorators" ), | |
| # ("constant", "def" ), | |
| # ("list", "first_formatting" ), | |
| # ("key", "name" ), | |
| # ("list", "second_formatting"), | |
| # ("constant", "(" ), | |
| # ("list", "third_formatting" ), | |
| # ("list", "arguments" ), | |
| # ("list", "fourth_formatting"), | |
| # ("constant", ")" ), | |
| # ("list", "fifth_formatting" ), | |
| # ("constant", ":" ), | |
| # ("list", "sixth_formatting" ), | |
| # ("list", "value" ) | |
| # ], | |
| # "space": [ | |
| # ("key", "value") | |
| # ], | |
| # "name": [ | |
| # ("key", "value") | |
| # ] | |
| # } | |
| rendering_dictionnary = {} | |
| def node(key=""): | |
| def wrap(func): | |
| if not key: | |
| rendering_dictionnary[func.__name__ if not func.__name__.endswith("_") else func.__name__[:-1]] = func | |
| rendering_dictionnary[key] = func | |
| return func | |
| return wrap | |
| @node() | |
| def assignment(node): | |
| yield ("key", "target") | |
| yield ("formatting", "first_formatting") | |
| if node.get("operator"): | |
| # FIXME should probably be a different node type | |
| yield ("key", "operator") | |
| yield ("constant", "=") | |
| yield ("formatting", "second_formatting") | |
| yield ("key", "value") | |
| @node("int") | |
| @node("name") | |
| @node("space") | |
| def get_value(node): | |
| yield ("key", "value") | |
| def endl(node): | |
| yield ("formatting", "formatting") | |
| yield ("key", "value") | |
| yield ("formatting", "indent") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from baron.baron import parse | |
| import baron.finder as finder | |
| import json | |
| def make_path(path, type, pos): | |
| return json.dumps({"path":path, "type":type, "position_in_rendering_list":pos}) | |
| def check_path(line, column, target_node): | |
| code = """def fun(arg1, arg2): | |
| var *= 1 | |
| @deco("arg") | |
| def fun2(arg1 = default, **kwargs): | |
| arg1.attr = 3 | |
| """ | |
| code = """vara = 1""" | |
| assert finder.path_to_location(parse(code), line, column) == target_node | |
| def test_line_before_scope(): | |
| check_path(-1, 3, None) | |
| def test_column_before_scope(): | |
| check_path(1, -3, None) | |
| def test_line_after_scope(): | |
| check_path(3, 3, None) | |
| def test_column_after_scope(): | |
| check_path(1, 100, None) | |
| def test_assignment(): | |
| check_path(1, 100, None) | |
| def test_assignement_target(): | |
| path = make_path([0, "target", "value"], "name", 1) | |
| check_path(1, 1, path) | |
| check_path(1, 2, path) | |
| check_path(1, 3, path) | |
| check_path(1, 4, path) | |
| def test_assignement_first_formatting(): | |
| path = make_path([0, "first_formatting"], "assignment", 2) | |
| check_path(1, 5, path) | |
| def test_assignement_operator(): | |
| path = make_path([0], "assignment", 3) | |
| check_path(1, 6, path) | |
| def test_assignement_second_formatting(): | |
| path = make_path([0, "second_formatting"], "assignment", 4) | |
| check_path(1, 7, path) | |
| def test_assignement_target(): | |
| path = make_path([0, "value", "value"], "int", 1) | |
| check_path(1, 8, path) | |
| #def test_first_def(): | |
| # path = make_path([0, "value"], "funcdef", 2) | |
| # check_path(1, 1, path) | |
| # check_path(1, 2, path) | |
| # check_path(1, 3, path) | |
| # | |
| #def test_first_formatting(): | |
| # path = make_path([0, "value"], "funcdef", 3) | |
| # check_path(1, 4, path) | |
| # | |
| #def test_first_name(): | |
| # path = make_path([0, "value"], "funcdef", 4) | |
| # check_path(1, 5, path) | |
| # check_path(1, 6, path) | |
| # check_path(1, 7, path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment