| 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 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 | 1584 |
| 1585 String& Parser::ParseNativeDeclaration() { | 1585 String& Parser::ParseNativeDeclaration() { |
| 1586 TRACE_PARSER("ParseNativeDeclaration"); | 1586 TRACE_PARSER("ParseNativeDeclaration"); |
| 1587 ASSERT(IsLiteral("native")); | 1587 ASSERT(IsLiteral("native")); |
| 1588 ConsumeToken(); | 1588 ConsumeToken(); |
| 1589 if (CurrentToken() != Token::kSTRING) { | 1589 if (CurrentToken() != Token::kSTRING) { |
| 1590 ErrorMsg("string literal expected"); | 1590 ErrorMsg("string literal expected"); |
| 1591 } | 1591 } |
| 1592 String& native_name = *CurrentLiteral(); | 1592 String& native_name = *CurrentLiteral(); |
| 1593 ConsumeToken(); | 1593 ConsumeToken(); |
| 1594 ExpectSemicolon(); | |
| 1595 return native_name; | 1594 return native_name; |
| 1596 } | 1595 } |
| 1597 | 1596 |
| 1598 | 1597 |
| 1599 // Resolve and return the dynamic function of the given name in the superclass. | 1598 // Resolve and return the dynamic function of the given name in the superclass. |
| 1600 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1599 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1601 // the same name. If it is still not found, return noSuchMethod and | 1600 // the same name. If it is still not found, return noSuchMethod and |
| 1602 // set is_no_such_method to true.. | 1601 // set is_no_such_method to true.. |
| 1603 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1602 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1604 const String& name, | 1603 const String& name, |
| (...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2742 if (IsInstantiatorRequired()) { | 2741 if (IsInstantiatorRequired()) { |
| 2743 // Make sure that the receiver of the enclosing instance function | 2742 // Make sure that the receiver of the enclosing instance function |
| 2744 // (or implicit first parameter of an enclosing factory) is marked as | 2743 // (or implicit first parameter of an enclosing factory) is marked as |
| 2745 // captured if type checks are enabled, because they may access it to | 2744 // captured if type checks are enabled, because they may access it to |
| 2746 // instantiate types. | 2745 // instantiate types. |
| 2747 CaptureInstantiator(); | 2746 CaptureInstantiator(); |
| 2748 } | 2747 } |
| 2749 } | 2748 } |
| 2750 | 2749 |
| 2751 OpenBlock(); // Open a nested scope for the outermost function block. | 2750 OpenBlock(); // Open a nested scope for the outermost function block. |
| 2751 intptr_t end_token_pos = 0; |
| 2752 if (CurrentToken() == Token::kLBRACE) { | 2752 if (CurrentToken() == Token::kLBRACE) { |
| 2753 ConsumeToken(); | 2753 ConsumeToken(); |
| 2754 ParseStatementSequence(); | 2754 ParseStatementSequence(); |
| 2755 end_token_pos = TokenPos(); |
| 2755 ExpectToken(Token::kRBRACE); | 2756 ExpectToken(Token::kRBRACE); |
| 2756 } else if (CurrentToken() == Token::kARROW) { | 2757 } else if (CurrentToken() == Token::kARROW) { |
| 2757 ConsumeToken(); | 2758 ConsumeToken(); |
| 2758 const intptr_t expr_pos = TokenPos(); | 2759 const intptr_t expr_pos = TokenPos(); |
| 2759 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 2760 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2760 ASSERT(expr != NULL); | 2761 ASSERT(expr != NULL); |
| 2761 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 2762 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 2763 end_token_pos = TokenPos(); |
| 2762 } else if (IsLiteral("native")) { | 2764 } else if (IsLiteral("native")) { |
| 2763 ParseNativeFunctionBlock(¶ms, func); | 2765 ParseNativeFunctionBlock(¶ms, func); |
| 2766 end_token_pos = TokenPos(); |
| 2767 ExpectSemicolon(); |
| 2764 } else if (func.is_external()) { | 2768 } else if (func.is_external()) { |
| 2765 // Body of an external method contains a single throw. | 2769 // Body of an external method contains a single throw. |
| 2766 const String& function_name = String::ZoneHandle(func.name()); | 2770 const String& function_name = String::ZoneHandle(func.name()); |
| 2767 // TODO(regis): For an instance function, pass the receiver to | 2771 // TODO(regis): For an instance function, pass the receiver to |
| 2768 // NoSuchMethodError. | 2772 // NoSuchMethodError. |
| 2769 current_block_->statements->Add( | 2773 current_block_->statements->Add( |
| 2770 ThrowNoSuchMethodError(TokenPos(), | 2774 ThrowNoSuchMethodError(TokenPos(), |
| 2771 current_class(), | 2775 current_class(), |
| 2772 function_name, | 2776 function_name, |
| 2773 func.is_static() ? | 2777 func.is_static() ? |
| 2774 InvocationMirror::kStatic : | 2778 InvocationMirror::kStatic : |
| 2775 InvocationMirror::kDynamic, | 2779 InvocationMirror::kDynamic, |
| 2776 InvocationMirror::kMethod)); | 2780 InvocationMirror::kMethod)); |
| 2781 end_token_pos = TokenPos(); |
| 2777 } else { | 2782 } else { |
| 2778 UnexpectedToken(); | 2783 UnexpectedToken(); |
| 2779 } | 2784 } |
| 2785 ASSERT(func.end_token_pos() == func.token_pos() || |
| 2786 func.end_token_pos() == end_token_pos); |
| 2787 func.set_end_token_pos(end_token_pos); |
| 2780 SequenceNode* body = CloseBlock(); | 2788 SequenceNode* body = CloseBlock(); |
| 2781 current_block_->statements->Add(body); | 2789 current_block_->statements->Add(body); |
| 2782 innermost_function_ = saved_innermost_function.raw(); | 2790 innermost_function_ = saved_innermost_function.raw(); |
| 2783 last_used_try_index_ = saved_try_index; | 2791 last_used_try_index_ = saved_try_index; |
| 2784 return CloseBlock(); | 2792 return CloseBlock(); |
| 2785 } | 2793 } |
| 2786 | 2794 |
| 2787 | 2795 |
| 2788 void Parser::SkipIf(Token::Kind token) { | 2796 void Parser::SkipIf(Token::Kind token) { |
| 2789 if (CurrentToken() == token) { | 2797 if (CurrentToken() == token) { |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3068 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3076 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 3069 ErrorMsg(method->name_pos, | 3077 ErrorMsg(method->name_pos, |
| 3070 "const constructor or factory '%s' may not be native", | 3078 "const constructor or factory '%s' may not be native", |
| 3071 method->name->ToCString()); | 3079 method->name->ToCString()); |
| 3072 } | 3080 } |
| 3073 if (method->redirect_name != NULL) { | 3081 if (method->redirect_name != NULL) { |
| 3074 ErrorMsg(method->name_pos, | 3082 ErrorMsg(method->name_pos, |
| 3075 "Constructor with redirection may not have a function body"); | 3083 "Constructor with redirection may not have a function body"); |
| 3076 } | 3084 } |
| 3077 ParseNativeDeclaration(); | 3085 ParseNativeDeclaration(); |
| 3086 method_end_pos = TokenPos(); |
| 3087 ExpectSemicolon(); |
| 3078 } else { | 3088 } else { |
| 3079 // We haven't found a method body. Issue error if one is required. | 3089 // We haven't found a method body. Issue error if one is required. |
| 3080 const bool must_have_body = | 3090 const bool must_have_body = |
| 3081 method->has_static && | 3091 method->has_static && |
| 3082 !method->has_external && | 3092 !method->has_external && |
| 3083 redirection_type.IsNull(); | 3093 redirection_type.IsNull(); |
| 3084 if (must_have_body) { | 3094 if (must_have_body) { |
| 3085 ErrorMsg(method->name_pos, | 3095 ErrorMsg(method->name_pos, |
| 3086 "function body expected for method '%s'", | 3096 "function body expected for method '%s'", |
| 3087 method->name->ToCString()); | 3097 method->name->ToCString()); |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4417 if (CurrentToken() != Token::kLPAREN) { | 4427 if (CurrentToken() != Token::kLPAREN) { |
| 4418 ErrorMsg("'(' expected"); | 4428 ErrorMsg("'(' expected"); |
| 4419 } | 4429 } |
| 4420 const intptr_t function_pos = TokenPos(); | 4430 const intptr_t function_pos = TokenPos(); |
| 4421 ParamList params; | 4431 ParamList params; |
| 4422 const bool allow_explicit_default_values = true; | 4432 const bool allow_explicit_default_values = true; |
| 4423 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 4433 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 4424 | 4434 |
| 4425 intptr_t function_end_pos = function_pos; | 4435 intptr_t function_end_pos = function_pos; |
| 4426 if (is_external) { | 4436 if (is_external) { |
| 4437 function_end_pos = TokenPos(); |
| 4427 ExpectSemicolon(); | 4438 ExpectSemicolon(); |
| 4428 } else if (CurrentToken() == Token::kLBRACE) { | 4439 } else if (CurrentToken() == Token::kLBRACE) { |
| 4429 SkipBlock(); | 4440 SkipBlock(); |
| 4430 function_end_pos = TokenPos() - 1; | 4441 function_end_pos = TokenPos() - 1; |
| 4431 } else if (CurrentToken() == Token::kARROW) { | 4442 } else if (CurrentToken() == Token::kARROW) { |
| 4432 ConsumeToken(); | 4443 ConsumeToken(); |
| 4433 SkipExpr(); | 4444 SkipExpr(); |
| 4445 function_end_pos = TokenPos(); |
| 4434 ExpectSemicolon(); | 4446 ExpectSemicolon(); |
| 4435 function_end_pos = TokenPos() - 1; | |
| 4436 } else if (IsLiteral("native")) { | 4447 } else if (IsLiteral("native")) { |
| 4437 ParseNativeDeclaration(); | 4448 ParseNativeDeclaration(); |
| 4449 function_end_pos = TokenPos(); |
| 4450 ExpectSemicolon(); |
| 4438 } else { | 4451 } else { |
| 4439 ErrorMsg("function block expected"); | 4452 ErrorMsg("function block expected"); |
| 4440 } | 4453 } |
| 4441 Function& func = Function::Handle( | 4454 Function& func = Function::Handle( |
| 4442 Function::New(func_name, | 4455 Function::New(func_name, |
| 4443 RawFunction::kRegularFunction, | 4456 RawFunction::kRegularFunction, |
| 4444 is_static, | 4457 is_static, |
| 4445 /* is_const = */ false, | 4458 /* is_const = */ false, |
| 4446 /* is_abstract = */ false, | 4459 /* is_abstract = */ false, |
| 4447 is_external, | 4460 is_external, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4542 is_getter ? "getter" : "setter", | 4555 is_getter ? "getter" : "setter", |
| 4543 field_name->ToCString()); | 4556 field_name->ToCString()); |
| 4544 } else if (!found && is_patch) { | 4557 } else if (!found && is_patch) { |
| 4545 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", | 4558 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", |
| 4546 is_getter ? "getter" : "setter", | 4559 is_getter ? "getter" : "setter", |
| 4547 field_name->ToCString()); | 4560 field_name->ToCString()); |
| 4548 } | 4561 } |
| 4549 | 4562 |
| 4550 intptr_t accessor_end_pos = accessor_pos; | 4563 intptr_t accessor_end_pos = accessor_pos; |
| 4551 if (is_external) { | 4564 if (is_external) { |
| 4565 accessor_end_pos = TokenPos(); |
| 4552 ExpectSemicolon(); | 4566 ExpectSemicolon(); |
| 4553 } else if (CurrentToken() == Token::kLBRACE) { | 4567 } else if (CurrentToken() == Token::kLBRACE) { |
| 4554 SkipBlock(); | 4568 SkipBlock(); |
| 4555 accessor_end_pos = TokenPos() - 1; | 4569 accessor_end_pos = TokenPos() - 1; |
| 4556 } else if (CurrentToken() == Token::kARROW) { | 4570 } else if (CurrentToken() == Token::kARROW) { |
| 4557 ConsumeToken(); | 4571 ConsumeToken(); |
| 4558 SkipExpr(); | 4572 SkipExpr(); |
| 4573 accessor_end_pos = TokenPos(); |
| 4559 ExpectSemicolon(); | 4574 ExpectSemicolon(); |
| 4560 accessor_end_pos = TokenPos() - 1; | |
| 4561 } else if (IsLiteral("native")) { | 4575 } else if (IsLiteral("native")) { |
| 4562 ParseNativeDeclaration(); | 4576 ParseNativeDeclaration(); |
| 4577 accessor_end_pos = TokenPos(); |
| 4578 ExpectSemicolon(); |
| 4563 } else { | 4579 } else { |
| 4564 ErrorMsg("function block expected"); | 4580 ErrorMsg("function block expected"); |
| 4565 } | 4581 } |
| 4566 Function& func = Function::Handle( | 4582 Function& func = Function::Handle( |
| 4567 Function::New(accessor_name, | 4583 Function::New(accessor_name, |
| 4568 is_getter? RawFunction::kGetterFunction : | 4584 is_getter? RawFunction::kGetterFunction : |
| 4569 RawFunction::kSetterFunction, | 4585 RawFunction::kSetterFunction, |
| 4570 is_static, | 4586 is_static, |
| 4571 /* is_const = */ false, | 4587 /* is_const = */ false, |
| 4572 /* is_abstract = */ false, | 4588 /* is_abstract = */ false, |
| (...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5358 "'%s' from outer scope has already been used, cannot redefine", | 5374 "'%s' from outer scope has already been used, cannot redefine", |
| 5359 function_variable->name().ToCString()); | 5375 function_variable->name().ToCString()); |
| 5360 } | 5376 } |
| 5361 } | 5377 } |
| 5362 } | 5378 } |
| 5363 | 5379 |
| 5364 // Parse the local function. | 5380 // Parse the local function. |
| 5365 Array& default_parameter_values = Array::Handle(); | 5381 Array& default_parameter_values = Array::Handle(); |
| 5366 SequenceNode* statements = Parser::ParseFunc(function, | 5382 SequenceNode* statements = Parser::ParseFunc(function, |
| 5367 default_parameter_values); | 5383 default_parameter_values); |
| 5368 ASSERT(is_new_closure || (function.end_token_pos() == (TokenPos() - 1))); | |
| 5369 function.set_end_token_pos(TokenPos() - 1); | |
| 5370 | 5384 |
| 5371 // Now that the local function has formal parameters, lookup the signature | 5385 // Now that the local function has formal parameters, lookup the signature |
| 5372 // class in the current library (but not in its imports) and only create a new | 5386 // class in the current library (but not in its imports) and only create a new |
| 5373 // canonical signature class if it does not exist yet. | 5387 // canonical signature class if it does not exist yet. |
| 5374 const String& signature = String::Handle(function.Signature()); | 5388 const String& signature = String::Handle(function.Signature()); |
| 5375 Class& signature_class = Class::ZoneHandle(); | 5389 Class& signature_class = Class::ZoneHandle(); |
| 5376 if (!is_new_closure) { | 5390 if (!is_new_closure) { |
| 5377 signature_class = function.signature_class(); | 5391 signature_class = function.signature_class(); |
| 5378 } | 5392 } |
| 5379 if (signature_class.IsNull()) { | 5393 if (signature_class.IsNull()) { |
| (...skipping 5005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10385 void Parser::SkipQualIdent() { | 10399 void Parser::SkipQualIdent() { |
| 10386 ASSERT(IsIdentifier()); | 10400 ASSERT(IsIdentifier()); |
| 10387 ConsumeToken(); | 10401 ConsumeToken(); |
| 10388 if (CurrentToken() == Token::kPERIOD) { | 10402 if (CurrentToken() == Token::kPERIOD) { |
| 10389 ConsumeToken(); // Consume the kPERIOD token. | 10403 ConsumeToken(); // Consume the kPERIOD token. |
| 10390 ExpectIdentifier("identifier expected after '.'"); | 10404 ExpectIdentifier("identifier expected after '.'"); |
| 10391 } | 10405 } |
| 10392 } | 10406 } |
| 10393 | 10407 |
| 10394 } // namespace dart | 10408 } // namespace dart |
| OLD | NEW |