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 |