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

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

Issue 12207137: Reduce allocation of ArrayNode-s where a GrowableArray could be used instead. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months 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') | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 8576 matching lines...) Expand 10 before | Expand all | Expand 10 after
8587 "a type variable"); 8587 "a type variable");
8588 } 8588 }
8589 } 8589 }
8590 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); 8590 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1));
8591 const Class& array_class = Class::Handle( 8591 const Class& array_class = Class::Handle(
8592 Isolate::Current()->object_store()->array_class()); 8592 Isolate::Current()->object_store()->array_class());
8593 Type& type = Type::ZoneHandle( 8593 Type& type = Type::ZoneHandle(
8594 Type::New(array_class, type_arguments, type_pos)); 8594 Type::New(array_class, type_arguments, type_pos));
8595 type ^= ClassFinalizer::FinalizeType( 8595 type ^= ClassFinalizer::FinalizeType(
8596 current_class(), type, ClassFinalizer::kCanonicalize); 8596 current_class(), type, ClassFinalizer::kCanonicalize);
8597 ArrayNode* list = new ArrayNode(TokenPos(), type); 8597 GrowableArray<AstNode*> element_list;
8598
8599 // Parse the list elements. Note: there may be an optional extra 8598 // Parse the list elements. Note: there may be an optional extra
8600 // comma after the last element. 8599 // comma after the last element.
8601 if (!is_empty_literal) { 8600 if (!is_empty_literal) {
8602 const bool saved_mode = SetAllowFunctionLiterals(true); 8601 const bool saved_mode = SetAllowFunctionLiterals(true);
8603 while (CurrentToken() != Token::kRBRACK) { 8602 while (CurrentToken() != Token::kRBRACK) {
8604 const intptr_t element_pos = TokenPos(); 8603 const intptr_t element_pos = TokenPos();
8605 AstNode* element = ParseExpr(is_const, kConsumeCascades); 8604 AstNode* element = ParseExpr(is_const, kConsumeCascades);
8606 if (FLAG_enable_type_checks && 8605 if (FLAG_enable_type_checks &&
8607 !is_const && 8606 !is_const &&
8608 !element_type.IsDynamicType()) { 8607 !element_type.IsDynamicType()) {
8609 element = new AssignableNode(element_pos, 8608 element = new AssignableNode(element_pos,
8610 element, 8609 element,
8611 element_type, 8610 element_type,
8612 Symbols::ListLiteralElement()); 8611 Symbols::ListLiteralElement());
8613 } 8612 }
8614 list->AddElement(element); 8613 element_list.Add(element);
8615 if (CurrentToken() == Token::kCOMMA) { 8614 if (CurrentToken() == Token::kCOMMA) {
8616 ConsumeToken(); 8615 ConsumeToken();
8617 } else if (CurrentToken() != Token::kRBRACK) { 8616 } else if (CurrentToken() != Token::kRBRACK) {
8618 ErrorMsg("comma or ']' expected"); 8617 ErrorMsg("comma or ']' expected");
8619 } 8618 }
8620 } 8619 }
8621 ExpectToken(Token::kRBRACK); 8620 ExpectToken(Token::kRBRACK);
8622 SetAllowFunctionLiterals(saved_mode); 8621 SetAllowFunctionLiterals(saved_mode);
8623 } 8622 }
8624 8623
8625 if (is_const) { 8624 if (is_const) {
8626 // Allocate and initialize the const list at compile time. 8625 // Allocate and initialize the const list at compile time.
8627 Array& const_list = 8626 Array& const_list =
8628 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); 8627 Array::ZoneHandle(Array::New(element_list.length(), Heap::kOld));
8629 const_list.SetTypeArguments( 8628 const_list.SetTypeArguments(
8630 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); 8629 AbstractTypeArguments::Handle(type_arguments.Canonicalize()));
8631 Error& malformed_error = Error::Handle(); 8630 Error& malformed_error = Error::Handle();
8632 for (int i = 0; i < list->length(); i++) { 8631 for (int i = 0; i < element_list.length(); i++) {
8633 AstNode* elem = list->ElementAt(i); 8632 AstNode* elem = element_list[i];
8634 // Arguments have been evaluated to a literal value already. 8633 // Arguments have been evaluated to a literal value already.
8635 ASSERT(elem->IsLiteralNode()); 8634 ASSERT(elem->IsLiteralNode());
8636 if (FLAG_enable_type_checks && 8635 if (FLAG_enable_type_checks &&
8637 !element_type.IsDynamicType() && 8636 !element_type.IsDynamicType() &&
8638 (!elem->AsLiteralNode()->literal().IsNull() && 8637 (!elem->AsLiteralNode()->literal().IsNull() &&
8639 !elem->AsLiteralNode()->literal().IsInstanceOf( 8638 !elem->AsLiteralNode()->literal().IsInstanceOf(
8640 element_type, TypeArguments::Handle(), &malformed_error))) { 8639 element_type, TypeArguments::Handle(), &malformed_error))) {
8641 // If the failure is due to a malformed type error, display it instead. 8640 // If the failure is due to a malformed type error, display it instead.
8642 if (!malformed_error.IsNull()) { 8641 if (!malformed_error.IsNull()) {
8643 ErrorMsg(malformed_error); 8642 ErrorMsg(malformed_error);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
8677 ASSERT(factory_type_args.Length() == 1); 8676 ASSERT(factory_type_args.Length() == 1);
8678 Type& factory_type = Type::Handle(Type::New( 8677 Type& factory_type = Type::Handle(Type::New(
8679 factory_class, factory_type_args, type_pos, Heap::kNew)); 8678 factory_class, factory_type_args, type_pos, Heap::kNew));
8680 factory_type ^= ClassFinalizer::FinalizeType( 8679 factory_type ^= ClassFinalizer::FinalizeType(
8681 current_class(), factory_type, ClassFinalizer::kFinalize); 8680 current_class(), factory_type, ClassFinalizer::kFinalize);
8682 factory_type_args = factory_type.arguments(); 8681 factory_type_args = factory_type.arguments();
8683 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); 8682 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments());
8684 } 8683 }
8685 factory_type_args = factory_type_args.Canonicalize(); 8684 factory_type_args = factory_type_args.Canonicalize();
8686 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); 8685 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
8686 ArrayNode* list = new ArrayNode(TokenPos(), type, element_list);
8687 factory_param->Add(list); 8687 factory_param->Add(list);
8688 return CreateConstructorCallNode(literal_pos, 8688 return CreateConstructorCallNode(literal_pos,
8689 factory_type_args, 8689 factory_type_args,
8690 factory_method, 8690 factory_method,
8691 factory_param); 8691 factory_param);
8692 } 8692 }
8693 } 8693 }
8694 8694
8695 8695
8696 ConstructorCallNode* Parser::CreateConstructorCallNode( 8696 ConstructorCallNode* Parser::CreateConstructorCallNode(
8697 intptr_t token_pos, 8697 intptr_t token_pos,
8698 const AbstractTypeArguments& type_arguments, 8698 const AbstractTypeArguments& type_arguments,
8699 const Function& constructor, 8699 const Function& constructor,
8700 ArgumentListNode* arguments) { 8700 ArgumentListNode* arguments) {
8701 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { 8701 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) {
8702 EnsureExpressionTemp(); 8702 EnsureExpressionTemp();
8703 } 8703 }
8704 LocalVariable* allocated = 8704 LocalVariable* allocated =
8705 CreateTempConstVariable(token_pos, "alloc"); 8705 CreateTempConstVariable(token_pos, "alloc");
8706 return new ConstructorCallNode(token_pos, 8706 return new ConstructorCallNode(token_pos,
8707 type_arguments, 8707 type_arguments,
8708 constructor, 8708 constructor,
8709 arguments, 8709 arguments,
8710 allocated); 8710 allocated);
8711 } 8711 }
8712 8712
8713 8713
8714 static void AddKeyValuePair(ArrayNode* pairs, 8714 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs,
8715 bool is_const, 8715 bool is_const,
8716 AstNode* key, 8716 AstNode* key,
8717 AstNode* value) { 8717 AstNode* value) {
8718 if (is_const) { 8718 if (is_const) {
8719 ASSERT(key->IsLiteralNode()); 8719 ASSERT(key->IsLiteralNode());
8720 ASSERT(key->AsLiteralNode()->literal().IsString()); 8720 ASSERT(key->AsLiteralNode()->literal().IsString());
8721 const Instance& new_key = key->AsLiteralNode()->literal(); 8721 const Instance& new_key = key->AsLiteralNode()->literal();
8722 for (int i = 0; i < pairs->length(); i += 2) { 8722 for (int i = 0; i < pairs->length(); i += 2) {
8723 const Instance& key_i = 8723 const Instance& key_i =
8724 pairs->ElementAt(i)->AsLiteralNode()->literal(); 8724 (*pairs)[i]->AsLiteralNode()->literal();
8725 ASSERT(key_i.IsString()); 8725 ASSERT(key_i.IsString());
8726 if (new_key.Equals(key_i)) { 8726 if (new_key.Equals(key_i)) {
8727 // Duplicate key found. The new value replaces the previously 8727 // Duplicate key found. The new value replaces the previously
8728 // defined value. 8728 // defined value.
8729 pairs->SetElementAt(i + 1, value); 8729 (*pairs)[i + 1] = value;
8730 return; 8730 return;
8731 } 8731 }
8732 } 8732 }
8733 } 8733 }
8734 pairs->AddElement(key); 8734 pairs->Add(key);
8735 pairs->AddElement(value); 8735 pairs->Add(value);
8736 } 8736 }
8737 8737
8738 8738
8739 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, 8739 AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
8740 bool is_const, 8740 bool is_const,
8741 const AbstractTypeArguments& type_arguments) { 8741 const AbstractTypeArguments& type_arguments) {
8742 TRACE_PARSER("ParseMapLiteral"); 8742 TRACE_PARSER("ParseMapLiteral");
8743 ASSERT(type_pos >= 0); 8743 ASSERT(type_pos >= 0);
8744 ASSERT(CurrentToken() == Token::kLBRACE); 8744 ASSERT(CurrentToken() == Token::kLBRACE);
8745 const intptr_t literal_pos = TokenPos(); 8745 const intptr_t literal_pos = TokenPos();
(...skipping 22 matching lines...) Expand all
8768 ErrorMsg(type_pos, 8768 ErrorMsg(type_pos,
8769 "the type argument of a constant map literal cannot include " 8769 "the type argument of a constant map literal cannot include "
8770 "a type variable"); 8770 "a type variable");
8771 } 8771 }
8772 } 8772 }
8773 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); 8773 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2));
8774 map_type_arguments ^= map_type_arguments.Canonicalize(); 8774 map_type_arguments ^= map_type_arguments.Canonicalize();
8775 8775
8776 // The kv_pair array is temporary and of element type dynamic. It is passed 8776 // The kv_pair array is temporary and of element type dynamic. It is passed
8777 // to the factory to initialize a properly typed map. 8777 // to the factory to initialize a properly typed map.
8778 ArrayNode* kv_pairs = new ArrayNode( 8778 GrowableArray<AstNode*> kv_pairs_list;
8779 TokenPos(), Type::ZoneHandle(Type::ArrayType()));
8780
8781 // Parse the map entries. Note: there may be an optional extra 8779 // Parse the map entries. Note: there may be an optional extra
8782 // comma after the last entry. 8780 // comma after the last entry.
8783 while (CurrentToken() != Token::kRBRACE) { 8781 while (CurrentToken() != Token::kRBRACE) {
8784 AstNode* key = NULL; 8782 AstNode* key = NULL;
8785 if (CurrentToken() == Token::kSTRING) { 8783 if (CurrentToken() == Token::kSTRING) {
8786 key = ParseStringLiteral(); 8784 key = ParseStringLiteral();
8787 } 8785 }
8788 if (key == NULL) { 8786 if (key == NULL) {
8789 ErrorMsg("map entry key must be string literal"); 8787 ErrorMsg("map entry key must be string literal");
8790 } else if (is_const && !key->IsLiteralNode()) { 8788 } else if (is_const && !key->IsLiteralNode()) {
8791 ErrorMsg("map entry key must be compile-time constant string"); 8789 ErrorMsg("map entry key must be compile-time constant string");
8792 } 8790 }
8793 ExpectToken(Token::kCOLON); 8791 ExpectToken(Token::kCOLON);
8794 const bool saved_mode = SetAllowFunctionLiterals(true); 8792 const bool saved_mode = SetAllowFunctionLiterals(true);
8795 const intptr_t value_pos = TokenPos(); 8793 const intptr_t value_pos = TokenPos();
8796 AstNode* value = ParseExpr(is_const, kConsumeCascades); 8794 AstNode* value = ParseExpr(is_const, kConsumeCascades);
8797 SetAllowFunctionLiterals(saved_mode); 8795 SetAllowFunctionLiterals(saved_mode);
8798 if (FLAG_enable_type_checks && 8796 if (FLAG_enable_type_checks &&
8799 !is_const && 8797 !is_const &&
8800 !value_type.IsDynamicType()) { 8798 !value_type.IsDynamicType()) {
8801 value = new AssignableNode(value_pos, 8799 value = new AssignableNode(value_pos,
8802 value, 8800 value,
8803 value_type, 8801 value_type,
8804 Symbols::ListLiteralElement()); 8802 Symbols::ListLiteralElement());
8805 } 8803 }
8806 AddKeyValuePair(kv_pairs, is_const, key, value); 8804 AddKeyValuePair(&kv_pairs_list, is_const, key, value);
8807 8805
8808 if (CurrentToken() == Token::kCOMMA) { 8806 if (CurrentToken() == Token::kCOMMA) {
8809 ConsumeToken(); 8807 ConsumeToken();
8810 } else if (CurrentToken() != Token::kRBRACE) { 8808 } else if (CurrentToken() != Token::kRBRACE) {
8811 ErrorMsg("comma or '}' expected"); 8809 ErrorMsg("comma or '}' expected");
8812 } 8810 }
8813 } 8811 }
8814 ASSERT(kv_pairs->length() % 2 == 0); 8812 ASSERT(kv_pairs_list.length() % 2 == 0);
8815 ExpectToken(Token::kRBRACE); 8813 ExpectToken(Token::kRBRACE);
8816 8814
8817 if (is_const) { 8815 if (is_const) {
8818 // Create the key-value pair array, canonicalize it and then create 8816 // Create the key-value pair array, canonicalize it and then create
8819 // the immutable map object with it. This all happens at compile time. 8817 // the immutable map object with it. This all happens at compile time.
8820 // The resulting immutable map object is returned as a literal. 8818 // The resulting immutable map object is returned as a literal.
8821 8819
8822 // First, create the canonicalized key-value pair array. 8820 // First, create the canonicalized key-value pair array.
8823 Array& key_value_array = 8821 Array& key_value_array =
8824 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); 8822 Array::ZoneHandle(Array::New(kv_pairs_list.length(), Heap::kOld));
8825 Error& malformed_error = Error::Handle(); 8823 Error& malformed_error = Error::Handle();
8826 for (int i = 0; i < kv_pairs->length(); i++) { 8824 for (int i = 0; i < kv_pairs_list.length(); i++) {
8827 AstNode* arg = kv_pairs->ElementAt(i); 8825 AstNode* arg = kv_pairs_list[i];
8828 // Arguments have been evaluated to a literal value already. 8826 // Arguments have been evaluated to a literal value already.
8829 ASSERT(arg->IsLiteralNode()); 8827 ASSERT(arg->IsLiteralNode());
8830 if (FLAG_enable_type_checks && 8828 if (FLAG_enable_type_checks &&
8831 ((i % 2) == 1) && // Check values only, not keys. 8829 ((i % 2) == 1) && // Check values only, not keys.
8832 !value_type.IsDynamicType() && 8830 !value_type.IsDynamicType() &&
8833 (!arg->AsLiteralNode()->literal().IsNull() && 8831 (!arg->AsLiteralNode()->literal().IsNull() &&
8834 !arg->AsLiteralNode()->literal().IsInstanceOf( 8832 !arg->AsLiteralNode()->literal().IsInstanceOf(
8835 value_type, TypeArguments::Handle(), &malformed_error))) { 8833 value_type, TypeArguments::Handle(), &malformed_error))) {
8836 // If the failure is due to a malformed type error, display it instead. 8834 // If the failure is due to a malformed type error, display it instead.
8837 if (!malformed_error.IsNull()) { 8835 if (!malformed_error.IsNull()) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
8897 ASSERT(factory_type_args.Length() == 2); 8895 ASSERT(factory_type_args.Length() == 2);
8898 Type& factory_type = Type::Handle(Type::New( 8896 Type& factory_type = Type::Handle(Type::New(
8899 factory_class, factory_type_args, type_pos, Heap::kNew)); 8897 factory_class, factory_type_args, type_pos, Heap::kNew));
8900 factory_type ^= ClassFinalizer::FinalizeType( 8898 factory_type ^= ClassFinalizer::FinalizeType(
8901 current_class(), factory_type, ClassFinalizer::kFinalize); 8899 current_class(), factory_type, ClassFinalizer::kFinalize);
8902 factory_type_args = factory_type.arguments(); 8900 factory_type_args = factory_type.arguments();
8903 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); 8901 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments());
8904 } 8902 }
8905 factory_type_args = factory_type_args.Canonicalize(); 8903 factory_type_args = factory_type_args.Canonicalize();
8906 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); 8904 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
8905 ArrayNode* kv_pairs = new ArrayNode(
8906 TokenPos(), Type::ZoneHandle(Type::ArrayType()), kv_pairs_list);
8907 factory_param->Add(kv_pairs); 8907 factory_param->Add(kv_pairs);
8908 return CreateConstructorCallNode(literal_pos, 8908 return CreateConstructorCallNode(literal_pos,
8909 factory_type_args, 8909 factory_type_args,
8910 factory_method, 8910 factory_method,
8911 factory_param); 8911 factory_param);
8912 } 8912 }
8913 } 8913 }
8914 8914
8915 8915
8916 AstNode* Parser::ParseCompoundLiteral() { 8916 AstNode* Parser::ParseCompoundLiteral() {
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
9178 if (!type_bound.IsNull()) { 9178 if (!type_bound.IsNull()) {
9179 new_object = new AssignableNode(new_pos, 9179 new_object = new AssignableNode(new_pos,
9180 new_object, 9180 new_object,
9181 type_bound, 9181 type_bound,
9182 Symbols::FactoryResult()); 9182 Symbols::FactoryResult());
9183 } 9183 }
9184 return new_object; 9184 return new_object;
9185 } 9185 }
9186 9186
9187 9187
9188 String& Parser::Interpolate(ArrayNode* values) { 9188 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) {
9189 const Class& cls = Class::Handle(LookupCoreClass(Symbols::StringBase())); 9189 const Class& cls = Class::Handle(LookupCoreClass(Symbols::StringBase()));
9190 ASSERT(!cls.IsNull()); 9190 ASSERT(!cls.IsNull());
9191 const Function& func = 9191 const Function& func =
9192 Function::Handle(cls.LookupStaticFunction( 9192 Function::Handle(cls.LookupStaticFunction(
9193 PrivateCoreLibName(Symbols::Interpolate()))); 9193 PrivateCoreLibName(Symbols::Interpolate())));
9194 ASSERT(!func.IsNull()); 9194 ASSERT(!func.IsNull());
9195 9195
9196 // Build the array of literal values to interpolate. 9196 // Build the array of literal values to interpolate.
9197 const Array& value_arr = Array::Handle(Array::New(values->length())); 9197 const Array& value_arr = Array::Handle(Array::New(values.length()));
9198 for (int i = 0; i < values->length(); i++) { 9198 for (int i = 0; i < values.length(); i++) {
9199 ASSERT(values->ElementAt(i)->IsLiteralNode()); 9199 ASSERT(values[i]->IsLiteralNode());
9200 value_arr.SetAt(i, values->ElementAt(i)->AsLiteralNode()->literal()); 9200 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal());
9201 } 9201 }
9202 9202
9203 // Build argument array to pass to the interpolation function. 9203 // Build argument array to pass to the interpolation function.
9204 const Array& interpolate_arg = Array::Handle(Array::New(1)); 9204 const Array& interpolate_arg = Array::Handle(Array::New(1));
9205 interpolate_arg.SetAt(0, value_arr); 9205 interpolate_arg.SetAt(0, value_arr);
9206 9206
9207 // Call interpolation function. 9207 // Call interpolation function.
9208 String& concatenated = String::ZoneHandle(); 9208 String& concatenated = String::ZoneHandle();
9209 concatenated ^= DartEntry::InvokeStatic(func, interpolate_arg); 9209 concatenated ^= DartEntry::InvokeStatic(func, interpolate_arg);
9210 if (concatenated.IsUnhandledException()) { 9210 if (concatenated.IsUnhandledException()) {
(...skipping 19 matching lines...) Expand all
9230 if ((l1_token != Token::kSTRING) && 9230 if ((l1_token != Token::kSTRING) &&
9231 (l1_token != Token::kINTERPOL_VAR) && 9231 (l1_token != Token::kINTERPOL_VAR) &&
9232 (l1_token != Token::kINTERPOL_START)) { 9232 (l1_token != Token::kINTERPOL_START)) {
9233 // Common case: no interpolation. 9233 // Common case: no interpolation.
9234 primary = new LiteralNode(literal_start, *CurrentLiteral()); 9234 primary = new LiteralNode(literal_start, *CurrentLiteral());
9235 ConsumeToken(); 9235 ConsumeToken();
9236 return primary; 9236 return primary;
9237 } 9237 }
9238 // String interpolation needed. 9238 // String interpolation needed.
9239 bool is_compiletime_const = true; 9239 bool is_compiletime_const = true;
9240 ArrayNode* values = new ArrayNode( 9240 GrowableArray<AstNode*> values_list;
9241 TokenPos(), Type::ZoneHandle(Type::ArrayType()));
9242 while (CurrentToken() == Token::kSTRING) { 9241 while (CurrentToken() == Token::kSTRING) {
9243 values->AddElement(new LiteralNode(TokenPos(), *CurrentLiteral())); 9242 values_list.Add(new LiteralNode(TokenPos(), *CurrentLiteral()));
9244 ConsumeToken(); 9243 ConsumeToken();
9245 while ((CurrentToken() == Token::kINTERPOL_VAR) || 9244 while ((CurrentToken() == Token::kINTERPOL_VAR) ||
9246 (CurrentToken() == Token::kINTERPOL_START)) { 9245 (CurrentToken() == Token::kINTERPOL_START)) {
9247 AstNode* expr = NULL; 9246 AstNode* expr = NULL;
9248 const intptr_t expr_pos = TokenPos(); 9247 const intptr_t expr_pos = TokenPos();
9249 if (CurrentToken() == Token::kINTERPOL_VAR) { 9248 if (CurrentToken() == Token::kINTERPOL_VAR) {
9250 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); 9249 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true);
9251 ConsumeToken(); 9250 ConsumeToken();
9252 } else { 9251 } else {
9253 ASSERT(CurrentToken() == Token::kINTERPOL_START); 9252 ASSERT(CurrentToken() == Token::kINTERPOL_START);
(...skipping 11 matching lines...) Expand all
9265 (const_expr->IsNumber() || 9264 (const_expr->IsNumber() ||
9266 const_expr->IsString() || 9265 const_expr->IsString() ||
9267 const_expr->IsBool() || 9266 const_expr->IsBool() ||
9268 const_expr->IsNull())) { 9267 const_expr->IsNull())) {
9269 // Change expr into a literal. 9268 // Change expr into a literal.
9270 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr)); 9269 expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr));
9271 } else { 9270 } else {
9272 is_compiletime_const = false; 9271 is_compiletime_const = false;
9273 } 9272 }
9274 } 9273 }
9275 values->AddElement(expr); 9274 values_list.Add(expr);
9276 } 9275 }
9277 } 9276 }
9278 if (is_compiletime_const) { 9277 if (is_compiletime_const) {
9279 primary = new LiteralNode(literal_start, Interpolate(values)); 9278 primary = new LiteralNode(literal_start, Interpolate(values_list));
9280 } else { 9279 } else {
9281 ArgumentListNode* interpolate_arg = 9280 ArgumentListNode* interpolate_arg = new ArgumentListNode(TokenPos());
9282 new ArgumentListNode(values->token_pos()); 9281 ArrayNode* values = new ArrayNode(
9282 TokenPos(), Type::ZoneHandle(Type::ArrayType()), values_list);
9283 interpolate_arg->Add(values); 9283 interpolate_arg->Add(values);
9284 primary = MakeStaticCall(Symbols::StringBase(), 9284 primary = MakeStaticCall(Symbols::StringBase(),
9285 PrivateCoreLibName(Symbols::Interpolate()), 9285 PrivateCoreLibName(Symbols::Interpolate()),
9286 interpolate_arg); 9286 interpolate_arg);
9287 } 9287 }
9288 return primary; 9288 return primary;
9289 } 9289 }
9290 9290
9291 9291
9292 AstNode* Parser::ParseArgumentDefinitionTest() { 9292 AstNode* Parser::ParseArgumentDefinitionTest() {
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
9778 void Parser::SkipQualIdent() { 9778 void Parser::SkipQualIdent() {
9779 ASSERT(IsIdentifier()); 9779 ASSERT(IsIdentifier());
9780 ConsumeToken(); 9780 ConsumeToken();
9781 if (CurrentToken() == Token::kPERIOD) { 9781 if (CurrentToken() == Token::kPERIOD) {
9782 ConsumeToken(); // Consume the kPERIOD token. 9782 ConsumeToken(); // Consume the kPERIOD token.
9783 ExpectIdentifier("identifier expected after '.'"); 9783 ExpectIdentifier("identifier expected after '.'");
9784 } 9784 }
9785 } 9785 }
9786 9786
9787 } // namespace dart 9787 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698