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

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

Issue 740823002: Allow await expressions in arrow-style functions (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 | « no previous file | tests/language/await_future_test.dart » ('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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 int TraceParser::indent_ = 0; 92 int TraceParser::indent_ = 0;
93 93
94 #define TRACE_PARSER(s) \ 94 #define TRACE_PARSER(s) \
95 TraceParser __p__(this->TokenPos(), this->script_, s) 95 TraceParser __p__(this->TokenPos(), this->script_, s)
96 96
97 #else // not DEBUG 97 #else // not DEBUG
98 #define TRACE_PARSER(s) 98 #define TRACE_PARSER(s)
99 #endif // DEBUG 99 #endif // DEBUG
100 100
101 101
102 class BoolScope : public ValueObject {
103 public:
104 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) {
105 *_addr = new_value;
106 }
107 ~BoolScope() {
108 *_addr = _saved_value;
109 }
110
111 private:
112 bool* _addr;
113 bool _saved_value;
114 };
115
116
102 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { 117 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) {
103 const TypeArguments& a = 118 const TypeArguments& a =
104 TypeArguments::Handle(TypeArguments::New(objs.Length())); 119 TypeArguments::Handle(TypeArguments::New(objs.Length()));
105 AbstractType& type = AbstractType::Handle(); 120 AbstractType& type = AbstractType::Handle();
106 for (int i = 0; i < objs.Length(); i++) { 121 for (int i = 0; i < objs.Length(); i++) {
107 type ^= objs.At(i); 122 type ^= objs.At(i);
108 a.SetTypeAt(i, type); 123 a.SetTypeAt(i, type);
109 } 124 }
110 // Cannot canonicalize TypeArgument yet as its types may not have been 125 // Cannot canonicalize TypeArgument yet as its types may not have been
111 // finalized yet. 126 // finalized yet.
(...skipping 2936 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 3063
3049 OpenBlock(); // Open a nested scope for the outermost function block. 3064 OpenBlock(); // Open a nested scope for the outermost function block.
3050 3065
3051 Function& async_closure = Function::ZoneHandle(I); 3066 Function& async_closure = Function::ZoneHandle(I);
3052 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3067 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3053 async_closure = OpenAsyncFunction(formal_params_pos); 3068 async_closure = OpenAsyncFunction(formal_params_pos);
3054 } else if (func.is_async_closure()) { 3069 } else if (func.is_async_closure()) {
3055 OpenAsyncClosure(); 3070 OpenAsyncClosure();
3056 } 3071 }
3057 3072
3058 bool saved_await_is_keyword = await_is_keyword_; 3073 BoolScope allow_await(&this->await_is_keyword_,
3059 await_is_keyword_ = func.IsAsyncFunction() || func.is_async_closure(); 3074 func.IsAsyncFunction() || func.is_async_closure());
3060
3061 intptr_t end_token_pos = 0; 3075 intptr_t end_token_pos = 0;
3062 if (CurrentToken() == Token::kLBRACE) { 3076 if (CurrentToken() == Token::kLBRACE) {
3063 ConsumeToken(); 3077 ConsumeToken();
3064 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) { 3078 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) {
3065 const Class& owner = Class::Handle(I, func.Owner()); 3079 const Class& owner = Class::Handle(I, func.Owner());
3066 if (!owner.IsObjectClass()) { 3080 if (!owner.IsObjectClass()) {
3067 AddEqualityNullCheck(); 3081 AddEqualityNullCheck();
3068 } 3082 }
3069 } 3083 }
3070 ParseStatementSequence(); 3084 ParseStatementSequence();
3071 end_token_pos = TokenPos(); 3085 end_token_pos = TokenPos();
3072 ExpectToken(Token::kRBRACE); 3086 ExpectToken(Token::kRBRACE);
3073 } else if (CurrentToken() == Token::kARROW) { 3087 } else if (CurrentToken() == Token::kARROW) {
3074 ConsumeToken(); 3088 ConsumeToken();
3075 if (String::Handle(I, func.name()).Equals( 3089 if (String::Handle(I, func.name()).Equals(
3076 Symbols::EqualOperator())) { 3090 Symbols::EqualOperator())) {
3077 const Class& owner = Class::Handle(I, func.Owner()); 3091 const Class& owner = Class::Handle(I, func.Owner());
3078 if (!owner.IsObjectClass()) { 3092 if (!owner.IsObjectClass()) {
3079 AddEqualityNullCheck(); 3093 AddEqualityNullCheck();
3080 } 3094 }
3081 } 3095 }
3082 const intptr_t expr_pos = TokenPos(); 3096 const intptr_t expr_pos = TokenPos();
3083 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 3097 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
3084 ASSERT(expr != NULL); 3098 ASSERT(expr != NULL);
3085 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 3099 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
3086 end_token_pos = TokenPos(); 3100 end_token_pos = TokenPos();
3087 } else if (IsLiteral("native")) { 3101 } else if (IsLiteral("native")) {
3088 if (String::Handle(I, func.name()).Equals( 3102 if (String::Handle(I, func.name()).Equals(
3089 Symbols::EqualOperator())) { 3103 Symbols::EqualOperator())) {
3090 const Class& owner = Class::Handle(I, func.Owner()); 3104 const Class& owner = Class::Handle(I, func.Owner());
3091 if (!owner.IsObjectClass()) { 3105 if (!owner.IsObjectClass()) {
3092 AddEqualityNullCheck(); 3106 AddEqualityNullCheck();
3093 } 3107 }
(...skipping 25 matching lines...) Expand all
3119 SequenceNode* body = CloseBlock(); 3133 SequenceNode* body = CloseBlock();
3120 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3134 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3121 body = CloseAsyncFunction(async_closure, body); 3135 body = CloseAsyncFunction(async_closure, body);
3122 async_closure.set_end_token_pos(end_token_pos); 3136 async_closure.set_end_token_pos(end_token_pos);
3123 } else if (func.is_async_closure()) { 3137 } else if (func.is_async_closure()) {
3124 body = CloseAsyncClosure(body); 3138 body = CloseAsyncClosure(body);
3125 } 3139 }
3126 current_block_->statements->Add(body); 3140 current_block_->statements->Add(body);
3127 innermost_function_ = saved_innermost_function.raw(); 3141 innermost_function_ = saved_innermost_function.raw();
3128 last_used_try_index_ = saved_try_index; 3142 last_used_try_index_ = saved_try_index;
3129 await_is_keyword_ = saved_await_is_keyword;
3130 async_temp_scope_ = saved_async_temp_scope; 3143 async_temp_scope_ = saved_async_temp_scope;
3131 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); 3144 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx);
3132 parsed_function()->set_async_saved_try_ctx_name( 3145 parsed_function()->set_async_saved_try_ctx_name(
3133 saved_async_saved_try_ctx_name); 3146 saved_async_saved_try_ctx_name);
3134 return CloseBlock(); 3147 return CloseBlock();
3135 } 3148 }
3136 3149
3137 3150
3138 void Parser::AddEqualityNullCheck() { 3151 void Parser::AddEqualityNullCheck() {
3139 AstNode* argument = 3152 AstNode* argument =
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
3475 if (method->redirect_name != NULL) { 3488 if (method->redirect_name != NULL) {
3476 ReportError(method->name_pos, 3489 ReportError(method->name_pos,
3477 "Constructor with redirection may not have a function body"); 3490 "Constructor with redirection may not have a function body");
3478 } 3491 }
3479 if (CurrentToken() == Token::kLBRACE) { 3492 if (CurrentToken() == Token::kLBRACE) {
3480 SkipBlock(); 3493 SkipBlock();
3481 method_end_pos = TokenPos(); 3494 method_end_pos = TokenPos();
3482 ExpectToken(Token::kRBRACE); 3495 ExpectToken(Token::kRBRACE);
3483 } else { 3496 } else {
3484 ConsumeToken(); 3497 ConsumeToken();
3498 BoolScope allow_await(&this->await_is_keyword_,
3499 async_modifier != RawFunction::kNoModifier);
3485 SkipExpr(); 3500 SkipExpr();
3486 method_end_pos = TokenPos(); 3501 method_end_pos = TokenPos();
3487 ExpectSemicolon(); 3502 ExpectSemicolon();
3488 } 3503 }
3489 } else if (IsLiteral("native")) { 3504 } else if (IsLiteral("native")) {
3490 if (method->has_abstract) { 3505 if (method->has_abstract) {
3491 ReportError(method->name_pos, 3506 ReportError(method->name_pos,
3492 "abstract method '%s' may not have a function body", 3507 "abstract method '%s' may not have a function body",
3493 method->name->ToCString()); 3508 method->name->ToCString());
3494 } else if (method->IsConstructor() && method->has_const) { 3509 } else if (method->IsConstructor() && method->has_const) {
(...skipping 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after
5149 bool is_native = false; 5164 bool is_native = false;
5150 if (is_external) { 5165 if (is_external) {
5151 function_end_pos = TokenPos(); 5166 function_end_pos = TokenPos();
5152 ExpectSemicolon(); 5167 ExpectSemicolon();
5153 } else if (CurrentToken() == Token::kLBRACE) { 5168 } else if (CurrentToken() == Token::kLBRACE) {
5154 SkipBlock(); 5169 SkipBlock();
5155 function_end_pos = TokenPos(); 5170 function_end_pos = TokenPos();
5156 ExpectToken(Token::kRBRACE); 5171 ExpectToken(Token::kRBRACE);
5157 } else if (CurrentToken() == Token::kARROW) { 5172 } else if (CurrentToken() == Token::kARROW) {
5158 ConsumeToken(); 5173 ConsumeToken();
5174 BoolScope allow_await(&this->await_is_keyword_,
5175 func_modifier != RawFunction::kNoModifier);
5159 SkipExpr(); 5176 SkipExpr();
5160 function_end_pos = TokenPos(); 5177 function_end_pos = TokenPos();
5161 ExpectSemicolon(); 5178 ExpectSemicolon();
5162 } else if (IsLiteral("native")) { 5179 } else if (IsLiteral("native")) {
5163 ParseNativeDeclaration(); 5180 ParseNativeDeclaration();
5164 function_end_pos = TokenPos(); 5181 function_end_pos = TokenPos();
5165 ExpectSemicolon(); 5182 ExpectSemicolon();
5166 is_native = true; 5183 is_native = true;
5167 } else { 5184 } else {
5168 ReportError("function block expected"); 5185 ReportError("function block expected");
(...skipping 6627 matching lines...) Expand 10 before | Expand all | Expand 10 after
11796 SkipType(true); 11813 SkipType(true);
11797 } 11814 }
11798 ExpectIdentifier("function name expected"); 11815 ExpectIdentifier("function name expected");
11799 } 11816 }
11800 if (CurrentToken() == Token::kLPAREN) { 11817 if (CurrentToken() == Token::kLPAREN) {
11801 const bool allow_explicit_default_values = true; 11818 const bool allow_explicit_default_values = true;
11802 ParamList params; 11819 ParamList params;
11803 params.skipped = true; 11820 params.skipped = true;
11804 ParseFormalParameterList(allow_explicit_default_values, false, &params); 11821 ParseFormalParameterList(allow_explicit_default_values, false, &params);
11805 } 11822 }
11806 ParseFunctionModifier(); 11823 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier();
11824 BoolScope allow_await(&this->await_is_keyword_,
11825 async_modifier != RawFunction::kNoModifier);
11807 if (CurrentToken() == Token::kLBRACE) { 11826 if (CurrentToken() == Token::kLBRACE) {
11808 SkipBlock(); 11827 SkipBlock();
11809 ExpectToken(Token::kRBRACE); 11828 ExpectToken(Token::kRBRACE);
11810 } else if (CurrentToken() == Token::kARROW) { 11829 } else if (CurrentToken() == Token::kARROW) {
11811 ConsumeToken(); 11830 ConsumeToken();
11812 SkipExpr(); 11831 SkipExpr();
11813 } 11832 }
11814 } 11833 }
11815 11834
11816 11835
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
12043 SkipPrimary(); 12062 SkipPrimary();
12044 SkipSelectors(); 12063 SkipSelectors();
12045 if (IsIncrementOperator(CurrentToken())) { 12064 if (IsIncrementOperator(CurrentToken())) {
12046 ConsumeToken(); 12065 ConsumeToken();
12047 } 12066 }
12048 } 12067 }
12049 12068
12050 12069
12051 void Parser::SkipUnaryExpr() { 12070 void Parser::SkipUnaryExpr() {
12052 if (IsPrefixOperator(CurrentToken()) || 12071 if (IsPrefixOperator(CurrentToken()) ||
12053 IsIncrementOperator(CurrentToken())) { 12072 IsIncrementOperator(CurrentToken()) ||
12073 IsAwaitKeyword()) {
12054 ConsumeToken(); 12074 ConsumeToken();
12055 SkipUnaryExpr(); 12075 SkipUnaryExpr();
12056 } else { 12076 } else {
12057 SkipPostfixExpr(); 12077 SkipPostfixExpr();
12058 } 12078 }
12059 } 12079 }
12060 12080
12061 12081
12062 void Parser::SkipBinaryExpr() { 12082 void Parser::SkipBinaryExpr() {
12063 SkipUnaryExpr(); 12083 SkipUnaryExpr();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
12118 void Parser::SkipQualIdent() { 12138 void Parser::SkipQualIdent() {
12119 ASSERT(IsIdentifier()); 12139 ASSERT(IsIdentifier());
12120 ConsumeToken(); 12140 ConsumeToken();
12121 if (CurrentToken() == Token::kPERIOD) { 12141 if (CurrentToken() == Token::kPERIOD) {
12122 ConsumeToken(); // Consume the kPERIOD token. 12142 ConsumeToken(); // Consume the kPERIOD token.
12123 ExpectIdentifier("identifier expected after '.'"); 12143 ExpectIdentifier("identifier expected after '.'");
12124 } 12144 }
12125 } 12145 }
12126 12146
12127 } // namespace dart 12147 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/await_future_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698