示例#1
0
    def _find_node(self, text):
        goal = text
        if not isinstance(text, (tuple, list)):
            goal = [text]

        class Search(object):
            result = None

            def __call__(self, node):
                for text in goal:
                    if sys.version_info >= (3, 8) and text in [
                            'Num', 'Str', 'NameConstant', 'Ellipsis'
                    ]:
                        text = 'Constant'
                    if str(node).startswith(text):
                        self.result = node
                        break
                    if node.__class__.__name__.startswith(text):
                        self.result = node
                        break
                return self.result is not None

        search = Search()
        ast.call_for_nodes(self.ast, search, recursive=True)
        return search.result
示例#2
0
 def _handle(self, node, base_children, eat_parens=False, eat_spaces=False):
     if hasattr(node, 'region'):
         # ???: The same node was seen twice; what should we do?
         warnings.warn(
             'Node <%s> has been already patched; please report!' %
             node.__class__.__name__, RuntimeWarning)
         return
     base_children = collections.deque(base_children)
     self.children_stack.append(base_children)
     children = collections.deque()
     formats = []
     suspected_start = self.source.offset
     start = suspected_start
     first_token = True
     while base_children:
         child = base_children.popleft()
         if child is None:
             continue
         offset = self.source.offset
         if isinstance(child, ast.AST):
             ast.call_for_nodes(child, self)
             token_start = child.region[0]
         else:
             if child is self.String:
                 region = self.source.consume_string(
                     end=self._find_next_statement_start())
             elif child is self.Number:
                 region = self.source.consume_number()
             elif child == '!=':
                 # INFO: This has been added to handle deprecated ``<>``
                 region = self.source.consume_not_equal()
             else:
                 region = self.source.consume(child)
             child = self.source[region[0]:region[1]]
             token_start = region[0]
         if not first_token:
             formats.append(self.source[offset:token_start])
             if self.children:
                 children.append(self.source[offset:token_start])
         else:
             first_token = False
             start = token_start
         if self.children:
             children.append(child)
     start = self._handle_parens(children, start, formats)
     if eat_parens:
         start = self._eat_surrounding_parens(
             children, suspected_start, start)
     if eat_spaces:
         if self.children:
             children.appendleft(self.source[0:start])
         end_spaces = self.source[self.source.offset:]
         self.source.consume(end_spaces)
         if self.children:
             children.append(end_spaces)
         start = 0
     if self.children:
         node.sorted_children = children
     node.region = (start, self.source.offset)
     self.children_stack.pop()
示例#3
0
 def _handle(self, node, base_children, eat_parens=False, eat_spaces=False):
     if hasattr(node, 'region'):
         # ???: The same node was seen twice; what should we do?
         warnings.warn(
             'Node <%s> has been already patched; please report!' %
             node.__class__.__name__, RuntimeWarning)
         return
     base_children = collections.deque(base_children)
     self.children_stack.append(base_children)
     children = collections.deque()
     formats = []
     suspected_start = self.source.offset
     start = suspected_start
     first_token = True
     while base_children:
         child = base_children.popleft()
         if child is None:
             continue
         offset = self.source.offset
         if isinstance(child, ast.AST):
             ast.call_for_nodes(child, self)
             token_start = child.region[0]
         else:
             if child is self.String:
                 region = self.source.consume_string(
                     end=self._find_next_statement_start())
             elif child is self.Number:
                 region = self.source.consume_number()
             elif child == '!=':
                 # INFO: This has been added to handle deprecated ``<>``
                 region = self.source.consume_not_equal()
             else:
                 region = self.source.consume(child)
             child = self.source[region[0]:region[1]]
             token_start = region[0]
         if not first_token:
             formats.append(self.source[offset:token_start])
             if self.children:
                 children.append(self.source[offset:token_start])
         else:
             first_token = False
             start = token_start
         if self.children:
             children.append(child)
     start = self._handle_parens(children, start, formats)
     if eat_parens:
         start = self._eat_surrounding_parens(children, suspected_start,
                                              start)
     if eat_spaces:
         if self.children:
             children.appendleft(self.source[0:start])
         end_spaces = self.source[self.source.offset:]
         self.source.consume(end_spaces)
         if self.children:
             children.append(end_spaces)
         start = 0
     if self.children:
         node.sorted_children = children
     node.region = (start, self.source.offset)
     self.children_stack.pop()
