-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathprepare.py
47 lines (39 loc) · 1.72 KB
/
prepare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from typing import Any, Dict, Sequence
from fluent.syntax import ast as FTL
from . import resolver
class Compiler:
def __call__(self, item: Any) -> Any:
if isinstance(item, FTL.BaseNode):
return self.compile(item)
if isinstance(item, (tuple, list)):
return [self(elem) for elem in item]
return item
def compile(self, node: Any) -> Any:
nodename: str = type(node).__name__
if not hasattr(resolver, nodename):
return node
kwargs: Dict[str, Any] = vars(node).copy()
for propname, propvalue in kwargs.items():
kwargs[propname] = self(propvalue)
handler = getattr(self, 'compile_' + nodename, self.compile_generic)
return handler(nodename, **kwargs)
def compile_generic(self, nodename: str, **kwargs: Any) -> Any:
return getattr(resolver, nodename)(**kwargs)
def compile_Placeable(self, _: Any, expression: Any, **kwargs: Any) -> Any:
if isinstance(expression, resolver.Literal):
return expression
return resolver.Placeable(expression=expression, **kwargs)
def compile_Pattern(self, _: Any, elements: Sequence[Any], **kwargs: Any) -> Any:
if len(elements) == 1 and isinstance(elements[0], resolver.Placeable):
# Don't isolate isolated placeables
return resolver.NeverIsolatingPlaceable(elements[0].expression)
if any(
not isinstance(child, resolver.Literal)
for child in elements
):
return resolver.Pattern(elements=elements, **kwargs)
if len(elements) == 1:
return elements[0]
return resolver.TextElement(
''.join(child(None) for child in elements)
)