Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: runtime/vm/parser.cc

Issue 1016833002: Fix await/async/yield keyword recognition (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 } 1823 }
1824 } else { 1824 } else {
1825 ConsumeToken(); 1825 ConsumeToken();
1826 } 1826 }
1827 ExpectToken(Token::kRPAREN); 1827 ExpectToken(Token::kRPAREN);
1828 } 1828 }
1829 1829
1830 1830
1831 String& Parser::ParseNativeDeclaration() { 1831 String& Parser::ParseNativeDeclaration() {
1832 TRACE_PARSER("ParseNativeDeclaration"); 1832 TRACE_PARSER("ParseNativeDeclaration");
1833 ASSERT(IsLiteral("native")); 1833 ASSERT(IsSymbol(Symbols::Native()));
1834 ConsumeToken(); 1834 ConsumeToken();
1835 CheckToken(Token::kSTRING, "string literal expected"); 1835 CheckToken(Token::kSTRING, "string literal expected");
1836 String& native_name = *CurrentLiteral(); 1836 String& native_name = *CurrentLiteral();
1837 ConsumeToken(); 1837 ConsumeToken();
1838 return native_name; 1838 return native_name;
1839 } 1839 }
1840 1840
1841 1841
1842 // Resolve and return the dynamic function of the given name in the superclass. 1842 // Resolve and return the dynamic function of the given name in the superclass.
1843 // If it is not found, and resolve_getter is true, try to resolve a getter of 1843 // If it is not found, and resolve_getter is true, try to resolve a getter of
(...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2973 2973
2974 if (CurrentToken() == Token::kLBRACE) { 2974 if (CurrentToken() == Token::kLBRACE) {
2975 // We checked in the top-level parse phase that a redirecting 2975 // We checked in the top-level parse phase that a redirecting
2976 // constructor does not have a body. 2976 // constructor does not have a body.
2977 ASSERT(!is_redirecting_constructor); 2977 ASSERT(!is_redirecting_constructor);
2978 ConsumeToken(); 2978 ConsumeToken();
2979 ParseStatementSequence(); 2979 ParseStatementSequence();
2980 ExpectToken(Token::kRBRACE); 2980 ExpectToken(Token::kRBRACE);
2981 } else if (CurrentToken() == Token::kARROW) { 2981 } else if (CurrentToken() == Token::kARROW) {
2982 ReportError("constructors may not return a value"); 2982 ReportError("constructors may not return a value");
2983 } else if (IsLiteral("native")) { 2983 } else if (IsSymbol(Symbols::Native())) {
2984 ReportError("native constructors not supported"); 2984 ReportError("native constructors not supported");
2985 } else if (CurrentToken() == Token::kSEMICOLON) { 2985 } else if (CurrentToken() == Token::kSEMICOLON) {
2986 // Some constructors have no function body. 2986 // Some constructors have no function body.
2987 ConsumeToken(); 2987 ConsumeToken();
2988 if (func.is_external()) { 2988 if (func.is_external()) {
2989 // Body of an external method contains a single throw. 2989 // Body of an external method contains a single throw.
2990 const String& function_name = String::ZoneHandle(func.name()); 2990 const String& function_name = String::ZoneHandle(func.name());
2991 current_block_->statements->Add( 2991 current_block_->statements->Add(
2992 ThrowNoSuchMethodError(TokenPos(), 2992 ThrowNoSuchMethodError(TokenPos(),
2993 cls, 2993 cls,
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 const Class& owner = Class::Handle(Z, func.Owner()); 3232 const Class& owner = Class::Handle(Z, func.Owner());
3233 if (!owner.IsObjectClass()) { 3233 if (!owner.IsObjectClass()) {
3234 AddEqualityNullCheck(); 3234 AddEqualityNullCheck();
3235 } 3235 }
3236 } 3236 }
3237 const intptr_t expr_pos = TokenPos(); 3237 const intptr_t expr_pos = TokenPos();
3238 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 3238 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
3239 ASSERT(expr != NULL); 3239 ASSERT(expr != NULL);
3240 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 3240 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
3241 end_token_pos = TokenPos(); 3241 end_token_pos = TokenPos();
3242 } else if (IsLiteral("native")) { 3242 } else if (IsSymbol(Symbols::Native())) {
3243 if (String::Handle(Z, func.name()).Equals( 3243 if (String::Handle(Z, func.name()).Equals(
3244 Symbols::EqualOperator())) { 3244 Symbols::EqualOperator())) {
3245 const Class& owner = Class::Handle(Z, func.Owner()); 3245 const Class& owner = Class::Handle(Z, func.Owner());
3246 if (!owner.IsObjectClass()) { 3246 if (!owner.IsObjectClass()) {
3247 AddEqualityNullCheck(); 3247 AddEqualityNullCheck();
3248 } 3248 }
3249 } 3249 }
3250 ParseNativeFunctionBlock(&params, func); 3250 ParseNativeFunctionBlock(&params, func);
3251 end_token_pos = TokenPos(); 3251 end_token_pos = TokenPos();
3252 ExpectSemicolon(); 3252 ExpectSemicolon();
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 "=> style function may not be sync* or async* generator"); 3647 "=> style function may not be sync* or async* generator");
3648 } 3648 }
3649 3649
3650 ConsumeToken(); 3650 ConsumeToken();
3651 BoolScope allow_await(&this->await_is_keyword_, 3651 BoolScope allow_await(&this->await_is_keyword_,
3652 async_modifier != RawFunction::kNoModifier); 3652 async_modifier != RawFunction::kNoModifier);
3653 SkipExpr(); 3653 SkipExpr();
3654 method_end_pos = TokenPos(); 3654 method_end_pos = TokenPos();
3655 ExpectSemicolon(); 3655 ExpectSemicolon();
3656 } 3656 }
3657 } else if (IsLiteral("native")) { 3657 } else if (IsSymbol(Symbols::Native())) {
3658 if (method->has_abstract) { 3658 if (method->has_abstract) {
3659 ReportError(method->name_pos, 3659 ReportError(method->name_pos,
3660 "abstract method '%s' may not have a function body", 3660 "abstract method '%s' may not have a function body",
3661 method->name->ToCString()); 3661 method->name->ToCString());
3662 } else if (method->IsConstructor() && method->has_const) { 3662 } else if (method->IsConstructor() && method->has_const) {
3663 ReportError(method->name_pos, 3663 ReportError(method->name_pos,
3664 "const constructor '%s' may not be native", 3664 "const constructor '%s' may not be native",
3665 method->name->ToCString()); 3665 method->name->ToCString());
3666 } 3666 }
3667 if (method->redirect_name != NULL) { 3667 if (method->redirect_name != NULL) {
(...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after
5281 ConsumeToken(); 5281 ConsumeToken();
5282 break; 5282 break;
5283 } else { 5283 } else {
5284 ExpectSemicolon(); // Reports error. 5284 ExpectSemicolon(); // Reports error.
5285 } 5285 }
5286 } 5286 }
5287 } 5287 }
5288 5288
5289 5289
5290 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { 5290 RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
5291 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { 5291 if (IsSymbol(Symbols::Async())) {
5292 ConsumeToken(); 5292 ConsumeToken();
5293 if (CurrentToken() == Token::kMUL) { 5293 if (CurrentToken() == Token::kMUL) {
5294 const bool enableAsyncStar = true; 5294 const bool enableAsyncStar = true;
5295 if (!enableAsyncStar) { 5295 if (!enableAsyncStar) {
5296 ReportError("async* generator functions are not yet supported"); 5296 ReportError("async* generator functions are not yet supported");
5297 } 5297 }
5298 ConsumeToken(); 5298 ConsumeToken();
5299 return RawFunction::kAsyncGen; 5299 return RawFunction::kAsyncGen;
5300 } else { 5300 } else {
5301 return RawFunction::kAsync; 5301 return RawFunction::kAsync;
5302 } 5302 }
5303 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) && 5303 } else if (IsSymbol(Symbols::Sync()) &&
5304 (LookaheadToken(1) == Token::kMUL)) { 5304 (LookaheadToken(1) == Token::kMUL)) {
5305 const bool enableSyncStar = true; 5305 const bool enableSyncStar = true;
5306 if (!enableSyncStar) { 5306 if (!enableSyncStar) {
5307 ReportError("sync* generator functions are not yet supported"); 5307 ReportError("sync* generator functions are not yet supported");
5308 } 5308 }
5309 ConsumeToken(); 5309 ConsumeToken();
5310 ConsumeToken(); 5310 ConsumeToken();
5311 return RawFunction::kSyncGen; 5311 return RawFunction::kSyncGen;
5312 } 5312 }
5313 return RawFunction::kNoModifier; 5313 return RawFunction::kNoModifier;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 if ((func_modifier & RawFunction::kGeneratorBit) != 0) { 5383 if ((func_modifier & RawFunction::kGeneratorBit) != 0) {
5384 ReportError(modifier_pos, 5384 ReportError(modifier_pos,
5385 "=> style function may not be sync* or async* generator"); 5385 "=> style function may not be sync* or async* generator");
5386 } 5386 }
5387 ConsumeToken(); 5387 ConsumeToken();
5388 BoolScope allow_await(&this->await_is_keyword_, 5388 BoolScope allow_await(&this->await_is_keyword_,
5389 func_modifier != RawFunction::kNoModifier); 5389 func_modifier != RawFunction::kNoModifier);
5390 SkipExpr(); 5390 SkipExpr();
5391 function_end_pos = TokenPos(); 5391 function_end_pos = TokenPos();
5392 ExpectSemicolon(); 5392 ExpectSemicolon();
5393 } else if (IsLiteral("native")) { 5393 } else if (IsSymbol(Symbols::Native())) {
5394 ParseNativeDeclaration(); 5394 ParseNativeDeclaration();
5395 function_end_pos = TokenPos(); 5395 function_end_pos = TokenPos();
5396 ExpectSemicolon(); 5396 ExpectSemicolon();
5397 is_native = true; 5397 is_native = true;
5398 } else { 5398 } else {
5399 ReportError("function block expected"); 5399 ReportError("function block expected");
5400 } 5400 }
5401 Function& func = Function::Handle(Z, 5401 Function& func = Function::Handle(Z,
5402 Function::New(func_name, 5402 Function::New(func_name,
5403 RawFunction::kRegularFunction, 5403 RawFunction::kRegularFunction,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
5533 if (is_getter && ((func_modifier & RawFunction::kGeneratorBit) != 0)) { 5533 if (is_getter && ((func_modifier & RawFunction::kGeneratorBit) != 0)) {
5534 ReportError(modifier_pos, 5534 ReportError(modifier_pos,
5535 "=> style getter may not be sync* or async* generator"); 5535 "=> style getter may not be sync* or async* generator");
5536 } 5536 }
5537 ConsumeToken(); 5537 ConsumeToken();
5538 BoolScope allow_await(&this->await_is_keyword_, 5538 BoolScope allow_await(&this->await_is_keyword_,
5539 func_modifier != RawFunction::kNoModifier); 5539 func_modifier != RawFunction::kNoModifier);
5540 SkipExpr(); 5540 SkipExpr();
5541 accessor_end_pos = TokenPos(); 5541 accessor_end_pos = TokenPos();
5542 ExpectSemicolon(); 5542 ExpectSemicolon();
5543 } else if (IsLiteral("native")) { 5543 } else if (IsSymbol(Symbols::Native())) {
5544 ParseNativeDeclaration(); 5544 ParseNativeDeclaration();
5545 accessor_end_pos = TokenPos(); 5545 accessor_end_pos = TokenPos();
5546 ExpectSemicolon(); 5546 ExpectSemicolon();
5547 is_native = true; 5547 is_native = true;
5548 } else { 5548 } else {
5549 ReportError("function block expected"); 5549 ReportError("function block expected");
5550 } 5550 }
5551 Function& func = Function::Handle(Z, 5551 Function& func = Function::Handle(Z,
5552 Function::New(accessor_name, 5552 Function::New(accessor_name,
5553 is_getter ? RawFunction::kGetterFunction : 5553 is_getter ? RawFunction::kGetterFunction :
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5659 ConsumeToken(); 5659 ConsumeToken();
5660 CheckToken(Token::kSTRING, "library url expected"); 5660 CheckToken(Token::kSTRING, "library url expected");
5661 AstNode* url_literal = ParseStringLiteral(false); 5661 AstNode* url_literal = ParseStringLiteral(false);
5662 ASSERT(url_literal->IsLiteralNode()); 5662 ASSERT(url_literal->IsLiteralNode());
5663 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); 5663 ASSERT(url_literal->AsLiteralNode()->literal().IsString());
5664 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); 5664 const String& url = String::Cast(url_literal->AsLiteralNode()->literal());
5665 if (url.Length() == 0) { 5665 if (url.Length() == 0) {
5666 ReportError("library url expected"); 5666 ReportError("library url expected");
5667 } 5667 }
5668 bool is_deferred_import = false; 5668 bool is_deferred_import = false;
5669 if (is_import && (IsLiteral("deferred"))) { 5669 if (is_import && (IsSymbol(Symbols::Deferred()))) {
5670 is_deferred_import = true; 5670 is_deferred_import = true;
5671 ConsumeToken(); 5671 ConsumeToken();
5672 CheckToken(Token::kAS, "'as' expected"); 5672 CheckToken(Token::kAS, "'as' expected");
5673 } 5673 }
5674 String& prefix = String::Handle(Z); 5674 String& prefix = String::Handle(Z);
5675 intptr_t prefix_pos = 0; 5675 intptr_t prefix_pos = 0;
5676 if (is_import && (CurrentToken() == Token::kAS)) { 5676 if (is_import && (CurrentToken() == Token::kAS)) {
5677 ConsumeToken(); 5677 ConsumeToken();
5678 prefix_pos = TokenPos(); 5678 prefix_pos = TokenPos();
5679 prefix = ExpectIdentifier("prefix identifier expected")->raw(); 5679 prefix = ExpectIdentifier("prefix identifier expected")->raw();
5680 } 5680 }
5681 5681
5682 Array& show_names = Array::Handle(Z); 5682 Array& show_names = Array::Handle(Z);
5683 Array& hide_names = Array::Handle(Z); 5683 Array& hide_names = Array::Handle(Z);
5684 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { 5684 if (is_deferred_import ||
5685 IsSymbol(Symbols::Show()) ||
5686 IsSymbol(Symbols::Hide())) {
5685 GrowableObjectArray& show_list = 5687 GrowableObjectArray& show_list =
5686 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); 5688 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
5687 GrowableObjectArray& hide_list = 5689 GrowableObjectArray& hide_list =
5688 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); 5690 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
5689 // Libraries imported through deferred import automatically hide 5691 // Libraries imported through deferred import automatically hide
5690 // the name 'loadLibrary'. 5692 // the name 'loadLibrary'.
5691 if (is_deferred_import) { 5693 if (is_deferred_import) {
5692 hide_list.Add(Symbols::LoadLibrary()); 5694 hide_list.Add(Symbols::LoadLibrary());
5693 } 5695 }
5694 for (;;) { 5696 for (;;) {
5695 if (IsLiteral("show")) { 5697 if (IsSymbol(Symbols::Show())) {
5696 ConsumeToken(); 5698 ConsumeToken();
5697 ParseIdentList(&show_list); 5699 ParseIdentList(&show_list);
5698 } else if (IsLiteral("hide")) { 5700 } else if (IsSymbol(Symbols::Hide())) {
5699 ConsumeToken(); 5701 ConsumeToken();
5700 ParseIdentList(&hide_list); 5702 ParseIdentList(&hide_list);
5701 } else { 5703 } else {
5702 break; 5704 break;
5703 } 5705 }
5704 } 5706 }
5705 if (show_list.Length() > 0) { 5707 if (show_list.Length() > 0) {
5706 show_names = Array::MakeArray(show_list); 5708 show_names = Array::MakeArray(show_list);
5707 } 5709 }
5708 if (hide_list.Length() > 0) { 5710 if (hide_list.Length() > 0) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
5839 metadata_pos = SkipMetadata(); 5841 metadata_pos = SkipMetadata();
5840 } 5842 }
5841 SetPosition(rewind_pos); 5843 SetPosition(rewind_pos);
5842 } 5844 }
5843 5845
5844 5846
5845 void Parser::ParsePartHeader() { 5847 void Parser::ParsePartHeader() {
5846 SkipMetadata(); 5848 SkipMetadata();
5847 CheckToken(Token::kPART, "'part of' expected"); 5849 CheckToken(Token::kPART, "'part of' expected");
5848 ConsumeToken(); 5850 ConsumeToken();
5849 if (!IsLiteral("of")) { 5851 if (!IsSymbol(Symbols::Of())) {
5850 ReportError("'part of' expected"); 5852 ReportError("'part of' expected");
5851 } 5853 }
5852 ConsumeToken(); 5854 ConsumeToken();
5853 // The VM is not required to check that the library name matches the 5855 // The VM is not required to check that the library name matches the
5854 // name of the current library, so we ignore it. 5856 // name of the current library, so we ignore it.
5855 ExpectIdentifier("library name expected"); 5857 ExpectIdentifier("library name expected");
5856 while (CurrentToken() == Token::kPERIOD) { 5858 while (CurrentToken() == Token::kPERIOD) {
5857 ConsumeToken(); 5859 ConsumeToken();
5858 ExpectIdentifier("malformed library name"); 5860 ExpectIdentifier("malformed library name");
5859 } 5861 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5891 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); 5893 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
5892 } else if (CurrentToken() == Token::kENUM) { 5894 } else if (CurrentToken() == Token::kENUM) {
5893 ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos); 5895 ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos);
5894 } else if ((CurrentToken() == Token::kTYPEDEF) && 5896 } else if ((CurrentToken() == Token::kTYPEDEF) &&
5895 (LookaheadToken(1) != Token::kLPAREN)) { 5897 (LookaheadToken(1) != Token::kLPAREN)) {
5896 set_current_class(toplevel_class); 5898 set_current_class(toplevel_class);
5897 ParseTypedef(pending_classes, toplevel_class, metadata_pos); 5899 ParseTypedef(pending_classes, toplevel_class, metadata_pos);
5898 } else if ((CurrentToken() == Token::kABSTRACT) && 5900 } else if ((CurrentToken() == Token::kABSTRACT) &&
5899 (LookaheadToken(1) == Token::kCLASS)) { 5901 (LookaheadToken(1) == Token::kCLASS)) {
5900 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); 5902 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
5901 } else if (is_patch_source() && IsLiteral("patch") && 5903 } else if (is_patch_source() && IsSymbol(Symbols::Patch()) &&
5902 (LookaheadToken(1) == Token::kCLASS)) { 5904 (LookaheadToken(1) == Token::kCLASS)) {
5903 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); 5905 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
5904 } else { 5906 } else {
5905 set_current_class(toplevel_class); 5907 set_current_class(toplevel_class);
5906 if (IsVariableDeclaration()) { 5908 if (IsVariableDeclaration()) {
5907 ParseTopLevelVariable(&top_level, metadata_pos); 5909 ParseTopLevelVariable(&top_level, metadata_pos);
5908 } else if (IsFunctionDeclaration()) { 5910 } else if (IsFunctionDeclaration()) {
5909 ParseTopLevelFunction(&top_level, metadata_pos); 5911 ParseTopLevelFunction(&top_level, metadata_pos);
5910 } else if (IsTopLevelAccessor()) { 5912 } else if (IsTopLevelAccessor()) {
5911 ParseTopLevelAccessor(&top_level, metadata_pos); 5913 ParseTopLevelAccessor(&top_level, metadata_pos);
(...skipping 1624 matching lines...) Expand 10 before | Expand all | Expand 10 after
7536 // Returns true if the current token is kIDENT or a pseudo-keyword. 7538 // Returns true if the current token is kIDENT or a pseudo-keyword.
7537 bool Parser::IsIdentifier() { 7539 bool Parser::IsIdentifier() {
7538 return Token::IsIdentifier(CurrentToken()) && 7540 return Token::IsIdentifier(CurrentToken()) &&
7539 !(await_is_keyword_ && 7541 !(await_is_keyword_ &&
7540 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || 7542 ((CurrentLiteral()->raw() == Symbols::Await().raw()) ||
7541 (CurrentLiteral()->raw() == Symbols::Async().raw()) || 7543 (CurrentLiteral()->raw() == Symbols::Async().raw()) ||
7542 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); 7544 (CurrentLiteral()->raw() == Symbols::YieldKw().raw())));
7543 } 7545 }
7544 7546
7545 7547
7548 bool Parser::IsSymbol(const String& symbol) {
7549 return (CurrentLiteral()->raw() == symbol.raw()) &&
7550 (CurrentToken() == Token::kIDENT);
7551 }
7552
7553
7546 // Returns true if the next tokens can be parsed as a an optionally 7554 // Returns true if the next tokens can be parsed as a an optionally
7547 // qualified identifier: [ident '.'] ident. 7555 // qualified identifier: [ident '.'] ident.
7548 // Current token position is not restored. 7556 // Current token position is not restored.
7549 bool Parser::TryParseQualIdent() { 7557 bool Parser::TryParseQualIdent() {
7550 if (CurrentToken() != Token::kIDENT) { 7558 if (CurrentToken() != Token::kIDENT) {
7551 return false; 7559 return false;
7552 } 7560 }
7553 ConsumeToken(); 7561 ConsumeToken();
7554 if (CurrentToken() == Token::kPERIOD) { 7562 if (CurrentToken() == Token::kPERIOD) {
7555 ConsumeToken(); 7563 ConsumeToken();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
7679 ConsumeToken(); // Consume function identifier. 7687 ConsumeToken(); // Consume function identifier.
7680 } else { 7688 } else {
7681 SetPosition(saved_pos); 7689 SetPosition(saved_pos);
7682 return false; 7690 return false;
7683 } 7691 }
7684 // Check parameter list and the following token. 7692 // Check parameter list and the following token.
7685 if (CurrentToken() == Token::kLPAREN) { 7693 if (CurrentToken() == Token::kLPAREN) {
7686 SkipToMatchingParenthesis(); 7694 SkipToMatchingParenthesis();
7687 if ((CurrentToken() == Token::kLBRACE) || 7695 if ((CurrentToken() == Token::kLBRACE) ||
7688 (CurrentToken() == Token::kARROW) || 7696 (CurrentToken() == Token::kARROW) ||
7689 (is_top_level_ && IsLiteral("native")) || 7697 (is_top_level_ && IsSymbol(Symbols::Native())) ||
7690 is_external || 7698 is_external ||
7691 (CurrentLiteral()->raw() == Symbols::Async().raw()) || 7699 IsSymbol(Symbols::Async()) ||
7692 (CurrentLiteral()->raw() == Symbols::Sync().raw())) { 7700 IsSymbol(Symbols::Sync())) {
7693 SetPosition(saved_pos); 7701 SetPosition(saved_pos);
7694 return true; 7702 return true;
7695 } 7703 }
7696 } 7704 }
7697 SetPosition(saved_pos); 7705 SetPosition(saved_pos);
7698 return false; 7706 return false;
7699 } 7707 }
7700 7708
7701 7709
7702 bool Parser::IsTopLevelAccessor() { 7710 bool Parser::IsTopLevelAccessor() {
7703 const intptr_t saved_pos = TokenPos(); 7711 const intptr_t saved_pos = TokenPos();
7704 if (is_patch_source() && 7712 if (is_patch_source() && IsSymbol(Symbols::Patch())) {
7705 (CurrentToken() == Token::kIDENT) &&
7706 (CurrentLiteral()->Equals("patch"))) {
7707 ConsumeToken(); 7713 ConsumeToken();
7708 } else if (CurrentToken() == Token::kEXTERNAL) { 7714 } else if (CurrentToken() == Token::kEXTERNAL) {
7709 ConsumeToken(); 7715 ConsumeToken();
7710 } 7716 }
7711 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { 7717 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
7712 SetPosition(saved_pos); 7718 SetPosition(saved_pos);
7713 return true; 7719 return true;
7714 } 7720 }
7715 if (TryParseReturnType()) { 7721 if (TryParseReturnType()) {
7716 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { 7722 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
8819 const GrowableObjectArray& handler_types, 8825 const GrowableObjectArray& handler_types,
8820 bool* needs_stack_trace) { 8826 bool* needs_stack_trace) {
8821 // All catch blocks are merged into an if-then-else sequence of the 8827 // All catch blocks are merged into an if-then-else sequence of the
8822 // different types specified using the 'is' operator. While parsing 8828 // different types specified using the 'is' operator. While parsing
8823 // record the type tests (either a ComparisonNode or else the LiteralNode 8829 // record the type tests (either a ComparisonNode or else the LiteralNode
8824 // true for a generic catch) and the catch bodies in a pair of parallel 8830 // true for a generic catch) and the catch bodies in a pair of parallel
8825 // lists. Afterward, construct the nested if-then-else. 8831 // lists. Afterward, construct the nested if-then-else.
8826 bool generic_catch_seen = false; 8832 bool generic_catch_seen = false;
8827 GrowableArray<AstNode*> type_tests; 8833 GrowableArray<AstNode*> type_tests;
8828 GrowableArray<SequenceNode*> catch_blocks; 8834 GrowableArray<SequenceNode*> catch_blocks;
8829 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { 8835 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) {
8830 // Open a block that contains the if or an unconditional body. It's 8836 // Open a block that contains the if or an unconditional body. It's
8831 // closed in the loop that builds the if-then-else nest. 8837 // closed in the loop that builds the if-then-else nest.
8832 OpenBlock(); 8838 OpenBlock();
8833 const intptr_t catch_pos = TokenPos(); 8839 const intptr_t catch_pos = TokenPos();
8834 CatchParamDesc exception_param; 8840 CatchParamDesc exception_param;
8835 CatchParamDesc stack_trace_param; 8841 CatchParamDesc stack_trace_param;
8836 if (IsLiteral("on")) { 8842 if (IsSymbol(Symbols::On())) {
8837 ConsumeToken(); 8843 ConsumeToken();
8838 exception_param.type = &AbstractType::ZoneHandle(Z, 8844 exception_param.type = &AbstractType::ZoneHandle(Z,
8839 ParseType(ClassFinalizer::kCanonicalize)); 8845 ParseType(ClassFinalizer::kCanonicalize));
8840 } else { 8846 } else {
8841 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8847 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
8842 } 8848 }
8843 if (CurrentToken() == Token::kCATCH) { 8849 if (CurrentToken() == Token::kCATCH) {
8844 ConsumeToken(); // Consume the 'catch'. 8850 ConsumeToken(); // Consume the 'catch'.
8845 ExpectToken(Token::kLPAREN); 8851 ExpectToken(Token::kLPAREN);
8846 exception_param.token_pos = TokenPos(); 8852 exception_param.token_pos = TokenPos();
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
9149 ExpectToken(Token::kLBRACE); 9155 ExpectToken(Token::kLBRACE);
9150 9156
9151 if (is_async) { 9157 if (is_async) {
9152 SetupSavedTryContext(context_var); 9158 SetupSavedTryContext(context_var);
9153 } 9159 }
9154 9160
9155 ParseStatementSequence(); 9161 ParseStatementSequence();
9156 ExpectToken(Token::kRBRACE); 9162 ExpectToken(Token::kRBRACE);
9157 SequenceNode* try_block = CloseBlock(); 9163 SequenceNode* try_block = CloseBlock();
9158 9164
9159 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 9165 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) &&
9160 (CurrentToken() != Token::kFINALLY)) { 9166 (CurrentToken() != Token::kFINALLY)) {
9161 ReportError("catch or finally clause expected"); 9167 ReportError("catch or finally clause expected");
9162 } 9168 }
9163 9169
9164 // Now parse the 'catch' blocks if any. 9170 // Now parse the 'catch' blocks if any.
9165 try_stack_->enter_catch(); 9171 try_stack_->enter_catch();
9166 const intptr_t handler_pos = TokenPos(); 9172 const intptr_t handler_pos = TokenPos();
9167 const GrowableObjectArray& handler_types = 9173 const GrowableObjectArray& handler_types =
9168 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); 9174 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
9169 bool needs_stack_trace = false; 9175 bool needs_stack_trace = false;
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
9691 String* Parser::ExpectIdentifier(const char* msg) { 9697 String* Parser::ExpectIdentifier(const char* msg) {
9692 if (!IsIdentifier()) { 9698 if (!IsIdentifier()) {
9693 ReportError("%s", msg); 9699 ReportError("%s", msg);
9694 } 9700 }
9695 String* ident = CurrentLiteral(); 9701 String* ident = CurrentLiteral();
9696 ConsumeToken(); 9702 ConsumeToken();
9697 return ident; 9703 return ident;
9698 } 9704 }
9699 9705
9700 9706
9701 bool Parser::IsLiteral(const char* literal) {
9702 return IsIdentifier() && CurrentLiteral()->Equals(literal);
9703 }
9704
9705
9706 bool Parser::IsAwaitKeyword() { 9707 bool Parser::IsAwaitKeyword() {
9707 return await_is_keyword_ && 9708 return await_is_keyword_ && IsSymbol(Symbols::Await());
9708 (CurrentLiteral()->raw() == Symbols::Await().raw());
9709 } 9709 }
9710 9710
9711 9711
9712 bool Parser::IsYieldKeyword() { 9712 bool Parser::IsYieldKeyword() {
9713 return await_is_keyword_ && 9713 return await_is_keyword_ && IsSymbol(Symbols::YieldKw());
9714 (CurrentLiteral()->raw() == Symbols::YieldKw().raw());
9715 } 9714 }
9716 9715
9717 9716
9718 static bool IsIncrementOperator(Token::Kind token) { 9717 static bool IsIncrementOperator(Token::Kind token) {
9719 return token == Token::kINCR || token == Token::kDECR; 9718 return token == Token::kINCR || token == Token::kDECR;
9720 } 9719 }
9721 9720
9722 9721
9723 static bool IsPrefixOperator(Token::Kind token) { 9722 static bool IsPrefixOperator(Token::Kind token) {
9724 return (token == Token::kSUB) || 9723 return (token == Token::kSUB) ||
(...skipping 3499 matching lines...) Expand 10 before | Expand all | Expand 10 after
13224 void Parser::SkipQualIdent() { 13223 void Parser::SkipQualIdent() {
13225 ASSERT(IsIdentifier()); 13224 ASSERT(IsIdentifier());
13226 ConsumeToken(); 13225 ConsumeToken();
13227 if (CurrentToken() == Token::kPERIOD) { 13226 if (CurrentToken() == Token::kPERIOD) {
13228 ConsumeToken(); // Consume the kPERIOD token. 13227 ConsumeToken(); // Consume the kPERIOD token.
13229 ExpectIdentifier("identifier expected after '.'"); 13228 ExpectIdentifier("identifier expected after '.'");
13230 } 13229 }
13231 } 13230 }
13232 13231
13233 } // namespace dart 13232 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698