From 8d20f3d469e3d5627ebdc83374f6a3cf66b52458 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 17 Aug 2017 09:33:46 +0200 Subject: [PATCH] Finish refactoring rules. --- parso/normalizer.py | 53 ++++++++++++++++++++++++++++-------------- parso/python/errors.py | 2 +- parso/python/pep8.py | 2 +- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/parso/normalizer.py b/parso/normalizer.py index 86df086..13edffd 100644 --- a/parso/normalizer.py +++ b/parso/normalizer.py @@ -2,11 +2,23 @@ from contextlib import contextmanager class Normalizer(object): + _rule_value_classes = {} + _rule_type_classes = {} + def __init__(self, grammar, config): self._grammar = grammar self._config = config self.issues = [] + self._rule_type_instances = self._instantiate_rules(self._rule_type_classes) + self._rule_value_instances = self._instantiate_rules(self._rule_value_classes) + + def _instantiate_rules(self, rules_map): + dct = {} + for type_, rule_classes in rules_map.items(): + dct[type_] = [rule_cls(self) for rule_cls in rule_classes] + return dct + def walk(self, node): self.initialize(node) value = self.visit(node) @@ -24,9 +36,18 @@ class Normalizer(object): @contextmanager def visit_node(self, node): + for rule in self._rule_type_instances.get(node.type, []): + rule.feed_node(node) + yield def visit_leaf(self, leaf): + for rule in self._rule_type_instances.get(leaf.type, []): + rule.feed_node(leaf) + + for rule in self._rule_value_instances.get(leaf.value, []): + rule.feed_node(leaf) + return leaf.prefix + leaf.value def initialize(self, node): @@ -41,24 +62,12 @@ class Normalizer(object): self.issues.append(issue) return True - -class NormalizerConfig(object): - normalizer_class = Normalizer - rule_value_map = {} - rule_type_map = {} - - def create_normalizer(self, grammar): - if self.normalizer_class is None: - return None - - return self.normalizer_class(grammar, self) - @classmethod def register_rule(cls, **kwargs): """ Use it as a class decorator: - >>> normalizer = NormalizerConfig() + >>> normalizer = Normalizer('grammar', 'config') >>> @normalizer.register_rule(value='foo') ... class MyRule(Rule): ... error_code = 42 @@ -70,16 +79,26 @@ class NormalizerConfig(object): if value is None and type is None: raise ValueError("You must register at least something.") - def decorator(func): + def decorator(rule_cls): if value is not None: - cls.rule_value_map[value] = func + cls._rule_value_classes.setdefault(value, []).append(rule_cls) if type is not None: - cls.rule_type_map[type] = func - return func + cls._rule_type_classes.setdefault(type, []).append(rule_cls) + return rule_cls return decorator +class NormalizerConfig(object): + normalizer_class = Normalizer + + def create_normalizer(self, grammar): + if self.normalizer_class is None: + return None + + return self.normalizer_class(grammar, self) + + class Issue(object): def __init__(self, node, code, message): self._node = node diff --git a/parso/python/errors.py b/parso/python/errors.py index e7f0aa4..ef6dd62 100644 --- a/parso/python/errors.py +++ b/parso/python/errors.py @@ -793,7 +793,7 @@ class IndentationRule(Rule): code = 903 -@ErrorFinderConfig.register_rule(value='await') +@ErrorFinder.register_rule(value='await') class AwaitOutsideAsync(SyntaxRule): message = "'await' outside async function" diff --git a/parso/python/pep8.py b/parso/python/pep8.py index 99e0d27..fafcc0a 100644 --- a/parso/python/pep8.py +++ b/parso/python/pep8.py @@ -712,7 +712,7 @@ class PEP8NormalizerConfig(ErrorFinderConfig): self.spaces_before_comment = spaces_before_comment -@PEP8NormalizerConfig.register_rule(type='endmarker') +@PEP8Normalizer.register_rule(type='endmarker') class BlankLineAtEnd(Rule): code = 392 message = 'Blank line at end of file'