77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
from __future__ import absolute_import
|
|
import ast
|
|
from ast import *
|
|
|
|
from rope.base import fscommands
|
|
|
|
try:
|
|
unicode
|
|
except NameError:
|
|
unicode = str
|
|
|
|
|
|
def parse(source, filename="<string>"):
|
|
# NOTE: the raw string should be given to `compile` function
|
|
if isinstance(source, unicode):
|
|
source = fscommands.unicode_to_file_data(source)
|
|
if b"\r" in source:
|
|
source = source.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
|
|
if not source.endswith(b"\n"):
|
|
source += b"\n"
|
|
try:
|
|
return ast.parse(source, filename="<unknown>")
|
|
except (TypeError, ValueError) as e:
|
|
error = SyntaxError()
|
|
error.lineno = 1
|
|
error.filename = filename
|
|
error.msg = str(e)
|
|
raise error
|
|
|
|
|
|
def walk(node, walker):
|
|
"""Walk the syntax tree"""
|
|
method_name = "_" + node.__class__.__name__
|
|
method = getattr(walker, method_name, None)
|
|
if method is not None:
|
|
if isinstance(node, ast.ImportFrom) and node.module is None:
|
|
# In python < 2.7 ``node.module == ''`` for relative imports
|
|
# but for python 2.7 it is None. Generalizing it to ''.
|
|
node.module = ""
|
|
return method(node)
|
|
for child in get_child_nodes(node):
|
|
walk(child, walker)
|
|
|
|
|
|
def get_child_nodes(node):
|
|
if isinstance(node, ast.Module):
|
|
return node.body
|
|
result = []
|
|
if node._fields is not None:
|
|
for name in node._fields:
|
|
child = getattr(node, name)
|
|
if isinstance(child, list):
|
|
for entry in child:
|
|
if isinstance(entry, ast.AST):
|
|
result.append(entry)
|
|
if isinstance(child, ast.AST):
|
|
result.append(child)
|
|
return result
|
|
|
|
|
|
def call_for_nodes(node, callback, recursive=False):
|
|
"""If callback returns `True` the child nodes are skipped"""
|
|
result = callback(node)
|
|
if recursive and not result:
|
|
for child in get_child_nodes(node):
|
|
call_for_nodes(child, callback, recursive)
|
|
|
|
|
|
def get_children(node):
|
|
result = []
|
|
if node._fields is not None:
|
|
for name in node._fields:
|
|
if name in ["lineno", "col_offset"]:
|
|
continue
|
|
child = getattr(node, name)
|
|
result.append(child)
|
|
return result
|