[Checkins] SVN: zope.fixers/trunk/zope/fixers/ Now handles two statements on one class.

Lennart Regebro regebro at gmail.com
Wed Apr 8 02:47:03 EDT 2009


Log message for revision 98997:
  Now handles two statements on one class.
  

Changed:
  U   zope.fixers/trunk/zope/fixers/base.py
  A   zope.fixers/trunk/zope/fixers/fix_class_provides.py
  U   zope.fixers/trunk/zope/fixers/tests.py

-=-
Modified: zope.fixers/trunk/zope/fixers/base.py
===================================================================
--- zope.fixers/trunk/zope/fixers/base.py	2009-04-08 06:46:40 UTC (rev 98996)
+++ zope.fixers/trunk/zope/fixers/base.py	2009-04-08 06:47:02 UTC (rev 98997)
@@ -39,7 +39,9 @@
     """
     
     CLASS_PATTERN = """
-    classdef< 'class' any* ':' suite< any* simple_stmt< power< statement=(%s) trailer < '(' interface=any ')' > any* > any* > any* > >
+    decorated< decorator <any* > classdef< 'class' any* ':' suite< any* simple_stmt< power< statement=(%(match)s) trailer < '(' interface=any ')' > any* > any* > any* > > >
+    |
+    classdef< 'class' any* ':' suite< any* simple_stmt< power< statement=(%(match)s) trailer < '(' interface=any ')' > any* > any* > any* > >
     """
 
     FUNCTION_PATTERN = """
@@ -69,7 +71,7 @@
     
     def _add_pattern(self, match):
             self.class_patterns.append(PatternCompiler().compile_pattern(
-                self.CLASS_PATTERN % match))
+                self.CLASS_PATTERN % {'match': match}))
             self.function_patterns.append(PatternCompiler().compile_pattern(
                 self.FUNCTION_PATTERN % match))
         
@@ -83,11 +85,6 @@
         for pattern in self.class_patterns:
             if pattern.match(node, results):
                 return results
-
-        # And lastly on all actual calls to the function:
-        for pattern in self.function_patterns:
-            if pattern.match(node, results):
-                return results
                 
     def transform(self, node, results):
         if 'name' in results:
@@ -131,7 +128,6 @@
                 
             # Take the current class constructor prefix, and stick it into
             # the decorator, to set the decorators indentation.
-            #import pdb;pdb.set_trace()
             nodeprefix = node.get_prefix()
             decorator.set_prefix(nodeprefix)
             # Preserve only the indent:
@@ -153,18 +149,16 @@
             if not prefix or prefix[0] != '\n':
                 prefix = '\n' + prefix
             node.set_prefix(prefix)
-            node.insert_child(0, decorator)
-            
-        if 'old_statement' in results:
-            # This matched an function statement. We'll remove it.
-            self.fixups.append(node)
-    
-    def finish_tree(self, tree, filename):
-        for node in self.fixups:
-            parent = node.parent
-            node.remove()
-            if not str(parent).strip():
-                # This is an empty class. Stick in a pass
-                parent.insert_child(2, Leaf(0, 'pass'))
-                parent.insert_child(3, Leaf(0, '\n'))
-                
\ No newline at end of file
+            new_node = Node(syms.decorated, [decorator, node.clone()])
+            # Look for the actual function calls in the new node and remove it.
+            for node in new_node.post_order():
+                for pattern in self.function_patterns:
+                    if pattern.match(node, results):
+                        parent = node.parent
+                        node.remove()
+                        if not str(parent).strip():
+                            # This is an empty class. Stick in a pass
+                            parent.insert_child(2, Leaf(0, 'pass'))
+                            parent.insert_child(3, Leaf(0, '\n'))
+            return new_node
+                    
\ No newline at end of file

