summaryrefslogtreecommitdiffstats
path: root/Lib/lib2to3
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2008-05-02 21:30:20 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2008-05-02 21:30:20 (GMT)
commit6780a9dd9f8e8c79b9215e1f6e98cb5f711561bc (patch)
treee1d320fd4ae292157e4dae8a73805c2d31806d1e /Lib/lib2to3
parent85f19709f9d538db7567543006ad3740e30597f6 (diff)
downloadcpython-6780a9dd9f8e8c79b9215e1f6e98cb5f711561bc.zip
cpython-6780a9dd9f8e8c79b9215e1f6e98cb5f711561bc.tar.gz
cpython-6780a9dd9f8e8c79b9215e1f6e98cb5f711561bc.tar.bz2
Merged revisions 62263-62646 via svnmerge from
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r62470 | david.wolever | 2008-04-24 02:11:07 +0200 (Do, 24 Apr 2008) | 3 lines Fixed up and applied the patch for #2431 -- speeding up 2to3 with a lookup table. ........ r62646 | martin.v.loewis | 2008-05-02 23:29:27 +0200 (Fr, 02 Mai 2008) | 2 lines Fix whitespace. ........
Diffstat (limited to 'Lib/lib2to3')
-rwxr-xr-xLib/lib2to3/refactor.py51
-rwxr-xr-xLib/lib2to3/tests/test_fixers.py6
2 files changed, 53 insertions, 4 deletions
diff --git a/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py
index 74a4053..6057caf 100755
--- a/Lib/lib2to3/refactor.py
+++ b/Lib/lib2to3/refactor.py
@@ -18,6 +18,8 @@ import sys
import difflib
import optparse
import logging
+from collections import defaultdict
+from itertools import chain
# Local imports
from .pgen2 import driver
@@ -96,6 +98,43 @@ def get_all_fix_names():
fix_names.sort()
return fix_names
+def get_head_types(pat):
+ """ Accepts a pytree Pattern Node and returns a set
+ of the pattern types which will match first. """
+
+ if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)):
+ # NodePatters must either have no type and no content
+ # or a type and content -- so they don't get any farther
+ # Always return leafs
+ return set([pat.type])
+
+ if isinstance(pat, pytree.NegatedPattern):
+ if pat.content:
+ return get_head_types(pat.content)
+ return set([None]) # Negated Patterns don't have a type
+
+ if isinstance(pat, pytree.WildcardPattern):
+ # Recurse on each node in content
+ r = set()
+ for p in pat.content:
+ for x in p:
+ r.update(get_head_types(x))
+ return r
+
+ raise Exception("Oh no! I don't understand pattern %s" %(pat))
+
+def get_headnode_dict(fixer_list):
+ """ Accepts a list of fixers and returns a dictionary
+ of head node type --> fixer list. """
+ head_nodes = defaultdict(list)
+ for fixer in fixer_list:
+ if not fixer.pattern:
+ head_nodes[None].append(fixer)
+ continue
+ for t in get_head_types(fixer.pattern):
+ head_nodes[t].append(fixer)
+ return head_nodes
+
class RefactoringTool(object):
@@ -114,6 +153,10 @@ class RefactoringTool(object):
convert=pytree.convert,
logger=self.logger)
self.pre_order, self.post_order = self.get_fixers()
+
+ self.pre_order = get_headnode_dict(self.pre_order)
+ self.post_order = get_headnode_dict(self.post_order)
+
self.files = [] # List of files that were or should be modified
def get_fixers(self):
@@ -286,7 +329,11 @@ class RefactoringTool(object):
Returns:
True if the tree was modified, False otherwise.
"""
- all_fixers = self.pre_order + self.post_order
+ # Two calls to chain are required because pre_order.values()
+ # will be a list of lists of fixers:
+ # [[<fixer ...>, <fixer ...>], [<fixer ...>]]
+ all_fixers = chain(chain(*self.pre_order.values()),\
+ chain(*self.post_order.values()))
for fixer in all_fixers:
fixer.start_tree(tree, name)
@@ -312,7 +359,7 @@ class RefactoringTool(object):
if not fixers:
return
for node in traversal:
- for fixer in fixers:
+ for fixer in fixers[node.type] + fixers[None]:
results = fixer.match(node)
if results:
new = fixer.transform(node, results)
diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/lib2to3/tests/test_fixers.py
index 20d6008..890ce22 100755
--- a/Lib/lib2to3/tests/test_fixers.py
+++ b/Lib/lib2to3/tests/test_fixers.py
@@ -33,8 +33,10 @@ class FixerTestCase(support.TestCase):
self.fixer_log = []
self.filename = "<string>"
- for order in (self.refactor.pre_order, self.refactor.post_order):
- for fixer in order:
+ from itertools import chain
+ for order in (self.refactor.pre_order.values(),\
+ self.refactor.post_order.values()):
+ for fixer in chain(*order):
fixer.log = self.fixer_log
def _check(self, before, after):