Chromium Code Reviews| 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 10010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10021 const TokenPosition expr_pos = TokenPos(); | 10021 const TokenPosition expr_pos = TokenPos(); |
| 10022 if (current_function().IsGenerativeConstructor() && | 10022 if (current_function().IsGenerativeConstructor() && |
| 10023 (current_block_->scope->function_level() == 0)) { | 10023 (current_block_->scope->function_level() == 0)) { |
| 10024 ReportError(expr_pos, | 10024 ReportError(expr_pos, |
| 10025 "return of a value is not allowed in constructors"); | 10025 "return of a value is not allowed in constructors"); |
| 10026 } else if (current_function().IsGeneratorClosure() && | 10026 } else if (current_function().IsGeneratorClosure() && |
| 10027 (current_block_->scope->function_level() == 0)) { | 10027 (current_block_->scope->function_level() == 0)) { |
| 10028 ReportError(expr_pos, "generator functions may not return a value"); | 10028 ReportError(expr_pos, "generator functions may not return a value"); |
| 10029 } | 10029 } |
| 10030 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10030 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 10031 if (I->type_checks() && | |
| 10032 current_function().IsAsyncClosure() && | |
| 10033 (current_block_->scope->function_level() == 0)) { | |
| 10034 // In checked mode, when the declared result type is Future<T>, verify | |
| 10035 // that the returned expression is of type T or Future<T> as follows: | |
| 10036 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; | |
| 10037 // In case of a mismatch, we need a TypeError and not a CastError, so | |
| 10038 // we do not actually implement an "as" test, but an "assignable" test. | |
| 10039 const Function& async_func = | |
| 10040 Function::Handle(Z, current_function().parent_function()); | |
| 10041 const AbstractType& result_type = | |
| 10042 AbstractType::ZoneHandle(Z, async_func.result_type()); | |
| 10043 const Class& future_class = | |
| 10044 Class::ZoneHandle(Z, I->object_store()->future_class()); | |
| 10045 ASSERT(!future_class.IsNull()); | |
| 10046 if (result_type.type_class() == future_class.raw()) { | |
| 10047 const TypeArguments& result_type_args = | |
| 10048 TypeArguments::ZoneHandle(Z, result_type.arguments()); | |
| 10049 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { | |
| 10050 const AbstractType& result_type_arg = | |
| 10051 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); | |
| 10052 LetNode* checked_expr = new(Z) LetNode(statement_pos); | |
|
hausner
2016/05/09 21:42:34
Should this point to the expression being returned
regis
2016/05/09 21:58:22
Good point! I replaced all occurrences of statemen
| |
| 10053 LocalVariable* temp = checked_expr->AddInitializer(expr); | |
| 10054 temp->set_is_final(); | |
| 10055 const AbstractType& future_type = | |
| 10056 AbstractType::ZoneHandle(Z, future_class.RareType()); | |
| 10057 AstNode* is_future = new(Z) LoadLocalNode(statement_pos, temp); | |
| 10058 is_future = new(Z) ComparisonNode(statement_pos, | |
| 10059 Token::kIS, | |
| 10060 is_future, | |
| 10061 new(Z) TypeNode(statement_pos, | |
| 10062 future_type)); | |
| 10063 AstNode* as_future_t = new(Z) LoadLocalNode(statement_pos, temp); | |
| 10064 as_future_t = new(Z) AssignableNode(statement_pos, | |
| 10065 as_future_t, | |
| 10066 result_type, | |
| 10067 Symbols::FunctionResult()); | |
| 10068 AstNode* as_t = new(Z) LoadLocalNode(statement_pos, temp); | |
| 10069 as_t = new(Z) AssignableNode(statement_pos, | |
| 10070 as_t, | |
| 10071 result_type_arg, | |
| 10072 Symbols::FunctionResult()); | |
| 10073 checked_expr->AddNode(new(Z) ConditionalExprNode(statement_pos, | |
| 10074 is_future, | |
| 10075 as_future_t, | |
| 10076 as_t)); | |
| 10077 expr = checked_expr; | |
| 10078 } | |
| 10079 } | |
| 10080 } | |
| 10031 statement = new(Z) ReturnNode(statement_pos, expr); | 10081 statement = new(Z) ReturnNode(statement_pos, expr); |
| 10032 } else { | 10082 } else { |
| 10033 if (current_function().IsSyncGenClosure() && | 10083 if (current_function().IsSyncGenClosure() && |
| 10034 (current_block_->scope->function_level() == 0)) { | 10084 (current_block_->scope->function_level() == 0)) { |
| 10035 // In a synchronous generator, return without an expression | 10085 // In a synchronous generator, return without an expression |
| 10036 // returns false, signaling that the iterator terminates and | 10086 // returns false, signaling that the iterator terminates and |
| 10037 // did not yield a value. | 10087 // did not yield a value. |
| 10038 statement = new(Z) ReturnNode(statement_pos, | 10088 statement = new(Z) ReturnNode(statement_pos, |
| 10039 new(Z) LiteralNode(return_pos, Bool::False())); | 10089 new(Z) LiteralNode(return_pos, Bool::False())); |
| 10040 } else { | 10090 } else { |
| (...skipping 4444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14485 const ArgumentListNode& function_args, | 14535 const ArgumentListNode& function_args, |
| 14486 const LocalVariable* temp_for_last_arg, | 14536 const LocalVariable* temp_for_last_arg, |
| 14487 bool is_super_invocation) { | 14537 bool is_super_invocation) { |
| 14488 UNREACHABLE(); | 14538 UNREACHABLE(); |
| 14489 return NULL; | 14539 return NULL; |
| 14490 } | 14540 } |
| 14491 | 14541 |
| 14492 } // namespace dart | 14542 } // namespace dart |
| 14493 | 14543 |
| 14494 #endif // DART_PRECOMPILED_RUNTIME | 14544 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |