Пример #1
0
        def rename_transform(node: LN, capture: Capture, filename: Filename) -> None:
            log.debug(f"{filename} [{list(capture)}]: {node}")

            # If two keys reference the same underlying object, do not modify it twice
            visited: List[LN] = []
            for _key, value in capture.items():
                log.debug(f"{_key}: {value}")
                if value in visited:
                    continue
                visited.append(value)

                if isinstance(value, Leaf) and value.type == TOKEN.NAME:
                    if value.value == old_name and value.parent is not None:
                        value.replace(Name(new_name, prefix=value.prefix))
                        break
                elif isinstance(value, Node):
                    if type_repr(value.type) == "dotted_name":
                        dp_old = dotted_parts(old_name)
                        dp_new = dotted_parts(new_name)
                        parts = zip(dp_old, dp_new, value.children)
                        for old, new, leaf in parts:
                            if old != leaf.value:
                                break
                            if old != new:
                                leaf.replace(Name(new, prefix=leaf.prefix))

                        if len(dp_new) < len(dp_old):
                            # if new path is shorter, remove excess children
                            del value.children[len(dp_new) : len(dp_old)]
                        elif len(dp_new) > len(dp_old):
                            # if new path is longer, add new children
                            children = [
                                Name(new) for new in dp_new[len(dp_old) : len(dp_new)]
                            ]
                            value.children[len(dp_old) : len(dp_old)] = children

                    elif type_repr(value.type) == "power":
                        # We don't actually need the '.' so just skip it
                        dp_old = old_name.split(".")
                        dp_new = new_name.split(".")

                        for old, new, leaf in zip(dp_old, dp_new, value.children):
                            if isinstance(leaf, Node):
                                name_leaf = leaf.children[1]
                            else:
                                name_leaf = leaf
                            if old != name_leaf.value:
                                break
                            name_leaf.replace(Name(new, prefix=name_leaf.prefix))

                        if len(dp_new) < len(dp_old):
                            # if new path is shorter, remove excess children
                            del value.children[len(dp_new) : len(dp_old)]
                        elif len(dp_new) > len(dp_old):
                            # if new path is longer, add new trailers in the middle
                            for i in range(len(dp_old), len(dp_new)):
                                value.insert_child(
                                    i, Node(SYMBOL.trailer, [Dot(), Name(dp_new[i])])
                                )
Пример #2
0
        def test_min_type(self):
            snippet = "True {} True\n".format(op)
            real_result = eval(snippet, {}, {})

            t = tree(snippet)
            expr = t.children[0].children[0]
            t_op = expr.children[1].type
            expr_type = pytree.type_repr(expr.type)
            key_type = TOKEN.tok_name[t_op]

            self.assertEqual(map_type(real_result), OP_MIN_TYPE.get(t_op),
                             key_type)
Пример #3
0
        def rename_transform(node: LN, capture: Capture,
                             filename: Filename) -> None:
            log.debug(f"{filename} [{list(capture)}]: {node}")
            for _key, value in capture.items():
                log.debug(f"{_key}: {value}")
                if isinstance(value, Leaf) and value.type == TOKEN.NAME:
                    if value.value == old_name and value.parent is not None:
                        value.replace(Name(new_name, prefix=value.prefix))
                        break
                elif isinstance(value, Node):
                    if type_repr(value.type) == "dotted_name":
                        parts = zip(
                            dotted_parts(old_name),
                            dotted_parts(new_name),
                            value.children,
                        )
                        for old, new, leaf in parts:
                            if old != leaf.value:
                                break
                            if old != new:
                                leaf.replace(Name(new, prefix=leaf.prefix))
                    elif type_repr(value.type) == "power":
                        pows = zip(dotted_parts(old_name),
                                   dotted_parts(new_name))
                        it = iter(value.children)
                        leaf = next(it)
                        for old, new in pows:
                            if old == ".":
                                leaf = leaf.children[1]
                                continue

                            if old != leaf.value:
                                break

                            if old == leaf.value and old != new:
                                leaf.replace(Name(new, prefix=leaf.prefix))

                            leaf = next(it)
