Refactor current() calculation so the Taskmaster passes the Sig calculator to the...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 21 Jul 2002 07:15:23 +0000 (07:15 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 21 Jul 2002 07:15:23 +0000 (07:15 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@420 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Node/Alias.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/Sig/SigTests.py
src/engine/SCons/Sig/__init__.py
src/engine/SCons/Taskmaster.py
src/engine/SCons/TaskmasterTests.py

index c6159da96980063e5545c94d7dc15cced22b281f..276750f2ca3c7ccbdb630b397faadaf325dd75e3 100644 (file)
@@ -65,15 +65,17 @@ class Alias(SCons.Node.Node):
 
     def set_bsig(self, bsig):
         """An alias has no signature."""
-        pass
+        self.bsig = None
 
     def set_csig(self, csig):
         """An alias has no signature."""
-        pass
+        self.csig = None
 
-    def current(self):
+    def current(self, calc):
         """If all of our children were up-to-date, then this
         Alias was up-to-date, too."""
+        # Allow the children to calculate their signatures.
+        calc.bsig(self)
         state = 0
         for kid in self.children(None):
             s = kid.get_state()
@@ -89,10 +91,10 @@ class Alias(SCons.Node.Node):
         pass
 
     def is_under(self, dir):
-       # Make Alias nodes get built regardless of 
-       # what directory scons was run from. Alias nodes
-       # are outside the filesystem:
-       return 1
+        # Make Alias nodes get built regardless of 
+        # what directory scons was run from. Alias nodes
+        # are outside the filesystem:
+        return 1
         
 default_ans = AliasNameSpace()
 
index 9a75f34c01f187a934b7fbb728ef1e1e6958e788..0837ed3dd7404abbd5c077ff8b2f918dabeb8716 100644 (file)
@@ -381,7 +381,6 @@ class Entry(SCons.Node.Node):
         self.path_ = self.path
         self.abspath_ = self.abspath
         self.dir = directory
-        self.use_signature = 1
         self.__doSrcpath(self.duplicate)
         self.srcpath_ = self.srcpath
         self.cwd = None # will hold the SConscript directory for target nodes
@@ -438,14 +437,15 @@ class Entry(SCons.Node.Node):
             parents.append(self.dir)
         return parents
 
-    def current(self):
+    def current(self, calc):
         """If the underlying path doesn't exist, we know the node is
         not current without even checking the signature, so return 0.
         Otherwise, return None to indicate that signature calculation
         should proceed as normal to find out if the node is current."""
+        bsig = calc.bsig(self)
         if not self.exists():
             return 0
-        return None
+        return calc.current(self, bsig)
 
     def is_under(self, dir):
         if self is dir:
@@ -489,7 +489,6 @@ class Dir(Entry):
         self.entries = {}
         self.entries['.'] = self
         self.entries['..'] = self.dir
-        self.use_signature = None
         self.builder = 1
         self._sconsign = None
 
@@ -536,19 +535,23 @@ class Dir(Entry):
         """A null "builder" for directories."""
         pass
 
+    def calc_signature(self, calc):
+        """A directory has no signature."""
+        return None
+
     def set_bsig(self, bsig):
         """A directory has no signature."""
-        pass
+        bsig = None
 
     def set_csig(self, csig):
         """A directory has no signature."""
-        pass
+        csig = None
 
     def get_contents(self):
         """Return a fixed "contents" value of a directory."""
         return ''
 
-    def current(self):
+    def current(self, calc):
         """If all of our children were up-to-date, then this
         directory was up-to-date, too."""
         state = 0
@@ -706,10 +709,10 @@ class File(Entry):
         if not hasattr(self, '_rfile'):
             self._rfile = self
             if not os.path.isabs(self.path) and not os.path.isfile(self.path):
-               def file_node(path, fs = self.fs):
-                   if os.path.isfile(path):
-                       return fs.File(path)
-                   return None
+                def file_node(path, fs = self.fs):
+                    if os.path.isfile(path):
+                        return fs.File(path)
+                    return None
                 n = self.fs.Rsearch(self.path, file_node)
                 if n:
                     self._rfile = n
index 2a5e5bc684db1ab714abb3128c821798392bc35b..45f5bc7994f053eeadf2c7f397ea82d1da74a651 100644 (file)
@@ -84,9 +84,6 @@ class Node:
         self.target_scanner = None      # explicit scanner from this node's Builder
         self.env = None
         self.state = None
-        self.bsig = None
-        self.csig = None
-        self.use_signature = 1
         self.precious = None
         self.found_includes = {}
         self.includes = None
@@ -151,13 +148,13 @@ class Node:
             def get_parents(node, parent): return node.get_parents()
             def clear_cache(node, parent):
                 node.implicit = None
-                node.bsig = None
+                node.del_bsig()
             w = Walker(self, get_parents, ignore_cycle, clear_cache)
             while w.next(): pass
 
         # clear out the content signature, since the contents of this
         # node were presumably just changed:
-        self.csig = None
+        self.del_csig()
 
     def depends_on(self, nodes):
         """Does this node depend on any of 'nodes'?"""
@@ -217,7 +214,7 @@ class Node:
                     # we need to recalculate the implicit deps,
                     # and the bsig:
                     self.implicit = []
-                    self.bsig = None
+                    self.del_bsig()
 
         for child in self.children(scan=0):
             self._add_child(self.implicit,
@@ -242,9 +239,39 @@ class Node:
             return
         self.env = env
 
+    def calc_signature(self, calc):
+        """
+        Select and calculate the appropriate build signature for a node.
+
+        self - the node
+        calc - the signature calculation module
+        returns - the signature
+
+        This method does not store the signature in the node or
+        in the .sconsign file.
+        """
+
+        if self.builder:
+            if SCons.Sig.build_signature:
+                if not hasattr(self, 'bsig'):
+                    self.set_bsig(calc.bsig(self))
+                return self.get_bsig()
+            else:
+                if not hasattr(self, 'csig'):
+                    self.set_csig(calc.csig(self))
+                return self.get_csig()
+        elif not self.exists():
+            return None
+        else:
+            if not hasattr(self, 'csig'):
+                self.set_csig(calc.csig(self))
+            return self.get_csig()
+
     def get_bsig(self):
         """Get the node's build signature (based on the signatures
         of its dependency files and build information)."""
+        if not hasattr(self, 'bsig'):
+            return None
         return self.bsig
 
     def set_bsig(self, bsig):
@@ -257,8 +284,15 @@ class Node:
         .sconsign file or equivalent)."""
         pass
 
+    def del_bsig(self):
+        """Delete the bsig from this node."""
+        if hasattr(self, 'bsig'):
+            delattr(self, 'bsig')
+
     def get_csig(self):
         """Get the signature of the node's content."""
+        if not hasattr(self, 'csig'):
+            return None
         return self.csig
 
     def set_csig(self, csig):
@@ -270,6 +304,11 @@ class Node:
         .sconsign file or equivalent)."""
         pass
 
+    def del_csig(self):
+        """Delete the csig from this node."""
+        if hasattr(self, 'csig'):
+            delattr(self, 'csig')
+
     def get_prevsiginfo(self):
         """Fetch the previous signature information from the
         .sconsign entry."""
index 548b2e4df28ed12eb4d86bed637ff39c372f66c9..8c9125a94e5e73caeee55a66d137ac6ad906f9ba 100644 (file)
@@ -93,6 +93,12 @@ class DummyNode:
             return 0
         return None
 
+    def calc_signature(self, calc):
+        if self.builder:
+            return calc.bsig(self)
+        else:
+            return calc.csig(self)
+
     def set_bsig(self, bsig):
         self.bsig = bsig
 
@@ -170,8 +176,7 @@ def create_nodes(files):
     return nodes
 
 def current(calc, node):
-    s = calc.get_signature(node)
-    return calc.current(node, s)
+    return calc.current(node, node.calc_signature(calc))
 
 def write(calc, nodes):
     for node in nodes:
@@ -196,8 +201,6 @@ class SigTestBase:
         self.test_built()
         self.test_modify()
         self.test_modify_same_time()
-        self.test_delete()
-        self.test_cache()
 
     def test_initial(self):
 
@@ -274,42 +277,6 @@ class SigTestBase:
             self.failUnless(current(calc, node),
                             "all of the nodes should be current")
 
-    def test_delete(self):
-
-        nodes = create_nodes(self.files)
-
-        calc = SCons.Sig.Calculator(self.module)
-
-        write(calc, nodes)
-
-        #simulate the deletion of some files
-        self.files[1].modify(None, 0)
-        self.files[7].modify(None, 0)
-        self.files[9].modify(None, 0)
-
-        self.failUnless(current(calc, nodes[0]))
-        self.failUnless(not current(calc, nodes[1]), "deleted")
-        self.failUnless(current(calc, nodes[2]))
-        self.failUnless(current(calc, nodes[3]))
-        self.failUnless(current(calc, nodes[4]))
-        self.failUnless(current(calc, nodes[5]))
-        self.failUnless(current(calc, nodes[6]))
-        self.failUnless(not current(calc, nodes[7]), "deleted")
-        self.failUnless(current(calc, nodes[8]))
-        self.failUnless(not current(calc, nodes[9]), "deleted")
-        self.failUnless(current(calc, nodes[10]),
-                        "current even though its source was deleted")
-
-    def test_cache(self):
-        """Test that signatures are cached properly."""
-        nodes = create_nodes(self.files)
-
-        calc = SCons.Sig.Calculator(self.module)
-        nodes[0].set_csig(1)
-        nodes[1].set_bsig(1)
-        assert calc.csig(nodes[0]) == 1, calc.csig(nodes[0])
-        assert calc.bsig(nodes[1]) == 1, calc.bsig(nodes[1])
-
 
 class MD5TestCase(unittest.TestCase, SigTestBase):
     """Test MD5 signatures"""
@@ -353,10 +320,14 @@ class CalcTestCase(unittest.TestCase):
                 return self.bsig
             def set_bsig(self, bsig):
                 self.bsig = bsig
-            def store_sigs(self):
-                pass
             def get_csig(self):
                 return self.csig
+            def set_csig(self, csig):
+                self.csig = csig
+            def store_csig(self):
+                pass
+            def store_timestamp(self):
+                pass
             def get_prevsiginfo(self):
                 return 0, self.bsig, self.csig
             def get_stored_implicit(self):
@@ -375,7 +346,6 @@ class CalcTestCase(unittest.TestCase):
         self.nodeclass = MyNode
         self.test_Calc___init__()
         self.test_Calc_bsig()
-        self.test_Calc_get_signature()
         self.test_Calc_current()
 
     def test_Calc___init__(self):
@@ -400,58 +370,11 @@ class CalcTestCase(unittest.TestCase):
 
         assert self.calc.csig(n) == 12
 
-    def test_Calc_get_signature(self):
-        class NE(self.nodeclass):
-            def exists(self):
-                return 0
-            def cached_exists(self):
-                return 0
-            def has_signature(self):
-                return None
-        class NN(self.nodeclass):
-            def exists(self):
-                return 1
-            def has_signature(self):
-                return None
-
-        n1 = self.nodeclass('n1', 11, 12)
-        n1.use_signature = 0
-        assert self.calc.get_signature(n1) is None
-
-        n2 = self.nodeclass('n2', 22, 23)
-        assert self.calc.get_signature(n2) == 23
-
-        n3 = self.nodeclass('n3', 33, 34)
-        n4 = self.nodeclass('n4', None, None)
-        n4.builder = 1
-        n4.kids = [n2, n3]
-        assert self.calc.get_signature(n4) == 390
-
-        n5 = NE('n5', 55, 56)
-        assert self.calc.get_signature(n5) is None
-
-        n6 = NN('n6', 66, 67)
-        assert self.calc.get_signature(n6) == 67
-
     def test_Calc_current(self):
-        class N0(self.nodeclass):
-            def current(self):
-                return 0
-        class N1(self.nodeclass):
-            def current(self):
-                return 1
         class NN(self.nodeclass):
             def current(self):
                 return None
 
-        n0 = N0('n0', 11, 12)
-        assert not self.calc.current(n0, 10)
-        assert not self.calc.current(n0, 11)
-
-        n1 = N1('n1', 22, 23)
-        assert self.calc.current(n1, 20)
-        assert self.calc.current(n1, 22)
-
         nn = NN('nn', 33, 34)
         assert not self.calc.current(nn, 30)
         assert self.calc.current(nn, 33)
index 0e629fb40d8269daef3949ccff2c5ecde31c1f95..7739aad7685028f0c27987643551739bf0725d19 100644 (file)
@@ -301,14 +301,7 @@ class Calculator:
         already built and updated by someone else, if that's
         what's wanted.
         """
-        if not node.use_signature:
-            return None
-
-        bsig = node.get_bsig()
-        if not bsig is None:
-            return bsig
-
-        sigs = map(self.get_signature, node.children())
+        sigs = map(lambda n, c=self: n.calc_signature(c), node.children())
         if node.builder:
             sigs.append(self.module.signature(node.builder_sig_adapter()))
 
@@ -329,13 +322,6 @@ class Calculator:
         node - the node
         returns - the content signature
         """
-        if not node.use_signature:
-            return None
-
-        csig = node.get_csig()
-        if not csig is None:
-            return csig
-
         if self.max_drift >= 0:
             info = node.get_prevsiginfo()
         else:
@@ -361,32 +347,6 @@ class Calculator:
 
         return csig
 
-    def get_signature(self, node):
-        """
-        Get the appropriate build signature for a node.
-
-        node - the node
-        returns - the signature or None if the signature could not
-        be computed.
-
-        This method does not store the signature in the node or
-        in the .sconsign file.
-        """
-
-        if not node.use_signature:
-            # This node type doesn't use a signature (e.g. a
-            # directory) so bail right away.
-            return None
-        elif node.builder:
-            if build_signature:
-                return self.bsig(node)
-            else:
-                return self.csig(node)
-        elif not node.exists():
-            return None
-        else:
-            return self.csig(node)
-
     def current(self, node, newsig):
         """
         Check if a signature is up to date with respect to a node.
@@ -397,15 +357,6 @@ class Calculator:
         returns - 1 if the file is current with the specified signature,
         0 if it isn't
         """
-
-        c = node.current()
-        if not c is None:
-            # The node itself has told us whether or not it's
-            # current without checking the signature.  The
-            # canonical uses here are a "0" return for a file
-            # that doesn't exist, or a directory.
-            return c
-
         oldtime, oldbsig, oldcsig = node.get_prevsiginfo()
 
         if not node.builder and node.get_timestamp() == oldtime:
index 3e4dbbc5a5ddd339cf0ccbec0de09c50d5c2d3e6..799582bd3759e37f1db2ddcfc15a6d1cd37ddaf7 100644 (file)
@@ -121,8 +121,7 @@ class Task:
         """Make a task ready for execution."""
         state = SCons.Node.up_to_date
         for t in self.targets:
-            bsig = self.tm.calc.bsig(t)
-            if not self.tm.calc.current(t, bsig):
+            if not t.current(self.tm.calc):
                 state = SCons.Node.executing
         for t in self.targets:
             if state == SCons.Node.executing:
index a4a2f479c95af2173a30732f8255b426a963a37e..f3bf1822e7089b85906efc3537f64d3ffaba687c 100644 (file)
@@ -100,7 +100,9 @@ class Node:
 
     def store_bsig(self):
         pass
-  
+
+    def current(self, calc):
+        return calc.current(self, calc.bsig(self))
     
     def depends_on(self, nodes):
         for node in nodes: