Skip to content

Commit c9a38fe

Browse files
reorganize code
1 parent e05f845 commit c9a38fe

File tree

12 files changed

+654
-597
lines changed

12 files changed

+654
-597
lines changed

hcl2/rule_transformer.py

Lines changed: 0 additions & 101 deletions
This file was deleted.

hcl2/rule_transformer/__init__.py

Whitespace-only changes.

hcl2/rule_transformer/json.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from json import JSONEncoder
2+
from typing import Any
3+
4+
from hcl2.rule_transformer.rules.abstract import LarkRule
5+
6+
7+
class LarkEncoder(JSONEncoder):
8+
def default(self, obj: Any):
9+
if isinstance(obj, LarkRule):
10+
return obj.serialize()
11+
else:
12+
return super().default(obj)

hcl2/rule_transformer/rules/__init__.py

Whitespace-only changes.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from abc import ABC, abstractmethod
2+
from typing import Any, Union, List, Optional
3+
4+
from lark import Token, Tree
5+
from lark.tree import Meta
6+
7+
8+
class LarkElement(ABC):
9+
@abstractmethod
10+
def tree(self) -> Token:
11+
raise NotImplementedError()
12+
13+
@abstractmethod
14+
def serialize(self) -> Any:
15+
raise NotImplementedError()
16+
17+
18+
class LarkToken(LarkElement):
19+
def __init__(self, name: str, value: Union[str, int]):
20+
self._name = name
21+
self._value = value
22+
23+
@property
24+
def name(self) -> str:
25+
return self._name
26+
27+
@property
28+
def value(self):
29+
return self._value
30+
31+
def serialize(self) -> Any:
32+
return self._value
33+
34+
def tree(self) -> Token:
35+
return Token(self.name, self.value)
36+
37+
def __str__(self) -> str:
38+
return str(self._value)
39+
40+
def __repr__(self) -> str:
41+
return f"<LarkToken instance: {self._name} {self._value}>"
42+
43+
44+
EQ_Token = LarkToken
45+
COLON_TOKEN = LarkToken
46+
LPAR_TOKEN = LarkToken # left parenthesis
47+
RPAR_TOKEN = LarkToken # right parenthesis
48+
49+
50+
class TokenSequence:
51+
def __init__(self, tokens: List[LarkToken]):
52+
self.tokens = tokens
53+
54+
def tree(self) -> List[Token]:
55+
return [token.tree() for token in self.tokens]
56+
57+
def joined(self):
58+
return "".join(str(token) for token in self.tokens)
59+
60+
61+
class LarkRule(ABC):
62+
@staticmethod
63+
@abstractmethod
64+
def rule_name() -> str:
65+
raise NotImplementedError()
66+
67+
@abstractmethod
68+
def serialize(self) -> Any:
69+
raise NotImplementedError()
70+
71+
@property
72+
def children(self) -> List[LarkElement]:
73+
return self._children
74+
75+
def tree(self) -> Tree:
76+
result_children = []
77+
for child in self._children:
78+
if child is None:
79+
continue
80+
81+
if isinstance(child, TokenSequence):
82+
result_children.extend(child.tree())
83+
else:
84+
result_children.append(child.tree())
85+
86+
return Tree(self.rule_name(), result_children)
87+
88+
def __init__(self, children, meta: Optional[Meta] = None):
89+
self._children = children
90+
self._meta = meta
91+
92+
def __repr__(self):
93+
return f"<LarkRule: {self.__class__.__name__} ({';'.join(str(child) for child in self._children)})>"

hcl2/rule_transformer/rules/base.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
from typing import Tuple, Any, List, Union, Optional
2+
3+
from lark.tree import Meta
4+
5+
from hcl2.rule_transformer.rules.abstract import LarkRule, EQ_Token
6+
from hcl2.rule_transformer.rules.expression import Expression
7+
from hcl2.rule_transformer.rules.token_sequence import IdentifierRule
8+
9+
from hcl2.rule_transformer.rules.whitespace import NewLineOrCommentRule
10+
11+
12+
class AttributeRule(LarkRule):
13+
_children: Tuple[
14+
IdentifierRule,
15+
EQ_Token,
16+
Expression,
17+
]
18+
19+
@staticmethod
20+
def rule_name() -> str:
21+
return "attribute"
22+
23+
@property
24+
def identifier(self) -> IdentifierRule:
25+
return self._children[0]
26+
27+
@property
28+
def expression(self) -> Expression:
29+
return self._children[2]
30+
31+
def serialize(self) -> Any:
32+
return {self.identifier.serialize(): self.expression.serialize()}
33+
34+
35+
class BodyRule(LarkRule):
36+
37+
_children: List[
38+
Union[
39+
NewLineOrCommentRule,
40+
AttributeRule,
41+
"BlockRule",
42+
]
43+
]
44+
45+
@staticmethod
46+
def rule_name() -> str:
47+
return "body"
48+
49+
def serialize(self) -> Any:
50+
blocks: List[BlockRule] = []
51+
attributes: List[AttributeRule] = []
52+
comments = []
53+
54+
for child in self._children:
55+
if isinstance(child, BlockRule):
56+
blocks.append(child)
57+
if isinstance(child, AttributeRule):
58+
attributes.append(child)
59+
if isinstance(child, NewLineOrCommentRule):
60+
child_comments = child.actual_comments()
61+
if child_comments:
62+
comments.extend(child_comments)
63+
64+
result = {}
65+
66+
for attribute in attributes:
67+
result.update(
68+
{attribute.identifier.serialize(): attribute.expression.serialize()}
69+
)
70+
71+
result.update(
72+
{block.labels[0].serialize(): block.serialize() for block in blocks}
73+
)
74+
75+
if comments:
76+
result["__comments__"] = comments
77+
78+
return result
79+
80+
81+
class StartRule(LarkRule):
82+
83+
_children: Tuple[BodyRule]
84+
85+
@staticmethod
86+
def rule_name() -> str:
87+
return "start"
88+
89+
@property
90+
def body(self) -> BodyRule:
91+
return self._children[0]
92+
93+
def serialize(self) -> Any:
94+
return self.body.serialize()
95+
96+
97+
class BlockRule(LarkRule):
98+
99+
_children: Tuple[BodyRule]
100+
101+
@staticmethod
102+
def rule_name() -> str:
103+
return "block"
104+
105+
def __init__(self, children, meta: Optional[Meta] = None):
106+
super().__init__(children)
107+
*self._labels, self._body = children
108+
109+
@property
110+
def labels(self) -> List[IdentifierRule]:
111+
return list(filter(lambda label: label is not None, self._labels))
112+
113+
@property
114+
def body(self) -> BodyRule:
115+
return self._body
116+
117+
def serialize(self) -> BodyRule:
118+
result = self._body.serialize()
119+
labels = self._labels
120+
for label in reversed(labels[1:]):
121+
result = {label.serialize(): result}
122+
return result

0 commit comments

Comments
 (0)