diff options
author | Steven Knight <knight@baldmt.com> | 2005-02-13 13:05:22 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2005-02-13 13:05:22 (GMT) |
commit | d3ba17c301be389cd15cc387e1df7fa530e6856e (patch) | |
tree | 71e69e51423a35771427ba095d28a6f323086f7a /src | |
parent | c4cf6660b5a05710dc603999010f5b4645b3f655 (diff) | |
download | SCons-d3ba17c301be389cd15cc387e1df7fa530e6856e.zip SCons-d3ba17c301be389cd15cc387e1df7fa530e6856e.tar.gz SCons-d3ba17c301be389cd15cc387e1df7fa530e6856e.tar.bz2 |
Refactor Environment/Executor/Node scanner interaction a little. Put --debug={dtree,includes,stree,tree} in separate tests.
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/SCons/Executor.py | 19 | ||||
-rw-r--r-- | src/engine/SCons/ExecutorTests.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 11 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 43 |
4 files changed, 78 insertions, 30 deletions
diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 013a125..5b45d55 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -88,20 +88,24 @@ class Executor: cwd = None return scanner.path(env, cwd, self.targets, self.sources) + def get_kw(self, kw={}): + result = self.builder_kw.copy() + result.update(kw) + return result + def do_nothing(self, target, errfunc, kw): pass def do_execute(self, target, errfunc, kw): """Actually execute the action list.""" - kw = kw.copy() - kw.update(self.builder_kw) - apply(self.action, (self.targets, self.sources, - self.get_build_env(), errfunc), kw) + apply(self.action, + (self.targets, self.sources, self.get_build_env(), errfunc), + self.get_kw(kw)) # use extra indirection because with new-style objects (Python 2.2 # and above) we can't override special methods, and nullify() needs # to be able to do this. - + def __call__(self, target, errfunc, **kw): self.do_execute(target, errfunc, kw) @@ -117,7 +121,7 @@ class Executor: self.sources.extend(slist) # another extra indirection for new-style objects and nullify... - + def my_str(self): return self.action.genstring(self.targets, self.sources, @@ -163,7 +167,8 @@ class Executor: if scanner: initial_scanners = lambda src, s=scanner: (src, s) else: - initial_scanners = lambda src, e=env: (src, e.get_scanner(src.scanner_key())) + kw = self.get_kw() + initial_scanners = lambda src, e=env, kw=kw: (src, src.get_scanner(e, kw)) scanner_list = map(initial_scanners, self.sources) scanner_list = filter(remove_null_scanners, scanner_list) scanner_list = map(select_specific_scanner, scanner_list) diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py index 189cbad..d3af914 100644 --- a/src/engine/SCons/ExecutorTests.py +++ b/src/engine/SCons/ExecutorTests.py @@ -78,8 +78,10 @@ class MyNode: [self], ['s1', 's2']) apply(executor, (self, errfunc), {}) + def get_scanner(self, env, kw): + return MyScanner('dep-') def get_implicit_deps(self, env, scanner, path): - return ['dep-' + str(self)] + return [scanner.prefix + str(self)] def add_to_implicit(self, deps): self.implicit.extend(deps) def missing(self): @@ -88,6 +90,8 @@ class MyNode: return 'cs-'+calc+'-'+self.name class MyScanner: + def __init__(self, prefix): + self.prefix = prefix def path(self, env, cwd, target, source): return () def select(self, node): @@ -162,6 +166,22 @@ class ExecutorTestCase(unittest.TestCase): p = x.get_build_scanner_path(s) assert p == "scanner: sss, here, ['t'], ['s1', 's2']", p + def test_get_kw(self): + """Test the get_kw() method""" + t = MyNode('t') + x = SCons.Executor.Executor(MyAction(), + MyEnvironment(), + [], + [t], + ['s1', 's2'], + builder_kw={'X':1, 'Y':2}) + kw = x.get_kw() + assert kw == {'X':1, 'Y':2}, kw + kw = x.get_kw({'Z':3}) + assert kw == {'X':1, 'Y':2, 'Z':3}, kw + kw = x.get_kw({'X':4}) + assert kw == {'X':4, 'Y':2}, kw + def test__call__(self): """Test calling an Executor""" result = [] @@ -296,9 +316,16 @@ class ExecutorTestCase(unittest.TestCase): targets = [MyNode('t')] sources = [MyNode('s1'), MyNode('s2')] x = SCons.Executor.Executor('b', env, [{}], targets, sources) - scanner = MyScanner() - deps = x.scan(scanner) - assert targets[0].implicit == ['dep-s1', 'dep-s2'], targets[0].implicit + + deps = x.scan(None) + t = targets[0] + assert t.implicit == ['dep-s1', 'dep-s2'], t.implicit + + t.implicit = [] + + deps = x.scan(MyScanner('scanner-')) + t = targets[0] + assert t.implicit == ['scanner-s1', 'scanner-s2'], t.implicit def test_get_missing_sources(self): """Test the ability to check if any sources are missing""" diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 0637ceb..281b5f2 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -830,6 +830,17 @@ class NodeTestCase(unittest.TestCase): deps = node.get_implicit_deps(env, s, target) assert deps == [d, e, f], map(str, deps) + def test_get_scanner(self): + """Test fetching the environment scanner for a Node + """ + node = SCons.Node.Node() + scanner = Scanner() + env = Environment(SCANNERS = [scanner]) + s = node.get_scanner(env) + assert s == scanner, s + s = node.get_scanner(env, {'X':1}) + assert s == scanner, s + def test_get_source_scanner(self): """Test fetching the source scanner for a Node """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index c7167a3..96a78ca 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -425,6 +425,8 @@ class Node: """ return self.builder.source_factory(path) + def get_scanner(self, env, kw={}): + return env.get_scanner(self.scanner_key()) def get_source_scanner(self, node): """Fetch the source scanner for the specified node @@ -447,7 +449,7 @@ class Node: # The builder didn't have an explicit scanner, so go look up # a scanner from env['SCANNERS'] based on the node's scanner # key (usually the file extension). - scanner = self.get_build_env().get_scanner(node.scanner_key()) + scanner = self.get_scanner(self.get_build_env()) if scanner: scanner = scanner.select(node) return scanner @@ -758,22 +760,7 @@ class Node: def do_not_ignore(self, node): return node not in self.ignore - def _children_get(self): - "__cacheable__" - children = self.all_children(scan=0) - if self.ignore: - children = filter(self.do_not_ignore, children) - return children - - def children(self, scan=1): - """Return a list of the node's direct children, minus those - that are ignored by this node.""" - if scan: - self.scan() - return self._children_get() - - def all_children(self, scan=1): - """Return a list of all the node's direct children.""" + def _all_children_get(self): # The return list may contain duplicate Nodes, especially in # source trees where there are a lot of repeated #includes # of a tangle of .h files. Profiling shows, however, that @@ -791,13 +778,31 @@ class Node: # using dictionary keys, lose the order, and the only ordered # dictionary patterns I found all ended up using "not in" # internally anyway...) - if scan: - self.scan() if self.implicit is None: return self.sources + self.depends else: return self.sources + self.depends + self.implicit + def _children_get(self): + "__cacheable__" + children = self._all_children_get() + if self.ignore: + children = filter(self.do_not_ignore, children) + return children + + def all_children(self, scan=1): + """Return a list of all the node's direct children.""" + if scan: + self.scan() + return self._all_children_get() + + def children(self, scan=1): + """Return a list of the node's direct children, minus those + that are ignored by this node.""" + if scan: + self.scan() + return self._children_get() + def set_state(self, state): self.state = state |