@@ -88,7 +88,7 @@ function getArguments(scope, args) {
8888 }
8989 }
9090
91- return [ positional , named ] ;
91+ return { positional, named} ;
9292}
9393
9494// Resolve an expression to a Fluent type.
@@ -117,15 +117,23 @@ function resolveExpression(scope, expr) {
117117
118118// Resolve a reference to a variable.
119119function 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 } ` ) ;
123127 }
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 } ` ) ) ;
124134 return new FluentNone ( `$${ name } ` ) ;
125135 }
126136
127- const arg = scope . args [ name ] ;
128-
129137 // Return early if the argument already is an instance of FluentType.
130138 if ( arg instanceof FluentType ) {
131139 return arg ;
@@ -183,20 +191,23 @@ function TermReference(scope, {name, attr, args}) {
183191 return new FluentNone ( id ) ;
184192 }
185193
186- // Every TermReference has its own variables.
187- const [ , params ] = getArguments ( scope , args ) ;
188- const local = scope . cloneForTermReference ( params ) ;
189-
190194 if ( attr ) {
191195 const attribute = term . attributes [ attr ] ;
192196 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 ;
194202 }
195203 scope . reportError ( new ReferenceError ( `Unknown attribute: ${ attr } ` ) ) ;
196204 return new FluentNone ( `${ id } .${ attr } ` ) ;
197205 }
198206
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 ;
200211}
201212
202213// Resolve a call to a Function with positional and key-value arguments.
@@ -215,7 +226,8 @@ function FunctionReference(scope, {name, args}) {
215226 }
216227
217228 try {
218- return func ( ...getArguments ( scope , args ) ) ;
229+ let resolved = getArguments ( scope , args ) ;
230+ return func ( resolved . positional , resolved . named ) ;
219231 } catch ( err ) {
220232 scope . reportError ( err ) ;
221233 return new FluentNone ( `${ name } ()` ) ;
0 commit comments