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

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

Issue 888463004: Add support for sync* and yield (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 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
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 3042 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 ASSERT(current_class().raw() == func.Owner()); 3053 ASSERT(current_class().raw() == func.Owner());
3054 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); 3054 params.AddReceiver(ReceiverType(current_class()), func.token_pos());
3055 } else if (func.IsFactory()) { 3055 } else if (func.IsFactory()) {
3056 // The first parameter of a factory is the TypeArguments vector of 3056 // The first parameter of a factory is the TypeArguments vector of
3057 // the type of the instance to be allocated. 3057 // the type of the instance to be allocated.
3058 params.AddFinalParameter( 3058 params.AddFinalParameter(
3059 TokenPos(), 3059 TokenPos(),
3060 &Symbols::TypeArgumentsParameter(), 3060 &Symbols::TypeArgumentsParameter(),
3061 &Type::ZoneHandle(Z, Type::DynamicType())); 3061 &Type::ZoneHandle(Z, Type::DynamicType()));
3062 } 3062 }
3063 // Expect the parameter list unless this is a getter function, or the
3064 // body closure of an async or generator getter function.
3063 ASSERT((CurrentToken() == Token::kLPAREN) || 3065 ASSERT((CurrentToken() == Token::kLPAREN) ||
3064 func.IsGetterFunction() || 3066 func.IsGetterFunction() ||
3065 func.is_async_closure()); 3067 (func.is_generated_body() &&
3068 Function::Handle(func.parent_function()).IsGetterFunction()));
3066 const bool allow_explicit_default_values = true; 3069 const bool allow_explicit_default_values = true;
3067 if (func.IsGetterFunction()) { 3070 if (func.IsGetterFunction()) {
3068 // Populate function scope with the formal parameters. Since in this case 3071 // Populate function scope with the formal parameters. Since in this case
3069 // we are compiling a getter this will at most populate the receiver. 3072 // we are compiling a getter this will at most populate the receiver.
3070 AddFormalParamsToScope(&params, current_block_->scope); 3073 AddFormalParamsToScope(&params, current_block_->scope);
3071 } else if (func.is_async_closure()) { 3074 } else if (func.IsAsyncClosure()) {
3072 // Async closures have two optional parameters: 3075 AddAsyncClosureParameters(&params);
3073 // * A continuation result.
3074 // * A continuation error.
3075 //
3076 // If the error!=null we rethrow the error at the next await.
3077 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
3078 ParamDesc result_param;
3079 result_param.name = &Symbols::AsyncOperationParam();
3080 result_param.default_value = &Object::null_instance();
3081 result_param.type = &dynamic_type;
3082 ParamDesc error_param;
3083 error_param.name = &Symbols::AsyncOperationErrorParam();
3084 error_param.default_value = &Object::null_instance();
3085 error_param.type = &dynamic_type;
3086 params.parameters->Add(result_param);
3087 params.parameters->Add(error_param);
3088 params.num_optional_parameters += 2;
3089 params.has_optional_positional_parameters = true;
3090 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3076 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3091 AddFormalParamsToScope(&params, current_block_->scope); 3077 AddFormalParamsToScope(&params, current_block_->scope);
3092 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3078 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3093 ASSERT(func.NumParameters() == params.parameters->length()); 3079 ASSERT(func.NumParameters() == params.parameters->length());
3094 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3080 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3095 // Parse and discard any formal parameters. They are accessed as 3081 // Parse and discard any formal parameters. They are accessed as
3096 // context variables. 3082 // context variables.
3097 ParamList parse_away; 3083 ParamList discarded_params;
3098 ParseFormalParameterList(allow_explicit_default_values, 3084 ParseFormalParameterList(allow_explicit_default_values,
3099 false, 3085 false,
3100 &parse_away); 3086 &discarded_params);
3087 }
3088 } else if (func.IsSyncGenClosure()) {
3089 AddSyncGenClosureParameters(&params);
3090 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3091 AddFormalParamsToScope(&params, current_block_->scope);
3092 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3093 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3094 // Parse and discard any formal parameters. They are accessed as
3095 // context variables.
3096 ParamList discarded_params;
3097 ParseFormalParameterList(allow_explicit_default_values,
3098 false,
3099 &discarded_params);
3101 } 3100 }
3102 } else { 3101 } else {
3103 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3102 ParseFormalParameterList(allow_explicit_default_values, false, &params);
3104 3103
3105 // The number of parameters and their type are not yet set in local 3104 // The number of parameters and their type are not yet set in local
3106 // functions, since they are not 'top-level' parsed. 3105 // functions, since they are not 'top-level' parsed.
3107 if (func.IsLocalFunction()) { 3106 if (func.IsLocalFunction()) {
3108 AddFormalParamsToFunction(&params, func); 3107 AddFormalParamsToFunction(&params, func);
3109 } 3108 }
3110 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3109 SetupDefaultsForOptionalParams(&params, default_parameter_values);
(...skipping 21 matching lines...) Expand all
3132 if (IsInstantiatorRequired()) { 3131 if (IsInstantiatorRequired()) {
3133 // Make sure that the receiver of the enclosing instance function 3132 // Make sure that the receiver of the enclosing instance function
3134 // (or implicit first parameter of an enclosing factory) is marked as 3133 // (or implicit first parameter of an enclosing factory) is marked as
3135 // captured if type checks are enabled, because they may access it to 3134 // captured if type checks are enabled, because they may access it to
3136 // instantiate types. 3135 // instantiate types.
3137 CaptureInstantiator(); 3136 CaptureInstantiator();
3138 } 3137 }
3139 } 3138 }
3140 } 3139 }
3141 3140
3141 const intptr_t modifier_pos = TokenPos();
3142 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 3142 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
3143 func.set_modifier(func_modifier); 3143 if (!func.is_generated_body()) {
3144 // Don't add a modifier to the closure representing the body of
3145 // the asynchronous function or generator.
3146 func.set_modifier(func_modifier);
3147 }
3144 3148
3145 OpenBlock(); // Open a nested scope for the outermost function block. 3149 OpenBlock(); // Open a nested scope for the outermost function block.
3146 3150
3147 Function& async_closure = Function::ZoneHandle(Z); 3151 Function& generated_body_closure = Function::ZoneHandle(Z);
3148 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3152 if (func.IsAsyncFunction()) {
3153 ASSERT(!func.is_generated_body());
3149 // The code of an async function is synthesized. Disable debugging. 3154 // The code of an async function is synthesized. Disable debugging.
3150 func.set_is_debuggable(false); 3155 func.set_is_debuggable(false);
3151 async_closure = OpenAsyncFunction(func.token_pos()); 3156 generated_body_closure = OpenAsyncFunction(func.token_pos());
3152 } else if (func.is_async_closure()) { 3157 } else if (func.IsAsyncClosure()) {
3153 // The closure containing the body of an async function is debuggable. 3158 // The closure containing the body of an async function is debuggable.
3154 ASSERT(func.is_debuggable()); 3159 ASSERT(func.is_debuggable());
3155 OpenAsyncClosure(); 3160 OpenAsyncClosure();
3161 } else if (func.IsSyncGenerator()) {
3162 // The code of a sync generator is synthesized. Disable debugging.
3163 func.set_is_debuggable(false);
3164 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos());
3165 } else if (func.IsSyncGenClosure()) {
3166 // The closure containing the body of a sync generator is debuggable.
3167 ASSERT(func.is_debuggable());
3168 // Nothing special to do.
3156 } 3169 }
3157 3170
3158 BoolScope allow_await(&this->await_is_keyword_, 3171 BoolScope allow_await(&this->await_is_keyword_,
3159 func.IsAsyncFunction() || func.is_async_closure()); 3172 func.IsAsyncOrGenerator() || func.is_generated_body());
3160 intptr_t end_token_pos = 0; 3173 intptr_t end_token_pos = 0;
3161 if (CurrentToken() == Token::kLBRACE) { 3174 if (CurrentToken() == Token::kLBRACE) {
3162 ConsumeToken(); 3175 ConsumeToken();
3163 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { 3176 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
3164 const Class& owner = Class::Handle(Z, func.Owner()); 3177 const Class& owner = Class::Handle(Z, func.Owner());
3165 if (!owner.IsObjectClass()) { 3178 if (!owner.IsObjectClass()) {
3166 AddEqualityNullCheck(); 3179 AddEqualityNullCheck();
3167 } 3180 }
3168 } 3181 }
3169 ParseStatementSequence(); 3182 ParseStatementSequence();
3170 end_token_pos = TokenPos(); 3183 end_token_pos = TokenPos();
3171 ExpectToken(Token::kRBRACE); 3184 ExpectToken(Token::kRBRACE);
3172 } else if (CurrentToken() == Token::kARROW) { 3185 } else if (CurrentToken() == Token::kARROW) {
3186 if (func.IsGenerator()) {
3187 ReportError(modifier_pos,
3188 "=> style function may not be sync* or async* generator");
3189 }
3173 ConsumeToken(); 3190 ConsumeToken();
3174 if (String::Handle(Z, func.name()).Equals( 3191 if (String::Handle(Z, func.name()).Equals(
3175 Symbols::EqualOperator())) { 3192 Symbols::EqualOperator())) {
3176 const Class& owner = Class::Handle(Z, func.Owner()); 3193 const Class& owner = Class::Handle(Z, func.Owner());
3177 if (!owner.IsObjectClass()) { 3194 if (!owner.IsObjectClass()) {
3178 AddEqualityNullCheck(); 3195 AddEqualityNullCheck();
3179 } 3196 }
3180 } 3197 }
3181 const intptr_t expr_pos = TokenPos(); 3198 const intptr_t expr_pos = TokenPos();
3182 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 3199 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
(...skipping 26 matching lines...) Expand all
3209 &func)); // Unpatched external function. 3226 &func)); // Unpatched external function.
3210 end_token_pos = TokenPos(); 3227 end_token_pos = TokenPos();
3211 } else { 3228 } else {
3212 UnexpectedToken(); 3229 UnexpectedToken();
3213 } 3230 }
3214 3231
3215 ASSERT(func.end_token_pos() == func.token_pos() || 3232 ASSERT(func.end_token_pos() == func.token_pos() ||
3216 func.end_token_pos() == end_token_pos); 3233 func.end_token_pos() == end_token_pos);
3217 func.set_end_token_pos(end_token_pos); 3234 func.set_end_token_pos(end_token_pos);
3218 SequenceNode* body = CloseBlock(); 3235 SequenceNode* body = CloseBlock();
3219 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3236 if (func.IsAsyncFunction()) {
3220 body = CloseAsyncFunction(async_closure, body); 3237 body = CloseAsyncFunction(generated_body_closure, body);
3221 async_closure.set_end_token_pos(end_token_pos); 3238 generated_body_closure.set_end_token_pos(end_token_pos);
3222 } else if (func.is_async_closure()) { 3239 } else if (func.IsAsyncClosure()) {
3223 body = CloseAsyncClosure(body); 3240 body = CloseAsyncClosure(body);
3241 } else if (func.IsSyncGenerator()) {
3242 body = CloseSyncGenFunction(generated_body_closure, body);
3243 generated_body_closure.set_end_token_pos(end_token_pos);
3244 } else if (func.IsSyncGenClosure()) {
3245 body->scope()->RecursivelyCaptureAllVariables();
3224 } 3246 }
3225 current_block_->statements->Add(body); 3247 current_block_->statements->Add(body);
3226 innermost_function_ = saved_innermost_function.raw(); 3248 innermost_function_ = saved_innermost_function.raw();
3227 last_used_try_index_ = saved_try_index; 3249 last_used_try_index_ = saved_try_index;
3228 async_temp_scope_ = saved_async_temp_scope; 3250 async_temp_scope_ = saved_async_temp_scope;
3229 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); 3251 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx);
3230 parsed_function()->set_async_saved_try_ctx_name( 3252 parsed_function()->set_async_saved_try_ctx_name(
3231 saved_async_saved_try_ctx_name); 3253 saved_async_saved_try_ctx_name);
3232 return CloseBlock(); 3254 return CloseBlock();
3233 } 3255 }
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
3532 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); 3554 ASSERT((method->redirect_name == NULL) || method->IsConstructor());
3533 3555
3534 if (method->IsConstructor() && 3556 if (method->IsConstructor() &&
3535 method->has_external && 3557 method->has_external &&
3536 method->params.has_field_initializer) { 3558 method->params.has_field_initializer) {
3537 ReportError(method->name_pos, 3559 ReportError(method->name_pos,
3538 "external constructor '%s' may not have field initializers", 3560 "external constructor '%s' may not have field initializers",
3539 method->name->ToCString()); 3561 method->name->ToCString());
3540 } 3562 }
3541 3563
3564 const intptr_t modifier_pos = TokenPos();
3542 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); 3565 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier();
3543 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && 3566 if ((method->IsFactoryOrConstructor() || method->IsSetter()) &&
3544 async_modifier != RawFunction::kNoModifier) { 3567 (async_modifier != RawFunction::kNoModifier)) {
3545 ReportError(method->name_pos, 3568 ReportError(modifier_pos,
3546 "%s '%s' may not be async", 3569 "%s '%s' may not be async, async* or sync*",
3547 (method->IsSetter()) ? "setter" : "constructor", 3570 (method->IsSetter()) ? "setter" : "constructor",
3548 method->name->ToCString()); 3571 method->name->ToCString());
3549 } 3572 }
3550 3573
3551 intptr_t method_end_pos = TokenPos(); 3574 intptr_t method_end_pos = TokenPos();
3552 if ((CurrentToken() == Token::kLBRACE) || 3575 if ((CurrentToken() == Token::kLBRACE) ||
3553 (CurrentToken() == Token::kARROW)) { 3576 (CurrentToken() == Token::kARROW)) {
3554 if (method->has_abstract) { 3577 if (method->has_abstract) {
3555 ReportError(TokenPos(), 3578 ReportError(TokenPos(),
3556 "abstract method '%s' may not have a function body", 3579 "abstract method '%s' may not have a function body",
(...skipping 14 matching lines...) Expand all
3571 } 3594 }
3572 if (method->redirect_name != NULL) { 3595 if (method->redirect_name != NULL) {
3573 ReportError(method->name_pos, 3596 ReportError(method->name_pos,
3574 "Constructor with redirection may not have a function body"); 3597 "Constructor with redirection may not have a function body");
3575 } 3598 }
3576 if (CurrentToken() == Token::kLBRACE) { 3599 if (CurrentToken() == Token::kLBRACE) {
3577 SkipBlock(); 3600 SkipBlock();
3578 method_end_pos = TokenPos(); 3601 method_end_pos = TokenPos();
3579 ExpectToken(Token::kRBRACE); 3602 ExpectToken(Token::kRBRACE);
3580 } else { 3603 } else {
3604 if ((async_modifier & RawFunction::kGeneratorBit) != 0) {
3605 ReportError(modifier_pos,
3606 "=> style function may not be sync* or async* generator");
3607 }
3608
3581 ConsumeToken(); 3609 ConsumeToken();
3582 BoolScope allow_await(&this->await_is_keyword_, 3610 BoolScope allow_await(&this->await_is_keyword_,
3583 async_modifier != RawFunction::kNoModifier); 3611 async_modifier != RawFunction::kNoModifier);
3584 SkipExpr(); 3612 SkipExpr();
3585 method_end_pos = TokenPos(); 3613 method_end_pos = TokenPos();
3586 ExpectSemicolon(); 3614 ExpectSemicolon();
3587 } 3615 }
3588 } else if (IsLiteral("native")) { 3616 } else if (IsLiteral("native")) {
3589 if (method->has_abstract) { 3617 if (method->has_abstract) {
3590 ReportError(method->name_pos, 3618 ReportError(method->name_pos,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3634 if (must_have_semicolon) { 3662 if (must_have_semicolon) {
3635 ExpectSemicolon(); 3663 ExpectSemicolon();
3636 } else { 3664 } else {
3637 ReportError(method->name_pos, 3665 ReportError(method->name_pos,
3638 "function body or semicolon expected for method '%s'", 3666 "function body or semicolon expected for method '%s'",
3639 method->name->ToCString()); 3667 method->name->ToCString());
3640 } 3668 }
3641 } 3669 }
3642 } 3670 }
3643 3671
3672 if (method->has_abstract && (async_modifier != RawFunction::kNoModifier)) {
3673 ReportError(modifier_pos,
3674 "abstract function '%s' may not be async, async* or sync*",
3675 method->name->ToCString());
3676 }
3677
3644 RawFunction::Kind function_kind; 3678 RawFunction::Kind function_kind;
3645 if (method->IsFactoryOrConstructor()) { 3679 if (method->IsFactoryOrConstructor()) {
3646 function_kind = RawFunction::kConstructor; 3680 function_kind = RawFunction::kConstructor;
3647 } else if (method->IsGetter()) { 3681 } else if (method->IsGetter()) {
3648 function_kind = RawFunction::kGetterFunction; 3682 function_kind = RawFunction::kGetterFunction;
3649 } else if (method->IsSetter()) { 3683 } else if (method->IsSetter()) {
3650 function_kind = RawFunction::kSetterFunction; 3684 function_kind = RawFunction::kSetterFunction;
3651 } else { 3685 } else {
3652 function_kind = RawFunction::kRegularFunction; 3686 function_kind = RawFunction::kRegularFunction;
3653 } 3687 }
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after
5183 } else { 5217 } else {
5184 ExpectSemicolon(); // Reports error. 5218 ExpectSemicolon(); // Reports error.
5185 } 5219 }
5186 } 5220 }
5187 } 5221 }
5188 5222
5189 5223
5190 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { 5224 RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
5191 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { 5225 if (CurrentLiteral()->raw() == Symbols::Async().raw()) {
5192 ConsumeToken(); 5226 ConsumeToken();
5193 return RawFunction::kAsync; 5227 if (CurrentToken() == Token::kMUL) {
5228 ReportError("async* generator functions are not yet supported");
5229 ConsumeToken();
5230 return RawFunction::kAsyncGen;
5231 } else {
5232 return RawFunction::kAsync;
5233 }
5234 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) &&
5235 (LookaheadToken(1) == Token::kMUL)) {
5236 const bool enableSyncStar = true;
5237 if (!enableSyncStar) {
5238 ReportError("sync* generator functions are not yet supported");
5239 }
5240 ConsumeToken();
5241 ConsumeToken();
5242 return RawFunction::kSyncGen;
5194 } 5243 }
5195 return RawFunction::kNoModifier; 5244 return RawFunction::kNoModifier;
5196 } 5245 }
5197 5246
5198 5247
5199 void Parser::ParseTopLevelFunction(TopLevel* top_level, 5248 void Parser::ParseTopLevelFunction(TopLevel* top_level,
5200 intptr_t metadata_pos) { 5249 intptr_t metadata_pos) {
5201 TRACE_PARSER("ParseTopLevelFunction"); 5250 TRACE_PARSER("ParseTopLevelFunction");
5202 const intptr_t decl_begin_pos = TokenPos(); 5251 const intptr_t decl_begin_pos = TokenPos();
5203 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); 5252 AbstractType& result_type = Type::Handle(Z, Type::DynamicType());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5242 } 5291 }
5243 // A setter named x= may co-exist with a function named x, thus we do 5292 // A setter named x= may co-exist with a function named x, thus we do
5244 // not need to check setters. 5293 // not need to check setters.
5245 5294
5246 CheckToken(Token::kLPAREN); 5295 CheckToken(Token::kLPAREN);
5247 const intptr_t function_pos = TokenPos(); 5296 const intptr_t function_pos = TokenPos();
5248 ParamList params; 5297 ParamList params;
5249 const bool allow_explicit_default_values = true; 5298 const bool allow_explicit_default_values = true;
5250 ParseFormalParameterList(allow_explicit_default_values, false, &params); 5299 ParseFormalParameterList(allow_explicit_default_values, false, &params);
5251 5300
5301 const intptr_t modifier_pos = TokenPos();
5252 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 5302 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
5253 5303
5254 intptr_t function_end_pos = function_pos; 5304 intptr_t function_end_pos = function_pos;
5255 bool is_native = false; 5305 bool is_native = false;
5256 if (is_external) { 5306 if (is_external) {
5257 function_end_pos = TokenPos(); 5307 function_end_pos = TokenPos();
5258 ExpectSemicolon(); 5308 ExpectSemicolon();
5259 } else if (CurrentToken() == Token::kLBRACE) { 5309 } else if (CurrentToken() == Token::kLBRACE) {
5260 SkipBlock(); 5310 SkipBlock();
5261 function_end_pos = TokenPos(); 5311 function_end_pos = TokenPos();
5262 ExpectToken(Token::kRBRACE); 5312 ExpectToken(Token::kRBRACE);
5263 } else if (CurrentToken() == Token::kARROW) { 5313 } else if (CurrentToken() == Token::kARROW) {
5314 if ((func_modifier & RawFunction::kGeneratorBit) != 0) {
5315 ReportError(modifier_pos,
5316 "=> style function may not be sync* or async* generator");
5317 }
5264 ConsumeToken(); 5318 ConsumeToken();
5265 BoolScope allow_await(&this->await_is_keyword_, 5319 BoolScope allow_await(&this->await_is_keyword_,
5266 func_modifier != RawFunction::kNoModifier); 5320 func_modifier != RawFunction::kNoModifier);
5267 SkipExpr(); 5321 SkipExpr();
5268 function_end_pos = TokenPos(); 5322 function_end_pos = TokenPos();
5269 ExpectSemicolon(); 5323 ExpectSemicolon();
5270 } else if (IsLiteral("native")) { 5324 } else if (IsLiteral("native")) {
5271 ParseNativeDeclaration(); 5325 ParseNativeDeclaration();
5272 function_end_pos = TokenPos(); 5326 function_end_pos = TokenPos();
5273 ExpectSemicolon(); 5327 ExpectSemicolon();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 if (found && !is_patch) { 5437 if (found && !is_patch) {
5384 ReportError(name_pos, "%s for '%s' is already defined", 5438 ReportError(name_pos, "%s for '%s' is already defined",
5385 is_getter ? "getter" : "setter", 5439 is_getter ? "getter" : "setter",
5386 field_name->ToCString()); 5440 field_name->ToCString());
5387 } else if (!found && is_patch) { 5441 } else if (!found && is_patch) {
5388 ReportError(name_pos, "missing %s for '%s' cannot be patched", 5442 ReportError(name_pos, "missing %s for '%s' cannot be patched",
5389 is_getter ? "getter" : "setter", 5443 is_getter ? "getter" : "setter",
5390 field_name->ToCString()); 5444 field_name->ToCString());
5391 } 5445 }
5392 5446
5447 const intptr_t modifier_pos = TokenPos();
5393 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 5448 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
5449 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) {
5450 ReportError(modifier_pos,
5451 "setter function cannot be async, async* or sync*");
5452 }
5394 5453
5395 intptr_t accessor_end_pos = accessor_pos; 5454 intptr_t accessor_end_pos = accessor_pos;
5396 bool is_native = false; 5455 bool is_native = false;
5397 if (is_external) { 5456 if (is_external) {
5398 accessor_end_pos = TokenPos(); 5457 accessor_end_pos = TokenPos();
5399 ExpectSemicolon(); 5458 ExpectSemicolon();
5400 } else if (CurrentToken() == Token::kLBRACE) { 5459 } else if (CurrentToken() == Token::kLBRACE) {
5401 SkipBlock(); 5460 SkipBlock();
5402 accessor_end_pos = TokenPos(); 5461 accessor_end_pos = TokenPos();
5403 ExpectToken(Token::kRBRACE); 5462 ExpectToken(Token::kRBRACE);
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
5903 stack_trace_param.var, 5962 stack_trace_param.var,
5904 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 5963 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
5905 current_block_->statements->Add(new(Z) InstanceCallNode( 5964 current_block_->statements->Add(new(Z) InstanceCallNode(
5906 Scanner::kNoSourcePos, 5965 Scanner::kNoSourcePos,
5907 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), 5966 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var),
5908 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), 5967 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()),
5909 no_args)); 5968 no_args));
5910 } 5969 }
5911 5970
5912 ASSERT(try_blocks_list_ != NULL); 5971 ASSERT(try_blocks_list_ != NULL);
5913 if (innermost_function().is_async_closure() || 5972 if (innermost_function().IsAsyncClosure() ||
5914 innermost_function().IsAsyncFunction()) { 5973 innermost_function().IsAsyncFunction()) {
5915 if ((try_blocks_list_->outer_try_block() != NULL) && 5974 if ((try_blocks_list_->outer_try_block() != NULL) &&
5916 (try_blocks_list_->outer_try_block()->try_block() 5975 (try_blocks_list_->outer_try_block()->try_block()
5917 ->scope->function_level() == 5976 ->scope->function_level() ==
5918 current_block_->scope->function_level())) { 5977 current_block_->scope->function_level())) {
5919 // We need to unchain three scope levels: catch clause, catch 5978 // We need to unchain three scope levels: catch clause, catch
5920 // parameters, and the general try block. 5979 // parameters, and the general try block.
5921 RestoreSavedTryContext( 5980 RestoreSavedTryContext(
5922 current_block_->scope->parent()->parent()->parent(), 5981 current_block_->scope->parent()->parent()->parent(),
5923 try_blocks_list_->outer_try_block()->try_index(), 5982 try_blocks_list_->outer_try_block()->try_index(),
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
6008 TokenPos(), 6067 TokenPos(),
6009 Symbols::StackTraceVar(), 6068 Symbols::StackTraceVar(),
6010 Type::ZoneHandle(Z, Type::DynamicType())); 6069 Type::ZoneHandle(Z, Type::DynamicType()));
6011 current_block_->scope->AddVariable(stack_trace_var); 6070 current_block_->scope->AddVariable(stack_trace_var);
6012 } 6071 }
6013 6072
6014 // Open the try block. 6073 // Open the try block.
6015 OpenBlock(); 6074 OpenBlock();
6016 PushTryBlock(current_block_); 6075 PushTryBlock(current_block_);
6017 6076
6018 if (innermost_function().is_async_closure() || 6077 if (innermost_function().IsAsyncClosure() ||
6019 innermost_function().IsAsyncFunction()) { 6078 innermost_function().IsAsyncFunction()) {
6020 SetupSavedTryContext(context_var); 6079 SetupSavedTryContext(context_var);
6021 } 6080 }
6022 } 6081 }
6023 6082
6024 6083
6084 void Parser::AddSyncGenClosureParameters(ParamList* params) {
6085 // Create the parameter list for the body closure of a sync generator:
6086 // 1) Implicit closure parameter;
6087 // 2) Iterator
6088 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6089 // Add implicit closure parameter if not already present.
6090 if (params->parameters->length() == 0) {
6091 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6092 }
6093 ParamDesc iterator_param;
6094 iterator_param.name = &Symbols::IteratorParameter();
6095 iterator_param.type = &dynamic_type;
6096 params->parameters->Add(iterator_param);
6097 params->num_fixed_parameters++;
6098 }
6099
6100
6101 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
6102 Function& body = Function::Handle(Z);
6103 String& body_closure_name = String::Handle(Z);
6104 bool is_new_closure = false;
6105
6106 AddContinuationVariables();
6107
6108 // Check whether a function for the body of this generator
6109 // function has already been created by a previous
6110 // compilation.
6111 const Function& found_func = Function::Handle(
6112 Z, current_class().LookupClosureFunction(func_pos));
6113 if (!found_func.IsNull() &&
6114 (found_func.token_pos() == func_pos) &&
6115 (found_func.script() == innermost_function().script()) &&
6116 (found_func.parent_function() == innermost_function().raw())) {
6117 ASSERT(found_func.IsSyncGenClosure());
6118 body = found_func.raw();
6119 body_closure_name = body.name();
6120 } else {
6121 // Create the closure containing the body of this generator function.
6122 String& generator_name = String::Handle(Z, innermost_function().name());
6123 body_closure_name =
6124 String::NewFormatted("<%s_sync_body>", generator_name.ToCString());
6125 body_closure_name = Symbols::New(body_closure_name);
6126 body = Function::NewClosureFunction(body_closure_name,
6127 innermost_function(),
6128 func_pos);
6129 body.set_is_generated_body(true);
6130 body.set_result_type(AbstractType::Handle(Type::DynamicType()));
6131 is_new_closure = true;
6132 }
6133
6134 ParamList closure_params;
6135 AddSyncGenClosureParameters(&closure_params);
6136
6137 if (is_new_closure) {
6138 // Add the parameters to the newly created closure.
6139 AddFormalParamsToFunction(&closure_params, body);
6140
6141 // Create and set the signature class of the closure.
6142 const String& sig = String::Handle(Z, body.Signature());
6143 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6144 if (sig_cls.IsNull()) {
6145 sig_cls = Class::NewSignatureClass(sig, body, script_, body.token_pos());
6146 library_.AddClass(sig_cls);
6147 }
6148 body.set_signature_class(sig_cls);
6149 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6150 if (!sig_type.IsFinalized()) {
6151 ClassFinalizer::FinalizeType(
6152 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6153 }
6154 ASSERT(AbstractType::Handle(Z, body.result_type()).IsResolved());
6155 ASSERT(body.NumParameters() == closure_params.parameters->length());
6156 }
6157
6158 OpenFunctionBlock(body);
6159 AddFormalParamsToScope(&closure_params, current_block_->scope);
6160 OpenBlock();
6161
6162 /*
6163 async_temp_scope_ = current_block_->scope; // Is this needed?
6164 */
6165 return body.raw();
6166 }
6167
6168 SequenceNode* Parser::CloseSyncGenFunction(const Function& closure,
6169 SequenceNode* closure_body) {
6170 // The block for the closure body has already been closed. Close the
6171 // corresponding function block.
6172 CloseBlock();
6173
6174 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6175 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6176
6177 // :await_jump_var = -1;
6178 LocalVariable* jump_var =
6179 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6180 LiteralNode* init_value =
6181 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6182 current_block_->statements->Add(
6183 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6184
6185 // return new SyncIterable(body_closure);
6186 const Class& iterable_class =
6187 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable()));
6188 ASSERT(!iterable_class.IsNull());
6189 const Function& iterable_constructor = Function::ZoneHandle(Z,
6190 iterable_class.LookupConstructorAllowPrivate(
6191 Symbols::_SyncIterableConstructor()));
6192 ASSERT(!iterable_constructor.IsNull());
6193
6194 const String& closure_name = String::Handle(Z, closure.name());
6195 ASSERT(closure_name.IsSymbol());
6196
6197 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6198 ClosureNode* closure_obj = new(Z) ClosureNode(
6199 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6200 arguments->Add(closure_obj);
6201 ConstructorCallNode* new_iterable =
6202 new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
6203 TypeArguments::ZoneHandle(Z),
6204 iterable_constructor,
6205 arguments);
6206 ReturnNode* return_node =
6207 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable);
6208 current_block_->statements->Add(return_node);
6209 return CloseBlock();
6210 }
6211
6212
6213 void Parser::AddAsyncClosureParameters(ParamList* params) {
6214 // Async closures have two optional parameters:
6215 // * A continuation result.
6216 // * A continuation error.
6217 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6218 // Add implicit closure parameter if not yet present.
6219 if (params->parameters->length() == 0) {
6220 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6221 }
6222 ParamDesc result_param;
6223 result_param.name = &Symbols::AsyncOperationParam();
6224 result_param.default_value = &Object::null_instance();
6225 result_param.type = &dynamic_type;
6226 params->parameters->Add(result_param);
6227 ParamDesc error_param;
6228 error_param.name = &Symbols::AsyncOperationErrorParam();
6229 error_param.default_value = &Object::null_instance();
6230 error_param.type = &dynamic_type;
6231 params->parameters->Add(error_param);
6232 params->has_optional_positional_parameters = true;
6233 params->num_optional_parameters += 2;
6234 }
6235
6236
6025 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { 6237 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) {
6026 TRACE_PARSER("OpenAsyncFunction"); 6238 TRACE_PARSER("OpenAsyncFunction");
6239 AddContinuationVariables();
6027 AddAsyncClosureVariables(); 6240 AddAsyncClosureVariables();
6028 Function& closure = Function::Handle(Z); 6241 Function& closure = Function::Handle(Z);
6029 bool is_new_closure = false; 6242 bool is_new_closure = false;
6030 6243
6031 // Check whether a function for the asynchronous function body of 6244 // Check whether a function for the asynchronous function body of
6032 // this async function has already been created by a previous 6245 // this async function has already been created by a previous
6033 // compilation of this function. 6246 // compilation of this function.
6034 const Function& found_func = Function::Handle( 6247 const Function& found_func = Function::Handle(
6035 Z, current_class().LookupClosureFunction(async_func_pos)); 6248 Z, current_class().LookupClosureFunction(async_func_pos));
6036 if (!found_func.IsNull() && 6249 if (!found_func.IsNull() &&
6037 (found_func.token_pos() == async_func_pos) && 6250 (found_func.token_pos() == async_func_pos) &&
6038 (found_func.script() == innermost_function().script()) && 6251 (found_func.script() == innermost_function().script()) &&
6039 (found_func.parent_function() == innermost_function().raw())) { 6252 (found_func.parent_function() == innermost_function().raw())) {
6040 ASSERT(found_func.is_async_closure()); 6253 ASSERT(found_func.IsAsyncClosure());
6041 closure = found_func.raw(); 6254 closure = found_func.raw();
6042 } else { 6255 } else {
6043 // Create the closure containing the body of this async function. 6256 // Create the closure containing the body of this async function.
6044 const String& async_func_name = 6257 const String& async_func_name =
6045 String::Handle(Z, innermost_function().name()); 6258 String::Handle(Z, innermost_function().name());
6046 String& closure_name = String::Handle(Z, 6259 String& closure_name = String::Handle(Z,
6047 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); 6260 String::NewFormatted("<%s_async_body>", async_func_name.ToCString()));
6048 closure = Function::NewClosureFunction( 6261 closure = Function::NewClosureFunction(
6049 String::Handle(Z, Symbols::New(closure_name)), 6262 String::Handle(Z, Symbols::New(closure_name)),
6050 innermost_function(), 6263 innermost_function(),
6051 async_func_pos); 6264 async_func_pos);
6052 closure.set_is_async_closure(true); 6265 closure.set_is_generated_body(true);
6053 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); 6266 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6054 is_new_closure = true; 6267 is_new_closure = true;
6055 } 6268 }
6056 // Create the parameter list for the async body closure. 6269 // Create the parameter list for the async body closure.
6057 ParamList closure_params; 6270 ParamList closure_params;
6058 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6271 AddAsyncClosureParameters(&closure_params);
6059 closure_params.AddFinalParameter(
6060 async_func_pos, &Symbols::ClosureParameter(), &dynamic_type);
6061 ParamDesc result_param;
6062 result_param.name = &Symbols::AsyncOperationParam();
6063 result_param.default_value = &Object::null_instance();
6064 result_param.type = &dynamic_type;
6065 closure_params.parameters->Add(result_param);
6066 ParamDesc error_param;
6067 error_param.name = &Symbols::AsyncOperationErrorParam();
6068 error_param.default_value = &Object::null_instance();
6069 error_param.type = &dynamic_type;
6070 closure_params.parameters->Add(error_param);
6071 closure_params.has_optional_positional_parameters = true;
6072 closure_params.num_optional_parameters += 2;
6073
6074 if (is_new_closure) { 6272 if (is_new_closure) {
6075 // Add the parameters to the newly created closure. 6273 // Add the parameters to the newly created closure.
6076 AddFormalParamsToFunction(&closure_params, closure); 6274 AddFormalParamsToFunction(&closure_params, closure);
6077 6275
6078 // Create and set the signature class of the closure. 6276 // Create and set the signature class of the closure.
6079 const String& sig = String::Handle(Z, closure.Signature()); 6277 const String& sig = String::Handle(Z, closure.Signature());
6080 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig)); 6278 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6081 if (sig_cls.IsNull()) { 6279 if (sig_cls.IsNull()) {
6082 sig_cls = 6280 sig_cls =
6083 Class::NewSignatureClass(sig, closure, script_, closure.token_pos()); 6281 Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
6084 library_.AddClass(sig_cls); 6282 library_.AddClass(sig_cls);
6085 } 6283 }
6086 closure.set_signature_class(sig_cls); 6284 closure.set_signature_class(sig_cls);
6087 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType()); 6285 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6088 if (!sig_type.IsFinalized()) { 6286 if (!sig_type.IsFinalized()) {
6089 ClassFinalizer::FinalizeType( 6287 ClassFinalizer::FinalizeType(
6090 sig_cls, sig_type, ClassFinalizer::kCanonicalize); 6288 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6091 } 6289 }
6092 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); 6290 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6093 ASSERT(closure.NumParameters() == closure_params.parameters->length()); 6291 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6094 } 6292 }
6095 OpenFunctionBlock(closure); 6293 OpenFunctionBlock(closure);
6096 AddFormalParamsToScope(&closure_params, current_block_->scope); 6294 AddFormalParamsToScope(&closure_params, current_block_->scope);
6097 OpenBlock(); 6295 OpenBlock();
6098 async_temp_scope_ = current_block_->scope; 6296 async_temp_scope_ = current_block_->scope;
6099 return closure.raw(); 6297 return closure.raw();
6100 } 6298 }
6101 6299
6102 6300
6103 void Parser::AddAsyncClosureVariables() { 6301 void Parser::AddContinuationVariables() {
6104 // Add to AST: 6302 // Add to current block's scope:
6105 // var :await_jump_var; 6303 // var :await_jump_var;
6106 // var :await_ctx_var; 6304 // var :await_ctx_var;
6107 // var :async_op;
6108 // var :async_completer;
6109 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6305 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6110 LocalVariable* await_jump_var = new (Z) LocalVariable( 6306 LocalVariable* await_jump_var = new (Z) LocalVariable(
6111 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); 6307 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
6112 current_block_->scope->AddVariable(await_jump_var); 6308 current_block_->scope->AddVariable(await_jump_var);
6113 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar()); 6309 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar());
6114 await_jump_var->set_is_captured(); 6310 await_jump_var->set_is_captured();
6115 LocalVariable* await_ctx_var = new (Z) LocalVariable( 6311 LocalVariable* await_ctx_var = new (Z) LocalVariable(
6116 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); 6312 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
6117 current_block_->scope->AddVariable(await_ctx_var); 6313 current_block_->scope->AddVariable(await_ctx_var);
6118 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar()); 6314 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar());
6119 await_ctx_var->set_is_captured(); 6315 await_ctx_var->set_is_captured();
6120 LocalVariable* async_op_var = new (Z) LocalVariable( 6316 }
6317
6318
6319 void Parser::AddAsyncClosureVariables() {
6320 // Add to current block's scope:
6321 // var :async_op;
6322 // var :async_completer;
6323 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6324 LocalVariable* async_op_var = new(Z) LocalVariable(
6121 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); 6325 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6122 current_block_->scope->AddVariable(async_op_var); 6326 current_block_->scope->AddVariable(async_op_var);
6123 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); 6327 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6124 async_op_var->set_is_captured(); 6328 async_op_var->set_is_captured();
6125 LocalVariable* async_completer = new (Z) LocalVariable( 6329 LocalVariable* async_completer = new(Z) LocalVariable(
6126 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6330 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6127 current_block_->scope->AddVariable(async_completer); 6331 current_block_->scope->AddVariable(async_completer);
6128 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); 6332 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter());
6129 async_completer->set_is_captured(); 6333 async_completer->set_is_captured();
6130 } 6334 }
6131 6335
6132 6336
6133 SequenceNode* Parser::CloseBlock() { 6337 SequenceNode* Parser::CloseBlock() {
6134 SequenceNode* statements = current_block_->statements; 6338 SequenceNode* statements = current_block_->statements;
6135 if (current_block_->scope != NULL) { 6339 if (current_block_->scope != NULL) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
6197 TypeArguments::ZoneHandle(Z), 6401 TypeArguments::ZoneHandle(Z),
6198 completer_constructor, 6402 completer_constructor,
6199 empty_args); 6403 empty_args);
6200 StoreLocalNode* store_completer = new (Z) StoreLocalNode( 6404 StoreLocalNode* store_completer = new (Z) StoreLocalNode(
6201 Scanner::kNoSourcePos, 6405 Scanner::kNoSourcePos,
6202 async_completer, 6406 async_completer,
6203 completer_constructor_node); 6407 completer_constructor_node);
6204 current_block_->statements->Add(store_completer); 6408 current_block_->statements->Add(store_completer);
6205 6409
6206 // :await_jump_var = -1; 6410 // :await_jump_var = -1;
6207 LocalVariable* jump_var = current_block_->scope->LookupVariable( 6411 LocalVariable* jump_var =
6208 Symbols::AwaitJumpVar(), false); 6412 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6209 LiteralNode* init_value = 6413 LiteralNode* init_value =
6210 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); 6414 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6211 current_block_->statements->Add( 6415 current_block_->statements->Add(
6212 new (Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); 6416 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6213 6417
6214 // Add to AST: 6418 // Add to AST:
6215 // :async_op = <closure>; (containing the original body) 6419 // :async_op = <closure>; (containing the original body)
6216 LocalVariable* async_op_var = current_block_->scope->LookupVariable( 6420 LocalVariable* async_op_var = current_block_->scope->LookupVariable(
6217 Symbols::AsyncOperation(), false); 6421 Symbols::AsyncOperation(), false);
6218 ClosureNode* cn = new(Z) ClosureNode( 6422 ClosureNode* cn = new(Z) ClosureNode(
6219 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); 6423 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6220 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( 6424 StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
6221 Scanner::kNoSourcePos, 6425 Scanner::kNoSourcePos,
6222 async_op_var, 6426 async_op_var,
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
6459 assign_pos, variable, expr); 6663 assign_pos, variable, expr);
6460 if (is_const) { 6664 if (is_const) {
6461 ASSERT(expr->IsLiteralNode()); 6665 ASSERT(expr->IsLiteralNode());
6462 variable->SetConstValue(expr->AsLiteralNode()->literal()); 6666 variable->SetConstValue(expr->AsLiteralNode()->literal());
6463 } 6667 }
6464 } else if (is_final || is_const) { 6668 } else if (is_final || is_const) {
6465 ReportError(ident_pos, 6669 ReportError(ident_pos,
6466 "missing initialization of 'final' or 'const' variable"); 6670 "missing initialization of 'final' or 'const' variable");
6467 } else { 6671 } else {
6468 // Initialize variable with null. 6672 // Initialize variable with null.
6469 AstNode* null_expr = new(Z) LiteralNode( 6673 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Instance::ZoneHandle(Z));
6470 ident_pos, Instance::ZoneHandle(Z));
6471 initialization = new(Z) StoreLocalNode( 6674 initialization = new(Z) StoreLocalNode(
6472 ident_pos, variable, null_expr); 6675 ident_pos, variable, null_expr);
6473 } 6676 }
6474 6677
6475 ASSERT(current_block_ != NULL); 6678 ASSERT(current_block_ != NULL);
6476 const intptr_t previous_pos = 6679 const intptr_t previous_pos =
6477 current_block_->scope->PreviousReferencePos(ident); 6680 current_block_->scope->PreviousReferencePos(ident);
6478 if (previous_pos >= 0) { 6681 if (previous_pos >= 0) {
6479 ASSERT(!script_.IsNull()); 6682 ASSERT(!script_.IsNull());
6480 if (previous_pos > ident_pos) { 6683 if (previous_pos > ident_pos) {
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
6890 } else if (CurrentToken() == Token::kFALSE) { 7093 } else if (CurrentToken() == Token::kFALSE) {
6891 *value = Bool::False().raw(); 7094 *value = Bool::False().raw();
6892 return true; 7095 return true;
6893 } 7096 }
6894 return false; 7097 return false;
6895 } 7098 }
6896 7099
6897 7100
6898 // Returns true if the current token is kIDENT or a pseudo-keyword. 7101 // Returns true if the current token is kIDENT or a pseudo-keyword.
6899 bool Parser::IsIdentifier() { 7102 bool Parser::IsIdentifier() {
6900 return Token::IsIdentifier(CurrentToken()) && !IsAwaitKeyword(); 7103 return Token::IsIdentifier(CurrentToken()) &&
7104 !(await_is_keyword_ &&
7105 ((CurrentLiteral()->raw() == Symbols::Await().raw()) ||
7106 (CurrentLiteral()->raw() == Symbols::Async().raw()) ||
7107 (CurrentLiteral()->raw() == Symbols::Yield().raw())));
6901 } 7108 }
6902 7109
6903 7110
6904 // Returns true if the next tokens can be parsed as a an optionally 7111 // Returns true if the next tokens can be parsed as a an optionally
6905 // qualified identifier: [ident '.'] ident. 7112 // qualified identifier: [ident '.'] ident.
6906 // Current token position is not restored. 7113 // Current token position is not restored.
6907 bool Parser::TryParseQualIdent() { 7114 bool Parser::TryParseQualIdent() {
6908 if (CurrentToken() != Token::kIDENT) { 7115 if (CurrentToken() != Token::kIDENT) {
6909 return false; 7116 return false;
6910 } 7117 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
7039 SetPosition(saved_pos); 7246 SetPosition(saved_pos);
7040 return false; 7247 return false;
7041 } 7248 }
7042 // Check parameter list and the following token. 7249 // Check parameter list and the following token.
7043 if (CurrentToken() == Token::kLPAREN) { 7250 if (CurrentToken() == Token::kLPAREN) {
7044 SkipToMatchingParenthesis(); 7251 SkipToMatchingParenthesis();
7045 if ((CurrentToken() == Token::kLBRACE) || 7252 if ((CurrentToken() == Token::kLBRACE) ||
7046 (CurrentToken() == Token::kARROW) || 7253 (CurrentToken() == Token::kARROW) ||
7047 (is_top_level_ && IsLiteral("native")) || 7254 (is_top_level_ && IsLiteral("native")) ||
7048 is_external || 7255 is_external ||
7049 (CurrentLiteral()->raw() == Symbols::Async().raw())) { 7256 (CurrentLiteral()->raw() == Symbols::Async().raw()) ||
7257 (CurrentLiteral()->raw() == Symbols::Sync().raw())) {
7050 SetPosition(saved_pos); 7258 SetPosition(saved_pos);
7051 return true; 7259 return true;
7052 } 7260 }
7053 } 7261 }
7054 SetPosition(saved_pos); 7262 SetPosition(saved_pos);
7055 return false; 7263 return false;
7056 } 7264 }
7057 7265
7058 7266
7059 bool Parser::IsTopLevelAccessor() { 7267 bool Parser::IsTopLevelAccessor() {
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
7529 7737
7530 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 7738 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
7531 TRACE_PARSER("ParseAwaitForStatement"); 7739 TRACE_PARSER("ParseAwaitForStatement");
7532 ASSERT(IsAwaitKeyword()); 7740 ASSERT(IsAwaitKeyword());
7533 const intptr_t await_for_pos = TokenPos(); 7741 const intptr_t await_for_pos = TokenPos();
7534 ConsumeToken(); // await. 7742 ConsumeToken(); // await.
7535 ASSERT(CurrentToken() == Token::kFOR); 7743 ASSERT(CurrentToken() == Token::kFOR);
7536 ConsumeToken(); // for. 7744 ConsumeToken(); // for.
7537 ExpectToken(Token::kLPAREN); 7745 ExpectToken(Token::kLPAREN);
7538 7746
7747 if (!innermost_function().IsAsyncFunction() &&
7748 !innermost_function().IsAsyncClosure()) {
7749 ReportError(await_for_pos,
7750 "await for loop is only allowed in async function");
7751 }
7752
7539 // Parse loop variable. 7753 // Parse loop variable.
7540 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); 7754 bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
7541 if (CurrentToken() == Token::kCONST) { 7755 if (CurrentToken() == Token::kCONST) {
7542 ReportError("Loop variable cannot be 'const'"); 7756 ReportError("Loop variable cannot be 'const'");
7543 } 7757 }
7544 bool new_loop_var = false; 7758 bool new_loop_var = false;
7545 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); 7759 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z);
7546 if (LookaheadToken(1) != Token::kIN) { 7760 if (LookaheadToken(1) != Token::kIN) {
7547 // Declaration of a new loop variable. 7761 // Declaration of a new loop variable.
7548 // Delay creation of the local variable until we know its actual 7762 // Delay creation of the local variable until we know its actual
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
7711 // It is better to leave the iterator untyped and postpone the type error 7925 // It is better to leave the iterator untyped and postpone the type error
7712 // until the loop variable is assigned to. 7926 // until the loop variable is assigned to.
7713 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); 7927 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
7714 LocalVariable* iterator_var = new(Z) LocalVariable( 7928 LocalVariable* iterator_var = new(Z) LocalVariable(
7715 collection_pos, Symbols::ForInIter(), iterator_type); 7929 collection_pos, Symbols::ForInIter(), iterator_type);
7716 current_block_->scope->AddVariable(iterator_var); 7930 current_block_->scope->AddVariable(iterator_var);
7717 7931
7718 // Generate initialization of iterator variable. 7932 // Generate initialization of iterator variable.
7719 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos); 7933 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos);
7720 AstNode* get_iterator = new(Z) InstanceGetterNode( 7934 AstNode* get_iterator = new(Z) InstanceGetterNode(
7721 collection_pos, collection_expr, Symbols::GetIterator()); 7935 collection_pos, collection_expr, Symbols::iterator());
7722 AstNode* iterator_init = 7936 AstNode* iterator_init =
7723 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); 7937 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator);
7724 current_block_->statements->Add(iterator_init); 7938 current_block_->statements->Add(iterator_init);
7725 7939
7726 // Generate while loop condition. 7940 // Generate while loop condition.
7727 AstNode* iterator_moveNext = new(Z) InstanceCallNode( 7941 AstNode* iterator_moveNext = new(Z) InstanceCallNode(
7728 collection_pos, 7942 collection_pos,
7729 new(Z) LoadLocalNode(collection_pos, iterator_var), 7943 new(Z) LoadLocalNode(collection_pos, iterator_var),
7730 Symbols::MoveNext(), 7944 Symbols::MoveNext(),
7731 no_args); 7945 no_args);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
7962 8176
7963 8177
7964 SequenceNode* Parser::ParseFinallyBlock() { 8178 SequenceNode* Parser::ParseFinallyBlock() {
7965 TRACE_PARSER("ParseFinallyBlock"); 8179 TRACE_PARSER("ParseFinallyBlock");
7966 OpenBlock(); 8180 OpenBlock();
7967 ExpectToken(Token::kLBRACE); 8181 ExpectToken(Token::kLBRACE);
7968 8182
7969 // In case of async closures we need to restore the saved try index of an 8183 // In case of async closures we need to restore the saved try index of an
7970 // outer try block (if it exists). The current try block has already been 8184 // outer try block (if it exists). The current try block has already been
7971 // removed from the stack of try blocks. 8185 // removed from the stack of try blocks.
7972 if ((innermost_function().is_async_closure() || 8186 if ((innermost_function().IsAsyncClosure() ||
7973 innermost_function().IsAsyncFunction()) && 8187 innermost_function().IsAsyncFunction()) &&
7974 (try_blocks_list_ != NULL)) { 8188 (try_blocks_list_ != NULL)) {
7975 // We need two unchain two scopes: finally clause, and the try block level. 8189 // We need two unchain two scopes: finally clause, and the try block level.
7976 RestoreSavedTryContext(current_block_->scope->parent()->parent(), 8190 RestoreSavedTryContext(current_block_->scope->parent()->parent(),
7977 try_blocks_list_->try_index(), 8191 try_blocks_list_->try_index(),
7978 current_block_->statements); 8192 current_block_->statements);
7979 } else { 8193 } else {
7980 parsed_function()->reset_saved_try_ctx_vars(); 8194 parsed_function()->reset_saved_try_ctx_vars();
7981 } 8195 }
7982 8196
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
8122 no_args)); 8336 no_args));
8123 } 8337 }
8124 8338
8125 // Add nested block with user-defined code. This blocks allows 8339 // Add nested block with user-defined code. This blocks allows
8126 // declarations in the body to shadow the catch parameters. 8340 // declarations in the body to shadow the catch parameters.
8127 CheckToken(Token::kLBRACE); 8341 CheckToken(Token::kLBRACE);
8128 8342
8129 // In case of async closures we need to restore the saved try index of an 8343 // In case of async closures we need to restore the saved try index of an
8130 // outer try block (if it exists). 8344 // outer try block (if it exists).
8131 ASSERT(try_blocks_list_ != NULL); 8345 ASSERT(try_blocks_list_ != NULL);
8132 if (innermost_function().is_async_closure() || 8346 if (innermost_function().IsAsyncClosure() ||
8133 innermost_function().IsAsyncFunction()) { 8347 innermost_function().IsAsyncFunction()) {
8134 if ((try_blocks_list_->outer_try_block() != NULL) && 8348 if ((try_blocks_list_->outer_try_block() != NULL) &&
8135 (try_blocks_list_->outer_try_block()->try_block() 8349 (try_blocks_list_->outer_try_block()->try_block()
8136 ->scope->function_level() == 8350 ->scope->function_level() ==
8137 current_block_->scope->function_level())) { 8351 current_block_->scope->function_level())) {
8138 // We need to unchain three scope levels: catch clause, catch 8352 // We need to unchain three scope levels: catch clause, catch
8139 // parameters, and the general try block. 8353 // parameters, and the general try block.
8140 RestoreSavedTryContext( 8354 RestoreSavedTryContext(
8141 current_block_->scope->parent()->parent()->parent(), 8355 current_block_->scope->parent()->parent()->parent(),
8142 try_blocks_list_->outer_try_block()->try_index(), 8356 try_blocks_list_->outer_try_block()->try_index(),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
8230 // If the last body was entered conditionally and there is no need to add 8444 // If the last body was entered conditionally and there is no need to add
8231 // a rethrow, use an empty else body (current = NULL above). 8445 // a rethrow, use an empty else body (current = NULL above).
8232 8446
8233 while (!type_tests.is_empty()) { 8447 while (!type_tests.is_empty()) {
8234 AstNode* type_test = type_tests.RemoveLast(); 8448 AstNode* type_test = type_tests.RemoveLast();
8235 SequenceNode* catch_block = catch_blocks.RemoveLast(); 8449 SequenceNode* catch_block = catch_blocks.RemoveLast();
8236 8450
8237 // In case of async closures we need to restore the saved try index of an 8451 // In case of async closures we need to restore the saved try index of an
8238 // outer try block (if it exists). 8452 // outer try block (if it exists).
8239 ASSERT(try_blocks_list_ != NULL); 8453 ASSERT(try_blocks_list_ != NULL);
8240 if (innermost_function().is_async_closure() || 8454 if (innermost_function().IsAsyncClosure() ||
8241 innermost_function().IsAsyncFunction()) { 8455 innermost_function().IsAsyncFunction()) {
8242 if ((try_blocks_list_->outer_try_block() != NULL) && 8456 if ((try_blocks_list_->outer_try_block() != NULL) &&
8243 (try_blocks_list_->outer_try_block()->try_block() 8457 (try_blocks_list_->outer_try_block()->try_block()
8244 ->scope->function_level() == 8458 ->scope->function_level() ==
8245 current_block_->scope->function_level())) { 8459 current_block_->scope->function_level())) {
8246 // We need to unchain three scope levels: catch clause, catch 8460 // We need to unchain three scope levels: catch clause, catch
8247 // parameters, and the general try block. 8461 // parameters, and the general try block.
8248 RestoreSavedTryContext( 8462 RestoreSavedTryContext(
8249 current_block_->scope->parent()->parent(), 8463 current_block_->scope->parent()->parent(),
8250 try_blocks_list_->outer_try_block()->try_index(), 8464 try_blocks_list_->outer_try_block()->try_index(),
(...skipping 17 matching lines...) Expand all
8268 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( 8482 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
8269 Scanner::kNoSourcePos, 8483 Scanner::kNoSourcePos,
8270 async_saved_try_ctx_name, 8484 async_saved_try_ctx_name,
8271 Type::ZoneHandle(Z, Type::DynamicType())); 8485 Type::ZoneHandle(Z, Type::DynamicType()));
8272 async_temp_scope_->AddVariable(async_saved_try_ctx); 8486 async_temp_scope_->AddVariable(async_saved_try_ctx);
8273 async_saved_try_ctx->set_is_captured(); 8487 async_saved_try_ctx->set_is_captured();
8274 async_saved_try_ctx = current_block_->scope->LookupVariable( 8488 async_saved_try_ctx = current_block_->scope->LookupVariable(
8275 async_saved_try_ctx_name, false); 8489 async_saved_try_ctx_name, false);
8276 ASSERT(async_saved_try_ctx != NULL); 8490 ASSERT(async_saved_try_ctx != NULL);
8277 ASSERT(saved_try_context != NULL); 8491 ASSERT(saved_try_context != NULL);
8278 current_block_->statements->Add(new (Z) StoreLocalNode( 8492 current_block_->statements->Add(new(Z) StoreLocalNode(
8279 Scanner::kNoSourcePos, async_saved_try_ctx, new (Z) LoadLocalNode( 8493 Scanner::kNoSourcePos,
8280 Scanner::kNoSourcePos, saved_try_context))); 8494 async_saved_try_ctx,
8495 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context)));
8281 parsed_function()->set_saved_try_ctx(saved_try_context); 8496 parsed_function()->set_saved_try_ctx(saved_try_context);
8282 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); 8497 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name);
8283 } 8498 }
8284 8499
8285 8500
8286 // Set up the currently relevant :saved_try_context_var on the stack: 8501 // Restore the currently relevant :saved_try_context_var on the stack
8502 // from the captured :async_saved_try_cts_var.
8287 // * Try blocks: Set the context variable for this try block. 8503 // * Try blocks: Set the context variable for this try block.
8288 // * Catch/finally blocks: Set the context variable for any outer try block (if 8504 // * Catch/finally blocks: Set the context variable for any outer try block (if
8289 // existent). 8505 // existent).
8290 // 8506 //
8291 // Also save the captured variable and the stack variable to be able to set 8507 // Also save the captured variable and the stack variable to be able to set
8292 // it after a function continues execution (await). 8508 // it after a function continues execution (await).
8293 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, 8509 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope,
8294 int16_t try_index, 8510 int16_t try_index,
8295 SequenceNode* target) { 8511 SequenceNode* target) {
8296 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( 8512 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable(
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
8364 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 8580 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
8365 OpenBlock(); 8581 OpenBlock();
8366 current_block_->scope->AddLabel(try_label); 8582 current_block_->scope->AddLabel(try_label);
8367 } 8583 }
8368 8584
8369 // Now parse the 'try' block. 8585 // Now parse the 'try' block.
8370 OpenBlock(); 8586 OpenBlock();
8371 PushTryBlock(current_block_); 8587 PushTryBlock(current_block_);
8372 ExpectToken(Token::kLBRACE); 8588 ExpectToken(Token::kLBRACE);
8373 8589
8374 if (innermost_function().is_async_closure() || 8590 if (innermost_function().IsAsyncClosure() ||
8375 innermost_function().IsAsyncFunction()) { 8591 innermost_function().IsAsyncFunction()) {
8376 SetupSavedTryContext(context_var); 8592 SetupSavedTryContext(context_var);
8377 } 8593 }
8378 8594
8379 ParseStatementSequence(); 8595 ParseStatementSequence();
8380 ExpectToken(Token::kRBRACE); 8596 ExpectToken(Token::kRBRACE);
8381 SequenceNode* try_block = CloseBlock(); 8597 SequenceNode* try_block = CloseBlock();
8382 8598
8383 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 8599 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
8384 (CurrentToken() != Token::kFINALLY)) { 8600 (CurrentToken() != Token::kFINALLY)) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
8543 } else if (token == Token::kDO) { 8759 } else if (token == Token::kDO) {
8544 statement = ParseDoWhileStatement(label_name); 8760 statement = ParseDoWhileStatement(label_name);
8545 } else if (token == Token::kSWITCH) { 8761 } else if (token == Token::kSWITCH) {
8546 statement = ParseSwitchStatement(label_name); 8762 statement = ParseSwitchStatement(label_name);
8547 } else if (token == Token::kTRY) { 8763 } else if (token == Token::kTRY) {
8548 statement = ParseTryStatement(label_name); 8764 statement = ParseTryStatement(label_name);
8549 } else if (token == Token::kRETURN) { 8765 } else if (token == Token::kRETURN) {
8550 const intptr_t return_pos = TokenPos(); 8766 const intptr_t return_pos = TokenPos();
8551 ConsumeToken(); 8767 ConsumeToken();
8552 if (CurrentToken() != Token::kSEMICOLON) { 8768 if (CurrentToken() != Token::kSEMICOLON) {
8769 const intptr_t expr_pos = TokenPos();
8553 if (current_function().IsConstructor() && 8770 if (current_function().IsConstructor() &&
8554 (current_block_->scope->function_level() == 0)) { 8771 (current_block_->scope->function_level() == 0)) {
8555 ReportError(return_pos, 8772 ReportError(expr_pos,
8556 "return of a value not allowed in constructors"); 8773 "return of a value is not allowed in constructors");
8774 } else if (current_function().IsGenerator()) {
8775 ReportError(expr_pos, "generator functions may not return a value");
8557 } 8776 }
8558 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 8777 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8559 statement = new(Z) ReturnNode(statement_pos, expr); 8778 statement = new(Z) ReturnNode(statement_pos, expr);
8560 } else { 8779 } else {
8561 statement = new(Z) ReturnNode(statement_pos); 8780 if (current_function().IsSyncGenClosure() &&
8781 (current_block_->scope->function_level() == 0)) {
8782 // In a synchronous generator, return without an expression
8783 // returns false, signaling that the iterator terminates and
8784 // did not yield a value.
8785 statement = new(Z) ReturnNode(statement_pos,
8786 new(Z) LiteralNode(return_pos, Bool::False()));
8787 } else {
8788 statement = new(Z) ReturnNode(statement_pos);
8789 }
8562 } 8790 }
8563 AddNodeForFinallyInlining(statement); 8791 AddNodeForFinallyInlining(statement);
8564 ExpectSemicolon(); 8792 ExpectSemicolon();
8793 } else if (IsYieldKeyword()) {
8794 bool is_yield_each = false;
8795 ConsumeToken();
8796 ASSERT(innermost_function().IsGenerator() ||
8797 innermost_function().IsSyncGenClosure());
8798 if (CurrentToken() == Token::kMUL) {
8799 is_yield_each = true;
8800 ConsumeToken();
8801 }
8802 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8803 LocalVariable* iterator_param =
8804 LookupLocalScope(Symbols::IteratorParameter());
8805 ASSERT(iterator_param != NULL);
8806 // Generate :iterator.current = expr;
8807 AstNode* iterator =
8808 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
8809 AstNode* store_current =
8810 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8811 iterator,
8812 String::ZoneHandle(Symbols::Current().raw()),
8813 expr);
8814 LetNode* yield = new(Z) LetNode(statement_pos);
8815 yield->AddNode(store_current);
8816 if (is_yield_each) {
8817 // Generate :iterator.isYieldEach = true;
8818 AstNode* set_is_yield_each =
8819 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8820 iterator,
8821 String::ZoneHandle(Symbols::IsYieldEach().raw()),
8822 new(Z) LiteralNode(TokenPos(), Bool::True()));
8823 yield->AddNode(set_is_yield_each);
8824 }
8825 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
8826 await_marker->set_scope(current_block_->scope);
8827 yield->AddNode(await_marker);
8828 // Return true to indicate that a value has been generated.
8829 ReturnNode* return_true = new(Z) ReturnNode(statement_pos,
8830 new(Z) LiteralNode(TokenPos(), Bool::True()));
8831 return_true->set_return_type(ReturnNode::kContinuationTarget);
8832 yield->AddNode(return_true);
8833 statement = yield;
8834 ExpectSemicolon();
8565 } else if (token == Token::kIF) { 8835 } else if (token == Token::kIF) {
8566 statement = ParseIfStatement(label_name); 8836 statement = ParseIfStatement(label_name);
8567 } else if (token == Token::kASSERT) { 8837 } else if (token == Token::kASSERT) {
8568 statement = ParseAssertStatement(); 8838 statement = ParseAssertStatement();
8569 ExpectSemicolon(); 8839 ExpectSemicolon();
8570 } else if (IsVariableDeclaration()) { 8840 } else if (IsVariableDeclaration()) {
8571 statement = ParseVariableDeclarationList(); 8841 statement = ParseVariableDeclarationList();
8572 ExpectSemicolon(); 8842 ExpectSemicolon();
8573 } else if (IsFunctionDeclaration()) { 8843 } else if (IsFunctionDeclaration()) {
8574 statement = ParseFunctionStatement(false); 8844 statement = ParseFunctionStatement(false);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
8740 return IsIdentifier() && CurrentLiteral()->Equals(literal); 9010 return IsIdentifier() && CurrentLiteral()->Equals(literal);
8741 } 9011 }
8742 9012
8743 9013
8744 bool Parser::IsAwaitKeyword() { 9014 bool Parser::IsAwaitKeyword() {
8745 return await_is_keyword_ && 9015 return await_is_keyword_ &&
8746 (CurrentLiteral()->raw() == Symbols::Await().raw()); 9016 (CurrentLiteral()->raw() == Symbols::Await().raw());
8747 } 9017 }
8748 9018
8749 9019
9020 bool Parser::IsYieldKeyword() {
9021 return await_is_keyword_ &&
9022 (CurrentLiteral()->raw() == Symbols::Yield().raw());
9023 }
9024
9025
8750 static bool IsIncrementOperator(Token::Kind token) { 9026 static bool IsIncrementOperator(Token::Kind token) {
8751 return token == Token::kINCR || token == Token::kDECR; 9027 return token == Token::kINCR || token == Token::kDECR;
8752 } 9028 }
8753 9029
8754 9030
8755 static bool IsPrefixOperator(Token::Kind token) { 9031 static bool IsPrefixOperator(Token::Kind token) {
8756 return (token == Token::kSUB) || 9032 return (token == Token::kSUB) ||
8757 (token == Token::kNOT) || 9033 (token == Token::kNOT) ||
8758 (token == Token::kBIT_NOT); 9034 (token == Token::kBIT_NOT);
8759 } 9035 }
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
9397 return expr; 9673 return expr;
9398 } 9674 }
9399 9675
9400 9676
9401 AstNode* Parser::ParseUnaryExpr() { 9677 AstNode* Parser::ParseUnaryExpr() {
9402 TRACE_PARSER("ParseUnaryExpr"); 9678 TRACE_PARSER("ParseUnaryExpr");
9403 AstNode* expr = NULL; 9679 AstNode* expr = NULL;
9404 const intptr_t op_pos = TokenPos(); 9680 const intptr_t op_pos = TokenPos();
9405 if (IsAwaitKeyword()) { 9681 if (IsAwaitKeyword()) {
9406 TRACE_PARSER("ParseAwaitExpr"); 9682 TRACE_PARSER("ParseAwaitExpr");
9683 if (!innermost_function().IsAsyncFunction() &&
9684 !innermost_function().IsAsyncClosure()) {
9685 ReportError("await operator is only allowed in async function");
9686 }
9407 ConsumeToken(); 9687 ConsumeToken();
9408 parsed_function()->record_await(); 9688 parsed_function()->record_await();
9409 expr = new (Z) AwaitNode(TokenPos(), ParseUnaryExpr()); 9689 expr = new (Z) AwaitNode(TokenPos(), ParseUnaryExpr());
9410 } else if (IsPrefixOperator(CurrentToken())) { 9690 } else if (IsPrefixOperator(CurrentToken())) {
9411 Token::Kind unary_op = CurrentToken(); 9691 Token::Kind unary_op = CurrentToken();
9412 if (unary_op == Token::kSUB) { 9692 if (unary_op == Token::kSUB) {
9413 unary_op = Token::kNEGATE; 9693 unary_op = Token::kNEGATE;
9414 } 9694 }
9415 ConsumeToken(); 9695 ConsumeToken();
9416 expr = ParseUnaryExpr(); 9696 expr = ParseUnaryExpr();
(...skipping 2815 matching lines...) Expand 10 before | Expand all | Expand 10 after
12232 void Parser::SkipQualIdent() { 12512 void Parser::SkipQualIdent() {
12233 ASSERT(IsIdentifier()); 12513 ASSERT(IsIdentifier());
12234 ConsumeToken(); 12514 ConsumeToken();
12235 if (CurrentToken() == Token::kPERIOD) { 12515 if (CurrentToken() == Token::kPERIOD) {
12236 ConsumeToken(); // Consume the kPERIOD token. 12516 ConsumeToken(); // Consume the kPERIOD token.
12237 ExpectIdentifier("identifier expected after '.'"); 12517 ExpectIdentifier("identifier expected after '.'");
12238 } 12518 }
12239 } 12519 }
12240 12520
12241 } // namespace dart 12521 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698