| 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 |