diff options
Diffstat (limited to 'bitbake/lib/bb/codeparser.py')
-rw-r--r-- | bitbake/lib/bb/codeparser.py | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/bitbake/lib/bb/codeparser.py b/bitbake/lib/bb/codeparser.py index 9d66d3ae41..c0b1d7966f 100644 --- a/bitbake/lib/bb/codeparser.py +++ b/bitbake/lib/bb/codeparser.py | |||
@@ -27,6 +27,7 @@ import ast | |||
27 | import sys | 27 | import sys |
28 | import codegen | 28 | import codegen |
29 | import logging | 29 | import logging |
30 | import inspect | ||
30 | import bb.pysh as pysh | 31 | import bb.pysh as pysh |
31 | import bb.utils, bb.data | 32 | import bb.utils, bb.data |
32 | import hashlib | 33 | import hashlib |
@@ -58,10 +59,33 @@ def check_indent(codestr): | |||
58 | 59 | ||
59 | return codestr | 60 | return codestr |
60 | 61 | ||
61 | # A custom getstate/setstate using tuples is actually worth 15% cachesize by | 62 | modulecode_deps = {} |
62 | # avoiding duplication of the attribute names! | ||
63 | 63 | ||
64 | def add_module_functions(fn, functions, namespace): | ||
65 | fstat = os.stat(fn) | ||
66 | fixedhash = fn + ":" + str(fstat.st_size) + ":" + str(fstat.st_mtime) | ||
67 | for f in functions: | ||
68 | name = "%s.%s" % (namespace, f) | ||
69 | parser = PythonParser(name, logger) | ||
70 | try: | ||
71 | parser.parse_python(None, filename=fn, lineno=1, fixedhash=fixedhash+f) | ||
72 | #bb.warn("Cached %s" % f) | ||
73 | except KeyError: | ||
74 | lines, lineno = inspect.getsourcelines(functions[f]) | ||
75 | src = "".join(lines) | ||
76 | parser.parse_python(src, filename=fn, lineno=lineno, fixedhash=fixedhash+f) | ||
77 | #bb.warn("Not cached %s" % f) | ||
78 | execs = parser.execs.copy() | ||
79 | # Expand internal module exec references | ||
80 | for e in parser.execs: | ||
81 | if e in functions: | ||
82 | execs.remove(e) | ||
83 | execs.add(namespace + "." + e) | ||
84 | modulecode_deps[name] = [parser.references.copy(), execs, parser.var_execs.copy(), parser.contains.copy()] | ||
85 | #bb.warn("%s: %s\nRefs:%s Execs: %s %s %s" % (name, src, parser.references, parser.execs, parser.var_execs, parser.contains)) | ||
64 | 86 | ||
87 | # A custom getstate/setstate using tuples is actually worth 15% cachesize by | ||
88 | # avoiding duplication of the attribute names! | ||
65 | class SetCache(object): | 89 | class SetCache(object): |
66 | def __init__(self): | 90 | def __init__(self): |
67 | self.setcache = {} | 91 | self.setcache = {} |
@@ -289,11 +313,17 @@ class PythonParser(): | |||
289 | self.unhandled_message = "in call of %s, argument '%s' is not a string literal" | 313 | self.unhandled_message = "in call of %s, argument '%s' is not a string literal" |
290 | self.unhandled_message = "while parsing %s, %s" % (name, self.unhandled_message) | 314 | self.unhandled_message = "while parsing %s, %s" % (name, self.unhandled_message) |
291 | 315 | ||
292 | def parse_python(self, node, lineno=0, filename="<string>"): | 316 | # For the python module code it is expensive to have the function text so it is |
293 | if not node or not node.strip(): | 317 | # uses a different fixedhash to cache against. We can take the hit on obtaining the |
318 | # text if it isn't in the cache. | ||
319 | def parse_python(self, node, lineno=0, filename="<string>", fixedhash=None): | ||
320 | if not fixedhash and (not node or not node.strip()): | ||
294 | return | 321 | return |
295 | 322 | ||
296 | h = bbhash(str(node)) | 323 | if fixedhash: |
324 | h = fixedhash | ||
325 | else: | ||
326 | h = bbhash(str(node)) | ||
297 | 327 | ||
298 | if h in codeparsercache.pythoncache: | 328 | if h in codeparsercache.pythoncache: |
299 | self.references = set(codeparsercache.pythoncache[h].refs) | 329 | self.references = set(codeparsercache.pythoncache[h].refs) |
@@ -311,6 +341,9 @@ class PythonParser(): | |||
311 | self.contains[i] = set(codeparsercache.pythoncacheextras[h].contains[i]) | 341 | self.contains[i] = set(codeparsercache.pythoncacheextras[h].contains[i]) |
312 | return | 342 | return |
313 | 343 | ||
344 | if fixedhash and not node: | ||
345 | raise KeyError | ||
346 | |||
314 | # Need to parse so take the hit on the real log buffer | 347 | # Need to parse so take the hit on the real log buffer |
315 | self.log = BufferedLogger('BitBake.Data.PythonParser', logging.DEBUG, self._log) | 348 | self.log = BufferedLogger('BitBake.Data.PythonParser', logging.DEBUG, self._log) |
316 | 349 | ||