| 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 7357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7368 // :controller = new _AsyncStarStreamController(:async_op); | 7368 // :controller = new _AsyncStarStreamController(:async_op); |
| 7369 // var :controller_stream = :controller.stream; | 7369 // var :controller_stream = :controller.stream; |
| 7370 // return :controller_stream; | 7370 // return :controller_stream; |
| 7371 // } | 7371 // } |
| 7372 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, | 7372 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, |
| 7373 SequenceNode* closure_body) { | 7373 SequenceNode* closure_body) { |
| 7374 TRACE_PARSER("CloseAsyncGeneratorFunction"); | 7374 TRACE_PARSER("CloseAsyncGeneratorFunction"); |
| 7375 ASSERT(!closure_func.IsNull()); | 7375 ASSERT(!closure_func.IsNull()); |
| 7376 ASSERT(closure_body != NULL); | 7376 ASSERT(closure_body != NULL); |
| 7377 | 7377 |
| 7378 // Explicitly reference variables of the async genenerator function from the | 7378 // Explicitly reference variables of the async generator function from the |
| 7379 // closure body in order to mark them as captured. | 7379 // closure body in order to mark them as captured. |
| 7380 LocalVariable* existing_var = | 7380 LocalVariable* existing_var = |
| 7381 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 7381 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 7382 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7382 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 7383 existing_var = | 7383 existing_var = |
| 7384 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 7384 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
| 7385 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7385 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 7386 existing_var = | 7386 existing_var = |
| 7387 closure_body->scope()->LookupVariable(Symbols::ColonController(), false); | 7387 closure_body->scope()->LookupVariable(Symbols::ColonController(), false); |
| 7388 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7388 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7991 ident.ToCString()); | 7991 ident.ToCString()); |
| 7992 | 7992 |
| 7993 } else { | 7993 } else { |
| 7994 intptr_t line_number; | 7994 intptr_t line_number; |
| 7995 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7995 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 7996 ReportError(ident_pos, "identifier '%s' previously used in line %" Pd "", | 7996 ReportError(ident_pos, "identifier '%s' previously used in line %" Pd "", |
| 7997 ident.ToCString(), line_number); | 7997 ident.ToCString(), line_number); |
| 7998 } | 7998 } |
| 7999 } | 7999 } |
| 8000 | 8000 |
| 8001 // Add variable to scope after parsing the initalizer expression. | 8001 // Add variable to scope after parsing the initializer expression. |
| 8002 // The expression must not be able to refer to the variable. | 8002 // The expression must not be able to refer to the variable. |
| 8003 if (!current_block_->scope->AddVariable(variable)) { | 8003 if (!current_block_->scope->AddVariable(variable)) { |
| 8004 LocalVariable* existing_var = | 8004 LocalVariable* existing_var = |
| 8005 current_block_->scope->LookupVariable(variable->name(), true); | 8005 current_block_->scope->LookupVariable(variable->name(), true); |
| 8006 ASSERT(existing_var != NULL); | 8006 ASSERT(existing_var != NULL); |
| 8007 // Use before define cases have already been detected and reported above. | 8007 // Use before define cases have already been detected and reported above. |
| 8008 ASSERT(existing_var->owner() == current_block_->scope); | 8008 ASSERT(existing_var->owner() == current_block_->scope); |
| 8009 ReportError(ident_pos, "identifier '%s' already defined", | 8009 ReportError(ident_pos, "identifier '%s' already defined", |
| 8010 variable->name().ToCString()); | 8010 variable->name().ToCString()); |
| 8011 } | 8011 } |
| (...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9829 } | 9829 } |
| 9830 arguments->Add(message); | 9830 arguments->Add(message); |
| 9831 AstNode* assert_throw = MakeStaticCall( | 9831 AstNode* assert_throw = MakeStaticCall( |
| 9832 Symbols::AssertionError(), | 9832 Symbols::AssertionError(), |
| 9833 Library::PrivateCoreLibName(Symbols::ThrowNew()), arguments); | 9833 Library::PrivateCoreLibName(Symbols::ThrowNew()), arguments); |
| 9834 | 9834 |
| 9835 AstNode* assertion_check = NULL; | 9835 AstNode* assertion_check = NULL; |
| 9836 if (parsed_function()->have_seen_await()) { | 9836 if (parsed_function()->have_seen_await()) { |
| 9837 // The await transformation must be done manually because assertions | 9837 // The await transformation must be done manually because assertions |
| 9838 // are parsed as statements, not expressions. Thus, we need to check | 9838 // are parsed as statements, not expressions. Thus, we need to check |
| 9839 // explicitely whether the arguments contain await operators. (Note that | 9839 // explicitly whether the arguments contain await operators. (Note that |
| 9840 // we must not parse the arguments with ParseAwaitableExpr(). In the | 9840 // we must not parse the arguments with ParseAwaitableExpr(). In the |
| 9841 // corner case of assert(await a, await b), this would create two | 9841 // corner case of assert(await a, await b), this would create two |
| 9842 // sibling scopes containing the temporary values for a and b. Both | 9842 // sibling scopes containing the temporary values for a and b. Both |
| 9843 // values would be allocated in the same internal context variable.) | 9843 // values would be allocated in the same internal context variable.) |
| 9844 // | 9844 // |
| 9845 // Build !condition ? _AsertionError._throwNew(...) : null; | 9845 // Build !condition ? _AsertionError._throwNew(...) : null; |
| 9846 // We need to use a conditional expression because the await transformer | 9846 // We need to use a conditional expression because the await transformer |
| 9847 // cannot transform if statements. | 9847 // cannot transform if statements. |
| 9848 assertion_check = new (Z) ConditionalExprNode( | 9848 assertion_check = new (Z) ConditionalExprNode( |
| 9849 condition_pos, not_condition, assert_throw, | 9849 condition_pos, not_condition, assert_throw, |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10199 | 10199 |
| 10200 // Build the if/then/else nest from the inside out. Keep the AST simple | 10200 // Build the if/then/else nest from the inside out. Keep the AST simple |
| 10201 // for the case of a single generic catch clause. The initial value of | 10201 // for the case of a single generic catch clause. The initial value of |
| 10202 // current is the last (innermost) else block if there were any catch | 10202 // current is the last (innermost) else block if there were any catch |
| 10203 // clauses. | 10203 // clauses. |
| 10204 SequenceNode* current = NULL; | 10204 SequenceNode* current = NULL; |
| 10205 if (!generic_catch_seen) { | 10205 if (!generic_catch_seen) { |
| 10206 // There isn't a generic catch clause so create a clause body that | 10206 // There isn't a generic catch clause so create a clause body that |
| 10207 // rethrows the exception. This includes the case that there were no | 10207 // rethrows the exception. This includes the case that there were no |
| 10208 // catch clauses. | 10208 // catch clauses. |
| 10209 // An await cannot possibly be executed inbetween the catch entry and here, | 10209 // An await cannot possibly be executed in between the catch entry and here, |
| 10210 // therefore, it is safe to rethrow the stack-based :exception_var instead | 10210 // therefore, it is safe to rethrow the stack-based :exception_var instead |
| 10211 // of the captured copy :saved_exception_var. | 10211 // of the captured copy :saved_exception_var. |
| 10212 current = new (Z) SequenceNode(handler_pos, NULL); | 10212 current = new (Z) SequenceNode(handler_pos, NULL); |
| 10213 current->Add(new (Z) ThrowNode( | 10213 current->Add(new (Z) ThrowNode( |
| 10214 handler_pos, new (Z) LoadLocalNode(handler_pos, exception_var), | 10214 handler_pos, new (Z) LoadLocalNode(handler_pos, exception_var), |
| 10215 new (Z) LoadLocalNode(handler_pos, stack_trace_var))); | 10215 new (Z) LoadLocalNode(handler_pos, stack_trace_var))); |
| 10216 } else if (type_tests.Last()->IsLiteralNode()) { | 10216 } else if (type_tests.Last()->IsLiteralNode()) { |
| 10217 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == | 10217 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == |
| 10218 Bool::True().raw()); | 10218 Bool::True().raw()); |
| 10219 // The last body is entered unconditionally. Start building the | 10219 // The last body is entered unconditionally. Start building the |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10831 statement = ParseJump(label_name); | 10831 statement = ParseJump(label_name); |
| 10832 AddNodeForFinallyInlining(statement); | 10832 AddNodeForFinallyInlining(statement); |
| 10833 ExpectSemicolon(); | 10833 ExpectSemicolon(); |
| 10834 } else if (token == Token::kSEMICOLON) { | 10834 } else if (token == Token::kSEMICOLON) { |
| 10835 // Empty statement, nothing to do. | 10835 // Empty statement, nothing to do. |
| 10836 ConsumeToken(); | 10836 ConsumeToken(); |
| 10837 } else if (token == Token::kRETHROW) { | 10837 } else if (token == Token::kRETHROW) { |
| 10838 // Rethrow of current exception. | 10838 // Rethrow of current exception. |
| 10839 ConsumeToken(); | 10839 ConsumeToken(); |
| 10840 ExpectSemicolon(); | 10840 ExpectSemicolon(); |
| 10841 // Check if it is ok to do a rethrow. Find the inntermost enclosing | 10841 // Check if it is ok to do a rethrow. Find the innermost enclosing |
| 10842 // catch block. | 10842 // catch block. |
| 10843 TryStack* try_statement = try_stack_; | 10843 TryStack* try_statement = try_stack_; |
| 10844 while ((try_statement != NULL) && !try_statement->inside_catch()) { | 10844 while ((try_statement != NULL) && !try_statement->inside_catch()) { |
| 10845 try_statement = try_statement->outer_try(); | 10845 try_statement = try_statement->outer_try(); |
| 10846 } | 10846 } |
| 10847 if (try_statement == NULL) { | 10847 if (try_statement == NULL) { |
| 10848 ReportError(statement_pos, "rethrow of an exception is not valid here"); | 10848 ReportError(statement_pos, "rethrow of an exception is not valid here"); |
| 10849 } | 10849 } |
| 10850 | 10850 |
| 10851 // If in async code, use :saved_exception_var and :saved_stack_trace_var | 10851 // If in async code, use :saved_exception_var and :saved_stack_trace_var |
| (...skipping 3895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14747 GrowableHandlePtrArray<const String> pieces(Z, 3); | 14747 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 14748 pieces.Add(String::Handle(Z, prefix.name())); | 14748 pieces.Add(String::Handle(Z, prefix.name())); |
| 14749 pieces.Add(Symbols::Dot()); | 14749 pieces.Add(Symbols::Dot()); |
| 14750 pieces.Add(ident); | 14750 pieces.Add(ident); |
| 14751 const String& qualified_name = | 14751 const String& qualified_name = |
| 14752 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); | 14752 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); |
| 14753 InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN | 14753 InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN |
| 14754 ? InvocationMirror::kMethod | 14754 ? InvocationMirror::kMethod |
| 14755 : InvocationMirror::kGetter; | 14755 : InvocationMirror::kGetter; |
| 14756 // Note: Adding a statement to current block is a hack, parsing an | 14756 // Note: Adding a statement to current block is a hack, parsing an |
| 14757 // espression should have no side-effect. | 14757 // expression should have no side-effect. |
| 14758 current_block_->statements->Add(ThrowNoSuchMethodError( | 14758 current_block_->statements->Add(ThrowNoSuchMethodError( |
| 14759 qual_ident_pos, current_class(), qualified_name, | 14759 qual_ident_pos, current_class(), qualified_name, |
| 14760 NULL, // No arguments. | 14760 NULL, // No arguments. |
| 14761 InvocationMirror::kTopLevel, call_type, | 14761 InvocationMirror::kTopLevel, call_type, |
| 14762 NULL, // No existing function. | 14762 NULL, // No existing function. |
| 14763 &prefix)); | 14763 &prefix)); |
| 14764 } | 14764 } |
| 14765 } | 14765 } |
| 14766 ASSERT(primary != NULL); | 14766 ASSERT(primary != NULL); |
| 14767 } else if (token == Token::kTHIS) { | 14767 } else if (token == Token::kTHIS) { |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15396 TokenPosition* start, | 15396 TokenPosition* start, |
| 15397 TokenPosition* end) { | 15397 TokenPosition* end) { |
| 15398 UNREACHABLE(); | 15398 UNREACHABLE(); |
| 15399 return false; | 15399 return false; |
| 15400 } | 15400 } |
| 15401 | 15401 |
| 15402 | 15402 |
| 15403 } // namespace dart | 15403 } // namespace dart |
| 15404 | 15404 |
| 15405 #endif // DART_PRECOMPILED_RUNTIME | 15405 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |