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 7579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7590 sequence->Add(declaration); | 7590 sequence->Add(declaration); |
| 7591 initializers = sequence; | 7591 initializers = sequence; |
| 7592 } | 7592 } |
| 7593 return initializers; | 7593 return initializers; |
| 7594 } | 7594 } |
| 7595 | 7595 |
| 7596 | 7596 |
| 7597 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7597 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 7598 TRACE_PARSER("ParseFunctionStatement"); | 7598 TRACE_PARSER("ParseFunctionStatement"); |
| 7599 AbstractType& result_type = AbstractType::Handle(Z); | 7599 AbstractType& result_type = AbstractType::Handle(Z); |
| 7600 const String* variable_name = NULL; | |
|
Kevin Millikin (Google)
2016/05/27 14:07:36
If is_literal, variable_name is always NULL. If !
| |
| 7601 const String* function_name = NULL; | 7600 const String* function_name = NULL; |
| 7602 | 7601 |
| 7603 result_type = Type::DynamicType(); | 7602 result_type = Type::DynamicType(); |
| 7604 | 7603 |
| 7605 const TokenPosition function_pos = TokenPos(); | 7604 const TokenPosition function_pos = TokenPos(); |
| 7606 TokenPosition metadata_pos = TokenPosition::kNoSource; | 7605 TokenPosition metadata_pos = TokenPosition::kNoSource; |
| 7607 if (is_literal) { | 7606 if (is_literal) { |
| 7608 ASSERT(CurrentToken() == Token::kLPAREN); | 7607 ASSERT(CurrentToken() == Token::kLPAREN); |
| 7609 function_name = &Symbols::AnonymousClosure(); | 7608 function_name = &Symbols::AnonymousClosure(); |
| 7610 } else { | 7609 } else { |
| 7611 metadata_pos = SkipMetadata(); | 7610 metadata_pos = SkipMetadata(); |
| 7612 if (CurrentToken() == Token::kVOID) { | 7611 if (CurrentToken() == Token::kVOID) { |
| 7613 ConsumeToken(); | 7612 ConsumeToken(); |
| 7614 result_type = Type::VoidType(); | 7613 result_type = Type::VoidType(); |
| 7615 } else if ((CurrentToken() == Token::kIDENT) && | 7614 } else if ((CurrentToken() == Token::kIDENT) && |
| 7616 (LookaheadToken(1) != Token::kLPAREN)) { | 7615 (LookaheadToken(1) != Token::kLPAREN)) { |
| 7617 result_type = ParseType(ClassFinalizer::kCanonicalize); | 7616 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 7618 } | 7617 } |
| 7619 const TokenPosition name_pos = TokenPos(); | 7618 const TokenPosition name_pos = TokenPos(); |
| 7620 variable_name = ExpectIdentifier("function name expected"); | 7619 function_name = ExpectIdentifier("function name expected"); |
| 7621 function_name = variable_name; | |
| 7622 | 7620 |
| 7623 // Check that the function name has not been referenced | 7621 // Check that the function name has not been referenced |
| 7624 // before this declaration. | 7622 // before this declaration. |
| 7625 ASSERT(current_block_ != NULL); | 7623 ASSERT(current_block_ != NULL); |
| 7626 const TokenPosition previous_pos = | 7624 const TokenPosition previous_pos = |
| 7627 current_block_->scope->PreviousReferencePos(*function_name); | 7625 current_block_->scope->PreviousReferencePos(*function_name); |
| 7628 if (previous_pos.IsReal()) { | 7626 if (previous_pos.IsReal()) { |
| 7629 ASSERT(!script_.IsNull()); | 7627 ASSERT(!script_.IsNull()); |
| 7630 intptr_t line_number; | 7628 intptr_t line_number; |
| 7631 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7629 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 7659 library_.AddFunctionMetadata(function, metadata_pos); | 7657 library_.AddFunctionMetadata(function, metadata_pos); |
| 7660 } | 7658 } |
| 7661 } | 7659 } |
| 7662 | 7660 |
| 7663 // The function type needs to be finalized at compile time, since the closure | 7661 // The function type needs to be finalized at compile time, since the closure |
| 7664 // may be type checked at run time when assigned to a function variable, | 7662 // may be type checked at run time when assigned to a function variable, |
| 7665 // passed as a function argument, or returned as a function result. | 7663 // passed as a function argument, or returned as a function result. |
| 7666 | 7664 |
| 7667 LocalVariable* function_variable = NULL; | 7665 LocalVariable* function_variable = NULL; |
| 7668 Type& function_type = Type::ZoneHandle(Z); | 7666 Type& function_type = Type::ZoneHandle(Z); |
| 7669 if (variable_name != NULL) { | 7667 if (!is_literal) { |
| 7670 // Since the function type depends on the signature of the closure function, | 7668 // Since the function type depends on the signature of the closure function, |
| 7671 // it cannot be determined before the formal parameter list of the closure | 7669 // it cannot be determined before the formal parameter list of the closure |
| 7672 // function is parsed. Therefore, we set the function type to a new | 7670 // function is parsed. Therefore, we set the function type to a new |
| 7673 // function type to be patched after the actual type is known. | 7671 // function type to be patched after the actual type is known. |
| 7674 // We temporarily use the Closure class as scope class. | 7672 // We temporarily use the Closure class as scope class. |
| 7675 const Class& unknown_scope_class = Class::Handle(Z, | 7673 const Class& unknown_scope_class = Class::Handle(Z, |
| 7676 I->object_store()->closure_class()); | 7674 I->object_store()->closure_class()); |
| 7677 function_type = Type::New(unknown_scope_class, | 7675 function_type = Type::New(unknown_scope_class, |
| 7678 TypeArguments::Handle(Z), | 7676 TypeArguments::Handle(Z), |
| 7679 function_pos); | 7677 function_pos); |
| 7680 function_type.set_signature(function); | 7678 function_type.set_signature(function); |
| 7681 function_type.SetIsFinalized(); // No finalization needed. | 7679 function_type.SetIsFinalized(); // No finalization needed. |
| 7682 | 7680 |
| 7683 // Add the function variable to the scope before parsing the function in | 7681 // Add the function variable to the scope before parsing the function in |
| 7684 // order to allow self reference from inside the function. | 7682 // order to allow self reference from inside the function. |
| 7685 function_variable = new(Z) LocalVariable(function_pos, | 7683 function_variable = new(Z) LocalVariable(function_pos, |
| 7686 *variable_name, | 7684 *function_name, |
| 7687 function_type); | 7685 function_type); |
| 7688 function_variable->set_is_final(); | 7686 function_variable->set_is_final(); |
| 7689 ASSERT(current_block_ != NULL); | 7687 ASSERT(current_block_ != NULL); |
| 7690 ASSERT(current_block_->scope != NULL); | 7688 ASSERT(current_block_->scope != NULL); |
| 7691 if (!current_block_->scope->AddVariable(function_variable)) { | 7689 if (!current_block_->scope->AddVariable(function_variable)) { |
| 7692 LocalVariable* existing_var = | 7690 LocalVariable* existing_var = |
| 7693 current_block_->scope->LookupVariable(function_variable->name(), | 7691 current_block_->scope->LookupVariable(function_variable->name(), |
| 7694 true); | 7692 true); |
| 7695 ASSERT(existing_var != NULL); | 7693 ASSERT(existing_var != NULL); |
| 7696 // Use before define cases have already been detected and reported above. | 7694 // Use before define cases have already been detected and reported above. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 7720 if ((current_block_->scope->function_level() > 0) && | 7718 if ((current_block_->scope->function_level() > 0) && |
| 7721 Class::Handle(signature_type.type_class()).IsGeneric()) { | 7719 Class::Handle(signature_type.type_class()).IsGeneric()) { |
| 7722 CaptureInstantiator(); | 7720 CaptureInstantiator(); |
| 7723 } | 7721 } |
| 7724 | 7722 |
| 7725 // A local signature type itself cannot be malformed or malbounded, only its | 7723 // A local signature type itself cannot be malformed or malbounded, only its |
| 7726 // signature function's result type or parameter types may be. | 7724 // signature function's result type or parameter types may be. |
| 7727 ASSERT(!signature_type.IsMalformed()); | 7725 ASSERT(!signature_type.IsMalformed()); |
| 7728 ASSERT(!signature_type.IsMalbounded()); | 7726 ASSERT(!signature_type.IsMalbounded()); |
| 7729 | 7727 |
| 7730 if (variable_name != NULL) { | 7728 if (!is_literal) { |
| 7731 // Patch the function type of the variable now that the signature is known. | 7729 // Patch the function type of the variable now that the signature is known. |
| 7732 function_type.set_type_class( | 7730 function_type.set_type_class( |
| 7733 Class::Handle(Z, signature_type.type_class())); | 7731 Class::Handle(Z, signature_type.type_class())); |
| 7734 function_type.set_arguments( | 7732 function_type.set_arguments( |
| 7735 TypeArguments::Handle(Z, signature_type.arguments())); | 7733 TypeArguments::Handle(Z, signature_type.arguments())); |
| 7736 ASSERT(function_type.signature() == function.raw()); | 7734 ASSERT(function_type.signature() == function.raw()); |
| 7737 | 7735 |
| 7738 // The function type was initially marked as instantiated, but it may | 7736 // The function type was initially marked as instantiated, but it may |
| 7739 // actually be uninstantiated. | 7737 // actually be uninstantiated. |
| 7740 function_type.ResetIsFinalized(); | 7738 function_type.ResetIsFinalized(); |
| 7741 | 7739 |
| 7742 // The function variable type should have been patched above. | 7740 // The function variable type should have been patched above. |
| 7743 ASSERT((function_variable == NULL) || | 7741 ASSERT(function_variable->type().raw() == function_type.raw()); |
| 7744 (function_variable->type().raw() == function_type.raw())); | |
| 7745 } | 7742 } |
| 7746 | 7743 |
| 7747 // The code generator does not compile the closure function when visiting | 7744 // The code generator does not compile the closure function when visiting |
| 7748 // a ClosureNode. The generated code allocates a new Closure object containing | 7745 // a ClosureNode. The generated code allocates a new Closure object containing |
| 7749 // the current context. The type of the Closure object refers to the closure | 7746 // the current context. The type of the Closure object refers to the closure |
| 7750 // function, which will be compiled on first invocation of the closure object. | 7747 // function, which will be compiled on first invocation of the closure object. |
| 7751 // Therefore, we ignore the parsed default_parameter_values and the | 7748 // Therefore, we ignore the parsed default_parameter_values and the |
| 7752 // node_sequence representing the body of the closure function, which will be | 7749 // node_sequence representing the body of the closure function, which will be |
| 7753 // parsed again when compiled later. | 7750 // parsed again when compiled later. |
| 7754 // The only purpose of parsing the function now (besides reporting obvious | 7751 // The only purpose of parsing the function now (besides reporting obvious |
| 7755 // errors) is to mark referenced variables of the enclosing scopes as | 7752 // errors) is to mark referenced variables of the enclosing scopes as |
| 7756 // captured. The captured variables will be recorded along with their | 7753 // captured. The captured variables will be recorded along with their |
| 7757 // allocation information in a Scope object stored in the function object. | 7754 // allocation information in a Scope object stored in the function object. |
| 7758 // This Scope object is then provided to the compiler when compiling the local | 7755 // This Scope object is then provided to the compiler when compiling the local |
| 7759 // function. It would be too early to record the captured variables here, | 7756 // function. It would be too early to record the captured variables here, |
| 7760 // since further closure functions may capture more variables. | 7757 // since further closure functions may capture more variables. |
| 7761 // This Scope object is constructed after all variables have been allocated. | 7758 // This Scope object is constructed after all variables have been allocated. |
| 7762 // The local scope of the parsed function can be pruned, since contained | 7759 // The local scope of the parsed function can be pruned, since contained |
| 7763 // variables are not relevant for the compilation of the enclosing function. | 7760 // variables are not relevant for the compilation of the enclosing function. |
| 7764 // This pruning is done by omitting to hook the local scope in its parent | 7761 // This pruning is done by omitting to hook the local scope in its parent |
| 7765 // scope in the constructor of LocalScope. | 7762 // scope in the constructor of LocalScope. |
| 7766 AstNode* closure = new(Z) ClosureNode( | 7763 AstNode* closure = new(Z) ClosureNode( |
| 7767 function_pos, function, NULL, statements->scope()); | 7764 function_pos, function, NULL, statements->scope()); |
| 7768 | 7765 |
| 7769 if (function_variable == NULL) { | 7766 return is_literal |
| 7770 ASSERT(is_literal); | 7767 ? closure |
| 7771 return closure; | 7768 : new(Z) StoreLocalNode(function_pos, function_variable, closure); |
| 7772 } else { | |
| 7773 AstNode* initialization = new(Z) StoreLocalNode( | |
| 7774 function_pos, function_variable, closure); | |
| 7775 return initialization; | |
| 7776 } | |
| 7777 } | 7769 } |
| 7778 | 7770 |
| 7779 | 7771 |
| 7780 // Returns true if the current and next tokens can be parsed as type | 7772 // Returns true if the current and next tokens can be parsed as type |
| 7781 // parameters. Current token position is not saved and restored. | 7773 // parameters. Current token position is not saved and restored. |
| 7782 bool Parser::TryParseTypeParameters() { | 7774 bool Parser::TryParseTypeParameters() { |
| 7783 if (CurrentToken() == Token::kLT) { | 7775 if (CurrentToken() == Token::kLT) { |
| 7784 // We are possibly looking at type parameters. Find closing ">". | 7776 // We are possibly looking at type parameters. Find closing ">". |
| 7785 int nesting_level = 0; | 7777 int nesting_level = 0; |
| 7786 do { | 7778 do { |
| (...skipping 6057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13844 return primary; | 13836 return primary; |
| 13845 } | 13837 } |
| 13846 | 13838 |
| 13847 | 13839 |
| 13848 AstNode* Parser::ParsePrimary() { | 13840 AstNode* Parser::ParsePrimary() { |
| 13849 TRACE_PARSER("ParsePrimary"); | 13841 TRACE_PARSER("ParsePrimary"); |
| 13850 ASSERT(!is_top_level_); | 13842 ASSERT(!is_top_level_); |
| 13851 AstNode* primary = NULL; | 13843 AstNode* primary = NULL; |
| 13852 const Token::Kind token = CurrentToken(); | 13844 const Token::Kind token = CurrentToken(); |
| 13853 if (IsFunctionLiteral()) { | 13845 if (IsFunctionLiteral()) { |
| 13854 // The name of a literal function is visible from inside the function, but | |
| 13855 // must not collide with names in the scope declaring the literal. | |
| 13856 OpenBlock(); | |
| 13857 primary = ParseFunctionStatement(true); | 13846 primary = ParseFunctionStatement(true); |
| 13858 CloseBlock(); | |
| 13859 } else if (IsIdentifier()) { | 13847 } else if (IsIdentifier()) { |
| 13860 TokenPosition qual_ident_pos = TokenPos(); | 13848 TokenPosition qual_ident_pos = TokenPos(); |
| 13861 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13849 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
| 13862 if (!prefix.IsNull()) { | 13850 if (!prefix.IsNull()) { |
| 13863 if (CurrentToken() == Token::kHASH) { | 13851 if (CurrentToken() == Token::kHASH) { |
| 13864 // Closurization of top-level entity in prefix scope. | 13852 // Closurization of top-level entity in prefix scope. |
| 13865 return new(Z) LiteralNode(qual_ident_pos, prefix); | 13853 return new(Z) LiteralNode(qual_ident_pos, prefix); |
| 13866 } else { | 13854 } else { |
| 13867 ExpectToken(Token::kPERIOD); | 13855 ExpectToken(Token::kPERIOD); |
| 13868 } | 13856 } |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14537 const ArgumentListNode& function_args, | 14525 const ArgumentListNode& function_args, |
| 14538 const LocalVariable* temp_for_last_arg, | 14526 const LocalVariable* temp_for_last_arg, |
| 14539 bool is_super_invocation) { | 14527 bool is_super_invocation) { |
| 14540 UNREACHABLE(); | 14528 UNREACHABLE(); |
| 14541 return NULL; | 14529 return NULL; |
| 14542 } | 14530 } |
| 14543 | 14531 |
| 14544 } // namespace dart | 14532 } // namespace dart |
| 14545 | 14533 |
| 14546 #endif // DART_PRECOMPILED_RUNTIME | 14534 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |