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

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 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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scanner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
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
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
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
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 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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698