OLD | NEW |
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 Loading... |
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(¶ms, current_block_->scope); | 3073 AddFormalParamsToScope(¶ms, current_block_->scope); |
3071 } else if (func.is_async_closure()) { | 3074 } else if (func.IsAsyncClosure()) { |
3072 // Async closures have two optional parameters: | 3075 AddAsyncClosureParameters(¶ms); |
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(¶ms, default_parameter_values); | 3076 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
3091 AddFormalParamsToScope(¶ms, current_block_->scope); | 3077 AddFormalParamsToScope(¶ms, 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(¶ms); |
| 3090 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 3091 AddFormalParamsToScope(¶ms, 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, ¶ms); | 3102 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
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(¶ms, func); | 3107 AddFormalParamsToFunction(¶ms, func); |
3109 } | 3108 } |
3110 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3109 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
(...skipping 21 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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, ¶ms); | 5299 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |