Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 44558) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -860,8 +860,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: |
| @@ -1303,6 +1310,55 @@ |
| } |
| +SequenceNode* Parser::ParseImplicitClosure(const Function& func, |
| + Array* default_values) { |
| + TRACE_PARSER("ParseImplicitClosure"); |
| + |
| + intptr_t token_pos = func.token_pos(); |
|
Florian Schneider
2015/03/23 13:45:37
0 (Scanner::kNoSourcePos) does not work since it c
|
| + |
| + 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); |
|
hausner
2015/03/23 17:44:48
Can there be an implicit closure of a getter? If s
Florian Schneider
2015/03/24 09:19:38
Done. Added assertion and a comment.
|
| + SetupDefaultsForOptionalParams(¶ms, default_values); |
| + |
| + // 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); |
| + } |
| + const Function& parent = Function::ZoneHandle(func.parent_function()); |
| + 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; |