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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 10116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10127 statement = ParseDoWhileStatement(label_name); | 10127 statement = ParseDoWhileStatement(label_name); |
10128 } else if (token == Token::kSWITCH) { | 10128 } else if (token == Token::kSWITCH) { |
10129 statement = ParseSwitchStatement(label_name); | 10129 statement = ParseSwitchStatement(label_name); |
10130 } else if (token == Token::kTRY) { | 10130 } else if (token == Token::kTRY) { |
10131 statement = ParseTryStatement(label_name); | 10131 statement = ParseTryStatement(label_name); |
10132 } else if (token == Token::kRETURN) { | 10132 } else if (token == Token::kRETURN) { |
10133 const TokenPosition return_pos = TokenPos(); | 10133 const TokenPosition return_pos = TokenPos(); |
10134 ConsumeToken(); | 10134 ConsumeToken(); |
10135 if (CurrentToken() != Token::kSEMICOLON) { | 10135 if (CurrentToken() != Token::kSEMICOLON) { |
10136 const TokenPosition expr_pos = TokenPos(); | 10136 const TokenPosition expr_pos = TokenPos(); |
| 10137 const int function_level = FunctionLevel(); |
10137 if (current_function().IsGenerativeConstructor() && | 10138 if (current_function().IsGenerativeConstructor() && |
10138 (FunctionLevel() == 0)) { | 10139 (function_level == 0)) { |
10139 ReportError(expr_pos, | 10140 ReportError(expr_pos, |
10140 "return of a value is not allowed in constructors"); | 10141 "return of a value is not allowed in constructors"); |
10141 } else if (current_function().IsGeneratorClosure() && | 10142 } else if (current_function().IsGeneratorClosure() && |
10142 (FunctionLevel() == 0)) { | 10143 (function_level == 0)) { |
10143 ReportError(expr_pos, "generator functions may not return a value"); | 10144 ReportError(expr_pos, "generator functions may not return a value"); |
10144 } | 10145 } |
10145 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10146 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
10146 if (I->type_checks() && | 10147 if (I->type_checks() && |
10147 current_function().IsAsyncClosure() && (FunctionLevel() == 0)) { | 10148 (((function_level == 0) && current_function().IsAsyncClosure()) || |
| 10149 ((function_level > 0) && current_function().IsAsyncFunction()))) { |
10148 // In checked mode, when the declared result type is Future<T>, verify | 10150 // In checked mode, when the declared result type is Future<T>, verify |
10149 // that the returned expression is of type T or Future<T> as follows: | 10151 // that the returned expression is of type T or Future<T> as follows: |
10150 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; | 10152 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; |
10151 // In case of a mismatch, we need a TypeError and not a CastError, so | 10153 // In case of a mismatch, we need a TypeError and not a CastError, so |
10152 // we do not actually implement an "as" test, but an "assignable" test. | 10154 // we do not actually implement an "as" test, but an "assignable" test. |
10153 const Function& async_func = | 10155 Function& async_func = Function::Handle(Z, current_function().raw()); |
10154 Function::Handle(Z, current_function().parent_function()); | 10156 if (function_level == 0) { |
| 10157 async_func = async_func.parent_function(); |
| 10158 } |
10155 const AbstractType& result_type = | 10159 const AbstractType& result_type = |
10156 AbstractType::ZoneHandle(Z, async_func.result_type()); | 10160 AbstractType::ZoneHandle(Z, async_func.result_type()); |
10157 const Class& future_class = | 10161 const Class& future_class = |
10158 Class::ZoneHandle(Z, I->object_store()->future_class()); | 10162 Class::ZoneHandle(Z, I->object_store()->future_class()); |
10159 ASSERT(!future_class.IsNull()); | 10163 ASSERT(!future_class.IsNull()); |
10160 if (result_type.type_class() == future_class.raw()) { | 10164 if (result_type.type_class() == future_class.raw()) { |
10161 const TypeArguments& result_type_args = | 10165 const TypeArguments& result_type_args = |
10162 TypeArguments::ZoneHandle(Z, result_type.arguments()); | 10166 TypeArguments::ZoneHandle(Z, result_type.arguments()); |
10163 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { | 10167 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { |
10164 const AbstractType& result_type_arg = | 10168 const AbstractType& result_type_arg = |
10165 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); | 10169 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); |
10166 LetNode* checked_expr = new(Z) LetNode(expr_pos); | 10170 if (function_level == 0) { |
10167 LocalVariable* temp = checked_expr->AddInitializer(expr); | 10171 // Parsing and generating code for async closure. |
10168 temp->set_is_final(); | 10172 LetNode* checked_expr = new(Z) LetNode(expr_pos); |
10169 const AbstractType& future_type = | 10173 LocalVariable* temp = checked_expr->AddInitializer(expr); |
10170 AbstractType::ZoneHandle(Z, future_class.RareType()); | 10174 temp->set_is_final(); |
10171 AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp); | 10175 const AbstractType& future_type = |
10172 is_future = new(Z) ComparisonNode(expr_pos, | 10176 AbstractType::ZoneHandle(Z, future_class.RareType()); |
10173 Token::kIS, | 10177 AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp); |
10174 is_future, | 10178 is_future = new(Z) ComparisonNode(expr_pos, |
10175 new(Z) TypeNode(expr_pos, | 10179 Token::kIS, |
10176 future_type)); | 10180 is_future, |
10177 AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp); | 10181 new(Z) TypeNode(expr_pos, |
10178 as_future_t = new(Z) AssignableNode(expr_pos, | 10182 future_type)); |
10179 as_future_t, | 10183 AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp); |
10180 result_type, | 10184 as_future_t = new(Z) AssignableNode(expr_pos, |
10181 Symbols::FunctionResult()); | 10185 as_future_t, |
10182 AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp); | 10186 result_type, |
10183 as_t = new(Z) AssignableNode(expr_pos, | 10187 Symbols::FunctionResult()); |
10184 as_t, | 10188 AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp); |
10185 result_type_arg, | 10189 as_t = new(Z) AssignableNode(expr_pos, |
10186 Symbols::FunctionResult()); | 10190 as_t, |
10187 checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos, | 10191 result_type_arg, |
10188 is_future, | 10192 Symbols::FunctionResult()); |
10189 as_future_t, | 10193 checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos, |
10190 as_t)); | 10194 is_future, |
10191 expr = checked_expr; | 10195 as_future_t, |
| 10196 as_t)); |
| 10197 expr = checked_expr; |
| 10198 } else { |
| 10199 // Parsing async function, but not generating async closure code. |
| 10200 if (!result_type_arg.IsInstantiated()) { |
| 10201 // Make sure that the instantiator is captured. |
| 10202 CaptureInstantiator(); |
| 10203 } |
| 10204 } |
10192 } | 10205 } |
10193 } | 10206 } |
10194 } | 10207 } |
10195 statement = new(Z) ReturnNode(statement_pos, expr); | 10208 statement = new(Z) ReturnNode(statement_pos, expr); |
10196 } else { | 10209 } else { |
10197 if (current_function().IsSyncGenClosure() && | 10210 if (current_function().IsSyncGenClosure() && |
10198 (FunctionLevel() == 0)) { | 10211 (FunctionLevel() == 0)) { |
10199 // In a synchronous generator, return without an expression | 10212 // In a synchronous generator, return without an expression |
10200 // returns false, signaling that the iterator terminates and | 10213 // returns false, signaling that the iterator terminates and |
10201 // did not yield a value. | 10214 // did not yield a value. |
(...skipping 4415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14617 const ArgumentListNode& function_args, | 14630 const ArgumentListNode& function_args, |
14618 const LocalVariable* temp_for_last_arg, | 14631 const LocalVariable* temp_for_last_arg, |
14619 bool is_super_invocation) { | 14632 bool is_super_invocation) { |
14620 UNREACHABLE(); | 14633 UNREACHABLE(); |
14621 return NULL; | 14634 return NULL; |
14622 } | 14635 } |
14623 | 14636 |
14624 } // namespace dart | 14637 } // namespace dart |
14625 | 14638 |
14626 #endif // DART_PRECOMPILED_RUNTIME | 14639 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |