Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 24876) |
+++ runtime/vm/parser.cc (working copy) |
@@ -773,7 +773,8 @@ |
node_sequence = parser.ParseMethodExtractor(func); |
break; |
case RawFunction::kNoSuchMethodDispatcher: |
- node_sequence = parser.ParseNoSuchMethodDispatcher(func); |
+ node_sequence = |
+ parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); |
break; |
default: |
UNREACHABLE(); |
@@ -1107,7 +1108,8 @@ |
} |
-SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
+SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, |
+ Array& default_values) { |
TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
ASSERT(func.IsNoSuchMethodDispatcher()); |
@@ -1117,18 +1119,36 @@ |
ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc())); |
ASSERT(desc.Count() > 0); |
+ |
+ // Create parameter list. Receiver first. |
ParamList params; |
params.AddReceiver(ReceiverType(), token_pos); |
- for (intptr_t i = 1; i < desc.Count(); ++i) { |
+ |
+ // Remaining positional parameters. |
+ intptr_t i = 1; |
+ for (; i < desc.PositionalCount(); ++i) { |
ParamDesc p; |
char name[64]; |
OS::SNPrint(name, 64, ":p%"Pd, i); |
p.name = &String::ZoneHandle(Symbols::New(name)); |
p.type = &Type::ZoneHandle(Type::DynamicType()); |
params.parameters->Add(p); |
+ params.num_fixed_parameters++; |
} |
- ASSERT(!func.HasOptionalParameters()); |
+ // Named parameters. |
+ for (; i < desc.Count(); ++i) { |
+ ParamDesc p; |
+ intptr_t index = i - desc.PositionalCount(); |
+ p.name = &String::ZoneHandle(desc.NameAt(index)); |
+ p.type = &Type::ZoneHandle(Type::DynamicType()); |
+ p.default_value = &Object::ZoneHandle(); |
+ params.parameters->Add(p); |
+ params.num_optional_parameters++; |
+ params.has_optional_named_parameters = true; |
+ } |
+ SetupDefaultsForOptionalParams(¶ms, default_values); |
+ |
// Build local scope for function and populate with the formal parameters. |
OpenFunctionBlock(func); |
LocalScope* scope = current_block_->scope; |
@@ -1140,6 +1160,15 @@ |
func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
} |
+ if (params.num_optional_parameters > 0) { |
+ const Array& arg_names = |
+ Array::ZoneHandle(Array::New(params.num_optional_parameters)); |
+ for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
+ arg_names.SetAt(i, String::Handle(desc.NameAt(i))); |
+ } |
+ func_args->set_names(arg_names); |
+ } |
+ |
const String& func_name = String::ZoneHandle(func.name()); |
ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos, |
func_name, |