codeparser: merge the nested python parsing classes

The split is even less necessary now that we use ast.walk rather than an
actual NodeVisitor subclass.

(Bitbake rev: d6c44fac184abae8395bfa7078f06675218aa534)

Signed-off-by: Christopher Larson <kergoth@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Christopher Larson 2011-10-27 22:23:05 -07:00 committed by Richard Purdie
parent 9a68fb1364
commit ada59bde67
1 changed files with 85 additions and 100 deletions

View File

@ -151,15 +151,9 @@ def parser_cache_savemerge(d):
class PythonParser():
class ValueVisitor():
"""Visitor to traverse a python abstract syntax tree and obtain
the variables referenced via bitbake metadata APIs, and the external
functions called.
"""
getvars = ("d.getVar", "bb.data.getVar", "data.getVar")
expands = ("d.expand", "bb.data.expand", "data.expand")
execs = ("bb.build.exec_func", "bb.build.exec_task")
execfuncs = ("bb.build.exec_func", "bb.build.exec_task")
@classmethod
def _compare_name(cls, strparts, node):
@ -195,13 +189,6 @@ class PythonParser():
else:
return any(cls.compare_name(item, node) for item in value)
def __init__(self, value):
self.var_references = set()
self.var_execs = set()
self.direct_func_calls = set()
self.var_expands = set()
self.value = value
@classmethod
def warn(cls, func, arg):
"""Warn about calls of bitbake APIs which pass a non-literal
@ -233,13 +220,13 @@ class PythonParser():
pass
else:
self.warn(node.func, node.args[0])
elif self.compare_name(self.execs, node.func):
elif self.compare_name(self.execfuncs, node.func):
if isinstance(node.args[0], ast.Str):
self.var_execs.add(node.args[0].s)
else:
self.warn(node.func, node.args[0])
elif isinstance(node.func, ast.Name):
self.direct_func_calls.add(node.func.id)
self.execs.add(node.func.id)
elif isinstance(node.func, ast.Attribute):
# We must have a qualified name. Therefore we need
# to walk the chain of 'Attribute' nodes to determine
@ -251,16 +238,16 @@ class PythonParser():
attr_node = attr_node.value
if isinstance(attr_node, ast.Name):
identifier = attr_node.id + "." + identifier
self.direct_func_calls.add(identifier)
self.execs.add(identifier)
def __init__(self):
#self.funcdefs = set()
self.var_references = set()
self.var_execs = set()
self.execs = set()
#self.external_cmds = set()
self.var_expands = set()
self.references = set()
def parse_python(self, node):
h = hash(str(node))
if h in pythonparsecache:
@ -271,14 +258,12 @@ class PythonParser():
code = compile(check_indent(str(node)), "<string>", "exec",
ast.PyCF_ONLY_AST)
visitor = self.ValueVisitor(code)
for n in ast.walk(code):
if n.__class__.__name__ == "Call":
visitor.visit_Call(n)
self.visit_Call(n)
self.references.update(visitor.var_references)
self.references.update(visitor.var_execs)
self.execs = visitor.direct_func_calls
self.references.update(self.var_references)
self.references.update(self.var_execs)
pythonparsecache[h] = {}
pythonparsecache[h]["refs"] = self.references