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

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

Issue 511483003: Revert "Fix scope/context behavior in await transformer." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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),
290 current_member_(NULL), 289 current_member_(NULL),
291 allow_function_literals_(true), 290 allow_function_literals_(true),
292 parsed_function_(NULL), 291 parsed_function_(NULL),
293 innermost_function_(Function::Handle(isolate_)), 292 innermost_function_(Function::Handle(isolate_)),
294 literal_token_(LiteralToken::Handle(isolate_)), 293 literal_token_(LiteralToken::Handle(isolate_)),
295 current_class_(Class::Handle(isolate_)), 294 current_class_(Class::Handle(isolate_)),
296 library_(Library::Handle(isolate_, library.raw())), 295 library_(Library::Handle(isolate_, library.raw())),
297 try_blocks_list_(NULL), 296 try_blocks_list_(NULL),
298 last_used_try_index_(0), 297 last_used_try_index_(0),
299 unregister_pending_function_(false) { 298 unregister_pending_function_(false) {
300 ASSERT(tokens_iterator_.IsValid()); 299 ASSERT(tokens_iterator_.IsValid());
301 ASSERT(!library.IsNull()); 300 ASSERT(!library.IsNull());
302 } 301 }
303 302
304 303
305 // For parsing a function. 304 // For parsing a function.
306 Parser::Parser(const Script& script, 305 Parser::Parser(const Script& script,
307 ParsedFunction* parsed_function, 306 ParsedFunction* parsed_function,
308 intptr_t token_position) 307 intptr_t token_position)
309 : isolate_(Isolate::Current()), 308 : isolate_(Isolate::Current()),
310 script_(Script::Handle(isolate_, script.raw())), 309 script_(Script::Handle(isolate_, script.raw())),
311 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), 310 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()),
312 token_position), 311 token_position),
313 token_kind_(Token::kILLEGAL), 312 token_kind_(Token::kILLEGAL),
314 current_block_(NULL), 313 current_block_(NULL),
315 is_top_level_(false), 314 is_top_level_(false),
316 await_is_keyword_(false),
317 current_member_(NULL), 315 current_member_(NULL),
318 allow_function_literals_(true), 316 allow_function_literals_(true),
319 parsed_function_(parsed_function), 317 parsed_function_(parsed_function),
320 innermost_function_(Function::Handle(isolate_, 318 innermost_function_(Function::Handle(isolate_,
321 parsed_function->function().raw())), 319 parsed_function->function().raw())),
322 literal_token_(LiteralToken::Handle(isolate_)), 320 literal_token_(LiteralToken::Handle(isolate_)),
323 current_class_(Class::Handle(isolate_, 321 current_class_(Class::Handle(isolate_,
324 parsed_function->function().Owner())), 322 parsed_function->function().Owner())),
325 library_(Library::Handle(isolate_, Class::Handle( 323 library_(Library::Handle(isolate_, Class::Handle(
326 isolate_, 324 isolate_,
(...skipping 2721 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 3046
3049 OpenBlock(); // Open a nested scope for the outermost function block. 3047 OpenBlock(); // Open a nested scope for the outermost function block.
3050 3048
3051 Function& async_closure = Function::ZoneHandle(I); 3049 Function& async_closure = Function::ZoneHandle(I);
3052 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3050 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3053 async_closure = OpenAsyncFunction(formal_params_pos); 3051 async_closure = OpenAsyncFunction(formal_params_pos);
3054 } else if (func.is_async_closure()) { 3052 } else if (func.is_async_closure()) {
3055 OpenAsyncClosure(); 3053 OpenAsyncClosure();
3056 } 3054 }
3057 3055
3058 // For async functions and their inner closures parse "await" as a keyword.
3059 if (func.IsAsyncFunction() || func.is_async_closure()) {
3060 await_is_keyword_ = true;
3061 }
3062
3063 intptr_t end_token_pos = 0; 3056 intptr_t end_token_pos = 0;
3064 if (CurrentToken() == Token::kLBRACE) { 3057 if (CurrentToken() == Token::kLBRACE) {
3065 ConsumeToken(); 3058 ConsumeToken();
3066 if (String::Handle(I, func.name()).Equals( 3059 if (String::Handle(I, func.name()).Equals(
3067 Symbols::EqualOperator())) { 3060 Symbols::EqualOperator())) {
3068 const Class& owner = Class::Handle(I, func.Owner()); 3061 const Class& owner = Class::Handle(I, func.Owner());
3069 if (!owner.IsObjectClass()) { 3062 if (!owner.IsObjectClass()) {
3070 AddEqualityNullCheck(); 3063 AddEqualityNullCheck();
3071 } 3064 }
3072 } 3065 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 func.set_end_token_pos(end_token_pos); 3114 func.set_end_token_pos(end_token_pos);
3122 SequenceNode* body = CloseBlock(); 3115 SequenceNode* body = CloseBlock();
3123 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3116 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3124 body = CloseAsyncFunction(async_closure, body); 3117 body = CloseAsyncFunction(async_closure, body);
3125 } else if (func.is_async_closure()) { 3118 } else if (func.is_async_closure()) {
3126 CloseAsyncClosure(body); 3119 CloseAsyncClosure(body);
3127 } 3120 }
3128 current_block_->statements->Add(body); 3121 current_block_->statements->Add(body);
3129 innermost_function_ = saved_innermost_function.raw(); 3122 innermost_function_ = saved_innermost_function.raw();
3130 last_used_try_index_ = saved_try_index; 3123 last_used_try_index_ = saved_try_index;
3131 await_is_keyword_ = false;
3132 return CloseBlock(); 3124 return CloseBlock();
3133 } 3125 }
3134 3126
3135 3127
3136 void Parser::AddEqualityNullCheck() { 3128 void Parser::AddEqualityNullCheck() {
3137 AstNode* argument = 3129 AstNode* argument =
3138 new LoadLocalNode(Scanner::kNoSourcePos, 3130 new LoadLocalNode(Scanner::kNoSourcePos,
3139 current_block_->scope->parent()->VariableAt(1)); 3131 current_block_->scope->parent()->VariableAt(1));
3140 LiteralNode* null_operand = 3132 LiteralNode* null_operand =
3141 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(I)); 3133 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(I));
(...skipping 3210 matching lines...) Expand 10 before | Expand all | Expand 10 after
6352 *value = Bool::True().raw(); 6344 *value = Bool::True().raw();
6353 return true; 6345 return true;
6354 } else if (CurrentToken() == Token::kFALSE) { 6346 } else if (CurrentToken() == Token::kFALSE) {
6355 *value = Bool::False().raw(); 6347 *value = Bool::False().raw();
6356 return true; 6348 return true;
6357 } 6349 }
6358 return false; 6350 return false;
6359 } 6351 }
6360 6352
6361 6353
6362 // Returns true if the current token is 6354 // Returns true if the current token is kIDENT or a pseudo-keyword.
6363 // * kIDENT,
6364 // * or a pseudo-keyword,
6365 // * or is not the literal "await" in an async function.
6366 bool Parser::IsIdentifier() { 6355 bool Parser::IsIdentifier() {
6367 return Token::IsIdentifier(CurrentToken()) && 6356 return Token::IsIdentifier(CurrentToken());
6368 (!await_is_keyword_ ||
6369 (CurrentLiteral()->raw() != Symbols::Await().raw()));
6370 } 6357 }
6371 6358
6372 6359
6373 // Returns true if the next tokens can be parsed as a an optionally 6360 // Returns true if the next tokens can be parsed as a an optionally
6374 // qualified identifier: [ident '.'] ident. 6361 // qualified identifier: [ident '.'] ident.
6375 // Current token position is not restored. 6362 // Current token position is not restored.
6376 bool Parser::TryParseQualIdent() { 6363 bool Parser::TryParseQualIdent() {
6377 if (CurrentToken() != Token::kIDENT) { 6364 if (CurrentToken() != Token::kIDENT) {
6378 return false; 6365 return false;
6379 } 6366 }
(...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after
8556 parsed_function()->reset_have_seen_await(); 8543 parsed_function()->reset_have_seen_await();
8557 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); 8544 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades);
8558 if (parsed_function()->have_seen_await()) { 8545 if (parsed_function()->have_seen_await()) {
8559 if (!current_block_->scope->LookupVariable( 8546 if (!current_block_->scope->LookupVariable(
8560 Symbols::AsyncOperation(), true)) { 8547 Symbols::AsyncOperation(), true)) {
8561 // Async operations are always encapsulated into a local function. We only 8548 // Async operations are always encapsulated into a local function. We only
8562 // need to transform the expression when generating code for this inner 8549 // need to transform the expression when generating code for this inner
8563 // function. 8550 // function.
8564 return expr; 8551 return expr;
8565 } 8552 }
8566 OpenBlock(); 8553 SequenceNode* intermediates_block = new(I) SequenceNode(
8567 AwaitTransformer at(current_block_->statements, 8554 Scanner::kNoSourcePos, current_block_->scope);
8568 library_, 8555 AwaitTransformer at(intermediates_block, library_, parsed_function());
8569 parsed_function());
8570 AstNode* result = at.Transform(expr); 8556 AstNode* result = at.Transform(expr);
8571 current_block_->statements->Add(CloseBlock()); 8557 current_block_->statements->Add(intermediates_block);
8572 parsed_function()->reset_have_seen_await(); 8558 parsed_function()->reset_have_seen_await();
8573 return result; 8559 return result;
8574 } 8560 }
8575 return expr; 8561 return expr;
8576 } 8562 }
8577 8563
8578 8564
8579 AstNode* Parser::ParseExpr(bool require_compiletime_const, 8565 AstNode* Parser::ParseExpr(bool require_compiletime_const,
8580 bool consume_cascades) { 8566 bool consume_cascades) {
8581 TRACE_PARSER("ParseExpr"); 8567 TRACE_PARSER("ParseExpr");
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after
10946 TRACE_PARSER("ParsePrimary"); 10932 TRACE_PARSER("ParsePrimary");
10947 ASSERT(!is_top_level_); 10933 ASSERT(!is_top_level_);
10948 AstNode* primary = NULL; 10934 AstNode* primary = NULL;
10949 const Token::Kind token = CurrentToken(); 10935 const Token::Kind token = CurrentToken();
10950 if (IsFunctionLiteral()) { 10936 if (IsFunctionLiteral()) {
10951 // The name of a literal function is visible from inside the function, but 10937 // The name of a literal function is visible from inside the function, but
10952 // must not collide with names in the scope declaring the literal. 10938 // must not collide with names in the scope declaring the literal.
10953 OpenBlock(); 10939 OpenBlock();
10954 primary = ParseFunctionStatement(true); 10940 primary = ParseFunctionStatement(true);
10955 CloseBlock(); 10941 CloseBlock();
10956 } else if ((CurrentLiteral()->raw() == Symbols::Await().raw()) && 10942 } else if (IsLiteral("await") &&
10957 (parsed_function()->function().IsAsyncFunction() || 10943 (parsed_function()->function().IsAsyncFunction() ||
10958 parsed_function()->function().is_async_closure())) { 10944 parsed_function()->function().is_async_closure())) {
10959 // The body of an async function is parsed multiple times. The first time 10945 // The body of an async function is parsed multiple times. The first time
10960 // when setting up an AsyncFunction() for generating relevant scope 10946 // when setting up an AsyncFunction() for generating relevant scope
10961 // information. The second time the body is parsed for actually generating 10947 // information. The second time the body is parsed for actually generating
10962 // code. 10948 // code.
10963 TRACE_PARSER("ParseAwaitExpr"); 10949 TRACE_PARSER("ParseAwaitExpr");
10964 ConsumeToken(); 10950 ConsumeToken();
10965 parsed_function()->record_await(); 10951 parsed_function()->record_await();
10966 primary = new(I) AwaitNode( 10952 primary = new(I) AwaitNode(
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
11497 void Parser::SkipQualIdent() { 11483 void Parser::SkipQualIdent() {
11498 ASSERT(IsIdentifier()); 11484 ASSERT(IsIdentifier());
11499 ConsumeToken(); 11485 ConsumeToken();
11500 if (CurrentToken() == Token::kPERIOD) { 11486 if (CurrentToken() == Token::kPERIOD) {
11501 ConsumeToken(); // Consume the kPERIOD token. 11487 ConsumeToken(); // Consume the kPERIOD token.
11502 ExpectIdentifier("identifier expected after '.'"); 11488 ExpectIdentifier("identifier expected after '.'");
11503 } 11489 }
11504 } 11490 }
11505 11491
11506 } // namespace dart 11492 } // 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