Chromium Code Reviews| Index: lib/src/compiler/code_generator.dart |
| diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart |
| index bdbdbc6b3531ba7a55484df8c5a2cbe873002ef6..591f35669a21eb0a1fd0fba41d8475bd40f88dc3 100644 |
| --- a/lib/src/compiler/code_generator.dart |
| +++ b/lib/src/compiler/code_generator.dart |
| @@ -94,6 +94,7 @@ class CodeGenerator extends GeneralizingAstVisitor |
| final _dartxVar = new JS.Identifier('dartx'); |
| final _runtimeLibVar = new JS.Identifier('dart'); |
| final namedArgumentTemp = new JS.TemporaryId('opts'); |
| + final positionalArgumentsTemp = new JS.TemporaryId('positionalArgs'); |
| final _hasDeferredSupertype = new HashSet<ClassElement>(); |
| @@ -1409,13 +1410,13 @@ class CodeGenerator extends GeneralizingAstVisitor |
| /// new dart.InvocationImpl('eatFood', [food]))); |
| /// } |
| JS.Method _implementMockMethod(ExecutableElement method) { |
| - var positionalArgs = <JS.Identifier>[] |
| + var normalArgs = <JS.Identifier>[] |
| ..addAll( |
| - method.type.normalParameterNames.map((a) => new JS.Identifier(a))) |
| + method.type.normalParameterNames.map((a) => new JS.Identifier(a))); |
| + var optionalArgs = <JS.Identifier>[] |
| ..addAll( |
| method.type.optionalParameterNames.map((a) => new JS.Identifier(a))); |
| - |
| - var fnArgs = positionalArgs.toList(); |
| + var fnArgs = <JS.Identifier>[]..addAll(normalArgs)..addAll(optionalArgs); |
| var invocationProps = <JS.Property>[]; |
| addProperty(String name, JS.Expression value) { |
| @@ -1438,18 +1439,41 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } |
| } |
| - var fnBody = |
| + var posDecl = js.statement('let # = #;', |
| + [positionalArgumentsTemp, new JS.ArrayInitializer(normalArgs)]); |
| + |
| + var fnBody = <JS.Statement>[posDecl]; |
| + |
| + if (optionalArgs.length > 0) { |
| + final argTemp = new JS.TemporaryId('arg'); |
| + // Optional arguments must only be passed on to noSuchMethod if they were |
| + // actually passed here. This code loops through them, pushing the ones |
| + // that were actually passed. |
| + var existenceCheckLoop = js.statement( |
| + 'for (let arg of #) { if (# !== void 0) { #.push(#); } }', [ |
|
srawlins
2016/08/01 18:30:38
I think I need help on this line: `arg` needs to b
|
| + //argTemp, |
| + new JS.ArrayInitializer(optionalArgs), |
| + argTemp, |
| + positionalArgumentsTemp, |
| + argTemp, |
| + ]); |
| + fnBody.add(existenceCheckLoop); |
| + } |
| + |
| + var nSMCall = |
| js.call('this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [ |
| _elementMemberName(method), |
| - new JS.ArrayInitializer(positionalArgs), |
| + positionalArgumentsTemp, |
| new JS.ObjectInitializer(invocationProps) |
| ]); |
| if (!method.returnType.isDynamic) { |
| - fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]); |
| + nSMCall = js.call('#._check(#)', [_emitType(method.returnType), nSMCall]); |
| } |
| - var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]), |
| + fnBody.add(js.statement('return #', [nSMCall])); |
| + |
| + var fn = new JS.Fun(fnArgs, js.statement('{ # }', [_statement(fnBody)]), |
| typeParams: _emitTypeFormals(method.type.typeFormals)); |
| // TODO(jmesserly): generic type arguments will get dropped. |