Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: runtime/vm/parser.cc

Issue 8676001: Implement type checking of list literals (issue 220). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 14 matching lines...) Expand all
25 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); 25 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
26 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); 26 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
27 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); 27 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
28 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); 28 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
29 DECLARE_FLAG(bool, expose_core_impl); 29 DECLARE_FLAG(bool, expose_core_impl);
30 30
31 // All references to Dart names are listed here. 31 // All references to Dart names are listed here.
32 static const char* kAssertionErrorName = "AssertionError"; 32 static const char* kAssertionErrorName = "AssertionError";
33 static const char* kFallThroughErrorName = "FallThroughError"; 33 static const char* kFallThroughErrorName = "FallThroughError";
34 static const char* kThrowNewName = "_throwNew"; 34 static const char* kThrowNewName = "_throwNew";
35 static const char* kGrowableObjectArrayFromArrayName = 35 static const char* kLiteralFactoryClassName = "_LiteralFactory";
36 "GrowableObjectArray._usingArray"; 36 static const char* kLiteralFactoryListFromLiteralName = "List.fromLiteral";
37 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; 37 static const char* kLiteralFactoryMapFromLiteralName = "Map.fromLiteral";
38 static const char* kLiteralMapFactoryName = "_LiteralMapFactory";
39 static const char* kLiteralMapFactoryFromLiteralName = "Map.fromLiteral";
40 static const char* kImmutableMapName = "ImmutableMap"; 38 static const char* kImmutableMapName = "ImmutableMap";
41 static const char* kImmutableMapConstructorName = "ImmutableMap."; 39 static const char* kImmutableMapConstructorName = "ImmutableMap.";
42 static const char* kStringClassName = "StringBase"; 40 static const char* kStringClassName = "StringBase";
43 static const char* kInterpolateName = "_interpolate"; 41 static const char* kInterpolateName = "_interpolate";
44 static const char* kThisName = "this"; 42 static const char* kThisName = "this";
45 static const char* kPhaseParameterName = ":phase"; 43 static const char* kPhaseParameterName = ":phase";
46 static const char* kGetIteratorName = "iterator"; 44 static const char* kGetIteratorName = "iterator";
47 45
48 #if defined(DEBUG) 46 #if defined(DEBUG)
49 47
(...skipping 6527 matching lines...) Expand 10 before | Expand all | Expand 10 after
6577 // Do not report the expected vs. actual number of type arguments, because 6575 // Do not report the expected vs. actual number of type arguments, because
6578 // the type argument vector is flattened and raw types are allowed. 6576 // the type argument vector is flattened and raw types are allowed.
6579 if (type_arguments.Length() != signature_class.NumTypeArguments()) { 6577 if (type_arguments.Length() != signature_class.NumTypeArguments()) {
6580 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); 6578 ErrorMsg(pos, "wrong number of type arguments passed to constructor");
6581 } 6579 }
6582 } 6580 }
6583 } 6581 }
6584 6582
6585 6583
6586 // Parse "[" [ expr { "," expr } ["," ] "]". 6584 // Parse "[" [ expr { "," expr } ["," ] "]".
6587 // Note: if the array literal is empty and the brackets have no whitespace 6585 // Note: if the list literal is empty and the brackets have no whitespace
6588 // between them, the scanner recognizes the opening and closing bracket 6586 // between them, the scanner recognizes the opening and closing bracket
6589 // as one token of type Token::kINDEX. 6587 // as one token of type Token::kINDEX.
6590 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, 6588 AstNode* Parser::ParseListLiteral(intptr_t type_pos,
6591 bool is_const, 6589 bool is_const,
6592 const TypeArguments& type_arguments) { 6590 const TypeArguments& type_arguments) {
6591 TRACE_PARSER("ParseListLiteral");
6592 ASSERT(type_pos >= 0);
6593 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); 6593 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX);
6594 const intptr_t literal_pos = token_index_; 6594 const intptr_t literal_pos = token_index_;
6595 bool is_empty_literal = CurrentToken() == Token::kINDEX; 6595 bool is_empty_literal = CurrentToken() == Token::kINDEX;
6596 ConsumeToken(); 6596 ConsumeToken();
6597 6597
6598 // If no type arguments are provided, leave them as null, which is equivalent 6598 Type& element_type = Type::Handle(Type::DynamicType());
6599 // to using Array<Dynamic>. See issue 4966724. 6599 // If no type argument vector is provided, leave it as null, which is
6600 // equivalent to using Dynamic as the type argument for the element type.
6600 if (!type_arguments.IsNull()) { 6601 if (!type_arguments.IsNull()) {
6601 // For now, only check the number of type arguments. See issue 4975876. 6602 ASSERT(type_arguments.Length() > 0);
6603 // List literals take a single type argument.
6604 element_type = type_arguments.TypeAt(0);
6602 if (type_arguments.Length() != 1) { 6605 if (type_arguments.Length() != 1) {
6603 ASSERT(type_pos >= 0); 6606 ErrorMsg(type_pos,
6604 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); 6607 "a list literal takes one type argument specifying "
6608 "the element type");
6609 }
6610 if (is_const && !element_type.IsInstantiated()) {
6611 ErrorMsg(type_pos,
6612 "the type argument of a constant list literal cannot include "
6613 "a type variable");
6605 } 6614 }
6606 } 6615 }
6616 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1));
6607 6617
6608 // Parse the array elements. Note: there may be an optional extra 6618 // Parse the list elements. Note: there may be an optional extra
6609 // comma after the last element. 6619 // comma after the last element.
6610 ArrayNode* array = new ArrayNode(token_index_, type_arguments); 6620 ArrayNode* list = new ArrayNode(token_index_, TypeArguments::ZoneHandle());
6611 if (!is_empty_literal) { 6621 if (!is_empty_literal) {
6612 const bool saved_mode = SetAllowFunctionLiterals(true); 6622 const bool saved_mode = SetAllowFunctionLiterals(true);
6613 while (CurrentToken() != Token::kRBRACK) { 6623 while (CurrentToken() != Token::kRBRACK) {
6614 array->AddElement(ParseExpr(is_const)); 6624 list->AddElement(ParseExpr(is_const));
6615 if (CurrentToken() == Token::kCOMMA) { 6625 if (CurrentToken() == Token::kCOMMA) {
6616 ConsumeToken(); 6626 ConsumeToken();
6617 } else if (CurrentToken() != Token::kRBRACK) { 6627 } else if (CurrentToken() != Token::kRBRACK) {
6618 ErrorMsg("comma or ']' expected"); 6628 ErrorMsg("comma or ']' expected");
6619 } 6629 }
6620 } 6630 }
6621 ExpectToken(Token::kRBRACK); 6631 ExpectToken(Token::kRBRACK);
6622 SetAllowFunctionLiterals(saved_mode); 6632 SetAllowFunctionLiterals(saved_mode);
6623 } 6633 }
6624 6634
6625 if (is_const) { 6635 if (is_const) {
6626 // Allocate and initialize the array at compile time. 6636 // Allocate and initialize the const list at compile time.
6627 Array& lit_array = 6637 Array& const_list =
6628 Array::ZoneHandle(Array::New(array->length(), Heap::kOld)); 6638 Array::ZoneHandle(Array::New(list->length(), Heap::kOld));
6629 if (!type_arguments.IsNull()) { 6639 const_list.SetTypeArguments(type_arguments);
6630 // TODO(regis): Where should we check the constraints on type parameters?
6631 if (!type_arguments.IsInstantiated()) {
6632 ErrorMsg("type must be constant in const constructor");
6633 }
6634 lit_array.SetTypeArguments(type_arguments);
6635 }
6636 6640
6637 for (int i = 0; i < array->length(); i++) { 6641 for (int i = 0; i < list->length(); i++) {
6638 AstNode* elem = array->ElementAt(i); 6642 AstNode* elem = list->ElementAt(i);
6639 // Arguments have been evaluated to a literal value already. 6643 // Arguments have been evaluated to a literal value already.
6640 ASSERT(elem->IsLiteralNode()); 6644 ASSERT(elem->IsLiteralNode());
6641 lit_array.SetAt(i, elem->AsLiteralNode()->literal()); 6645 if (!element_type.IsDynamicType() &&
6646 !elem->AsLiteralNode()->literal().Is(element_type)) {
6647 ErrorMsg(elem->AsLiteralNode()->token_index(),
6648 "list literal element must be a constant of type '%s'",
hausner 2011/11/23 17:34:34 Even though we indicate the column position of the
regis 2011/11/23 19:29:44 Done here and for map literals below.
6649 String::Handle(element_type.Name()).ToCString());
6650 }
6651 const_list.SetAt(i, elem->AsLiteralNode()->literal());
6642 } 6652 }
6643 lit_array ^= lit_array.Canonicalize(); 6653 const_list ^= const_list.Canonicalize();
6644 lit_array.MakeImmutable(); 6654 const_list.MakeImmutable();
6645 return new LiteralNode(literal_pos, lit_array); 6655 return new LiteralNode(literal_pos, const_list);
6646 } else { 6656 } else {
6657 // Factory call at runtime.
6658 String& literal_factory_class_name = String::Handle(
6659 String::NewSymbol(kLiteralFactoryClassName));
6660 const Class& literal_factory_class =
6661 Class::Handle(LookupCoreClass(literal_factory_class_name));
6662 ASSERT(!literal_factory_class.IsNull());
6663 const String& literal_list_factory_name =
6664 String::Handle(String::NewSymbol(kLiteralFactoryListFromLiteralName));
6665 const Function& literal_list_factory = Function::ZoneHandle(
6666 literal_factory_class.LookupFactory(literal_list_factory_name));
6667 ASSERT(!literal_list_factory.IsNull());
6647 if (!type_arguments.IsNull() && 6668 if (!type_arguments.IsNull() &&
6648 !type_arguments.IsInstantiated() && 6669 !type_arguments.IsInstantiated() &&
6649 (current_block_->scope->function_level() > 0)) { 6670 (current_block_->scope->function_level() > 0)) {
6650 // Make sure that the instantiator is captured. 6671 // Make sure that the instantiator is captured.
6651 CaptureReceiver(); 6672 CaptureReceiver();
6652 } 6673 }
6653 6674 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
6654 // Make a new growable array from the fixed array. 6675 factory_param->Add(
6655 String& growable_object_array_class_name = String::Handle( 6676 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos))));
6656 String::NewSymbol(kGrowableObjectArrayName)); 6677 factory_param->Add(
6657 const Class& growable_array_class = Class::Handle( 6678 new LiteralNode(literal_pos, String::ZoneHandle(element_type.Name())));
6658 LookupImplClass(growable_object_array_class_name)); 6679 factory_param->Add(list);
6659 String& ctor_name =
6660 String::Handle(String::NewSymbol(kGrowableObjectArrayFromArrayName));
6661 Function& array_ctor = Function::ZoneHandle(
6662 growable_array_class.LookupConstructor(ctor_name));
6663 ASSERT(!array_ctor.IsNull());
6664 ArgumentListNode* ctor_args = new ArgumentListNode(literal_pos);
6665 ctor_args->Add(array);
6666 CheckConstructorCallTypeArguments(literal_pos, array_ctor, type_arguments);
6667 return new ConstructorCallNode( 6680 return new ConstructorCallNode(
6668 literal_pos, type_arguments, array_ctor, ctor_args); 6681 literal_pos, type_arguments, literal_list_factory, factory_param);
6669 } 6682 }
6670 } 6683 }
6671 6684
6672 6685
6673 static void AddKeyValuePair(ArrayNode* pairs, 6686 static void AddKeyValuePair(ArrayNode* pairs,
6674 bool is_const, 6687 bool is_const,
6675 AstNode* key, 6688 AstNode* key,
6676 AstNode* value) { 6689 AstNode* value) {
6677 if (is_const) { 6690 if (is_const) {
6678 ASSERT(key->IsLiteralNode()); 6691 ASSERT(key->IsLiteralNode());
(...skipping 18 matching lines...) Expand all
6697 6710
6698 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, 6711 AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
6699 bool is_const, 6712 bool is_const,
6700 const TypeArguments& type_arguments) { 6713 const TypeArguments& type_arguments) {
6701 TRACE_PARSER("ParseMapLiteral"); 6714 TRACE_PARSER("ParseMapLiteral");
6702 ASSERT(type_pos >= 0); 6715 ASSERT(type_pos >= 0);
6703 ASSERT(CurrentToken() == Token::kLBRACE); 6716 ASSERT(CurrentToken() == Token::kLBRACE);
6704 const intptr_t literal_pos = token_index_; 6717 const intptr_t literal_pos = token_index_;
6705 ConsumeToken(); 6718 ConsumeToken();
6706 6719
6707 Type& value_type_argument = Type::Handle(Type::DynamicType()); 6720 Type& value_type = Type::Handle(Type::DynamicType());
6708 TypeArguments& map_type_arguments = 6721 TypeArguments& map_type_arguments =
6709 TypeArguments::ZoneHandle(type_arguments.raw()); 6722 TypeArguments::ZoneHandle(type_arguments.raw());
6710 // If no type argument is provided, leave it as null, which is equivalent 6723 // If no type argument vector is provided, leave it as null, which is
6711 // to using Dynamic as the type argument for the value type. 6724 // equivalent to using Dynamic as the type argument for the value type.
6712 if (!map_type_arguments.IsNull()) { 6725 if (!map_type_arguments.IsNull()) {
6713 // Map literals only take one type argument. 6726 ASSERT(map_type_arguments.Length() > 0);
6714 value_type_argument = map_type_arguments.TypeAt(0); 6727 // Map literals take a single type argument.
6728 value_type = map_type_arguments.TypeAt(0);
6715 if (map_type_arguments.Length() > 1) { 6729 if (map_type_arguments.Length() > 1) {
6716 // We temporarily accept two type arguments, as long as the first one is 6730 // We temporarily accept two type arguments, as long as the first one is
6717 // type String. 6731 // type String.
6718 if (map_type_arguments.Length() != 2) { 6732 if (map_type_arguments.Length() != 2) {
6719 ErrorMsg(type_pos, 6733 ErrorMsg(type_pos,
6720 "a map literal takes one type argument specifying " 6734 "a map literal takes one type argument specifying "
6721 "the value type"); 6735 "the value type");
6722 } 6736 }
6723 if (!value_type_argument.IsStringInterface()) { 6737 if (!value_type.IsStringInterface()) {
6724 ErrorMsg(type_pos, 6738 ErrorMsg(type_pos,
6725 "the key type of a map literal is implicitly 'String'"); 6739 "the key type of a map literal is implicitly 'String'");
6726 } 6740 }
6727 Warning(type_pos, 6741 Warning(type_pos,
6728 "a map literal takes one type argument specifying " 6742 "a map literal takes one type argument specifying "
6729 "the value type"); 6743 "the value type");
6730 value_type_argument = map_type_arguments.TypeAt(1); 6744 value_type = map_type_arguments.TypeAt(1);
6731 } else { 6745 } else {
6732 TypeArray& type_array = TypeArray::Handle(TypeArray::New(2)); 6746 TypeArray& type_array = TypeArray::Handle(TypeArray::New(2));
6733 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface())); 6747 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface()));
6734 type_array.SetTypeAt(1, value_type_argument); 6748 type_array.SetTypeAt(1, value_type);
6735 map_type_arguments = type_array.raw(); 6749 map_type_arguments = type_array.raw();
6736 } 6750 }
6737 if (is_const && !value_type_argument.IsInstantiated()) { 6751 if (is_const && !value_type.IsInstantiated()) {
6738 ErrorMsg(type_pos, 6752 ErrorMsg(type_pos,
6739 "the type argument of a constant map literal cannot include " 6753 "the type argument of a constant map literal cannot include "
6740 "a type variable"); 6754 "a type variable");
6741 } 6755 }
6742 } 6756 }
6743 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); 6757 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2));
6744 6758
6745 // Parse the map entries. Note: there may be an optional extra 6759 // Parse the map entries. Note: there may be an optional extra
6746 // comma after the last entry. 6760 // comma after the last entry.
6747 ArrayNode* kv_pairs = 6761 ArrayNode* kv_pairs =
(...skipping 30 matching lines...) Expand all
6778 // The resulting immutable map object is returned as a literal. 6792 // The resulting immutable map object is returned as a literal.
6779 6793
6780 // First, create the canonicalized key-value pair array. 6794 // First, create the canonicalized key-value pair array.
6781 Array& key_value_array = 6795 Array& key_value_array =
6782 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); 6796 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld));
6783 for (int i = 0; i < kv_pairs->length(); i++) { 6797 for (int i = 0; i < kv_pairs->length(); i++) {
6784 AstNode* arg = kv_pairs->ElementAt(i); 6798 AstNode* arg = kv_pairs->ElementAt(i);
6785 // Arguments have been evaluated to a literal value already. 6799 // Arguments have been evaluated to a literal value already.
6786 ASSERT(arg->IsLiteralNode()); 6800 ASSERT(arg->IsLiteralNode());
6787 if (((i % 2) == 1) && // Check values only, not keys. 6801 if (((i % 2) == 1) && // Check values only, not keys.
6788 !value_type_argument.IsDynamicType() && 6802 !value_type.IsDynamicType() &&
6789 !arg->AsLiteralNode()->literal().Is(value_type_argument)) { 6803 !arg->AsLiteralNode()->literal().Is(value_type)) {
6790 ErrorMsg(arg->AsLiteralNode()->token_index(), 6804 ErrorMsg(arg->AsLiteralNode()->token_index(),
6791 "map literal entry value must be a constant of type '%s'", 6805 "map literal entry value must be a constant of type '%s'",
6792 String::Handle(value_type_argument.Name()).ToCString()); 6806 String::Handle(value_type.Name()).ToCString());
6793 } 6807 }
6794 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); 6808 key_value_array.SetAt(i, arg->AsLiteralNode()->literal());
6795 } 6809 }
6796 key_value_array ^= key_value_array.Canonicalize(); 6810 key_value_array ^= key_value_array.Canonicalize();
6797 key_value_array.MakeImmutable(); 6811 key_value_array.MakeImmutable();
6798 6812
6799 // Construct the map object. 6813 // Construct the map object.
6800 const String& immutable_map_class_name = 6814 const String& immutable_map_class_name =
6801 String::Handle(String::NewSymbol(kImmutableMapName)); 6815 String::Handle(String::NewSymbol(kImmutableMapName));
6802 const Class& immutable_map_class = 6816 const Class& immutable_map_class =
(...skipping 11 matching lines...) Expand all
6814 map_type_arguments, 6828 map_type_arguments,
6815 map_constr, 6829 map_constr,
6816 constr_args)); 6830 constr_args));
6817 if (const_instance.IsUnhandledException()) { 6831 if (const_instance.IsUnhandledException()) {
6818 return CreateEvalConstConstructorThrow(literal_pos, const_instance); 6832 return CreateEvalConstConstructorThrow(literal_pos, const_instance);
6819 } else { 6833 } else {
6820 return new LiteralNode(literal_pos, const_instance); 6834 return new LiteralNode(literal_pos, const_instance);
6821 } 6835 }
6822 } else { 6836 } else {
6823 // Factory call at runtime. 6837 // Factory call at runtime.
6824 String& literal_map_factory_class_name = String::Handle( 6838 String& literal_factory_class_name = String::Handle(
6825 String::NewSymbol(kLiteralMapFactoryName)); 6839 String::NewSymbol(kLiteralFactoryClassName));
6826 const Class& literal_map_factory_class = 6840 const Class& literal_factory_class =
6827 Class::Handle(LookupCoreClass(literal_map_factory_class_name)); 6841 Class::Handle(LookupCoreClass(literal_factory_class_name));
6828 ASSERT(!literal_map_factory_class.IsNull()); 6842 ASSERT(!literal_factory_class.IsNull());
6829 const String& literal_map_factory_name = 6843 const String& literal_map_factory_name =
6830 String::Handle(String::NewSymbol(kLiteralMapFactoryFromLiteralName)); 6844 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName));
6831 const Function& literal_map_factory = Function::ZoneHandle( 6845 const Function& literal_map_factory = Function::ZoneHandle(
6832 literal_map_factory_class.LookupFactory(literal_map_factory_name)); 6846 literal_factory_class.LookupFactory(literal_map_factory_name));
6833 ASSERT(!literal_map_factory.IsNull()); 6847 ASSERT(!literal_map_factory.IsNull());
6834 if (!map_type_arguments.IsNull() && 6848 if (!map_type_arguments.IsNull() &&
6835 !map_type_arguments.IsInstantiated() && 6849 !map_type_arguments.IsInstantiated() &&
6836 (current_block_->scope->function_level() > 0)) { 6850 (current_block_->scope->function_level() > 0)) {
6837 // Make sure that the instantiator is captured. 6851 // Make sure that the instantiator is captured.
6838 CaptureReceiver(); 6852 CaptureReceiver();
6839 } 6853 }
6840 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); 6854 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
6841 factory_param->Add( 6855 factory_param->Add(
6842 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); 6856 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos))));
6843 factory_param->Add( 6857 factory_param->Add(
6844 new LiteralNode(literal_pos, 6858 new LiteralNode(literal_pos, String::ZoneHandle(value_type.Name())));
6845 String::ZoneHandle(value_type_argument.Name())));
6846 factory_param->Add(kv_pairs); 6859 factory_param->Add(kv_pairs);
6847 return new ConstructorCallNode( 6860 return new ConstructorCallNode(
6848 literal_pos, map_type_arguments, literal_map_factory, factory_param); 6861 literal_pos, map_type_arguments, literal_map_factory, factory_param);
6849 } 6862 }
6850 } 6863 }
6851 6864
6852 6865
6853 AstNode* Parser::ParseCompoundLiteral() { 6866 AstNode* Parser::ParseCompoundLiteral() {
6854 bool is_const = false; 6867 bool is_const = false;
6855 if (CurrentToken() == Token::kCONST) { 6868 if (CurrentToken() == Token::kCONST) {
6856 is_const = true; 6869 is_const = true;
6857 ConsumeToken(); 6870 ConsumeToken();
6858 } 6871 }
6859 const intptr_t type_pos = token_index_; 6872 const intptr_t type_pos = token_index_;
6860 TypeArguments& type_arguments = 6873 TypeArguments& type_arguments =
6861 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); 6874 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve));
6862 AstNode* primary = NULL; 6875 AstNode* primary = NULL;
6863 if ((CurrentToken() == Token::kLBRACK) || 6876 if ((CurrentToken() == Token::kLBRACK) ||
6864 (CurrentToken() == Token::kINDEX)) { 6877 (CurrentToken() == Token::kINDEX)) {
6865 primary = ParseArrayLiteral(type_pos, is_const, type_arguments); 6878 primary = ParseListLiteral(type_pos, is_const, type_arguments);
6866 } else if (CurrentToken() == Token::kLBRACE) { 6879 } else if (CurrentToken() == Token::kLBRACE) {
6867 primary = ParseMapLiteral(type_pos, is_const, type_arguments); 6880 primary = ParseMapLiteral(type_pos, is_const, type_arguments);
6868 } else { 6881 } else {
6869 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); 6882 ErrorMsg("unexpected token %s", Token::Str(CurrentToken()));
6870 } 6883 }
6871 return primary; 6884 return primary;
6872 } 6885 }
6873 6886
6874 6887
6875 static const String& BuildConstructorName(const String& type_class_name, 6888 static const String& BuildConstructorName(const String& type_class_name,
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
7300 } 7313 }
7301 if (CurrentToken() == Token::kLBRACE) { 7314 if (CurrentToken() == Token::kLBRACE) {
7302 SkipBlock(); 7315 SkipBlock();
7303 } else if (CurrentToken() == Token::kARROW) { 7316 } else if (CurrentToken() == Token::kARROW) {
7304 ConsumeToken(); 7317 ConsumeToken();
7305 SkipExpr(); 7318 SkipExpr();
7306 } 7319 }
7307 } 7320 }
7308 7321
7309 7322
7310 void Parser::SkipArrayLiteral() { 7323 void Parser::SkipListLiteral() {
7311 if (CurrentToken() == Token::kINDEX) { 7324 if (CurrentToken() == Token::kINDEX) {
7312 // Empty array literal. 7325 // Empty list literal.
7313 ConsumeToken(); 7326 ConsumeToken();
7314 return; 7327 return;
7315 } 7328 }
7316 ExpectToken(Token::kLBRACK); 7329 ExpectToken(Token::kLBRACK);
7317 while (CurrentToken() != Token::kRBRACK) { 7330 while (CurrentToken() != Token::kRBRACK) {
7318 SkipNestedExpr(); 7331 SkipNestedExpr();
7319 if (CurrentToken() == Token::kCOMMA) { 7332 if (CurrentToken() == Token::kCOMMA) {
7320 ConsumeToken(); 7333 ConsumeToken();
7321 } 7334 }
7322 } 7335 }
(...skipping 26 matching lines...) Expand all
7349 ExpectToken(Token::kRPAREN); 7362 ExpectToken(Token::kRPAREN);
7350 } 7363 }
7351 7364
7352 7365
7353 void Parser::SkipCompoundLiteral() { 7366 void Parser::SkipCompoundLiteral() {
7354 if (CurrentToken() == Token::kLT) { 7367 if (CurrentToken() == Token::kLT) {
7355 SkipTypeArguments(); 7368 SkipTypeArguments();
7356 } 7369 }
7357 if ((CurrentToken() == Token::kLBRACK) || 7370 if ((CurrentToken() == Token::kLBRACK) ||
7358 (CurrentToken() == Token::kINDEX)) { 7371 (CurrentToken() == Token::kINDEX)) {
7359 SkipArrayLiteral(); 7372 SkipListLiteral();
7360 } else if (CurrentToken() == Token::kLBRACE) { 7373 } else if (CurrentToken() == Token::kLBRACE) {
7361 SkipMapLiteral(); 7374 SkipMapLiteral();
7362 } 7375 }
7363 } 7376 }
7364 7377
7365 7378
7366 void Parser::SkipNewOperator() { 7379 void Parser::SkipNewOperator() {
7367 ConsumeToken(); // Skip new or const keyword. 7380 ConsumeToken(); // Skip new or const keyword.
7368 if (CurrentToken() == Token::kIDENT) { 7381 if (CurrentToken() == Token::kIDENT) {
7369 SkipType(false); 7382 SkipType(false);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
7515 } 7528 }
7516 7529
7517 7530
7518 void Parser::SkipNestedExpr() { 7531 void Parser::SkipNestedExpr() {
7519 const bool saved_mode = SetAllowFunctionLiterals(true); 7532 const bool saved_mode = SetAllowFunctionLiterals(true);
7520 SkipExpr(); 7533 SkipExpr();
7521 SetAllowFunctionLiterals(saved_mode); 7534 SetAllowFunctionLiterals(saved_mode);
7522 } 7535 }
7523 7536
7524 } // namespace dart 7537 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698