Skip to content

Commit 4da58c3

Browse files
authored
Merge pull request #352 from projectfluent/zeronine
Support Syntax 0.9 in fluent and fluent-syntax
2 parents c5f0ea7 + 0af4d59 commit 4da58c3

File tree

272 files changed

+6444
-3602
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

272 files changed

+6444
-3602
lines changed

fluent-syntax/src/ast.js

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,6 @@ export class Term extends Entry {
114114
}
115115
}
116116

117-
export class VariantList extends SyntaxNode {
118-
constructor(variants) {
119-
super();
120-
this.type = "VariantList";
121-
this.variants = variants;
122-
}
123-
}
124-
125117
export class Pattern extends SyntaxNode {
126118
constructor(elements) {
127119
super();
@@ -156,36 +148,87 @@ export class Placeable extends PatternElement {
156148
*/
157149
export class Expression extends SyntaxNode {}
158150

159-
export class StringLiteral extends Expression {
160-
constructor(raw, value) {
151+
// An abstract base class for Literals.
152+
export class Literal extends Expression {
153+
constructor(value) {
161154
super();
162-
this.type = "StringLiteral";
163-
this.raw = raw;
155+
// The "value" field contains the exact contents of the literal,
156+
// character-for-character.
164157
this.value = value;
165158
}
159+
160+
parse() {
161+
return {value: this.value};
162+
}
166163
}
167164

168-
export class NumberLiteral extends Expression {
165+
export class StringLiteral extends Literal {
169166
constructor(value) {
170-
super();
167+
super(value);
168+
this.type = "StringLiteral";
169+
}
170+
171+
parse() {
172+
// Backslash backslash, backslash double quote, uHHHH, UHHHHHH.
173+
const KNOWN_ESCAPES =
174+
/(?:\\\\|\\"|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g;
175+
176+
function from_escape_sequence(match, codepoint4, codepoint6) {
177+
switch (match) {
178+
case "\\\\":
179+
return "\\";
180+
case "\\\"":
181+
return "\"";
182+
default:
183+
let codepoint = parseInt(codepoint4 || codepoint6, 16);
184+
if (codepoint <= 0xD7FF || 0xE000 <= codepoint) {
185+
// It's a Unicode scalar value.
186+
return String.fromCodePoint(codepoint);
187+
}
188+
// Escape sequences reresenting surrogate code points are
189+
// well-formed but invalid in Fluent. Replace them with U+FFFD
190+
// REPLACEMENT CHARACTER.
191+
return "�";
192+
}
193+
}
194+
195+
let value = this.value.replace(KNOWN_ESCAPES, from_escape_sequence);
196+
return {value};
197+
}
198+
}
199+
200+
export class NumberLiteral extends Literal {
201+
constructor(value) {
202+
super(value);
171203
this.type = "NumberLiteral";
172-
this.value = value;
204+
}
205+
206+
parse() {
207+
let value = parseFloat(this.value);
208+
let decimal_position = this.value.indexOf(".");
209+
let precision = decimal_position > 0
210+
? this.value.length - decimal_position - 1
211+
: 0;
212+
return {value, precision};
173213
}
174214
}
175215

176216
export class MessageReference extends Expression {
177-
constructor(id) {
217+
constructor(id, attribute = null) {
178218
super();
179219
this.type = "MessageReference";
180220
this.id = id;
221+
this.attribute = attribute;
181222
}
182223
}
183224

184225
export class TermReference extends Expression {
185-
constructor(id) {
226+
constructor(id, attribute = null, args = null) {
186227
super();
187228
this.type = "TermReference";
188229
this.id = id;
230+
this.attribute = attribute;
231+
this.arguments = args;
189232
}
190233
}
191234

@@ -198,10 +241,11 @@ export class VariableReference extends Expression {
198241
}
199242

200243
export class FunctionReference extends Expression {
201-
constructor(id) {
244+
constructor(id, args) {
202245
super();
203246
this.type = "FunctionReference";
204247
this.id = id;
248+
this.arguments = args;
205249
}
206250
}
207251

@@ -214,29 +258,10 @@ export class SelectExpression extends Expression {
214258
}
215259
}
216260

217-
export class AttributeExpression extends Expression {
218-
constructor(ref, name) {
219-
super();
220-
this.type = "AttributeExpression";
221-
this.ref = ref;
222-
this.name = name;
223-
}
224-
}
225-
226-
export class VariantExpression extends Expression {
227-
constructor(ref, key) {
228-
super();
229-
this.type = "VariantExpression";
230-
this.ref = ref;
231-
this.key = key;
232-
}
233-
}
234-
235-
export class CallExpression extends Expression {
236-
constructor(callee, positional = [], named = []) {
261+
export class CallArguments extends SyntaxNode {
262+
constructor(positional = [], named = []) {
237263
super();
238-
this.type = "CallExpression";
239-
this.callee = callee;
264+
this.type = "CallArguments";
240265
this.positional = positional;
241266
this.named = named;
242267
}
@@ -333,7 +358,7 @@ export class Annotation extends SyntaxNode {
333358
super();
334359
this.type = "Annotation";
335360
this.code = code;
336-
this.args = args;
361+
this.arguments = args;
337362
this.message = message;
338363
}
339364
}

fluent-syntax/src/errors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function getErrorMessage(code, args) {
3535
case "E0008":
3636
return "The callee has to be an upper-case identifier or a term";
3737
case "E0009":
38-
return "The key has to be a simple identifier";
38+
return "The argument name has to be a simple identifier";
3939
case "E0010":
4040
return "Expected one of the variants to be marked as default (*)";
4141
case "E0011":

0 commit comments

Comments
 (0)