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

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

Issue 507233002: Fix conditionally parsing await as keyword. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 6 years, 3 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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 279
280 // For parsing a compilation unit. 280 // For parsing a compilation unit.
281 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) 281 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos)
282 : isolate_(Isolate::Current()), 282 : isolate_(Isolate::Current()),
283 script_(Script::Handle(isolate_, script.raw())), 283 script_(Script::Handle(isolate_, script.raw())),
284 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), 284 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()),
285 token_pos), 285 token_pos),
286 token_kind_(Token::kILLEGAL), 286 token_kind_(Token::kILLEGAL),
287 current_block_(NULL), 287 current_block_(NULL),
288 is_top_level_(false), 288 is_top_level_(false),
289 await_is_keyword_(false),
289 current_member_(NULL), 290 current_member_(NULL),
290 allow_function_literals_(true), 291 allow_function_literals_(true),
291 parsed_function_(NULL), 292 parsed_function_(NULL),
292 innermost_function_(Function::Handle(isolate_)), 293 innermost_function_(Function::Handle(isolate_)),
293 literal_token_(LiteralToken::Handle(isolate_)), 294 literal_token_(LiteralToken::Handle(isolate_)),
294 current_class_(Class::Handle(isolate_)), 295 current_class_(Class::Handle(isolate_)),
295 library_(Library::Handle(isolate_, library.raw())), 296 library_(Library::Handle(isolate_, library.raw())),
296 try_blocks_list_(NULL), 297 try_blocks_list_(NULL),
297 last_used_try_index_(0), 298 last_used_try_index_(0),
298 unregister_pending_function_(false) { 299 unregister_pending_function_(false) {
299 ASSERT(tokens_iterator_.IsValid()); 300 ASSERT(tokens_iterator_.IsValid());
300 ASSERT(!library.IsNull()); 301 ASSERT(!library.IsNull());
301 } 302 }
302 303
303 304
304 // For parsing a function. 305 // For parsing a function.
305 Parser::Parser(const Script& script, 306 Parser::Parser(const Script& script,
306 ParsedFunction* parsed_function, 307 ParsedFunction* parsed_function,
307 intptr_t token_position) 308 intptr_t token_position)
308 : isolate_(Isolate::Current()), 309 : isolate_(Isolate::Current()),
309 script_(Script::Handle(isolate_, script.raw())), 310 script_(Script::Handle(isolate_, script.raw())),
310 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), 311 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()),
311 token_position), 312 token_position),
312 token_kind_(Token::kILLEGAL), 313 token_kind_(Token::kILLEGAL),
313 current_block_(NULL), 314 current_block_(NULL),
314 is_top_level_(false), 315 is_top_level_(false),
316 await_is_keyword_(false),
315 current_member_(NULL), 317 current_member_(NULL),
316 allow_function_literals_(true), 318 allow_function_literals_(true),
317 parsed_function_(parsed_function), 319 parsed_function_(parsed_function),
318 innermost_function_(Function::Handle(isolate_, 320 innermost_function_(Function::Handle(isolate_,
319 parsed_function->function().raw())), 321 parsed_function->function().raw())),
320 literal_token_(LiteralToken::Handle(isolate_)), 322 literal_token_(LiteralToken::Handle(isolate_)),
321 current_class_(Class::Handle(isolate_, 323 current_class_(Class::Handle(isolate_,
322 parsed_function->function().Owner())), 324 parsed_function->function().Owner())),
323 library_(Library::Handle(isolate_, Class::Handle( 325 library_(Library::Handle(isolate_, Class::Handle(
324 isolate_, 326 isolate_,
(...skipping 2721 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 3048
3047 OpenBlock(); // Open a nested scope for the outermost function block. 3049 OpenBlock(); // Open a nested scope for the outermost function block.
3048 3050
3049 Function& async_closure = Function::ZoneHandle(I); 3051 Function& async_closure = Function::ZoneHandle(I);
3050 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3052 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3051 async_closure = OpenAsyncFunction(formal_params_pos); 3053 async_closure = OpenAsyncFunction(formal_params_pos);
3052 } else if (func.is_async_closure()) { 3054 } else if (func.is_async_closure()) {
3053 OpenAsyncClosure(); 3055 OpenAsyncClosure();
3054 } 3056 }
3055 3057
3058 bool saved_await_is_keyword = await_is_keyword_;
3059 if (func.IsAsyncFunction() || func.is_async_closure()) {
3060 await_is_keyword_ = true;
3061 }
3062
3056 intptr_t end_token_pos = 0; 3063 intptr_t end_token_pos = 0;
3057 if (CurrentToken() == Token::kLBRACE) { 3064 if (CurrentToken() == Token::kLBRACE) {
3058 ConsumeToken(); 3065 ConsumeToken();
3059 if (String::Handle(I, func.name()).Equals( 3066 if (String::Handle(I, func.name()).Equals(
3060 Symbols::EqualOperator())) { 3067 Symbols::EqualOperator())) {
3061 const Class& owner = Class::Handle(I, func.Owner()); 3068 const Class& owner = Class::Handle(I, func.Owner());
3062 if (!owner.IsObjectClass()) { 3069 if (!owner.IsObjectClass()) {
3063 AddEqualityNullCheck(); 3070 AddEqualityNullCheck();
3064 } 3071 }
3065 } 3072 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3114 func.set_end_token_pos(end_token_pos); 3121 func.set_end_token_pos(end_token_pos);
3115 SequenceNode* body = CloseBlock(); 3122 SequenceNode* body = CloseBlock();
3116 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3123 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3117 body = CloseAsyncFunction(async_closure, body); 3124 body = CloseAsyncFunction(async_closure, body);
3118 } else if (func.is_async_closure()) { 3125 } else if (func.is_async_closure()) {
3119 CloseAsyncClosure(body); 3126 CloseAsyncClosure(body);
3120 } 3127 }
3121 current_block_->statements->Add(body); 3128 current_block_->statements->Add(body);
3122 innermost_function_ = saved_innermost_function.raw(); 3129 innermost_function_ = saved_innermost_function.raw();
3123 last_used_try_index_ = saved_try_index; 3130 last_used_try_index_ = saved_try_index;
3131 await_is_keyword_ = saved_await_is_keyword;
3124 return CloseBlock(); 3132 return CloseBlock();
3125 } 3133 }
3126 3134
3127 3135
3128 void Parser::AddEqualityNullCheck() { 3136 void Parser::AddEqualityNullCheck() {
3129 AstNode* argument = 3137 AstNode* argument =
3130 new LoadLocalNode(Scanner::kNoSourcePos, 3138 new LoadLocalNode(Scanner::kNoSourcePos,
3131 current_block_->scope->parent()->VariableAt(1)); 3139 current_block_->scope->parent()->VariableAt(1));
3132 LiteralNode* null_operand = 3140 LiteralNode* null_operand =
3133 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(I)); 3141 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(I));
(...skipping 3212 matching lines...) Expand 10 before | Expand all | Expand 10 after
6346 } else if (CurrentToken() == Token::kFALSE) { 6354 } else if (CurrentToken() == Token::kFALSE) {
6347 *value = Bool::False().raw(); 6355 *value = Bool::False().raw();
6348 return true; 6356 return true;
6349 } 6357 }
6350 return false; 6358 return false;
6351 } 6359 }
6352 6360
6353 6361
6354 // Returns true if the current token is kIDENT or a pseudo-keyword. 6362 // Returns true if the current token is kIDENT or a pseudo-keyword.
6355 bool Parser::IsIdentifier() { 6363 bool Parser::IsIdentifier() {
6356 return Token::IsIdentifier(CurrentToken()); 6364 return Token::IsIdentifier(CurrentToken()) && !IsAwaitAsKeyword();
6357 } 6365 }
6358 6366
6359 6367
6360 // Returns true if the next tokens can be parsed as a an optionally 6368 // Returns true if the next tokens can be parsed as a an optionally
6361 // qualified identifier: [ident '.'] ident. 6369 // qualified identifier: [ident '.'] ident.
6362 // Current token position is not restored. 6370 // Current token position is not restored.
6363 bool Parser::TryParseQualIdent() { 6371 bool Parser::TryParseQualIdent() {
6364 if (CurrentToken() != Token::kIDENT) { 6372 if (CurrentToken() != Token::kIDENT) {
6365 return false; 6373 return false;
6366 } 6374 }
(...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after
7995 ConsumeToken(); 8003 ConsumeToken();
7996 return ident; 8004 return ident;
7997 } 8005 }
7998 8006
7999 8007
8000 bool Parser::IsLiteral(const char* literal) { 8008 bool Parser::IsLiteral(const char* literal) {
8001 return IsIdentifier() && CurrentLiteral()->Equals(literal); 8009 return IsIdentifier() && CurrentLiteral()->Equals(literal);
8002 } 8010 }
8003 8011
8004 8012
8013 bool Parser::IsAwaitAsKeyword() {
8014 return await_is_keyword_ &&
8015 (CurrentLiteral()->raw() == Symbols::Await().raw());
8016 }
8017
8018
8005 static bool IsIncrementOperator(Token::Kind token) { 8019 static bool IsIncrementOperator(Token::Kind token) {
8006 return token == Token::kINCR || token == Token::kDECR; 8020 return token == Token::kINCR || token == Token::kDECR;
8007 } 8021 }
8008 8022
8009 8023
8010 static bool IsPrefixOperator(Token::Kind token) { 8024 static bool IsPrefixOperator(Token::Kind token) {
8011 return (token == Token::kSUB) || 8025 return (token == Token::kSUB) ||
8012 (token == Token::kNOT) || 8026 (token == Token::kNOT) ||
8013 (token == Token::kBIT_NOT); 8027 (token == Token::kBIT_NOT);
8014 } 8028 }
(...skipping 2917 matching lines...) Expand 10 before | Expand all | Expand 10 after
10932 TRACE_PARSER("ParsePrimary"); 10946 TRACE_PARSER("ParsePrimary");
10933 ASSERT(!is_top_level_); 10947 ASSERT(!is_top_level_);
10934 AstNode* primary = NULL; 10948 AstNode* primary = NULL;
10935 const Token::Kind token = CurrentToken(); 10949 const Token::Kind token = CurrentToken();
10936 if (IsFunctionLiteral()) { 10950 if (IsFunctionLiteral()) {
10937 // The name of a literal function is visible from inside the function, but 10951 // The name of a literal function is visible from inside the function, but
10938 // must not collide with names in the scope declaring the literal. 10952 // must not collide with names in the scope declaring the literal.
10939 OpenBlock(); 10953 OpenBlock();
10940 primary = ParseFunctionStatement(true); 10954 primary = ParseFunctionStatement(true);
10941 CloseBlock(); 10955 CloseBlock();
10942 } else if (IsLiteral("await") && 10956 } else if (IsAwaitAsKeyword()) {
10943 (parsed_function()->function().IsAsyncFunction() ||
10944 parsed_function()->function().is_async_closure())) {
10945 // The body of an async function is parsed multiple times. The first time 10957 // The body of an async function is parsed multiple times. The first time
10946 // when setting up an AsyncFunction() for generating relevant scope 10958 // when setting up an AsyncFunction() for generating relevant scope
10947 // information. The second time the body is parsed for actually generating 10959 // information. The second time the body is parsed for actually generating
10948 // code. 10960 // code.
10949 TRACE_PARSER("ParseAwaitExpr"); 10961 TRACE_PARSER("ParseAwaitExpr");
10950 ConsumeToken(); 10962 ConsumeToken();
10951 parsed_function()->record_await(); 10963 parsed_function()->record_await();
10952 primary = new(I) AwaitNode( 10964 primary = new(I) AwaitNode(
10953 TokenPos(), ParseExpr(kAllowConst, kConsumeCascades)); 10965 TokenPos(), ParseExpr(kAllowConst, kConsumeCascades));
10954 } else if (IsIdentifier()) { 10966 } else if (IsIdentifier()) {
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
11483 void Parser::SkipQualIdent() { 11495 void Parser::SkipQualIdent() {
11484 ASSERT(IsIdentifier()); 11496 ASSERT(IsIdentifier());
11485 ConsumeToken(); 11497 ConsumeToken();
11486 if (CurrentToken() == Token::kPERIOD) { 11498 if (CurrentToken() == Token::kPERIOD) {
11487 ConsumeToken(); // Consume the kPERIOD token. 11499 ConsumeToken(); // Consume the kPERIOD token.
11488 ExpectIdentifier("identifier expected after '.'"); 11500 ExpectIdentifier("identifier expected after '.'");
11489 } 11501 }
11490 } 11502 }
11491 11503
11492 } // namespace dart 11504 } // 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