| 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" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/flags.h" | 13 #include "vm/flags.h" |
| 14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
| 16 #include "vm/native_entry.h" | 16 #include "vm/native_entry.h" |
| 17 #include "vm/object.h" | 17 #include "vm/object.h" |
| 18 #include "vm/object_store.h" | 18 #include "vm/object_store.h" |
| 19 #include "vm/resolver.h" | 19 #include "vm/resolver.h" |
| 20 #include "vm/scopes.h" | 20 #include "vm/scopes.h" |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 24 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 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); | |
| 30 | 29 |
| 31 // All references to Dart names are listed here. | 30 // All references to Dart names are listed here. |
| 32 static const char* kAssertionErrorName = "AssertionError"; | 31 static const char* kAssertionErrorName = "AssertionError"; |
| 33 static const char* kFallThroughErrorName = "FallThroughError"; | 32 static const char* kFallThroughErrorName = "FallThroughError"; |
| 34 static const char* kThrowNewName = "_throwNew"; | 33 static const char* kThrowNewName = "_throwNew"; |
| 35 static const char* kGrowableObjectArrayFromArrayName = | 34 static const char* kLiteralFactoryClassName = "_LiteralFactory"; |
| 36 "GrowableObjectArray._usingArray"; | 35 static const char* kLiteralFactoryListFromLiteralName = "List.fromLiteral"; |
| 37 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; | 36 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"; | 37 static const char* kImmutableMapName = "ImmutableMap"; |
| 41 static const char* kImmutableMapConstructorName = "ImmutableMap."; | 38 static const char* kImmutableMapConstructorName = "ImmutableMap."; |
| 42 static const char* kStringClassName = "StringBase"; | 39 static const char* kStringClassName = "StringBase"; |
| 43 static const char* kInterpolateName = "_interpolate"; | 40 static const char* kInterpolateName = "_interpolate"; |
| 44 static const char* kThisName = "this"; | 41 static const char* kThisName = "this"; |
| 45 static const char* kPhaseParameterName = ":phase"; | 42 static const char* kPhaseParameterName = ":phase"; |
| 46 static const char* kGetIteratorName = "iterator"; | 43 static const char* kGetIteratorName = "iterator"; |
| 47 | 44 |
| 48 #if defined(DEBUG) | 45 #if defined(DEBUG) |
| 49 | 46 |
| (...skipping 4379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4429 static RawClass* LookupImplClass(const String& class_name) { | 4426 static RawClass* LookupImplClass(const String& class_name) { |
| 4430 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name); | 4427 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name); |
| 4431 } | 4428 } |
| 4432 | 4429 |
| 4433 | 4430 |
| 4434 // Lookup class in the corelib which also contains various VM | 4431 // Lookup class in the corelib which also contains various VM |
| 4435 // helper methods and classes. Allow look up of private classes. | 4432 // helper methods and classes. Allow look up of private classes. |
| 4436 static RawClass* LookupCoreClass(const String& class_name) { | 4433 static RawClass* LookupCoreClass(const String& class_name) { |
| 4437 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 4434 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 4438 String& name = String::Handle(class_name.raw()); | 4435 String& name = String::Handle(class_name.raw()); |
| 4439 if ((class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) && | 4436 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| 4440 !FLAG_expose_core_impl) { | |
| 4441 // Private identifiers are mangled on a per script basis. | 4437 // Private identifiers are mangled on a per script basis. |
| 4442 name = String::Concat(name, String::Handle(core_lib.private_key())); | 4438 name = String::Concat(name, String::Handle(core_lib.private_key())); |
| 4443 name = String::NewSymbol(name); | 4439 name = String::NewSymbol(name); |
| 4444 } | 4440 } |
| 4445 return core_lib.LookupClass(name); | 4441 return core_lib.LookupClass(name); |
| 4446 } | 4442 } |
| 4447 | 4443 |
| 4448 | 4444 |
| 4449 RawClass* Parser::LookupClass(const String& class_name) { | 4445 RawClass* Parser::LookupClass(const String& class_name) { |
| 4450 return library_.LookupClass(class_name); | 4446 return library_.LookupClass(class_name); |
| (...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6577 // Do not report the expected vs. actual number of type arguments, because | 6573 // Do not report the expected vs. actual number of type arguments, because |
| 6578 // the type argument vector is flattened and raw types are allowed. | 6574 // the type argument vector is flattened and raw types are allowed. |
| 6579 if (type_arguments.Length() != signature_class.NumTypeArguments()) { | 6575 if (type_arguments.Length() != signature_class.NumTypeArguments()) { |
| 6580 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); | 6576 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); |
| 6581 } | 6577 } |
| 6582 } | 6578 } |
| 6583 } | 6579 } |
| 6584 | 6580 |
| 6585 | 6581 |
| 6586 // Parse "[" [ expr { "," expr } ["," ] "]". | 6582 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 6587 // Note: if the array literal is empty and the brackets have no whitespace | 6583 // Note: if the list literal is empty and the brackets have no whitespace |
| 6588 // between them, the scanner recognizes the opening and closing bracket | 6584 // between them, the scanner recognizes the opening and closing bracket |
| 6589 // as one token of type Token::kINDEX. | 6585 // as one token of type Token::kINDEX. |
| 6590 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, | 6586 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| 6591 bool is_const, | 6587 bool is_const, |
| 6592 const TypeArguments& type_arguments) { | 6588 const TypeArguments& type_arguments) { |
| 6589 TRACE_PARSER("ParseListLiteral"); |
| 6590 ASSERT(type_pos >= 0); |
| 6593 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 6591 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 6594 const intptr_t literal_pos = token_index_; | 6592 const intptr_t literal_pos = token_index_; |
| 6595 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 6593 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 6596 ConsumeToken(); | 6594 ConsumeToken(); |
| 6597 | 6595 |
| 6598 // If no type arguments are provided, leave them as null, which is equivalent | 6596 Type& element_type = Type::Handle(Type::DynamicType()); |
| 6599 // to using Array<Dynamic>. See issue 4966724. | 6597 // If no type argument vector is provided, leave it as null, which is |
| 6598 // equivalent to using Dynamic as the type argument for the element type. |
| 6600 if (!type_arguments.IsNull()) { | 6599 if (!type_arguments.IsNull()) { |
| 6601 // For now, only check the number of type arguments. See issue 4975876. | 6600 ASSERT(type_arguments.Length() > 0); |
| 6601 // List literals take a single type argument. |
| 6602 element_type = type_arguments.TypeAt(0); |
| 6602 if (type_arguments.Length() != 1) { | 6603 if (type_arguments.Length() != 1) { |
| 6603 ASSERT(type_pos >= 0); | 6604 ErrorMsg(type_pos, |
| 6604 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); | 6605 "a list literal takes one type argument specifying " |
| 6606 "the element type"); |
| 6607 } |
| 6608 if (is_const && !element_type.IsInstantiated()) { |
| 6609 ErrorMsg(type_pos, |
| 6610 "the type argument of a constant list literal cannot include " |
| 6611 "a type variable"); |
| 6605 } | 6612 } |
| 6606 } | 6613 } |
| 6614 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); |
| 6607 | 6615 |
| 6608 // Parse the array elements. Note: there may be an optional extra | 6616 // Parse the list elements. Note: there may be an optional extra |
| 6609 // comma after the last element. | 6617 // comma after the last element. |
| 6610 ArrayNode* array = new ArrayNode(token_index_, type_arguments); | 6618 ArrayNode* list = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| 6611 if (!is_empty_literal) { | 6619 if (!is_empty_literal) { |
| 6612 const bool saved_mode = SetAllowFunctionLiterals(true); | 6620 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6613 while (CurrentToken() != Token::kRBRACK) { | 6621 while (CurrentToken() != Token::kRBRACK) { |
| 6614 array->AddElement(ParseExpr(is_const)); | 6622 list->AddElement(ParseExpr(is_const)); |
| 6615 if (CurrentToken() == Token::kCOMMA) { | 6623 if (CurrentToken() == Token::kCOMMA) { |
| 6616 ConsumeToken(); | 6624 ConsumeToken(); |
| 6617 } else if (CurrentToken() != Token::kRBRACK) { | 6625 } else if (CurrentToken() != Token::kRBRACK) { |
| 6618 ErrorMsg("comma or ']' expected"); | 6626 ErrorMsg("comma or ']' expected"); |
| 6619 } | 6627 } |
| 6620 } | 6628 } |
| 6621 ExpectToken(Token::kRBRACK); | 6629 ExpectToken(Token::kRBRACK); |
| 6622 SetAllowFunctionLiterals(saved_mode); | 6630 SetAllowFunctionLiterals(saved_mode); |
| 6623 } | 6631 } |
| 6624 | 6632 |
| 6625 if (is_const) { | 6633 if (is_const) { |
| 6626 // Allocate and initialize the array at compile time. | 6634 // Allocate and initialize the const list at compile time. |
| 6627 Array& lit_array = | 6635 Array& const_list = |
| 6628 Array::ZoneHandle(Array::New(array->length(), Heap::kOld)); | 6636 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); |
| 6629 if (!type_arguments.IsNull()) { | 6637 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 | 6638 |
| 6637 for (int i = 0; i < array->length(); i++) { | 6639 for (int i = 0; i < list->length(); i++) { |
| 6638 AstNode* elem = array->ElementAt(i); | 6640 AstNode* elem = list->ElementAt(i); |
| 6639 // Arguments have been evaluated to a literal value already. | 6641 // Arguments have been evaluated to a literal value already. |
| 6640 ASSERT(elem->IsLiteralNode()); | 6642 ASSERT(elem->IsLiteralNode()); |
| 6641 lit_array.SetAt(i, elem->AsLiteralNode()->literal()); | 6643 if (!element_type.IsDynamicType() && |
| 6644 !elem->AsLiteralNode()->literal().Is(element_type)) { |
| 6645 ErrorMsg(elem->AsLiteralNode()->token_index(), |
| 6646 "list literal element at index %d must be " |
| 6647 "a constant of type '%s'", |
| 6648 i, |
| 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 Loading... |
| 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 Loading... |
| 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 value at index %d must be " |
| 6792 String::Handle(value_type_argument.Name()).ToCString()); | 6806 "a constant of type '%s'", |
| 6807 i >> 1, |
| 6808 String::Handle(value_type.Name()).ToCString()); |
| 6793 } | 6809 } |
| 6794 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 6810 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 6795 } | 6811 } |
| 6796 key_value_array ^= key_value_array.Canonicalize(); | 6812 key_value_array ^= key_value_array.Canonicalize(); |
| 6797 key_value_array.MakeImmutable(); | 6813 key_value_array.MakeImmutable(); |
| 6798 | 6814 |
| 6799 // Construct the map object. | 6815 // Construct the map object. |
| 6800 const String& immutable_map_class_name = | 6816 const String& immutable_map_class_name = |
| 6801 String::Handle(String::NewSymbol(kImmutableMapName)); | 6817 String::Handle(String::NewSymbol(kImmutableMapName)); |
| 6802 const Class& immutable_map_class = | 6818 const Class& immutable_map_class = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 6814 map_type_arguments, | 6830 map_type_arguments, |
| 6815 map_constr, | 6831 map_constr, |
| 6816 constr_args)); | 6832 constr_args)); |
| 6817 if (const_instance.IsUnhandledException()) { | 6833 if (const_instance.IsUnhandledException()) { |
| 6818 return CreateEvalConstConstructorThrow(literal_pos, const_instance); | 6834 return CreateEvalConstConstructorThrow(literal_pos, const_instance); |
| 6819 } else { | 6835 } else { |
| 6820 return new LiteralNode(literal_pos, const_instance); | 6836 return new LiteralNode(literal_pos, const_instance); |
| 6821 } | 6837 } |
| 6822 } else { | 6838 } else { |
| 6823 // Factory call at runtime. | 6839 // Factory call at runtime. |
| 6824 String& literal_map_factory_class_name = String::Handle( | 6840 String& literal_factory_class_name = String::Handle( |
| 6825 String::NewSymbol(kLiteralMapFactoryName)); | 6841 String::NewSymbol(kLiteralFactoryClassName)); |
| 6826 const Class& literal_map_factory_class = | 6842 const Class& literal_factory_class = |
| 6827 Class::Handle(LookupCoreClass(literal_map_factory_class_name)); | 6843 Class::Handle(LookupCoreClass(literal_factory_class_name)); |
| 6828 ASSERT(!literal_map_factory_class.IsNull()); | 6844 ASSERT(!literal_factory_class.IsNull()); |
| 6829 const String& literal_map_factory_name = | 6845 const String& literal_map_factory_name = |
| 6830 String::Handle(String::NewSymbol(kLiteralMapFactoryFromLiteralName)); | 6846 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName)); |
| 6831 const Function& literal_map_factory = Function::ZoneHandle( | 6847 const Function& literal_map_factory = Function::ZoneHandle( |
| 6832 literal_map_factory_class.LookupFactory(literal_map_factory_name)); | 6848 literal_factory_class.LookupFactory(literal_map_factory_name)); |
| 6833 ASSERT(!literal_map_factory.IsNull()); | 6849 ASSERT(!literal_map_factory.IsNull()); |
| 6834 if (!map_type_arguments.IsNull() && | 6850 if (!map_type_arguments.IsNull() && |
| 6835 !map_type_arguments.IsInstantiated() && | 6851 !map_type_arguments.IsInstantiated() && |
| 6836 (current_block_->scope->function_level() > 0)) { | 6852 (current_block_->scope->function_level() > 0)) { |
| 6837 // Make sure that the instantiator is captured. | 6853 // Make sure that the instantiator is captured. |
| 6838 CaptureReceiver(); | 6854 CaptureReceiver(); |
| 6839 } | 6855 } |
| 6840 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 6856 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 6841 factory_param->Add( | 6857 factory_param->Add( |
| 6842 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); | 6858 new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); |
| 6843 factory_param->Add( | 6859 factory_param->Add( |
| 6844 new LiteralNode(literal_pos, | 6860 new LiteralNode(literal_pos, String::ZoneHandle(value_type.Name()))); |
| 6845 String::ZoneHandle(value_type_argument.Name()))); | |
| 6846 factory_param->Add(kv_pairs); | 6861 factory_param->Add(kv_pairs); |
| 6847 return new ConstructorCallNode( | 6862 return new ConstructorCallNode( |
| 6848 literal_pos, map_type_arguments, literal_map_factory, factory_param); | 6863 literal_pos, map_type_arguments, literal_map_factory, factory_param); |
| 6849 } | 6864 } |
| 6850 } | 6865 } |
| 6851 | 6866 |
| 6852 | 6867 |
| 6853 AstNode* Parser::ParseCompoundLiteral() { | 6868 AstNode* Parser::ParseCompoundLiteral() { |
| 6854 bool is_const = false; | 6869 bool is_const = false; |
| 6855 if (CurrentToken() == Token::kCONST) { | 6870 if (CurrentToken() == Token::kCONST) { |
| 6856 is_const = true; | 6871 is_const = true; |
| 6857 ConsumeToken(); | 6872 ConsumeToken(); |
| 6858 } | 6873 } |
| 6859 const intptr_t type_pos = token_index_; | 6874 const intptr_t type_pos = token_index_; |
| 6860 TypeArguments& type_arguments = | 6875 TypeArguments& type_arguments = |
| 6861 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); | 6876 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); |
| 6862 AstNode* primary = NULL; | 6877 AstNode* primary = NULL; |
| 6863 if ((CurrentToken() == Token::kLBRACK) || | 6878 if ((CurrentToken() == Token::kLBRACK) || |
| 6864 (CurrentToken() == Token::kINDEX)) { | 6879 (CurrentToken() == Token::kINDEX)) { |
| 6865 primary = ParseArrayLiteral(type_pos, is_const, type_arguments); | 6880 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 6866 } else if (CurrentToken() == Token::kLBRACE) { | 6881 } else if (CurrentToken() == Token::kLBRACE) { |
| 6867 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 6882 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 6868 } else { | 6883 } else { |
| 6869 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 6884 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
| 6870 } | 6885 } |
| 6871 return primary; | 6886 return primary; |
| 6872 } | 6887 } |
| 6873 | 6888 |
| 6874 | 6889 |
| 6875 static const String& BuildConstructorName(const String& type_class_name, | 6890 static const String& BuildConstructorName(const String& type_class_name, |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7300 } | 7315 } |
| 7301 if (CurrentToken() == Token::kLBRACE) { | 7316 if (CurrentToken() == Token::kLBRACE) { |
| 7302 SkipBlock(); | 7317 SkipBlock(); |
| 7303 } else if (CurrentToken() == Token::kARROW) { | 7318 } else if (CurrentToken() == Token::kARROW) { |
| 7304 ConsumeToken(); | 7319 ConsumeToken(); |
| 7305 SkipExpr(); | 7320 SkipExpr(); |
| 7306 } | 7321 } |
| 7307 } | 7322 } |
| 7308 | 7323 |
| 7309 | 7324 |
| 7310 void Parser::SkipArrayLiteral() { | 7325 void Parser::SkipListLiteral() { |
| 7311 if (CurrentToken() == Token::kINDEX) { | 7326 if (CurrentToken() == Token::kINDEX) { |
| 7312 // Empty array literal. | 7327 // Empty list literal. |
| 7313 ConsumeToken(); | 7328 ConsumeToken(); |
| 7314 return; | 7329 return; |
| 7315 } | 7330 } |
| 7316 ExpectToken(Token::kLBRACK); | 7331 ExpectToken(Token::kLBRACK); |
| 7317 while (CurrentToken() != Token::kRBRACK) { | 7332 while (CurrentToken() != Token::kRBRACK) { |
| 7318 SkipNestedExpr(); | 7333 SkipNestedExpr(); |
| 7319 if (CurrentToken() == Token::kCOMMA) { | 7334 if (CurrentToken() == Token::kCOMMA) { |
| 7320 ConsumeToken(); | 7335 ConsumeToken(); |
| 7321 } | 7336 } |
| 7322 } | 7337 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 7349 ExpectToken(Token::kRPAREN); | 7364 ExpectToken(Token::kRPAREN); |
| 7350 } | 7365 } |
| 7351 | 7366 |
| 7352 | 7367 |
| 7353 void Parser::SkipCompoundLiteral() { | 7368 void Parser::SkipCompoundLiteral() { |
| 7354 if (CurrentToken() == Token::kLT) { | 7369 if (CurrentToken() == Token::kLT) { |
| 7355 SkipTypeArguments(); | 7370 SkipTypeArguments(); |
| 7356 } | 7371 } |
| 7357 if ((CurrentToken() == Token::kLBRACK) || | 7372 if ((CurrentToken() == Token::kLBRACK) || |
| 7358 (CurrentToken() == Token::kINDEX)) { | 7373 (CurrentToken() == Token::kINDEX)) { |
| 7359 SkipArrayLiteral(); | 7374 SkipListLiteral(); |
| 7360 } else if (CurrentToken() == Token::kLBRACE) { | 7375 } else if (CurrentToken() == Token::kLBRACE) { |
| 7361 SkipMapLiteral(); | 7376 SkipMapLiteral(); |
| 7362 } | 7377 } |
| 7363 } | 7378 } |
| 7364 | 7379 |
| 7365 | 7380 |
| 7366 void Parser::SkipNewOperator() { | 7381 void Parser::SkipNewOperator() { |
| 7367 ConsumeToken(); // Skip new or const keyword. | 7382 ConsumeToken(); // Skip new or const keyword. |
| 7368 if (CurrentToken() == Token::kIDENT) { | 7383 if (CurrentToken() == Token::kIDENT) { |
| 7369 SkipType(false); | 7384 SkipType(false); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7515 } | 7530 } |
| 7516 | 7531 |
| 7517 | 7532 |
| 7518 void Parser::SkipNestedExpr() { | 7533 void Parser::SkipNestedExpr() { |
| 7519 const bool saved_mode = SetAllowFunctionLiterals(true); | 7534 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7520 SkipExpr(); | 7535 SkipExpr(); |
| 7521 SetAllowFunctionLiterals(saved_mode); | 7536 SetAllowFunctionLiterals(saved_mode); |
| 7522 } | 7537 } |
| 7523 | 7538 |
| 7524 } // namespace dart | 7539 } // namespace dart |
| OLD | NEW |