示例#4
0
文件: patchedast.py 项目: Kha/rope
def patch_ast(node, source, sorted_children=False):
    """Patches the given node

    After calling, each node in `node` will have a new field named
    `region` that is a tuple containing the start and end offsets
    of the code that generated it.

    If `sorted_children` is true, a `sorted_children` field will
    be created for each node, too.  It is a list containing child
    nodes as well as whitespaces and comments that occur between
    them.

    """
    if hasattr(node, 'region'):
        return node
    walker = _PatchingASTWalker(source, children=sorted_children)
    ast.call_for_nodes(node, walker)
    return node
示例#5
0
 def _find_node(self, text):
     goal = text
     if not isinstance(text, (tuple, list)):
         goal = [text]
     class Search(object):
         result = None
         def __call__(self, node):
             for text in goal:
                 if str(node).startswith(text):
                     self.result = node
                     break
                 if node.__class__.__name__.startswith(text):
                     self.result = node
                     break
             return self.result is not None
     search = Search()
     ast.call_for_nodes(self.ast, search, recursive=True)
     return search.result
示例#6
0
def patch_ast(node, source, sorted_children=False):
    """Patches the given node

    After calling, each node in `node` will have a new field named
    `region` that is a tuple containing the start and end offsets
    of the code that generated it.

    If `sorted_children` is true, a `sorted_children` field will
    be created for each node, too.  It is a list containing child
    nodes as well as whitespaces and comments that occur between
    them.

    """
    if hasattr(node, 'region'):
        return node
    walker = _PatchingASTWalker(source, children=sorted_children)
    ast.call_for_nodes(node, walker)
    return node
示例#7
0
文件: similarfinder.py 项目: Kha/rope
 def find_matches(self):
     if self.matches is None:
         self.matches = []
         ast.call_for_nodes(self.body, self._check_node, recursive=True)
     return self.matches
示例#8
0
 def find_matches(self):
     if self.matches is None:
         self.matches = []
         ast.call_for_nodes(self.body, self._check_node, recursive=True)
     return self.matches
示例#9
0
    def _handle(self, node, base_children, eat_parens=False, eat_spaces=False):
        if hasattr(node, "region"):
            # ???: The same node was seen twice; what should we do?
            warnings.warn(
                "Node <%s> has been already patched; please report!"
                % node.__class__.__name__,
                RuntimeWarning,
            )
            return

        base_children = collections.deque(base_children)
        self.children_stack.append(base_children)
        children = collections.deque()
        formats = []
        suspected_start = self.source.offset
        start = suspected_start
        first_token = True
        while base_children:
            child = base_children.popleft()
            if child is None:
                continue
            offset = self.source.offset
            if isinstance(child, ast.AST):
                ast.call_for_nodes(child, self)
                token_start = child.region[0]
            else:
                if child is self.String:
                    region = self.source.consume_string(
                        end=self._find_next_statement_start()
                    )
                elif child is self.Number:
                    region = self.source.consume_number()
                elif child == "!=":
                    # INFO: This has been added to handle deprecated ``<>``
                    region = self.source.consume_not_equal()
                elif child == self.semicolon_or_as_in_except:
                    # INFO: This has been added to handle deprecated
                    # semicolon in except
                    region = self.source.consume_except_as_or_semicolon()
                elif child == self.exec_open_paren_or_space:
                    # These three cases handle the differences between
                    # the deprecated exec statement and the exec
                    # function.
                    region = self.source.consume_exec_open_paren_or_space()
                elif child == self.exec_in_or_comma:
                    region = self.source.consume_exec_in_or_comma()
                elif child == self.exec_close_paren_or_space:
                    region = self.source.consume_exec_close_paren_or_space()
                elif child == self.with_or_comma_context_manager:
                    region = self.source.consume_with_or_comma_context_manager()
                else:
                    if hasattr(ast, "JoinedStr") and isinstance(
                        node, (ast.JoinedStr, ast.FormattedValue)
                    ):
                        region = self.source.consume_joined_string(child)
                    else:
                        region = self.source.consume(child)
                child = self.source[region[0] : region[1]]
                token_start = region[0]
            if not first_token:
                formats.append(self.source[offset:token_start])
                if self.children:
                    children.append(self.source[offset:token_start])
            else:
                first_token = False
                start = token_start
            if self.children:
                children.append(child)
        start = self._handle_parens(children, start, formats)
        if eat_parens:
            start = self._eat_surrounding_parens(children, suspected_start, start)
        if eat_spaces:
            if self.children:
                children.appendleft(self.source[0:start])
            end_spaces = self.source[self.source.offset :]
            self.source.consume(end_spaces)
            if self.children:
                children.append(end_spaces)
            start = 0
        if self.children:
            node.sorted_children = children
        node.region = (start, self.source.offset)
        self.children_stack.pop()