Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 44654) |
+++ runtime/vm/parser.cc (working copy) |
@@ -858,8 +858,15 @@ |
SequenceNode* node_sequence = NULL; |
Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); |
switch (func.kind()) { |
+ case RawFunction::kClosureFunction: |
+ if (func.IsImplicitClosureFunction()) { |
+ parser.SkipFunctionPreamble(); |
+ node_sequence = |
+ parser.ParseImplicitClosure(func, &default_parameter_values); |
+ break; |
+ } |
+ // Fall-through: Handle non-implicit closures. |
case RawFunction::kRegularFunction: |
- case RawFunction::kClosureFunction: |
case RawFunction::kGetterFunction: |
case RawFunction::kSetterFunction: |
case RawFunction::kConstructor: |
@@ -1301,6 +1308,59 @@ |
} |
+SequenceNode* Parser::ParseImplicitClosure(const Function& func, |
+ Array* default_values) { |
+ TRACE_PARSER("ParseImplicitClosure"); |
+ |
+ intptr_t token_pos = func.token_pos(); |
+ |
+ OpenFunctionBlock(func); |
+ |
+ ParamList params; |
+ |
+ params.AddFinalParameter( |
+ token_pos, |
+ &Symbols::ClosureParameter(), |
+ &Type::ZoneHandle(Type::DynamicType())); |
+ |
+ const bool allow_explicit_default_values = true; |
+ ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
+ SetupDefaultsForOptionalParams(¶ms, default_values); |
+ |
+ // Getters can't be closurized. If supported, they need special |
+ // handling of the parameters as in ParseFunc. |
+ const Function& parent = Function::ZoneHandle(func.parent_function()); |
+ ASSERT(!parent.IsGetterFunction()); |
+ |
+ // Populate function scope with the formal parameters. |
+ LocalScope* scope = current_block_->scope; |
+ AddFormalParamsToScope(¶ms, scope); |
+ |
+ ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
+ if (!func.is_static()) { |
+ func_args->Add(LoadReceiver(token_pos)); |
+ } |
+ // Skip implicit parameter at 0. |
+ for (intptr_t i = 1; i < func.NumParameters(); ++i) { |
+ func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
+ } |
+ |
+ if (func.HasOptionalNamedParameters()) { |
+ const Array& arg_names = |
+ Array::ZoneHandle(Array::New(func.NumOptionalParameters())); |
+ for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
+ intptr_t index = func.num_fixed_parameters() + i; |
+ arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); |
+ } |
+ func_args->set_names(arg_names); |
+ } |
+ StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args); |
+ ReturnNode* return_node = new ReturnNode(token_pos, call); |
+ current_block_->statements->Add(return_node); |
+ return CloseBlock(); |
+} |
+ |
+ |
SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
TRACE_PARSER("ParseMethodExtractor"); |
ParamList params; |