Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 853 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 854 CompilerStats::num_functions_compiled++; | 854 CompilerStats::num_functions_compiled++; |
| 855 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 855 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 856 ASSERT(parsed_function != NULL); | 856 ASSERT(parsed_function != NULL); |
| 857 const Function& func = parsed_function->function(); | 857 const Function& func = parsed_function->function(); |
| 858 const Script& script = Script::Handle(zone, func.script()); | 858 const Script& script = Script::Handle(zone, func.script()); |
| 859 Parser parser(script, parsed_function, func.token_pos()); | 859 Parser parser(script, parsed_function, func.token_pos()); |
| 860 SequenceNode* node_sequence = NULL; | 860 SequenceNode* node_sequence = NULL; |
| 861 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); | 861 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); |
| 862 switch (func.kind()) { | 862 switch (func.kind()) { |
| 863 case RawFunction::kClosureFunction: | |
| 864 if (func.IsImplicitClosureFunction()) { | |
| 865 parser.SkipFunctionPreamble(); | |
| 866 node_sequence = | |
| 867 parser.ParseImplicitClosure(func, &default_parameter_values); | |
| 868 break; | |
| 869 } | |
| 870 // Fall-through: Handle non-implicit closures. | |
| 863 case RawFunction::kRegularFunction: | 871 case RawFunction::kRegularFunction: |
| 864 case RawFunction::kClosureFunction: | |
| 865 case RawFunction::kGetterFunction: | 872 case RawFunction::kGetterFunction: |
| 866 case RawFunction::kSetterFunction: | 873 case RawFunction::kSetterFunction: |
| 867 case RawFunction::kConstructor: | 874 case RawFunction::kConstructor: |
| 868 // The call to a redirecting factory is redirected. | 875 // The call to a redirecting factory is redirected. |
| 869 ASSERT(!func.IsRedirectingFactory()); | 876 ASSERT(!func.IsRedirectingFactory()); |
| 870 if (!func.IsImplicitConstructor()) { | 877 if (!func.IsImplicitConstructor()) { |
| 871 parser.SkipFunctionPreamble(); | 878 parser.SkipFunctionPreamble(); |
| 872 } | 879 } |
| 873 node_sequence = parser.ParseFunc(func, &default_parameter_values); | 880 node_sequence = parser.ParseFunc(func, &default_parameter_values); |
| 874 break; | 881 break; |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 | 1303 |
| 1297 EnsureExpressionTemp(); | 1304 EnsureExpressionTemp(); |
| 1298 StoreInstanceFieldNode* store_field = | 1305 StoreInstanceFieldNode* store_field = |
| 1299 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1306 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 1300 current_block_->statements->Add(store_field); | 1307 current_block_->statements->Add(store_field); |
| 1301 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 1308 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
| 1302 return CloseBlock(); | 1309 return CloseBlock(); |
| 1303 } | 1310 } |
| 1304 | 1311 |
| 1305 | 1312 |
| 1313 SequenceNode* Parser::ParseImplicitClosure(const Function& func, | |
| 1314 Array* default_values) { | |
| 1315 TRACE_PARSER("ParseImplicitClosure"); | |
| 1316 | |
| 1317 intptr_t token_pos = func.token_pos(); | |
|
Florian Schneider
2015/03/23 13:45:37
0 (Scanner::kNoSourcePos) does not work since it c
| |
| 1318 | |
| 1319 OpenFunctionBlock(func); | |
| 1320 | |
| 1321 ParamList params; | |
| 1322 | |
| 1323 params.AddFinalParameter( | |
| 1324 token_pos, | |
| 1325 &Symbols::ClosureParameter(), | |
| 1326 &Type::ZoneHandle(Type::DynamicType())); | |
| 1327 | |
| 1328 const bool allow_explicit_default_values = true; | |
| 1329 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.
| |
| 1330 SetupDefaultsForOptionalParams(¶ms, default_values); | |
| 1331 | |
| 1332 // Populate function scope with the formal parameters. | |
| 1333 LocalScope* scope = current_block_->scope; | |
| 1334 AddFormalParamsToScope(¶ms, scope); | |
| 1335 | |
| 1336 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | |
| 1337 if (!func.is_static()) { | |
| 1338 func_args->Add(LoadReceiver(token_pos)); | |
| 1339 } | |
| 1340 // Skip implicit parameter at 0. | |
| 1341 for (intptr_t i = 1; i < func.NumParameters(); ++i) { | |
| 1342 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | |
| 1343 } | |
| 1344 | |
| 1345 if (func.HasOptionalNamedParameters()) { | |
| 1346 const Array& arg_names = | |
| 1347 Array::ZoneHandle(Array::New(func.NumOptionalParameters())); | |
| 1348 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | |
| 1349 intptr_t index = func.num_fixed_parameters() + i; | |
| 1350 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); | |
| 1351 } | |
| 1352 func_args->set_names(arg_names); | |
| 1353 } | |
| 1354 const Function& parent = Function::ZoneHandle(func.parent_function()); | |
| 1355 StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args); | |
| 1356 ReturnNode* return_node = new ReturnNode(token_pos, call); | |
| 1357 current_block_->statements->Add(return_node); | |
| 1358 return CloseBlock(); | |
| 1359 } | |
| 1360 | |
| 1361 | |
| 1306 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1362 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1307 TRACE_PARSER("ParseMethodExtractor"); | 1363 TRACE_PARSER("ParseMethodExtractor"); |
| 1308 ParamList params; | 1364 ParamList params; |
| 1309 | 1365 |
| 1310 const intptr_t ident_pos = func.token_pos(); | 1366 const intptr_t ident_pos = func.token_pos(); |
| 1311 ASSERT(func.token_pos() == 0); | 1367 ASSERT(func.token_pos() == 0); |
| 1312 ASSERT(current_class().raw() == func.Owner()); | 1368 ASSERT(current_class().raw() == func.Owner()); |
| 1313 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1369 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1314 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1370 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1315 ASSERT(!func.HasOptionalParameters()); | 1371 ASSERT(!func.HasOptionalParameters()); |
| (...skipping 11907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13223 void Parser::SkipQualIdent() { | 13279 void Parser::SkipQualIdent() { |
| 13224 ASSERT(IsIdentifier()); | 13280 ASSERT(IsIdentifier()); |
| 13225 ConsumeToken(); | 13281 ConsumeToken(); |
| 13226 if (CurrentToken() == Token::kPERIOD) { | 13282 if (CurrentToken() == Token::kPERIOD) { |
| 13227 ConsumeToken(); // Consume the kPERIOD token. | 13283 ConsumeToken(); // Consume the kPERIOD token. |
| 13228 ExpectIdentifier("identifier expected after '.'"); | 13284 ExpectIdentifier("identifier expected after '.'"); |
| 13229 } | 13285 } |
| 13230 } | 13286 } |
| 13231 | 13287 |
| 13232 } // namespace dart | 13288 } // namespace dart |
| OLD | NEW |