| 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 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1554 | 1554 |
| 1555 String& Parser::ParseNativeDeclaration() { | 1555 String& Parser::ParseNativeDeclaration() { |
| 1556 TRACE_PARSER("ParseNativeDeclaration"); | 1556 TRACE_PARSER("ParseNativeDeclaration"); |
| 1557 ASSERT(IsLiteral("native")); | 1557 ASSERT(IsLiteral("native")); |
| 1558 ConsumeToken(); | 1558 ConsumeToken(); |
| 1559 if (CurrentToken() != Token::kSTRING) { | 1559 if (CurrentToken() != Token::kSTRING) { |
| 1560 ErrorMsg("string literal expected"); | 1560 ErrorMsg("string literal expected"); |
| 1561 } | 1561 } |
| 1562 String& native_name = *CurrentLiteral(); | 1562 String& native_name = *CurrentLiteral(); |
| 1563 ConsumeToken(); | 1563 ConsumeToken(); |
| 1564 ExpectSemicolon(); | |
| 1565 return native_name; | 1564 return native_name; |
| 1566 } | 1565 } |
| 1567 | 1566 |
| 1568 | 1567 |
| 1569 // Resolve and return the dynamic function of the given name in the superclass. | 1568 // Resolve and return the dynamic function of the given name in the superclass. |
| 1570 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1569 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1571 // the same name. If it is still not found, return noSuchMethod and | 1570 // the same name. If it is still not found, return noSuchMethod and |
| 1572 // set is_no_such_method to true.. | 1571 // set is_no_such_method to true.. |
| 1573 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1572 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1574 const String& name, | 1573 const String& name, |
| (...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2687 if (IsInstantiatorRequired()) { | 2686 if (IsInstantiatorRequired()) { |
| 2688 // Make sure that the receiver of the enclosing instance function | 2687 // Make sure that the receiver of the enclosing instance function |
| 2689 // (or implicit first parameter of an enclosing factory) is marked as | 2688 // (or implicit first parameter of an enclosing factory) is marked as |
| 2690 // captured if type checks are enabled, because they may access it to | 2689 // captured if type checks are enabled, because they may access it to |
| 2691 // instantiate types. | 2690 // instantiate types. |
| 2692 CaptureInstantiator(); | 2691 CaptureInstantiator(); |
| 2693 } | 2692 } |
| 2694 } | 2693 } |
| 2695 | 2694 |
| 2696 OpenBlock(); // Open a nested scope for the outermost function block. | 2695 OpenBlock(); // Open a nested scope for the outermost function block. |
| 2696 intptr_t end_token_pos = 0; |
| 2697 if (CurrentToken() == Token::kLBRACE) { | 2697 if (CurrentToken() == Token::kLBRACE) { |
| 2698 ConsumeToken(); | 2698 ConsumeToken(); |
| 2699 ParseStatementSequence(); | 2699 ParseStatementSequence(); |
| 2700 end_token_pos = TokenPos(); |
| 2700 ExpectToken(Token::kRBRACE); | 2701 ExpectToken(Token::kRBRACE); |
| 2701 } else if (CurrentToken() == Token::kARROW) { | 2702 } else if (CurrentToken() == Token::kARROW) { |
| 2702 ConsumeToken(); | 2703 ConsumeToken(); |
| 2703 const intptr_t expr_pos = TokenPos(); | 2704 const intptr_t expr_pos = TokenPos(); |
| 2704 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 2705 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2705 ASSERT(expr != NULL); | 2706 ASSERT(expr != NULL); |
| 2706 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 2707 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 2708 end_token_pos = TokenPos(); |
| 2707 } else if (IsLiteral("native")) { | 2709 } else if (IsLiteral("native")) { |
| 2708 ParseNativeFunctionBlock(¶ms, func); | 2710 ParseNativeFunctionBlock(¶ms, func); |
| 2711 end_token_pos = TokenPos(); |
| 2712 ExpectSemicolon(); |
| 2709 } else if (func.is_external()) { | 2713 } else if (func.is_external()) { |
| 2710 // Body of an external method contains a single throw. | 2714 // Body of an external method contains a single throw. |
| 2711 const String& function_name = String::ZoneHandle(func.name()); | 2715 const String& function_name = String::ZoneHandle(func.name()); |
| 2712 // TODO(regis): For an instance function, pass the receiver to | 2716 // TODO(regis): For an instance function, pass the receiver to |
| 2713 // NoSuchMethodError. | 2717 // NoSuchMethodError. |
| 2714 current_block_->statements->Add( | 2718 current_block_->statements->Add( |
| 2715 ThrowNoSuchMethodError(TokenPos(), | 2719 ThrowNoSuchMethodError(TokenPos(), |
| 2716 current_class(), | 2720 current_class(), |
| 2717 function_name, | 2721 function_name, |
| 2718 func.is_static() ? | 2722 func.is_static() ? |
| 2719 InvocationMirror::kStatic : | 2723 InvocationMirror::kStatic : |
| 2720 InvocationMirror::kDynamic, | 2724 InvocationMirror::kDynamic, |
| 2721 InvocationMirror::kMethod)); | 2725 InvocationMirror::kMethod)); |
| 2726 end_token_pos = TokenPos(); |
| 2722 } else { | 2727 } else { |
| 2723 UnexpectedToken(); | 2728 UnexpectedToken(); |
| 2724 } | 2729 } |
| 2730 ASSERT(func.end_token_pos() == func.token_pos() || |
| 2731 func.end_token_pos() == end_token_pos); |
| 2732 func.set_end_token_pos(end_token_pos); |
| 2725 SequenceNode* body = CloseBlock(); | 2733 SequenceNode* body = CloseBlock(); |
| 2726 current_block_->statements->Add(body); | 2734 current_block_->statements->Add(body); |
| 2727 innermost_function_ = saved_innermost_function.raw(); | 2735 innermost_function_ = saved_innermost_function.raw(); |
| 2728 return CloseBlock(); | 2736 return CloseBlock(); |
| 2729 } | 2737 } |
| 2730 | 2738 |
| 2731 | 2739 |
| 2732 void Parser::SkipIf(Token::Kind token) { | 2740 void Parser::SkipIf(Token::Kind token) { |
| 2733 if (CurrentToken() == token) { | 2741 if (CurrentToken() == token) { |
| 2734 ConsumeToken(); | 2742 ConsumeToken(); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3012 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3020 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 3013 ErrorMsg(method->name_pos, | 3021 ErrorMsg(method->name_pos, |
| 3014 "const constructor or factory '%s' may not be native", | 3022 "const constructor or factory '%s' may not be native", |
| 3015 method->name->ToCString()); | 3023 method->name->ToCString()); |
| 3016 } | 3024 } |
| 3017 if (method->redirect_name != NULL) { | 3025 if (method->redirect_name != NULL) { |
| 3018 ErrorMsg(method->name_pos, | 3026 ErrorMsg(method->name_pos, |
| 3019 "Constructor with redirection may not have a function body"); | 3027 "Constructor with redirection may not have a function body"); |
| 3020 } | 3028 } |
| 3021 ParseNativeDeclaration(); | 3029 ParseNativeDeclaration(); |
| 3030 method_end_pos = TokenPos(); |
| 3031 ExpectSemicolon(); |
| 3022 } else { | 3032 } else { |
| 3023 // We haven't found a method body. Issue error if one is required. | 3033 // We haven't found a method body. Issue error if one is required. |
| 3024 const bool must_have_body = | 3034 const bool must_have_body = |
| 3025 method->has_static && | 3035 method->has_static && |
| 3026 !method->has_external && | 3036 !method->has_external && |
| 3027 redirection_type.IsNull(); | 3037 redirection_type.IsNull(); |
| 3028 if (must_have_body) { | 3038 if (must_have_body) { |
| 3029 ErrorMsg(method->name_pos, | 3039 ErrorMsg(method->name_pos, |
| 3030 "function body expected for method '%s'", | 3040 "function body expected for method '%s'", |
| 3031 method->name->ToCString()); | 3041 method->name->ToCString()); |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4361 if (CurrentToken() != Token::kLPAREN) { | 4371 if (CurrentToken() != Token::kLPAREN) { |
| 4362 ErrorMsg("'(' expected"); | 4372 ErrorMsg("'(' expected"); |
| 4363 } | 4373 } |
| 4364 const intptr_t function_pos = TokenPos(); | 4374 const intptr_t function_pos = TokenPos(); |
| 4365 ParamList params; | 4375 ParamList params; |
| 4366 const bool allow_explicit_default_values = true; | 4376 const bool allow_explicit_default_values = true; |
| 4367 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 4377 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 4368 | 4378 |
| 4369 intptr_t function_end_pos = function_pos; | 4379 intptr_t function_end_pos = function_pos; |
| 4370 if (is_external) { | 4380 if (is_external) { |
| 4381 function_end_pos = TokenPos(); |
| 4371 ExpectSemicolon(); | 4382 ExpectSemicolon(); |
| 4372 } else if (CurrentToken() == Token::kLBRACE) { | 4383 } else if (CurrentToken() == Token::kLBRACE) { |
| 4373 SkipBlock(); | 4384 SkipBlock(); |
| 4374 function_end_pos = TokenPos() - 1; | 4385 function_end_pos = TokenPos() - 1; |
| 4375 } else if (CurrentToken() == Token::kARROW) { | 4386 } else if (CurrentToken() == Token::kARROW) { |
| 4376 ConsumeToken(); | 4387 ConsumeToken(); |
| 4377 SkipExpr(); | 4388 SkipExpr(); |
| 4389 function_end_pos = TokenPos(); |
| 4378 ExpectSemicolon(); | 4390 ExpectSemicolon(); |
| 4379 function_end_pos = TokenPos() - 1; | |
| 4380 } else if (IsLiteral("native")) { | 4391 } else if (IsLiteral("native")) { |
| 4381 ParseNativeDeclaration(); | 4392 ParseNativeDeclaration(); |
| 4393 function_end_pos = TokenPos(); |
| 4394 ExpectSemicolon(); |
| 4382 } else { | 4395 } else { |
| 4383 ErrorMsg("function block expected"); | 4396 ErrorMsg("function block expected"); |
| 4384 } | 4397 } |
| 4385 Function& func = Function::Handle( | 4398 Function& func = Function::Handle( |
| 4386 Function::New(func_name, | 4399 Function::New(func_name, |
| 4387 RawFunction::kRegularFunction, | 4400 RawFunction::kRegularFunction, |
| 4388 is_static, | 4401 is_static, |
| 4389 /* is_const = */ false, | 4402 /* is_const = */ false, |
| 4390 /* is_abstract = */ false, | 4403 /* is_abstract = */ false, |
| 4391 is_external, | 4404 is_external, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4486 is_getter ? "getter" : "setter", | 4499 is_getter ? "getter" : "setter", |
| 4487 field_name->ToCString()); | 4500 field_name->ToCString()); |
| 4488 } else if (!found && is_patch) { | 4501 } else if (!found && is_patch) { |
| 4489 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", | 4502 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", |
| 4490 is_getter ? "getter" : "setter", | 4503 is_getter ? "getter" : "setter", |
| 4491 field_name->ToCString()); | 4504 field_name->ToCString()); |
| 4492 } | 4505 } |
| 4493 | 4506 |
| 4494 intptr_t accessor_end_pos = accessor_pos; | 4507 intptr_t accessor_end_pos = accessor_pos; |
| 4495 if (is_external) { | 4508 if (is_external) { |
| 4509 accessor_end_pos = TokenPos(); |
| 4496 ExpectSemicolon(); | 4510 ExpectSemicolon(); |
| 4497 } else if (CurrentToken() == Token::kLBRACE) { | 4511 } else if (CurrentToken() == Token::kLBRACE) { |
| 4498 SkipBlock(); | 4512 SkipBlock(); |
| 4499 accessor_end_pos = TokenPos() - 1; | 4513 accessor_end_pos = TokenPos() - 1; |
| 4500 } else if (CurrentToken() == Token::kARROW) { | 4514 } else if (CurrentToken() == Token::kARROW) { |
| 4501 ConsumeToken(); | 4515 ConsumeToken(); |
| 4502 SkipExpr(); | 4516 SkipExpr(); |
| 4517 accessor_end_pos = TokenPos(); |
| 4503 ExpectSemicolon(); | 4518 ExpectSemicolon(); |
| 4504 accessor_end_pos = TokenPos() - 1; | |
| 4505 } else if (IsLiteral("native")) { | 4519 } else if (IsLiteral("native")) { |
| 4506 ParseNativeDeclaration(); | 4520 ParseNativeDeclaration(); |
| 4521 accessor_end_pos = TokenPos(); |
| 4522 ExpectSemicolon(); |
| 4507 } else { | 4523 } else { |
| 4508 ErrorMsg("function block expected"); | 4524 ErrorMsg("function block expected"); |
| 4509 } | 4525 } |
| 4510 Function& func = Function::Handle( | 4526 Function& func = Function::Handle( |
| 4511 Function::New(accessor_name, | 4527 Function::New(accessor_name, |
| 4512 is_getter? RawFunction::kGetterFunction : | 4528 is_getter? RawFunction::kGetterFunction : |
| 4513 RawFunction::kSetterFunction, | 4529 RawFunction::kSetterFunction, |
| 4514 is_static, | 4530 is_static, |
| 4515 /* is_const = */ false, | 4531 /* is_const = */ false, |
| 4516 /* is_abstract = */ false, | 4532 /* is_abstract = */ false, |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5301 "'%s' from outer scope has already been used, cannot redefine", | 5317 "'%s' from outer scope has already been used, cannot redefine", |
| 5302 function_variable->name().ToCString()); | 5318 function_variable->name().ToCString()); |
| 5303 } | 5319 } |
| 5304 } | 5320 } |
| 5305 } | 5321 } |
| 5306 | 5322 |
| 5307 // Parse the local function. | 5323 // Parse the local function. |
| 5308 Array& default_parameter_values = Array::Handle(); | 5324 Array& default_parameter_values = Array::Handle(); |
| 5309 SequenceNode* statements = Parser::ParseFunc(function, | 5325 SequenceNode* statements = Parser::ParseFunc(function, |
| 5310 default_parameter_values); | 5326 default_parameter_values); |
| 5311 ASSERT(is_new_closure || (function.end_token_pos() == (TokenPos() - 1))); | |
| 5312 function.set_end_token_pos(TokenPos() - 1); | |
| 5313 | 5327 |
| 5314 // Now that the local function has formal parameters, lookup the signature | 5328 // Now that the local function has formal parameters, lookup the signature |
| 5315 // class in the current library (but not in its imports) and only create a new | 5329 // class in the current library (but not in its imports) and only create a new |
| 5316 // canonical signature class if it does not exist yet. | 5330 // canonical signature class if it does not exist yet. |
| 5317 const String& signature = String::Handle(function.Signature()); | 5331 const String& signature = String::Handle(function.Signature()); |
| 5318 Class& signature_class = Class::ZoneHandle(); | 5332 Class& signature_class = Class::ZoneHandle(); |
| 5319 if (!is_new_closure) { | 5333 if (!is_new_closure) { |
| 5320 signature_class = function.signature_class(); | 5334 signature_class = function.signature_class(); |
| 5321 } | 5335 } |
| 5322 if (signature_class.IsNull()) { | 5336 if (signature_class.IsNull()) { |
| (...skipping 5004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10327 void Parser::SkipQualIdent() { | 10341 void Parser::SkipQualIdent() { |
| 10328 ASSERT(IsIdentifier()); | 10342 ASSERT(IsIdentifier()); |
| 10329 ConsumeToken(); | 10343 ConsumeToken(); |
| 10330 if (CurrentToken() == Token::kPERIOD) { | 10344 if (CurrentToken() == Token::kPERIOD) { |
| 10331 ConsumeToken(); // Consume the kPERIOD token. | 10345 ConsumeToken(); // Consume the kPERIOD token. |
| 10332 ExpectIdentifier("identifier expected after '.'"); | 10346 ExpectIdentifier("identifier expected after '.'"); |
| 10333 } | 10347 } |
| 10334 } | 10348 } |
| 10335 | 10349 |
| 10336 } // namespace dart | 10350 } // namespace dart |
| OLD | NEW |