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. |