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 |