Added: zope.fixers/trunk/zope/fixers/fix_class_provides.py
===================================================================
--- zope.fixers/trunk/zope/fixers/fix_class_provides.py	                        (rev 0)
+++ zope.fixers/trunk/zope/fixers/fix_class_provides.py	2009-04-08 06:47:02 UTC (rev 98997)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Fixer for implements(IX) -> @implementer(IX).
+
+$Id$
+"""
+
+from .base import Function2DecoratorBase
+
+class FixClassProvides(Function2DecoratorBase):
+    FUNCTION_NAME = 'classProvides'
+    DECORATOR_NAME = 'provider'

Modified: zope.fixers/trunk/zope/fixers/tests.py
===================================================================
--- zope.fixers/trunk/zope/fixers/tests.py	2009-04-08 06:46:40 UTC (rev 98996)
+++ zope.fixers/trunk/zope/fixers/tests.py	2009-04-08 06:47:02 UTC (rev 98997)
@@ -287,11 +287,8 @@
 
 class FixerTest(unittest.TestCase):
     
-    def setUp(self):
-        self.tool = RefactoringTool(['zope.fixers.fix_implements'])
-    
     def _test(self, source, target):
-        refactored = str(self.tool.refactor_string(source, 'zope.fixer.test'))
+        refactored = str(self.refactor(source, 'zope.fixer.test'))
         if refactored != target:
             match = ''
             for i in range(min(len(refactored), len(target))):
@@ -311,8 +308,8 @@
 class ImplementsFixerTest(FixerTest):
     
     def setUp(self):
-        self.tool = RefactoringTool(['zope.fixers.fix_implements'])
-        
+        self.refactor = RefactoringTool(['zope.fixers.fix_implements']).refactor_string
+            
     def test_imports(self):
         self._test(imports_source, imports_target)
 
@@ -370,11 +367,12 @@
 class ImplementsOnlyFixerTest(FixerTest):
     
     def setUp(self):
-        self.tool = RefactoringTool(['zope.fixers.fix_implements_only'])
+        self.refactor = RefactoringTool(['zope.fixers.fix_implements_only']).refactor_string
+    
 
-    #def test_implements_only(self):
-        #self._test(implements_only_source, implements_only_target)
-
+    def test_implements_only(self):
+        self._test(implements_only_source, implements_only_target)
+        
 doctest_source = """
     >>> class A(object):
     ...     implements(I1)
@@ -393,28 +391,34 @@
     ...     pass
 """
 
-class DoctestFixerTest(unittest.TestCase):
-        
-    def _test(self, source, target):
-        refactored = str(self.tool.refactor_docstring(source, 'zope.fixer.test'))
-        if refactored != target:
-            match = ''
-            for i in range(min(len(refactored), len(target))):
-                if refactored[i] == target[i]:
-                    match += refactored[i]
-                else:
-                    break
-            msg = "\nResult:\n" + refactored
-            msg += "\nFailed:\n" + refactored[i:]
-            msg += "\nTarget:\n" + target[i:]
-            # Make spaces and tabs visible:
-            msg = msg.replace(' ', '°')
-            msg = msg.replace('\t', '------->')
-            msg = ("Test failed at character %i" % i) + msg
-            self.fail(msg)
-            
+class DoctestFixerTest(FixerTest):
+                    
     def setUp(self):
-        self.tool = RefactoringTool(['zope.fixers.fix_implements'])
+        self.refactor = RefactoringTool(['zope.fixers.fix_implements']).refactor_docstring
         
     def test_doctest(self):
         self._test(doctest_source, doctest_target)
+
+dual_fixes_source = """
+      >>> class C(object):
+      ...     implements(IFoo)
+      ...     classProvides(IFooFactory)      
+"""
+
+dual_fixes_target = """
+      >>> @provider(IFooFactory)
+      ... @implementer(IFoo)
+      ... class C(object):
+      ...     pass
+"""
+
+class DualFixersTest(FixerTest):
+    
+    def setUp(self):
+        self.refactor = RefactoringTool(['zope.fixers.fix_implements',
+                                         'zope.fixers.fix_class_provides']
+                                        ).refactor_docstring
+        
+    def test_dualfixers(self):
+        self._test(dual_fixes_source, dual_fixes_target)
+    
\ No newline at end of file



More information about the Checkins mailing list