Пример #4
0
def print_tree(
    node: LN,
    results: Capture = None,
    filename: Filename = None,
    indent: int = 0,
    recurse: int = -1,
):
    filename = filename or Filename("")
    tab = INDENT_STR * indent
    if filename and indent == 0:
        click.secho(filename, fg="red", bold=True)

    if isinstance(node, Leaf):
        click.echo(
            click.style(tab, fg="black", bold=True) + click.style(
                "[{}] {} {}".format(tok_name[node.type], repr(node.prefix),
                                    repr(node.value)),
                fg="yellow",
            ))
    else:
        click.echo(
            click.style(tab, fg="black", bold=True) + click.style(
                "[{}] {}".format(type_repr(node.type), repr(node.prefix)),
                fg="blue"))

    if node.children:
        if recurse:
            for child in node.children:
                # N.b. do not pass results here since we print them once
                # at the end.
                print_tree(child, indent=indent + 1, recurse=recurse - 1)
        else:
            click.echo(INDENT_STR * (indent + 1) + "...")

    if results is None:
        return

    for key in results:
        if key == "node":
            continue

        value = results[key]
        if isinstance(value, (Leaf, Node)):
            click.secho("results[{}] =".format(repr(key)), fg="red")
            print_tree(value, indent=1, recurse=1)
        else:
            # TODO: Improve display of multi-match here, see
            # test_print_tree_captures test.
            click.secho("results[{}] = {}".format(repr(key), value), fg="red")
Пример #5
0
def print_node(node: LN,
               max_depth: int = 1000,
               indent: str = "",
               last: bool = True,
               capture={}):
    """Debugging function to print node tree.
    Arguments:
        node: The node to print
        max_depth: The maximum recursion depth to walk children
    """
    if last:
        first_i = "└─"
        second_i = "  "
    else:
        first_i = "├─"
        second_i = "│ "
    prefix = indent + first_i
    name = ""
    if node in capture.values():
        name = ("\033[32m" + next(k for k, v in capture.items() if v == node) +
                "\033[0m= ")
    if type(node) is Node:
        print(prefix + name + "Node[{}] prefix={} suffix={}".format(
            type_repr(node.type), repr(node.prefix), repr(node.get_suffix())))
    elif type(node) is Leaf:
        print(indent + first_i + name + "Leaf({}, {}, col={}{})".format(
            token.tok_name[node.type],
            repr(node.value),
            node.column,
            ", prefix={}".format(repr(node.prefix)) if node.prefix else "",
        ))
    else:
        raise RuntimeError("Unknown node type")
    indent = indent + second_i

    children = list(node.children)
    if max_depth == 0 and children:
        print(indent + f"└─...{len(children)} children")
    else:
        for i, child in enumerate(node.children):
            print_node(
                child,
                indent=indent,
                last=(i + 1) == len(children),
                max_depth=max_depth - 1,
                capture=capture,
            )
Пример #6
0
def print_selector_pattern(node, results=None, filename=None):
    key = ""
    if results:
        for k, v in results.items():
            if node == v:
                key = k + "="
            elif isinstance(v, list) and node in v:  # v is a list?
                key = k + "="

    if isinstance(node, Leaf):
        click.echo("{}{} ".format(key, repr(node.value)), nl=False)
    else:
        click.echo("{}{} ".format(key, type_repr(node.type)), nl=False)
        if node.children:
            click.echo("< ", nl=False)
            for child in node.children:
                print_selector_pattern(child, results, filename)
            click.echo("> ", nl=False)
Пример #7
0
def print_node(node, indent="", last=True):
    """Debugging function to print node tree"""
    if last:
        first_i = "└─"
        second_i = "  "
    else:
        first_i = "├─"
        second_i = "│ "
    prefix = indent + first_i
    if type(node) is Node:
        print(prefix + "Node[{}] prefix={} suffix={}".format(
            type_repr(node.type), repr(node.prefix), repr(node.get_suffix())))
    else:
        print(indent + first_i + repr(node))
    indent = indent + second_i

    children = list(node.children)
    for i, child in enumerate(node.children):
        print_node(child, indent, last=(i + 1) == len(children))