Skip to content

Commit e5c9e1f

Browse files
authored
Inline Patterns may start with any character. (#150)
`}`, `.`, `*` and `[` are only special when they appear at the beginning of indented Pattern lines. When a Pattern starts on the same line as `id =` or `[variant key]`, its first character doesn't carry any special meaning and it may be one of those four ones as well. See also https://bugzilla.mozilla.org/show_bug.cgi?id=1436683. The tests for this uncovered a bug in how the runtime parser treated null attributes and variants. For compliance with fluent-syntax these are syntax errors now.
1 parent 22da361 commit e5c9e1f

File tree

8 files changed

+1149
-63
lines changed

8 files changed

+1149
-63
lines changed

fluent-syntax/src/ftlstream.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,20 @@ export class FTLParserStream extends ParserStream {
131131
return isDigit;
132132
}
133133

134-
isCharPatternStart(ch) {
134+
isCharPatternContinuation(ch) {
135135
return !includes(SPECIAL_LINE_START_CHARS, ch);
136136
}
137137

138138
isPeekPatternStart() {
139139
this.peekInlineWS();
140-
141140
const ch = this.currentPeek();
142141

143-
if (ch === '\n') {
144-
return this.isPeekNextLinePatternStart();
142+
// Inline Patterns may start with any char.
143+
if (ch !== undefined && ch !== '\n') {
144+
return true;
145145
}
146146

147-
const isPattern = this.isCharPatternStart(this.currentPeek());
148-
this.resetPeek();
149-
return isPattern;
147+
return this.isPeekNextLinePatternStart();
150148
}
151149

152150
isPeekNextLineZeroFourStyleComment() {
@@ -276,7 +274,7 @@ export class FTLParserStream extends ParserStream {
276274
return false;
277275
}
278276

279-
if (!this.isCharPatternStart(this.currentPeek())) {
277+
if (!this.isCharPatternContinuation(this.currentPeek())) {
280278
this.resetPeek();
281279
return false;
282280
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
key01 = .Value
2+
key02 = …Value
3+
key03 = {"."}Value
4+
key04 =
5+
{"."}Value
6+
7+
key05 = Value
8+
{"."}Continued
9+
10+
key06 = .Value
11+
{"."}Continued
12+
13+
# ERROR (attr .Continued must have a value)
14+
key07 = Value
15+
.Continued
16+
17+
# ERROR (attr .Value must have a value)
18+
key08 =
19+
.Value
20+
21+
# ERROR (attr .Value must have a value)
22+
key09 =
23+
.Value
24+
Continued
25+
26+
key10 =
27+
.Value = which looks like an attribute
28+
Continued
29+
30+
key11 =
31+
{"."}Value = which looks like an attribute
32+
Continued
33+
34+
key12 =
35+
.accesskey =
36+
A
37+
38+
key13 =
39+
.attribute = .Value
40+
41+
key14 =
42+
.attribute =
43+
{"."}Value
44+
45+
key15 =
46+
{ 1 ->
47+
[one] .Value
48+
*[other]
49+
{"."}Value
50+
}
51+
52+
# ERROR (variant must have a value)
53+
key16 =
54+
{ 1 ->
55+
*[one]
56+
.Value
57+
}
58+
59+
# ERROR (unclosed placeable)
60+
key17 =
61+
{ 1 ->
62+
*[one] Value
63+
.Continued
64+
}

0 commit comments

Comments
 (0)