Skip to content

Commit 7b80850

Browse files
authored
Merge pull request #37 from stasm/terms
Rename private messages to Terms
2 parents 1faf36b + 6b7fdaf commit 7b80850

16 files changed

+170
-57
lines changed

fluent/syntax/ast.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,15 @@ def __init__(self, id, value=None, attributes=None,
176176
self.attributes = attributes or []
177177
self.comment = comment
178178

179+
class Term(Entry):
180+
def __init__(self, id, value, attributes=None,
181+
comment=None, **kwargs):
182+
super(Term, self).__init__(**kwargs)
183+
self.id = id
184+
self.value = value
185+
self.attributes = attributes or []
186+
self.comment = comment
187+
179188
class Pattern(SyntaxNode):
180189
def __init__(self, elements, **kwargs):
181190
super(Pattern, self).__init__(**kwargs)

fluent/syntax/errors.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ def get_error_message(code, args):
1818
if code == 'E0004':
1919
return 'Expected a character from range: "{}"'.format(args[0])
2020
if code == 'E0005':
21-
msg = 'Expected entry "{}" to have a value or attributes'
21+
msg = 'Expected message "{}" to have a value or attributes'
2222
return msg.format(args[0])
2323
if code == 'E0006':
24-
return 'Expected field: "{}"'.format(args[0])
24+
msg = 'Expected term "{}" to have a value'
25+
return msg.format(args[0])
2526
if code == 'E0007':
2627
return 'Keyword cannot end with a whitespace'
2728
if code == 'E0008':
@@ -32,6 +33,8 @@ def get_error_message(code, args):
3233
return 'Expected one of the variants to be marked as default (*)'
3334
if code == 'E0011':
3435
return 'Expected at least one variant after "->"'
36+
if code == 'E0012':
37+
return 'Expected value'
3538
if code == 'E0013':
3639
return 'Expected variant key'
3740
if code == 'E0014':
@@ -43,9 +46,9 @@ def get_error_message(code, args):
4346
if code == 'E0017':
4447
return 'Variants cannot be used as selectors'
4548
if code == 'E0018':
46-
return 'Attributes of public messages cannot be used as selectors'
49+
return 'Attributes of messages cannot be used as selectors'
4750
if code == 'E0019':
48-
return 'Attributes of private messages cannot be used as placeables'
51+
return 'Attributes of terms cannot be used as placeables'
4952
if code == 'E0020':
5053
return 'Unterminated string expression'
5154
return code

fluent/syntax/ftlstream.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def is_char_id_start(self, ch=None):
8888
return (cc >= 97 and cc <= 122) or \
8989
(cc >= 65 and cc <= 90)
9090

91-
def is_message_id_start(self):
91+
def is_entry_id_start(self):
9292
if self.current_is('-'):
9393
self.peek()
9494

@@ -240,15 +240,15 @@ def skip_to_next_entry_start(self):
240240
self.next()
241241

242242
if self.ch is None or \
243-
self.is_message_id_start() or \
243+
self.is_entry_id_start() or \
244244
self.current_is('#') or \
245245
(self.current_is('/') and self.peek_char_is('/')) or \
246246
(self.current_is('[') and self.peek_char_is('[')):
247247
break
248248
self.next()
249249

250-
def take_id_start(self, allow_private):
251-
if allow_private and self.current_is('-'):
250+
def take_id_start(self, allow_term):
251+
if allow_term and self.current_is('-'):
252252
self.next()
253253
return '-'
254254

@@ -257,7 +257,7 @@ def take_id_start(self, allow_private):
257257
self.next()
258258
return ret
259259

260-
allowed_range = 'a-zA-Z-' if allow_private else 'a-zA-Z'
260+
allowed_range = 'a-zA-Z-' if allow_term else 'a-zA-Z'
261261
raise ParseError('E0004', allowed_range)
262262

263263
def take_id_char(self):

fluent/syntax/parser.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def get_entry(self, ps):
106106
return ast.GroupComment(comment.content)
107107
return None
108108

109-
if ps.is_message_id_start() \
109+
if ps.is_entry_id_start() \
110110
and (comment is None or isinstance(comment, ast.Comment)):
111111
return self.get_message(ps, comment)
112112

@@ -200,7 +200,7 @@ def skip_section(self, ps):
200200

201201
@with_span
202202
def get_message(self, ps, comment):
203-
id = self.get_private_identifier(ps)
203+
id = self.get_entry_identifier(ps)
204204

205205
ps.skip_inline_ws()
206206

@@ -215,9 +215,15 @@ def get_message(self, ps, comment):
215215
ps.skip_indent()
216216
pattern = self.get_pattern(ps)
217217

218+
if id.name.startswith('-') and pattern is None:
219+
raise ParseError('E0006', id.name)
220+
218221
if ps.is_peek_next_line_attribute_start():
219222
attrs = self.get_attributes(ps)
220223

224+
if id.name.startswith('-'):
225+
return ast.Term(id, pattern, attrs, comment)
226+
221227
if pattern is None and attrs is None:
222228
raise ParseError('E0005', id.name)
223229

@@ -228,7 +234,7 @@ def get_attribute(self, ps):
228234
ps.expect_indent()
229235
ps.expect_char('.')
230236

231-
key = self.get_public_identifier(ps)
237+
key = self.get_identifier(ps)
232238

233239
ps.skip_inline_ws()
234240
ps.expect_char('=')
@@ -238,7 +244,7 @@ def get_attribute(self, ps):
238244
value = self.get_pattern(ps)
239245
return ast.Attribute(key, value)
240246

241-
raise ParseError('E0006', 'value')
247+
raise ParseError('E0012')
242248

243249
def get_attributes(self, ps):
244250
attrs = []
@@ -251,18 +257,14 @@ def get_attributes(self, ps):
251257
break
252258
return attrs
253259

254-
@with_span
255-
def get_private_identifier(self, ps):
260+
def get_entry_identifier(self, ps):
256261
return self.get_identifier(ps, True)
257262

258263
@with_span
259-
def get_public_identifier(self, ps):
260-
return self.get_identifier(ps, False)
261-
262-
def get_identifier(self, ps, allow_private):
264+
def get_identifier(self, ps, allow_term=False):
263265
name = ''
264266

265-
name += ps.take_id_start(allow_private)
267+
name += ps.take_id_start(allow_term)
266268

267269
ch = ps.take_id_char()
268270
while ch:
@@ -306,7 +308,7 @@ def get_variant(self, ps, has_default):
306308
value = self.get_pattern(ps)
307309
return ast.Variant(key, value, default_index)
308310

309-
raise ParseError('E0006', 'value')
311+
raise ParseError('E0012')
310312

311313
def get_variants(self, ps):
312314
variants = []
@@ -501,7 +503,7 @@ def get_selector_expression(self, ps):
501503

502504
if (ch == '.'):
503505
ps.next()
504-
attr = self.get_public_identifier(ps)
506+
attr = self.get_identifier(ps)
505507
return ast.AttributeExpression(literal.id, attr)
506508

507509
if (ch == '['):
@@ -574,7 +576,7 @@ def get_arg_val(self, ps):
574576
return self.get_number(ps)
575577
elif ps.current_is('"'):
576578
return self.get_string(ps)
577-
raise ParseError('E0006', 'value')
579+
raise ParseError('E0012')
578580

579581
@with_span
580582
def get_string(self, ps):
@@ -603,10 +605,10 @@ def get_literal(self, ps):
603605

604606
if ch == '$':
605607
ps.next()
606-
name = self.get_public_identifier(ps)
608+
name = self.get_identifier(ps)
607609
return ast.ExternalArgument(name)
608-
elif ps.is_message_id_start():
609-
name = self.get_private_identifier(ps)
610+
elif ps.is_entry_id_start():
611+
name = self.get_entry_identifier(ps)
610612
return ast.MessageReference(name)
611613
elif ps.is_number_start():
612614
return self.get_number(ps)

fluent/syntax/serializer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def serialize(self, resource):
3939
def serialize_entry(self, entry, state=0):
4040
if isinstance(entry, ast.Message):
4141
return serialize_message(entry)
42+
if isinstance(entry, ast.Term):
43+
return serialize_message(entry)
4244
if isinstance(entry, ast.Comment):
4345
if state & self.HAS_ENTRIES:
4446
return "\n{}\n\n".format(serialize_comment(entry))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
key = Value
22
.label =
3-
//~ ERROR E0006, pos 24, args "value"
3+
//~ ERROR E0012, pos 24
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
key = { BUILTIN(key: foo) }
2-
//~ ERROR E0006, pos 21, args "value"
2+
//~ ERROR E0012, pos 21

tests/syntax/fixtures_behavior/private_message.ftl renamed to tests/syntax/fixtures_behavior/term.ftl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,10 @@ err2 = { $-foo }
2323

2424
err4 = { -brand() }
2525
//~ ERROR E0008, pos 340
26+
27+
-err5 =
28+
//~ ERROR E0006, pos 351, args "-err5"
29+
30+
-err6 =
31+
.attr = Attribute
32+
//~ ERROR E0006, pos 360, args "-err6"

tests/syntax/fixtures_behavior/variant_with_empty_pattern.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ key1 = {
55
err1 = {
66
*[one]
77
}
8-
//~ ERROR E0006, pos 51, args "value"
8+
//~ ERROR E0012, pos 51

tests/syntax/fixtures_structure/attribute_with_empty_pattern.json

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
"annotations": [
77
{
88
"type": "Annotation",
9-
"code": "E0006",
10-
"args": [
11-
"value"
12-
],
13-
"message": "Expected field: \"value\"",
9+
"code": "E0012",
10+
"args": [],
11+
"message": "Expected value",
1412
"span": {
1513
"type": "Span",
1614
"start": 26,
@@ -30,11 +28,9 @@
3028
"annotations": [
3129
{
3230
"type": "Annotation",
33-
"code": "E0006",
34-
"args": [
35-
"value"
36-
],
37-
"message": "Expected field: \"value\"",
31+
"code": "E0012",
32+
"args": [],
33+
"message": "Expected value",
3834
"span": {
3935
"type": "Span",
4036
"start": 46,
@@ -54,11 +50,9 @@
5450
"annotations": [
5551
{
5652
"type": "Annotation",
57-
"code": "E0006",
58-
"args": [
59-
"value"
60-
],
61-
"message": "Expected field: \"value\"",
53+
"code": "E0012",
54+
"args": [],
55+
"message": "Expected value",
6256
"span": {
6357
"type": "Span",
6458
"start": 87,
@@ -78,11 +72,9 @@
7872
"annotations": [
7973
{
8074
"type": "Annotation",
81-
"code": "E0006",
82-
"args": [
83-
"value"
84-
],
85-
"message": "Expected field: \"value\"",
75+
"code": "E0012",
76+
"args": [],
77+
"message": "Expected value",
8678
"span": {
8779
"type": "Span",
8880
"start": 108,
@@ -102,11 +94,9 @@
10294
"annotations": [
10395
{
10496
"type": "Annotation",
105-
"code": "E0006",
106-
"args": [
107-
"value"
108-
],
109-
"message": "Expected field: \"value\"",
97+
"code": "E0012",
98+
"args": [],
99+
"message": "Expected value",
110100
"span": {
111101
"type": "Span",
112102
"start": 149,

0 commit comments

Comments
 (0)