| 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 |