]>
crepu.dev Git - config.git/blob - djavu-asus/emacs/elpy/rpc-venv/lib/python3.11/site-packages/parso/normalizer.py
a95f029eb80c9acd937bdb39342c2ba19709e9a5
1 from contextlib
import contextmanager
2 from typing
import Dict
, List
5 class _NormalizerMeta(type):
6 def __new__(cls
, name
, bases
, dct
):
7 new_cls
= type.__new
__(cls
, name
, bases
, dct
)
8 new_cls
.rule_value_classes
= {}
9 new_cls
.rule_type_classes
= {}
13 class Normalizer(metaclass
=_NormalizerMeta
):
14 _rule_type_instances
: Dict
[str, List
[type]] = {}
15 _rule_value_instances
: Dict
[str, List
[type]] = {}
17 def __init__(self
, grammar
, config
):
18 self
.grammar
= grammar
22 self
._rule
_type
_instances
= self
._instantiate
_rules
('rule_type_classes')
23 self
._rule
_value
_instances
= self
._instantiate
_rules
('rule_value_classes')
25 def _instantiate_rules(self
, attr
):
27 for base
in type(self
).mro():
28 rules_map
= getattr(base
, attr
, {})
29 for type_
, rule_classes
in rules_map
.items():
30 new
= [rule_cls(self
) for rule_cls
in rule_classes
]
31 dct
.setdefault(type_
, []).extend(new
)
36 value
= self
.visit(node
)
40 def visit(self
, node
):
42 children
= node
.children
43 except AttributeError:
44 return self
.visit_leaf(node
)
46 with self
.visit_node(node
):
47 return ''.join(self
.visit(child
) for child
in children
)
50 def visit_node(self
, node
):
51 self
._check
_type
_rules
(node
)
54 def _check_type_rules(self
, node
):
55 for rule
in self
._rule
_type
_instances
.get(node
.type, []):
58 def visit_leaf(self
, leaf
):
59 self
._check
_type
_rules
(leaf
)
61 for rule
in self
._rule
_value
_instances
.get(leaf
.value
, []):
64 return leaf
.prefix
+ leaf
.value
66 def initialize(self
, node
):
72 def add_issue(self
, node
, code
, message
):
73 issue
= Issue(node
, code
, message
)
74 if issue
not in self
.issues
:
75 self
.issues
.append(issue
)
79 def register_rule(cls
, *, value
=None, values
=(), type=None, types
=()):
81 Use it as a class decorator::
83 normalizer = Normalizer('grammar', 'config')
84 @normalizer.register_rule(value='foo')
95 if not values
and not types
:
96 raise ValueError("You must register at least something.")
98 def decorator(rule_cls
):
100 cls
.rule_value_classes
.setdefault(v
, []).append(rule_cls
)
102 cls
.rule_type_classes
.setdefault(t
, []).append(rule_cls
)
108 class NormalizerConfig
:
109 normalizer_class
= Normalizer
111 def create_normalizer(self
, grammar
):
112 if self
.normalizer_class
is None:
115 return self
.normalizer_class(grammar
, self
)
119 def __init__(self
, node
, code
, message
):
122 An integer code that stands for the type of error.
124 self
.message
= message
126 A message (string) for the issue.
128 self
.start_pos
= node
.start_pos
130 The start position position of the error as a tuple (line, column). As
131 always in |parso| the first line is 1 and the first column 0.
133 self
.end_pos
= node
.end_pos
135 def __eq__(self
, other
):
136 return self
.start_pos
== other
.start_pos
and self
.code
== other
.code
138 def __ne__(self
, other
):
139 return not self
.__eq
__(other
)
142 return hash((self
.code
, self
.start_pos
))
145 return '<%s: %s>' % (self
.__class
__.__name
__, self
.code
)
152 def __init__(self
, normalizer
):
153 self
._normalizer
= normalizer
155 def is_issue(self
, node
):
156 raise NotImplementedError()
158 def get_node(self
, node
):
161 def _get_message(self
, message
, node
):
163 message
= self
.message
165 raise ValueError("The message on the class is not set.")
168 def add_issue(self
, node
, code
=None, message
=None):
172 raise ValueError("The error code on the class is not set.")
174 message
= self
._get
_message
(message
, node
)
176 self
._normalizer
.add_issue(node
, code
, message
)
178 def feed_node(self
, node
):
179 if self
.is_issue(node
):
180 issue_node
= self
.get_node(node
)
181 self
.add_issue(issue_node
)
184 class RefactoringNormalizer(Normalizer
):
185 def __init__(self
, node_to_str_map
):
186 self
._node
_to
_str
_map
= node_to_str_map
188 def visit(self
, node
):
190 return self
._node
_to
_str
_map
[node
]
192 return super().visit(node
)
194 def visit_leaf(self
, leaf
):
196 return self
._node
_to
_str
_map
[leaf
]
198 return super().visit_leaf(leaf
)