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 |