Skip to content

Commit 04ed570

Browse files
batch of different changes
1 parent c9a38fe commit 04ed570

File tree

7 files changed

+152
-102
lines changed

7 files changed

+152
-102
lines changed

hcl2/rule_transformer/rules/abstract.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
from lark import Token, Tree
55
from lark.tree import Meta
66

7+
from hcl2.rule_transformer.utils import SerializationOptions
8+
79

810
class LarkElement(ABC):
911
@abstractmethod
10-
def tree(self) -> Token:
12+
def reverse(self) -> Any:
1113
raise NotImplementedError()
1214

1315
@abstractmethod
14-
def serialize(self) -> Any:
16+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
1517
raise NotImplementedError()
1618

1719

@@ -28,10 +30,10 @@ def name(self) -> str:
2830
def value(self):
2931
return self._value
3032

31-
def serialize(self) -> Any:
33+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
3234
return self._value
3335

34-
def tree(self) -> Token:
36+
def reverse(self) -> Token:
3537
return Token(self.name, self.value)
3638

3739
def __str__(self) -> str:
@@ -47,45 +49,45 @@ def __repr__(self) -> str:
4749
RPAR_TOKEN = LarkToken # right parenthesis
4850

4951

50-
class TokenSequence:
52+
class TokenSequence(LarkElement):
5153
def __init__(self, tokens: List[LarkToken]):
5254
self.tokens = tokens
5355

54-
def tree(self) -> List[Token]:
55-
return [token.tree() for token in self.tokens]
56+
def reverse(self) -> List[Token]:
57+
return [token.reverse() for token in self.tokens]
5658

57-
def joined(self):
59+
def serialize(self, options: SerializationOptions = SerializationOptions()):
5860
return "".join(str(token) for token in self.tokens)
5961

6062

61-
class LarkRule(ABC):
63+
class LarkRule(LarkElement, ABC):
6264
@staticmethod
6365
@abstractmethod
6466
def rule_name() -> str:
6567
raise NotImplementedError()
6668

6769
@abstractmethod
68-
def serialize(self) -> Any:
70+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
6971
raise NotImplementedError()
7072

7173
@property
7274
def children(self) -> List[LarkElement]:
7375
return self._children
7476

75-
def tree(self) -> Tree:
77+
def reverse(self) -> Tree:
7678
result_children = []
7779
for child in self._children:
7880
if child is None:
7981
continue
8082

8183
if isinstance(child, TokenSequence):
82-
result_children.extend(child.tree())
84+
result_children.extend(child.reverse())
8385
else:
84-
result_children.append(child.tree())
86+
result_children.append(child.reverse())
8587

86-
return Tree(self.rule_name(), result_children)
88+
return Tree(self.rule_name(), result_children, meta=self._meta)
8789

88-
def __init__(self, children, meta: Optional[Meta] = None):
90+
def __init__(self, children: List, meta: Optional[Meta] = None):
8991
self._children = children
9092
self._meta = meta
9193

hcl2/rule_transformer/rules/base.py

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import defaultdict
12
from typing import Tuple, Any, List, Union, Optional
23

34
from lark.tree import Meta
@@ -7,6 +8,7 @@
78
from hcl2.rule_transformer.rules.token_sequence import IdentifierRule
89

910
from hcl2.rule_transformer.rules.whitespace import NewLineOrCommentRule
11+
from hcl2.rule_transformer.utils import SerializationOptions
1012

1113

1214
class AttributeRule(LarkRule):
@@ -28,8 +30,8 @@ def identifier(self) -> IdentifierRule:
2830
def expression(self) -> Expression:
2931
return self._children[2]
3032

31-
def serialize(self) -> Any:
32-
return {self.identifier.serialize(): self.expression.serialize()}
33+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
34+
return {self.identifier.serialize(options): self.expression.serialize(options)}
3335

3436

3537
class BodyRule(LarkRule):
@@ -46,34 +48,51 @@ class BodyRule(LarkRule):
4648
def rule_name() -> str:
4749
return "body"
4850

49-
def serialize(self) -> Any:
51+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
5052
blocks: List[BlockRule] = []
5153
attributes: List[AttributeRule] = []
5254
comments = []
53-
55+
inline_comments = []
5456
for child in self._children:
57+
5558
if isinstance(child, BlockRule):
5659
blocks.append(child)
60+
5761
if isinstance(child, AttributeRule):
5862
attributes.append(child)
63+
# collect in-line comments from attribute assignments, expressions etc
64+
inline_comments.extend(child.expression.inline_comments())
65+
5966
if isinstance(child, NewLineOrCommentRule):
60-
child_comments = child.actual_comments()
67+
child_comments = child.to_list()
6168
if child_comments:
6269
comments.extend(child_comments)
6370

6471
result = {}
6572

6673
for attribute in attributes:
6774
result.update(
68-
{attribute.identifier.serialize(): attribute.expression.serialize()}
75+
{
76+
attribute.identifier.serialize(
77+
options
78+
): attribute.expression.serialize(options)
79+
}
6980
)
7081

71-
result.update(
72-
{block.labels[0].serialize(): block.serialize() for block in blocks}
73-
)
82+
result_blocks = defaultdict(list)
83+
for block in blocks:
84+
name = block.labels[0].serialize(options)
85+
if name in result.keys():
86+
raise RuntimeError(f"Attribute {name} is already defined.")
87+
result_blocks[name].append(block.serialize(options))
88+
89+
result.update(**result_blocks)
7490

75-
if comments:
76-
result["__comments__"] = comments
91+
if options.with_comments:
92+
if comments:
93+
result["__comments__"] = comments
94+
if inline_comments:
95+
result["__inline_comments__"] = inline_comments
7796

7897
return result
7998

@@ -90,8 +109,8 @@ def rule_name() -> str:
90109
def body(self) -> BodyRule:
91110
return self._children[0]
92111

93-
def serialize(self) -> Any:
94-
return self.body.serialize()
112+
def serialize(self, options: SerializationOptions = SerializationOptions()) -> Any:
113+
return self.body.serialize(options)
95114

96115

97116
class BlockRule(LarkRule):
@@ -103,7 +122,7 @@ def rule_name() -> str:
103122
return "block"
104123

105124
def __init__(self, children, meta: Optional[Meta] = None):
106-
super().__init__(children)
125+
super().__init__(children, meta)
107126
*self._labels, self._body = children
108127

109128
@property
@@ -114,9 +133,11 @@ def labels(self) -> List[IdentifierRule]:
114133
def body(self) -> BodyRule:
115134
return self._body
116135

117-
def serialize(self) -> BodyRule:
118-
result = self._body.serialize()
136+
def serialize(
137+
self, options: SerializationOptions = SerializationOptions()
138+
) -> BodyRule:
139+
result = self._body.serialize(options)
119140
labels = self._labels
120141
for label in reversed(labels[1:]):
121-
result = {label.serialize(): result}
142+
result = {label.serialize(options): result}
122143
return result

0 commit comments

Comments
 (0)