[Checkins] SVN: Sandbox/malthe/chameleon.core/ Correctly transfer fill-slot variable scope.

Malthe Borch mborch at gmail.com
Sat Nov 15 15:25:51 EST 2008


Log message for revision 92988:
  Correctly transfer fill-slot variable scope.

Changed:
  U   Sandbox/malthe/chameleon.core/CHANGES.txt
  U   Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py
  U   Sandbox/malthe/chameleon.core/src/chameleon/core/translation.py

-=-
Modified: Sandbox/malthe/chameleon.core/CHANGES.txt
===================================================================
--- Sandbox/malthe/chameleon.core/CHANGES.txt	2008-11-15 20:23:32 UTC (rev 92987)
+++ Sandbox/malthe/chameleon.core/CHANGES.txt	2008-11-15 20:25:51 UTC (rev 92988)
@@ -4,6 +4,11 @@
 HEAD
 ~~~~
 
+- Correctly transfer scope to callback-function that will fill macro
+  slot contents. Previously, we would precompute fill-slots, but this
+  was wrong since it's expected to inherit the scope of the macro
+  currently in use. [malthe]
+
 - Made error handler compatible with Python 2.4 [malthe]
 
 - Maintain symbol mappings for joined expressions. [malthe]

Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py	2008-11-15 20:23:32 UTC (rev 92987)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py	2008-11-15 20:25:51 UTC (rev 92988)
@@ -67,6 +67,10 @@
             parts = types.parts((parts,))
 
         self.parts = parts
+
+        if isinstance(variable, tuple):
+            variable = ", ".join(variable)
+            
         self.variable = variable
         
     def begin(self, stream, variable=None):
@@ -924,6 +928,19 @@
         if self.defer:
             stream.out(self.string)
 
+class UpdateScope(object):
+    """Updates variable scope."""
+    
+    def __init__(self, scope, remote):
+        self.scope = scope
+        self.remote = remote
+
+    def begin(self, stream):
+        stream.write("%s.update(%s)" % (self.scope, self.remote))
+
+    def end(self, stream):
+        pass
+
 class Method(object):
     """
     >>> from chameleon.core import testing
@@ -940,18 +957,29 @@
       
     """
 
-    def __init__(self, name, args):
+    ret = None
+    
+    def __init__(self, name, args, ret=None):
         self.name = name
         self.args = args
 
+        if ret is not None:
+            self.ret = Assign(ret, '_ret')
+
     def begin(self, stream):
         stream.write('def %s(%s):' % (self.name, ", ".join(self.args)))
         stream.indent()
 
     def end(self, stream):
+        if self.ret is not None:
+            self.ret.begin(stream)
+            stream.write('return _ret')
+            self.ret.end(stream)
+        
         stream.outdent()
         assign = Assign(
             types.value(self.name), "%s['%s']" % \
             (stream.symbols.scope, self.name))
         assign.begin(stream)
         assign.end(stream)
+        

Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/translation.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/translation.py	2008-11-15 20:23:32 UTC (rev 92987)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/translation.py	2008-11-15 20:25:51 UTC (rev 92988)
@@ -120,11 +120,8 @@
         # variable definitions
         if self.define is not None:
             for declaration, expression in self.define:
-                if declaration.global_scope:
-                    _.append(clauses.Define(
-                        declaration, expression, self.symbols.scope))
-                else:
-                    _.append(clauses.Define(declaration, expression))
+                _.append(clauses.Define(
+                    declaration, expression, self.symbols.scope))
 
         # tag tail (deferred)
         tail = self.tail
@@ -168,9 +165,17 @@
         # macro slot definition
         if self.define_slot:
             # check if slot has been filled
-            variable = self.symbols.slot + self.define_slot
-            if variable in itertools.chain(*self.stream.scope):
-                content = types.value(variable)
+            name = self.symbols.slot + self.define_slot
+            if name in itertools.chain(*self.stream.scope):
+                _.append(clauses.Condition(
+                    types.value('not isinstance(%s, basestring)' % name),
+                    (clauses.Assign(
+                    types.value('%s(%s)' % (
+                    name, self.symbols.scope)),
+                    name),),
+                    finalize=True))
+                     
+                content = types.value(name)
 
         # set dynamic content flag
         dynamic = content or self.translate is not None
@@ -321,16 +326,24 @@
                     # (chrism)
                     continue
 
-                variable = self.symbols.slot+element.node.fill_slot
-                kwargs.append((variable, variable))
+                callback = self.symbols.slot+element.node.fill_slot
+                remote_scope = self.symbols.scope+"_remote"
+                kwargs.append((callback, callback))
                 
                 subclauses = []
-                subclauses.append(clauses.Define(
-                    types.declaration((self.symbols.out, self.symbols.write)),
-                    types.template('%(init)s.initialize_stream()')))
+                subclauses.append(
+                    clauses.Method(callback, (
+                    remote_scope,), types.value(
+                    '%s.getvalue()' % self.symbols.out)))
+                subclauses.append(
+                    clauses.UpdateScope(self.symbols.scope, remote_scope))
+                subclauses.append(clauses.Assign(
+                    types.template('%(init)s.initialize_stream()'),
+                    (self.symbols.out, self.symbols.write)))
                 subclauses.append(clauses.Visit(element.node))
-                subclauses.append(clauses.Assign(
-                    types.template('%(out)s.getvalue()'), variable))
+                
+                #subclauses.append(clauses.Assign(
+                #    types.template('%(out)s.getvalue()'), variable))
                 _.append(clauses.Group(subclauses))
 
             _.append(clauses.Assign(self.use_macro, self.symbols.metal))



More information about the Checkins mailing list