@@ -88,7 +88,7 @@ function getArguments(scope, args) {
88
88
}
89
89
}
90
90
91
- return [ positional , named ] ;
91
+ return { positional, named} ;
92
92
}
93
93
94
94
// Resolve an expression to a Fluent type.
@@ -117,15 +117,23 @@ function resolveExpression(scope, expr) {
117
117
118
118
// Resolve a reference to a variable.
119
119
function VariableReference ( scope , { name} ) {
120
- if ( ! scope . args || ! scope . args . hasOwnProperty ( name ) ) {
121
- if ( scope . insideTermReference === false ) {
122
- scope . reportError ( new ReferenceError ( `Unknown variable: $${ name } ` ) ) ;
120
+ let arg ;
121
+ if ( scope . params ) {
122
+ // We're inside a TermReference. It's OK to reference undefined parameters.
123
+ if ( scope . params . hasOwnProperty ( name ) ) {
124
+ arg = scope . params [ name ] ;
125
+ } else {
126
+ return new FluentNone ( `$${ name } ` ) ;
123
127
}
128
+ } else if ( scope . args && scope . args . hasOwnProperty ( name ) ) {
129
+ // We're in the top-level Pattern or inside a MessageReference. Missing
130
+ // variables references produce ReferenceErrors.
131
+ arg = scope . args [ name ] ;
132
+ } else {
133
+ scope . reportError ( new ReferenceError ( `Unknown variable: $${ name } ` ) ) ;
124
134
return new FluentNone ( `$${ name } ` ) ;
125
135
}
126
136
127
- const arg = scope . args [ name ] ;
128
-
129
137
// Return early if the argument already is an instance of FluentType.
130
138
if ( arg instanceof FluentType ) {
131
139
return arg ;
@@ -183,20 +191,23 @@ function TermReference(scope, {name, attr, args}) {
183
191
return new FluentNone ( id ) ;
184
192
}
185
193
186
- // Every TermReference has its own variables.
187
- const [ , params ] = getArguments ( scope , args ) ;
188
- const local = scope . cloneForTermReference ( params ) ;
189
-
190
194
if ( attr ) {
191
195
const attribute = term . attributes [ attr ] ;
192
196
if ( attribute ) {
193
- return resolvePattern ( local , attribute ) ;
197
+ // Every TermReference has its own variables.
198
+ scope . params = getArguments ( scope , args ) . named ;
199
+ const resolved = resolvePattern ( scope , attribute ) ;
200
+ scope . params = null ;
201
+ return resolved ;
194
202
}
195
203
scope . reportError ( new ReferenceError ( `Unknown attribute: ${ attr } ` ) ) ;
196
204
return new FluentNone ( `${ id } .${ attr } ` ) ;
197
205
}
198
206
199
- return resolvePattern ( local , term . value ) ;
207
+ scope . params = getArguments ( scope , args ) . named ;
208
+ const resolved = resolvePattern ( scope , term . value ) ;
209
+ scope . params = null ;
210
+ return resolved ;
200
211
}
201
212
202
213
// Resolve a call to a Function with positional and key-value arguments.
@@ -215,7 +226,8 @@ function FunctionReference(scope, {name, args}) {
215
226
}
216
227
217
228
try {
218
- return func ( ...getArguments ( scope , args ) ) ;
229
+ let resolved = getArguments ( scope , args ) ;
230
+ return func ( resolved . positional , resolved . named ) ;
219
231
} catch ( err ) {
220
232
scope . reportError ( err ) ;
221
233
return new FluentNone ( `${ name } ()` ) ;
0 commit comments