| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 6562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6573 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 6573 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| 6574 bool is_const, | 6574 bool is_const, |
| 6575 const TypeArguments& type_arguments) { | 6575 const TypeArguments& type_arguments) { |
| 6576 TRACE_PARSER("ParseListLiteral"); | 6576 TRACE_PARSER("ParseListLiteral"); |
| 6577 ASSERT(type_pos >= 0); | 6577 ASSERT(type_pos >= 0); |
| 6578 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 6578 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 6579 const intptr_t literal_pos = token_index_; | 6579 const intptr_t literal_pos = token_index_; |
| 6580 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 6580 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 6581 ConsumeToken(); | 6581 ConsumeToken(); |
| 6582 | 6582 |
| 6583 Type& element_type = Type::Handle(Type::DynamicType()); | 6583 Type& element_type = Type::ZoneHandle(Type::DynamicType()); |
| 6584 // If no type argument vector is provided, leave it as null, which is | 6584 // If no type argument vector is provided, leave it as null, which is |
| 6585 // equivalent to using Dynamic as the type argument for the element type. | 6585 // equivalent to using Dynamic as the type argument for the element type. |
| 6586 if (!type_arguments.IsNull()) { | 6586 if (!type_arguments.IsNull()) { |
| 6587 ASSERT(type_arguments.Length() > 0); | 6587 ASSERT(type_arguments.Length() > 0); |
| 6588 // List literals take a single type argument. | 6588 // List literals take a single type argument. |
| 6589 element_type = type_arguments.TypeAt(0); | 6589 element_type = type_arguments.TypeAt(0); |
| 6590 if (type_arguments.Length() != 1) { | 6590 if (type_arguments.Length() != 1) { |
| 6591 ErrorMsg(type_pos, | 6591 ErrorMsg(type_pos, |
| 6592 "a list literal takes one type argument specifying " | 6592 "a list literal takes one type argument specifying " |
| 6593 "the element type"); | 6593 "the element type"); |
| 6594 } | 6594 } |
| 6595 if (is_const && !element_type.IsInstantiated()) { | 6595 if (is_const && !element_type.IsInstantiated()) { |
| 6596 ErrorMsg(type_pos, | 6596 ErrorMsg(type_pos, |
| 6597 "the type argument of a constant list literal cannot include " | 6597 "the type argument of a constant list literal cannot include " |
| 6598 "a type variable"); | 6598 "a type variable"); |
| 6599 } | 6599 } |
| 6600 } | 6600 } |
| 6601 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); | 6601 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); |
| 6602 | 6602 |
| 6603 // Parse the list elements. Note: there may be an optional extra | 6603 // Parse the list elements. Note: there may be an optional extra |
| 6604 // comma after the last element. | 6604 // comma after the last element. |
| 6605 ArrayNode* list = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 6605 ArrayNode* list = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| 6606 if (!is_empty_literal) { | 6606 if (!is_empty_literal) { |
| 6607 const bool saved_mode = SetAllowFunctionLiterals(true); | 6607 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6608 const String& dst_name = String::ZoneHandle( |
| 6609 String::NewSymbol("list literal element")); |
| 6608 while (CurrentToken() != Token::kRBRACK) { | 6610 while (CurrentToken() != Token::kRBRACK) { |
| 6609 list->AddElement(ParseExpr(is_const)); | 6611 const intptr_t element_pos = token_index_; |
| 6612 AstNode* element = ParseExpr(is_const); |
| 6613 if (FLAG_enable_type_checks && |
| 6614 !is_const && |
| 6615 !element_type.IsDynamicType()) { |
| 6616 // The expression needs to be type checked at runtime. |
| 6617 // Eliminate the type check if it can be performed at compile time and |
| 6618 // if it succeeds. |
| 6619 if (!element_type.IsInstantiated() || |
| 6620 !element->IsLiteralNode() || |
| 6621 !element->AsLiteralNode()->literal(). |
| 6622 IsAssignableTo(element_type, TypeArguments::Handle())) { |
| 6623 element = new AssignableNode(element_pos, |
| 6624 element, |
| 6625 element_type, |
| 6626 dst_name); |
| 6627 } |
| 6628 } |
| 6629 list->AddElement(element); |
| 6610 if (CurrentToken() == Token::kCOMMA) { | 6630 if (CurrentToken() == Token::kCOMMA) { |
| 6611 ConsumeToken(); | 6631 ConsumeToken(); |
| 6612 } else if (CurrentToken() != Token::kRBRACK) { | 6632 } else if (CurrentToken() != Token::kRBRACK) { |
| 6613 ErrorMsg("comma or ']' expected"); | 6633 ErrorMsg("comma or ']' expected"); |
| 6614 } | 6634 } |
| 6615 } | 6635 } |
| 6616 ExpectToken(Token::kRBRACK); | 6636 ExpectToken(Token::kRBRACK); |
| 6617 SetAllowFunctionLiterals(saved_mode); | 6637 SetAllowFunctionLiterals(saved_mode); |
| 6618 } | 6638 } |
| 6619 | 6639 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6654 const Function& literal_list_factory = Function::ZoneHandle( | 6674 const Function& literal_list_factory = Function::ZoneHandle( |
| 6655 literal_factory_class.LookupFactory(literal_list_factory_name)); | 6675 literal_factory_class.LookupFactory(literal_list_factory_name)); |
| 6656 ASSERT(!literal_list_factory.IsNull()); | 6676 ASSERT(!literal_list_factory.IsNull()); |
| 6657 if (!type_arguments.IsNull() && | 6677 if (!type_arguments.IsNull() && |
| 6658 !type_arguments.IsInstantiated() && | 6678 !type_arguments.IsInstantiated() && |
| 6659 (current_block_->scope->function_level() > 0)) { | 6679 (current_block_->scope->function_level() > 0)) { |
| 6660 // Make sure that the instantiator is captured. | 6680 // Make sure that the instantiator is captured. |
| 6661 CaptureReceiver(); | 6681 CaptureReceiver(); |
| 6662 } | 6682 } |
| 6663 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 6683 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 6664 factory_param->Add( | |
| 6665 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); | |
| 6666 factory_param->Add( | |
| 6667 new LiteralNode(literal_pos, String::ZoneHandle(element_type.Name()))); | |
| 6668 factory_param->Add(list); | 6684 factory_param->Add(list); |
| 6669 return new ConstructorCallNode( | 6685 return new ConstructorCallNode( |
| 6670 literal_pos, type_arguments, literal_list_factory, factory_param); | 6686 literal_pos, type_arguments, literal_list_factory, factory_param); |
| 6671 } | 6687 } |
| 6672 } | 6688 } |
| 6673 | 6689 |
| 6674 | 6690 |
| 6675 static void AddKeyValuePair(ArrayNode* pairs, | 6691 static void AddKeyValuePair(ArrayNode* pairs, |
| 6676 bool is_const, | 6692 bool is_const, |
| 6677 AstNode* key, | 6693 AstNode* key, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6699 | 6715 |
| 6700 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 6716 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
| 6701 bool is_const, | 6717 bool is_const, |
| 6702 const TypeArguments& type_arguments) { | 6718 const TypeArguments& type_arguments) { |
| 6703 TRACE_PARSER("ParseMapLiteral"); | 6719 TRACE_PARSER("ParseMapLiteral"); |
| 6704 ASSERT(type_pos >= 0); | 6720 ASSERT(type_pos >= 0); |
| 6705 ASSERT(CurrentToken() == Token::kLBRACE); | 6721 ASSERT(CurrentToken() == Token::kLBRACE); |
| 6706 const intptr_t literal_pos = token_index_; | 6722 const intptr_t literal_pos = token_index_; |
| 6707 ConsumeToken(); | 6723 ConsumeToken(); |
| 6708 | 6724 |
| 6709 Type& value_type = Type::Handle(Type::DynamicType()); | 6725 Type& value_type = Type::ZoneHandle(Type::DynamicType()); |
| 6710 TypeArguments& map_type_arguments = | 6726 TypeArguments& map_type_arguments = |
| 6711 TypeArguments::ZoneHandle(type_arguments.raw()); | 6727 TypeArguments::ZoneHandle(type_arguments.raw()); |
| 6712 // If no type argument vector is provided, leave it as null, which is | 6728 // If no type argument vector is provided, leave it as null, which is |
| 6713 // equivalent to using Dynamic as the type argument for the value type. | 6729 // equivalent to using Dynamic as the type argument for the value type. |
| 6714 if (!map_type_arguments.IsNull()) { | 6730 if (!map_type_arguments.IsNull()) { |
| 6715 ASSERT(map_type_arguments.Length() > 0); | 6731 ASSERT(map_type_arguments.Length() > 0); |
| 6716 // Map literals take a single type argument. | 6732 // Map literals take a single type argument. |
| 6717 value_type = map_type_arguments.TypeAt(0); | 6733 value_type = map_type_arguments.TypeAt(0); |
| 6718 if (map_type_arguments.Length() > 1) { | 6734 if (map_type_arguments.Length() > 1) { |
| 6719 // We temporarily accept two type arguments, as long as the first one is | 6735 // We temporarily accept two type arguments, as long as the first one is |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6742 "the type argument of a constant map literal cannot include " | 6758 "the type argument of a constant map literal cannot include " |
| 6743 "a type variable"); | 6759 "a type variable"); |
| 6744 } | 6760 } |
| 6745 } | 6761 } |
| 6746 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 6762 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 6747 | 6763 |
| 6748 // Parse the map entries. Note: there may be an optional extra | 6764 // Parse the map entries. Note: there may be an optional extra |
| 6749 // comma after the last entry. | 6765 // comma after the last entry. |
| 6750 ArrayNode* kv_pairs = | 6766 ArrayNode* kv_pairs = |
| 6751 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 6767 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| 6768 const String& dst_name = String::ZoneHandle( |
| 6769 String::NewSymbol("list literal element")); |
| 6752 while (CurrentToken() != Token::kRBRACE) { | 6770 while (CurrentToken() != Token::kRBRACE) { |
| 6753 AstNode* key = NULL; | 6771 AstNode* key = NULL; |
| 6754 if (CurrentToken() == Token::kSTRING) { | 6772 if (CurrentToken() == Token::kSTRING) { |
| 6755 key = ParseStringLiteral(); | 6773 key = ParseStringLiteral(); |
| 6756 } | 6774 } |
| 6757 if (key == NULL) { | 6775 if (key == NULL) { |
| 6758 ErrorMsg("map entry key must be string literal"); | 6776 ErrorMsg("map entry key must be string literal"); |
| 6759 } else if (is_const && !key->IsLiteralNode()) { | 6777 } else if (is_const && !key->IsLiteralNode()) { |
| 6760 ErrorMsg("map entry key must be compile time constant string"); | 6778 ErrorMsg("map entry key must be compile time constant string"); |
| 6761 } | 6779 } |
| 6762 ExpectToken(Token::kCOLON); | 6780 ExpectToken(Token::kCOLON); |
| 6763 const bool saved_mode = SetAllowFunctionLiterals(true); | 6781 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6782 const intptr_t value_pos = token_index_; |
| 6764 AstNode* value = ParseExpr(is_const); | 6783 AstNode* value = ParseExpr(is_const); |
| 6765 SetAllowFunctionLiterals(saved_mode); | 6784 SetAllowFunctionLiterals(saved_mode); |
| 6766 | 6785 if (FLAG_enable_type_checks && |
| 6786 !is_const && |
| 6787 !value_type.IsDynamicType()) { |
| 6788 // The expression needs to be type checked at runtime. |
| 6789 // Eliminate the type check if it can be performed at compile time and |
| 6790 // if it succeeds. |
| 6791 if (!value_type.IsInstantiated() || |
| 6792 !value->IsLiteralNode() || |
| 6793 !value->AsLiteralNode()->literal(). |
| 6794 IsAssignableTo(value_type, TypeArguments::Handle())) { |
| 6795 value = new AssignableNode(value_pos, |
| 6796 value, |
| 6797 value_type, |
| 6798 dst_name); |
| 6799 } |
| 6800 } |
| 6767 AddKeyValuePair(kv_pairs, is_const, key, value); | 6801 AddKeyValuePair(kv_pairs, is_const, key, value); |
| 6768 | 6802 |
| 6769 if (CurrentToken() == Token::kCOMMA) { | 6803 if (CurrentToken() == Token::kCOMMA) { |
| 6770 ConsumeToken(); | 6804 ConsumeToken(); |
| 6771 } else if (CurrentToken() != Token::kRBRACE) { | 6805 } else if (CurrentToken() != Token::kRBRACE) { |
| 6772 ErrorMsg("comma or '}' expected"); | 6806 ErrorMsg("comma or '}' expected"); |
| 6773 } | 6807 } |
| 6774 } | 6808 } |
| 6775 ASSERT(kv_pairs->length() % 2 == 0); | 6809 ASSERT(kv_pairs->length() % 2 == 0); |
| 6776 ExpectToken(Token::kRBRACE); | 6810 ExpectToken(Token::kRBRACE); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6838 const Function& literal_map_factory = Function::ZoneHandle( | 6872 const Function& literal_map_factory = Function::ZoneHandle( |
| 6839 literal_factory_class.LookupFactory(literal_map_factory_name)); | 6873 literal_factory_class.LookupFactory(literal_map_factory_name)); |
| 6840 ASSERT(!literal_map_factory.IsNull()); | 6874 ASSERT(!literal_map_factory.IsNull()); |
| 6841 if (!map_type_arguments.IsNull() && | 6875 if (!map_type_arguments.IsNull() && |
| 6842 !map_type_arguments.IsInstantiated() && | 6876 !map_type_arguments.IsInstantiated() && |
| 6843 (current_block_->scope->function_level() > 0)) { | 6877 (current_block_->scope->function_level() > 0)) { |
| 6844 // Make sure that the instantiator is captured. | 6878 // Make sure that the instantiator is captured. |
| 6845 CaptureReceiver(); | 6879 CaptureReceiver(); |
| 6846 } | 6880 } |
| 6847 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 6881 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 6848 factory_param->Add( | |
| 6849 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); | |
| 6850 factory_param->Add( | |
| 6851 new LiteralNode(literal_pos, String::ZoneHandle(value_type.Name()))); | |
| 6852 factory_param->Add(kv_pairs); | 6882 factory_param->Add(kv_pairs); |
| 6853 return new ConstructorCallNode( | 6883 return new ConstructorCallNode( |
| 6854 literal_pos, map_type_arguments, literal_map_factory, factory_param); | 6884 literal_pos, map_type_arguments, literal_map_factory, factory_param); |
| 6855 } | 6885 } |
| 6856 } | 6886 } |
| 6857 | 6887 |
| 6858 | 6888 |
| 6859 AstNode* Parser::ParseCompoundLiteral() { | 6889 AstNode* Parser::ParseCompoundLiteral() { |
| 6860 bool is_const = false; | 6890 bool is_const = false; |
| 6861 if (CurrentToken() == Token::kCONST) { | 6891 if (CurrentToken() == Token::kCONST) { |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7521 } | 7551 } |
| 7522 | 7552 |
| 7523 | 7553 |
| 7524 void Parser::SkipNestedExpr() { | 7554 void Parser::SkipNestedExpr() { |
| 7525 const bool saved_mode = SetAllowFunctionLiterals(true); | 7555 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7526 SkipExpr(); | 7556 SkipExpr(); |
| 7527 SetAllowFunctionLiterals(saved_mode); | 7557 SetAllowFunctionLiterals(saved_mode); |
| 7528 } | 7558 } |
| 7529 | 7559 |
| 7530 } // namespace dart | 7560 } // namespace dart |
| OLD | NEW |