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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 ident_pos, | 1008 ident_pos, |
1009 Token::kEQ_STRICT, | 1009 Token::kEQ_STRICT, |
1010 new LoadStaticFieldNode(ident_pos, field), | 1010 new LoadStaticFieldNode(ident_pos, field), |
1011 new LiteralNode(ident_pos, Object::sentinel())); | 1011 new LiteralNode(ident_pos, Object::sentinel())); |
1012 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); | 1012 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); |
1013 initialize_field->Add( | 1013 initialize_field->Add( |
1014 new StoreStaticFieldNode( | 1014 new StoreStaticFieldNode( |
1015 ident_pos, | 1015 ident_pos, |
1016 field, | 1016 field, |
1017 new LiteralNode(ident_pos, Object::transition_sentinel()))); | 1017 new LiteralNode(ident_pos, Object::transition_sentinel()))); |
1018 // TODO(hausner): If evaluation of the field value throws an exception, | 1018 const String& init_name = String::Handle( |
1019 // we leave the field value as 'transition_sentinel', which is wrong. | 1019 Symbols::New(String::Handle(String::Concat( |
1020 // A second reference to the field later throws a circular dependency | 1020 Symbols::InitPrefix(), String::Handle(field.name()))))); |
1021 // exception. The field should instead be set to null after an exception. | |
1022 const String& init_name = | |
1023 String::Handle(Symbols::New(String::Handle( | |
1024 String::Concat(Symbols::InitPrefix(), String::Handle(field.name()))))); | |
1025 const Function& init_function = Function::ZoneHandle( | 1021 const Function& init_function = Function::ZoneHandle( |
1026 field_class.LookupStaticFunction(init_name)); | 1022 field_class.LookupStaticFunction(init_name)); |
1027 ASSERT(!init_function.IsNull()); | 1023 ASSERT(!init_function.IsNull()); |
1028 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); | 1024 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); |
1029 StaticCallNode* init_call = | 1025 StaticCallNode* init_call = |
1030 new StaticCallNode(expr_pos, init_function, arguments); | 1026 new StaticCallNode(expr_pos, init_function, arguments); |
| 1027 initialize_field->Add(init_call); |
1031 | 1028 |
1032 initialize_field->Add(new StoreStaticFieldNode(ident_pos, | |
1033 field, | |
1034 init_call)); | |
1035 AstNode* uninitialized_check = | 1029 AstNode* uninitialized_check = |
1036 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | 1030 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); |
1037 current_block_->statements->Add(uninitialized_check); | 1031 current_block_->statements->Add(uninitialized_check); |
1038 | 1032 |
1039 // Generate code returning the field value. | 1033 // Generate code returning the field value. |
1040 ReturnNode* return_node = | 1034 ReturnNode* return_node = |
1041 new ReturnNode(ident_pos, | 1035 new ReturnNode(ident_pos, |
1042 new LoadStaticFieldNode(ident_pos, field)); | 1036 new LoadStaticFieldNode(ident_pos, field)); |
1043 current_block_->statements->Add(return_node); | 1037 current_block_->statements->Add(return_node); |
1044 } | 1038 } |
1045 return CloseBlock(); | 1039 return CloseBlock(); |
1046 } | 1040 } |
1047 | 1041 |
1048 | 1042 |
1049 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | 1043 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { |
1050 TRACE_PARSER("ParseStaticInitializer"); | 1044 TRACE_PARSER("ParseStaticInitializer"); |
1051 ParamList params; | 1045 ParamList params; |
1052 ASSERT(func.num_fixed_parameters() == 0); // static. | 1046 ASSERT(func.num_fixed_parameters() == 0); // static. |
1053 ASSERT(!func.HasOptionalParameters()); | 1047 ASSERT(!func.HasOptionalParameters()); |
1054 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1048 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
1055 | 1049 |
1056 // Build local scope for function and populate with the formal parameters. | 1050 // Build local scope for function and populate with the formal parameters. |
1057 OpenFunctionBlock(func); | 1051 OpenFunctionBlock(func); |
1058 AddFormalParamsToScope(¶ms, current_block_->scope); | 1052 AddFormalParamsToScope(¶ms, current_block_->scope); |
1059 | 1053 |
1060 intptr_t expr_pos = func.token_pos(); | 1054 // Move forward to the start of the initializer expression. |
| 1055 ExpectIdentifier("identifier expected"); |
| 1056 ExpectToken(Token::kASSIGN); |
| 1057 intptr_t token_pos = TokenPos(); |
| 1058 |
| 1059 // Synthesize a try-catch block to wrap the initializer expression. |
| 1060 LocalVariable* context_var = |
| 1061 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 1062 if (context_var == NULL) { |
| 1063 context_var = new LocalVariable(token_pos, |
| 1064 Symbols::SavedTryContextVar(), |
| 1065 Type::ZoneHandle(Type::DynamicType())); |
| 1066 current_block_->scope->AddVariable(context_var); |
| 1067 } |
| 1068 LocalVariable* catch_excp_var = |
| 1069 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 1070 if (catch_excp_var == NULL) { |
| 1071 catch_excp_var = new LocalVariable(token_pos, |
| 1072 Symbols::ExceptionVar(), |
| 1073 Type::ZoneHandle(Type::DynamicType())); |
| 1074 current_block_->scope->AddVariable(catch_excp_var); |
| 1075 } |
| 1076 LocalVariable* catch_trace_var = |
| 1077 current_block_->scope->LocalLookupVariable(Symbols::StacktraceVar()); |
| 1078 if (catch_trace_var == NULL) { |
| 1079 catch_trace_var = new LocalVariable(token_pos, |
| 1080 Symbols::StacktraceVar(), |
| 1081 Type::ZoneHandle(Type::DynamicType())); |
| 1082 current_block_->scope->AddVariable(catch_trace_var); |
| 1083 } |
| 1084 |
| 1085 OpenBlock(); // Start try block. |
1061 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1086 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1062 ReturnNode* return_node = new ReturnNode(expr_pos, expr); | 1087 const Field& field = Field::ZoneHandle(func.saved_static_field()); |
1063 current_block_->statements->Add(return_node); | 1088 ASSERT(!field.is_const()); |
| 1089 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), |
| 1090 field, |
| 1091 expr); |
| 1092 current_block_->statements->Add(store); |
| 1093 SequenceNode* try_block = CloseBlock(); // End try block. |
| 1094 |
| 1095 OpenBlock(); // Start catch handler list. |
| 1096 SourceLabel* end_catch_label = |
| 1097 SourceLabel::New(token_pos, NULL, SourceLabel::kCatch); |
| 1098 current_block_->scope->AddLabel(end_catch_label); |
| 1099 |
| 1100 OpenBlock(); // Start catch clause. |
| 1101 AstNode* compare_transition_sentinel = new ComparisonNode( |
| 1102 token_pos, |
| 1103 Token::kEQ_STRICT, |
| 1104 new LoadStaticFieldNode(token_pos, field), |
| 1105 new LiteralNode(field.token_pos(), Object::transition_sentinel())); |
| 1106 |
| 1107 SequenceNode* store_null = new SequenceNode(token_pos, NULL); |
| 1108 store_null->Add(new StoreStaticFieldNode( |
| 1109 field.token_pos(), |
| 1110 field, |
| 1111 new LiteralNode(token_pos, Instance::ZoneHandle()))); |
| 1112 AstNode* transition_sentinel_check = |
| 1113 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); |
| 1114 current_block_->statements->Add(transition_sentinel_check); |
| 1115 |
| 1116 current_block_->statements->Add( |
| 1117 new ThrowNode(token_pos, |
| 1118 new LoadLocalNode(token_pos, catch_excp_var), |
| 1119 new LoadLocalNode(token_pos, catch_trace_var))); |
| 1120 current_block_->statements->Add( |
| 1121 new JumpNode(token_pos, Token::kCONTINUE, end_catch_label)); |
| 1122 SequenceNode* catch_clause = CloseBlock(); // End catch clause. |
| 1123 |
| 1124 current_block_->statements->Add(catch_clause); |
| 1125 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list. |
| 1126 CatchClauseNode* catch_block = |
| 1127 new CatchClauseNode(token_pos, |
| 1128 catch_handler_list, |
| 1129 Array::ZoneHandle(Object::empty_array().raw()), |
| 1130 context_var, |
| 1131 catch_excp_var, |
| 1132 catch_trace_var, |
| 1133 CatchClauseNode::kInvalidTryIndex, |
| 1134 false); // No stack trace needed. |
| 1135 |
| 1136 AstNode* try_catch_node = new TryCatchNode(token_pos, |
| 1137 try_block, |
| 1138 end_catch_label, |
| 1139 context_var, |
| 1140 catch_block, |
| 1141 NULL, // No finally block. |
| 1142 AllocateTryIndex()); |
| 1143 current_block_->statements->Add(try_catch_node); |
1064 return CloseBlock(); | 1144 return CloseBlock(); |
1065 } | 1145 } |
1066 | 1146 |
1067 | 1147 |
1068 // Create AstNodes for an implicit instance getter method: | 1148 // Create AstNodes for an implicit instance getter method: |
1069 // LoadLocalNode 0 ('this'); | 1149 // LoadLocalNode 0 ('this'); |
1070 // LoadInstanceFieldNode (field_name); | 1150 // LoadInstanceFieldNode (field_name); |
1071 // ReturnNode (field's value); | 1151 // ReturnNode (field's value); |
1072 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1152 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
1073 TRACE_PARSER("ParseInstanceGetter"); | 1153 TRACE_PARSER("ParseInstanceGetter"); |
(...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3300 if (field->has_factory) { | 3380 if (field->has_factory) { |
3301 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 3381 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
3302 } | 3382 } |
3303 if (!field->has_static && field->has_const) { | 3383 if (!field->has_static && field->has_const) { |
3304 ErrorMsg(field->name_pos, "instance field may not be 'const'"); | 3384 ErrorMsg(field->name_pos, "instance field may not be 'const'"); |
3305 } | 3385 } |
3306 Function& getter = Function::Handle(); | 3386 Function& getter = Function::Handle(); |
3307 Function& setter = Function::Handle(); | 3387 Function& setter = Function::Handle(); |
3308 Field& class_field = Field::ZoneHandle(); | 3388 Field& class_field = Field::ZoneHandle(); |
3309 Instance& init_value = Instance::Handle(); | 3389 Instance& init_value = Instance::Handle(); |
3310 intptr_t expr_pos = -1; | |
3311 while (true) { | 3390 while (true) { |
3312 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3391 bool has_initializer = CurrentToken() == Token::kASSIGN; |
3313 bool has_simple_literal = false; | 3392 bool has_simple_literal = false; |
3314 if (has_initializer) { | 3393 if (has_initializer) { |
3315 ConsumeToken(); | 3394 ConsumeToken(); |
3316 init_value = Object::sentinel().raw(); | 3395 init_value = Object::sentinel().raw(); |
3317 // For static const fields and static final non-const fields, the | 3396 // For static const fields and static final non-const fields, the |
3318 // initialization expression will be parsed through the | 3397 // initialization expression will be parsed through the |
3319 // kImplicitStaticFinalGetter method invocation/compilation. | 3398 // kImplicitStaticFinalGetter method invocation/compilation. |
3320 // For instance fields, the expression is parsed when a constructor | 3399 // For instance fields, the expression is parsed when a constructor |
3321 // is compiled. | 3400 // is compiled. |
3322 // For static const fields and static final non-const fields with very | 3401 // For static const fields and static final non-const fields with very |
3323 // simple initializer expressions (e.g. a literal number or string), we | 3402 // simple initializer expressions (e.g. a literal number or string), we |
3324 // optimize away the kImplicitStaticFinalGetter and initialize the field | 3403 // optimize away the kImplicitStaticFinalGetter and initialize the field |
3325 // here. However, the class finalizer will check the value type for | 3404 // here. However, the class finalizer will check the value type for |
3326 // assignability once the declared field type can be resolved. If the | 3405 // assignability once the declared field type can be resolved. If the |
3327 // value is not assignable (assuming checked mode and disregarding actual | 3406 // value is not assignable (assuming checked mode and disregarding actual |
3328 // mode), the field value is reset and a kImplicitStaticFinalGetter is | 3407 // mode), the field value is reset and a kImplicitStaticFinalGetter is |
3329 // created at finalization time. | 3408 // created at finalization time. |
3330 | 3409 |
3331 if (field->has_static && (field->has_const || field->has_final) && | 3410 if (field->has_static && (field->has_const || field->has_final) && |
3332 (LookaheadToken(1) == Token::kSEMICOLON)) { | 3411 (LookaheadToken(1) == Token::kSEMICOLON)) { |
3333 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3412 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
3334 } | 3413 } |
3335 expr_pos = TokenPos(); | |
3336 SkipExpr(); | 3414 SkipExpr(); |
3337 } else { | 3415 } else { |
3338 // Static const and static final fields must have an initializer. | 3416 // Static const and static final fields must have an initializer. |
3339 // Static const fields are implicitly final. | 3417 // Static const fields are implicitly final. |
3340 if (field->has_static && field->has_final) { | 3418 if (field->has_static && field->has_final) { |
3341 ErrorMsg(field->name_pos, | 3419 ErrorMsg(field->name_pos, |
3342 "static %s field '%s' must have an initializer expression", | 3420 "static %s field '%s' must have an initializer expression", |
3343 field->has_const ? "const" : "final", | 3421 field->has_const ? "const" : "final", |
3344 field->name->ToCString()); | 3422 field->name->ToCString()); |
3345 } | 3423 } |
(...skipping 24 matching lines...) Expand all Loading... |
3370 RawFunction::kImplicitStaticFinalGetter, | 3448 RawFunction::kImplicitStaticFinalGetter, |
3371 field->has_static, | 3449 field->has_static, |
3372 field->has_const, | 3450 field->has_const, |
3373 /* is_abstract = */ false, | 3451 /* is_abstract = */ false, |
3374 /* is_external = */ false, | 3452 /* is_external = */ false, |
3375 current_class(), | 3453 current_class(), |
3376 field->name_pos); | 3454 field->name_pos); |
3377 getter.set_result_type(*field->type); | 3455 getter.set_result_type(*field->type); |
3378 members->AddFunction(getter); | 3456 members->AddFunction(getter); |
3379 | 3457 |
3380 // Create initializer function. | 3458 // Create initializer function for non-const fields. |
3381 const Function& init_function = Function::ZoneHandle( | 3459 if (!class_field.is_const()) { |
3382 Function::NewStaticInitializer(*field->name, | 3460 const Function& init_function = Function::ZoneHandle( |
3383 *field->type, | 3461 Function::NewStaticInitializer(class_field)); |
3384 current_class(), | 3462 members->AddFunction(init_function); |
3385 expr_pos)); | 3463 } |
3386 members->AddFunction(init_function); | |
3387 } | 3464 } |
3388 } | 3465 } |
3389 | 3466 |
3390 // For instance fields, we create implicit getter and setter methods. | 3467 // For instance fields, we create implicit getter and setter methods. |
3391 if (!field->has_static) { | 3468 if (!field->has_static) { |
3392 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 3469 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
3393 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 3470 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
3394 field->has_static, | 3471 field->has_static, |
3395 field->has_final, | 3472 field->has_final, |
3396 /* is_abstract = */ false, | 3473 /* is_abstract = */ false, |
(...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4486 if (metadata_pos >= 0) { | 4563 if (metadata_pos >= 0) { |
4487 library_.AddFieldMetadata(field, metadata_pos); | 4564 library_.AddFieldMetadata(field, metadata_pos); |
4488 } | 4565 } |
4489 if (CurrentToken() == Token::kASSIGN) { | 4566 if (CurrentToken() == Token::kASSIGN) { |
4490 ConsumeToken(); | 4567 ConsumeToken(); |
4491 Instance& field_value = Instance::Handle(Object::sentinel().raw()); | 4568 Instance& field_value = Instance::Handle(Object::sentinel().raw()); |
4492 bool has_simple_literal = false; | 4569 bool has_simple_literal = false; |
4493 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) { | 4570 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) { |
4494 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4571 has_simple_literal = IsSimpleLiteral(type, &field_value); |
4495 } | 4572 } |
4496 const intptr_t expr_pos = TokenPos(); | |
4497 SkipExpr(); | 4573 SkipExpr(); |
4498 field.set_value(field_value); | 4574 field.set_value(field_value); |
4499 if (!has_simple_literal) { | 4575 if (!has_simple_literal) { |
4500 // Create a static final getter. | 4576 // Create a static final getter. |
4501 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); | 4577 String& getter_name = String::Handle(Field::GetterSymbol(var_name)); |
4502 getter = Function::New(getter_name, | 4578 getter = Function::New(getter_name, |
4503 RawFunction::kImplicitStaticFinalGetter, | 4579 RawFunction::kImplicitStaticFinalGetter, |
4504 is_static, | 4580 is_static, |
4505 is_const, | 4581 is_const, |
4506 /* is_abstract = */ false, | 4582 /* is_abstract = */ false, |
4507 /* is_external = */ false, | 4583 /* is_external = */ false, |
4508 current_class(), | 4584 current_class(), |
4509 name_pos); | 4585 name_pos); |
4510 getter.set_result_type(type); | 4586 getter.set_result_type(type); |
4511 top_level->functions.Add(getter); | 4587 top_level->functions.Add(getter); |
4512 | 4588 |
4513 // Create initializer function. | 4589 // Create initializer function. |
4514 const Function& init_function = Function::ZoneHandle( | 4590 if (!field.is_const()) { |
4515 Function::NewStaticInitializer(var_name, | 4591 const Function& init_function = Function::ZoneHandle( |
4516 type, | 4592 Function::NewStaticInitializer(field)); |
4517 current_class(), | 4593 top_level->functions.Add(init_function); |
4518 expr_pos)); | 4594 } |
4519 top_level->functions.Add(init_function); | |
4520 } | 4595 } |
4521 } else if (is_final) { | 4596 } else if (is_final) { |
4522 ErrorMsg(name_pos, "missing initializer for final or const variable"); | 4597 ErrorMsg(name_pos, "missing initializer for final or const variable"); |
4523 } | 4598 } |
4524 | 4599 |
4525 if (CurrentToken() == Token::kCOMMA) { | 4600 if (CurrentToken() == Token::kCOMMA) { |
4526 ConsumeToken(); | 4601 ConsumeToken(); |
4527 } else if (CurrentToken() == Token::kSEMICOLON) { | 4602 } else if (CurrentToken() == Token::kSEMICOLON) { |
4528 ConsumeToken(); | 4603 ConsumeToken(); |
4529 break; | 4604 break; |
(...skipping 2205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6735 // Now create a label for the end of catch block processing so that we can | 6810 // Now create a label for the end of catch block processing so that we can |
6736 // jump over the catch block code after executing the try block. | 6811 // jump over the catch block code after executing the try block. |
6737 SourceLabel* end_catch_label = | 6812 SourceLabel* end_catch_label = |
6738 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); | 6813 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); |
6739 | 6814 |
6740 // Now parse the 'catch' blocks if any and merge all of them into | 6815 // Now parse the 'catch' blocks if any and merge all of them into |
6741 // an if-then sequence of the different types specified using the 'is' | 6816 // an if-then sequence of the different types specified using the 'is' |
6742 // operator. | 6817 // operator. |
6743 bool catch_seen = false; | 6818 bool catch_seen = false; |
6744 bool generic_catch_seen = false; | 6819 bool generic_catch_seen = false; |
6745 SequenceNode* catch_handler_list = NULL; | |
6746 const intptr_t handler_pos = TokenPos(); | 6820 const intptr_t handler_pos = TokenPos(); |
6747 OpenBlock(); // Start the catch block sequence. | 6821 OpenBlock(); // Start the catch block sequence. |
6748 current_block_->scope->AddLabel(end_catch_label); | 6822 current_block_->scope->AddLabel(end_catch_label); |
6749 const GrowableObjectArray& handler_types = | 6823 const GrowableObjectArray& handler_types = |
6750 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6824 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
6751 bool needs_stacktrace = false; | 6825 bool needs_stacktrace = false; |
6752 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6826 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
6753 const intptr_t catch_pos = TokenPos(); | 6827 const intptr_t catch_pos = TokenPos(); |
6754 CatchParamDesc exception_param; | 6828 CatchParamDesc exception_param; |
6755 CatchParamDesc stack_trace_param; | 6829 CatchParamDesc stack_trace_param; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6859 // This catch clause will handle all exceptions. We can safely forget | 6933 // This catch clause will handle all exceptions. We can safely forget |
6860 // all previous catch clause types. | 6934 // all previous catch clause types. |
6861 handler_types.SetLength(0); | 6935 handler_types.SetLength(0); |
6862 handler_types.Add(*exception_param.type); | 6936 handler_types.Add(*exception_param.type); |
6863 } | 6937 } |
6864 SequenceNode* catch_clause = CloseBlock(); | 6938 SequenceNode* catch_clause = CloseBlock(); |
6865 | 6939 |
6866 // Add this individual catch handler to the catch handlers list. | 6940 // Add this individual catch handler to the catch handlers list. |
6867 current_block_->statements->Add(catch_clause); | 6941 current_block_->statements->Add(catch_clause); |
6868 } | 6942 } |
6869 catch_handler_list = CloseBlock(); | 6943 SequenceNode* catch_handler_list = CloseBlock(); |
6870 TryBlocks* inner_try_block = PopTryBlock(); | 6944 TryBlocks* inner_try_block = PopTryBlock(); |
6871 const intptr_t try_index = inner_try_block->try_index(); | 6945 const intptr_t try_index = inner_try_block->try_index(); |
6872 TryBlocks* outer_try_block = try_blocks_list_; | 6946 TryBlocks* outer_try_block = try_blocks_list_; |
6873 const intptr_t outer_try_index = (outer_try_block != NULL) | 6947 const intptr_t outer_try_index = (outer_try_block != NULL) |
6874 ? outer_try_block->try_index() | 6948 ? outer_try_block->try_index() |
6875 : CatchClauseNode::kInvalidTryIndex; | 6949 : CatchClauseNode::kInvalidTryIndex; |
6876 | 6950 |
6877 // Finally parse the 'finally' block. | 6951 // Finally parse the 'finally' block. |
6878 SequenceNode* finally_block = NULL; | 6952 SequenceNode* finally_block = NULL; |
6879 if (CurrentToken() == Token::kFINALLY) { | 6953 if (CurrentToken() == Token::kFINALLY) { |
(...skipping 3782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10662 void Parser::SkipQualIdent() { | 10736 void Parser::SkipQualIdent() { |
10663 ASSERT(IsIdentifier()); | 10737 ASSERT(IsIdentifier()); |
10664 ConsumeToken(); | 10738 ConsumeToken(); |
10665 if (CurrentToken() == Token::kPERIOD) { | 10739 if (CurrentToken() == Token::kPERIOD) { |
10666 ConsumeToken(); // Consume the kPERIOD token. | 10740 ConsumeToken(); // Consume the kPERIOD token. |
10667 ExpectIdentifier("identifier expected after '.'"); | 10741 ExpectIdentifier("identifier expected after '.'"); |
10668 } | 10742 } |
10669 } | 10743 } |
10670 | 10744 |
10671 } // namespace dart | 10745 } // namespace dart |
OLD | NEW |