diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-05-02 21:30:20 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-05-02 21:30:20 (GMT) |
commit | 6780a9dd9f8e8c79b9215e1f6e98cb5f711561bc (patch) | |
tree | e1d320fd4ae292157e4dae8a73805c2d31806d1e /Lib/lib2to3 | |
parent | 85f19709f9d538db7567543006ad3740e30597f6 (diff) | |
download | cpython-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-x | Lib/lib2to3/refactor.py | 51 | ||||
-rwxr-xr-x | Lib/lib2to3/tests/test_fixers.py | 6 |
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): |