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

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

Issue 11125005: Support for type dynamic in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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/object.cc ('k') | runtime/vm/raw_object.h » ('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) 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 13 matching lines...) Expand all
24 24
25 DEFINE_FLAG(bool, constructor_name_check, false, 25 DEFINE_FLAG(bool, constructor_name_check, false,
26 "Named constructors may not clash with other members"); 26 "Named constructors may not clash with other members");
27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); 27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); 28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); 29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); 30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); 31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
32 DEFINE_FLAG(bool, warn_legacy_map_literal, false, 32 DEFINE_FLAG(bool, warn_legacy_map_literal, false,
33 "Warning on legacy map literal syntax (single type argument)"); 33 "Warning on legacy map literal syntax (single type argument)");
34 DEFINE_FLAG(bool, warn_legacy_dynamic, false,
35 "Warning on legacy type Dynamic)");
34 36
35 static void CheckedModeHandler(bool value) { 37 static void CheckedModeHandler(bool value) {
36 FLAG_enable_asserts = value; 38 FLAG_enable_asserts = value;
37 FLAG_enable_type_checks = value; 39 FLAG_enable_type_checks = value;
38 } 40 }
39 41
40 // --enable-checked-mode and --checked both enable checked mode which is 42 // --enable-checked-mode and --checked both enable checked mode which is
41 // equivalent to setting --enable-asserts and --enable-type-checks. 43 // equivalent to setting --enable-asserts and --enable-type-checks.
42 DEFINE_FLAG_HANDLER(CheckedModeHandler, 44 DEFINE_FLAG_HANDLER(CheckedModeHandler,
43 enable_checked_mode, 45 enable_checked_mode,
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 bool var_seen = false; 1009 bool var_seen = false;
1008 bool this_seen = false; 1010 bool this_seen = false;
1009 1011
1010 SkipMetadata(); 1012 SkipMetadata();
1011 if (CurrentToken() == Token::kFINAL) { 1013 if (CurrentToken() == Token::kFINAL) {
1012 ConsumeToken(); 1014 ConsumeToken();
1013 parameter.is_final = true; 1015 parameter.is_final = true;
1014 } else if (CurrentToken() == Token::kVAR) { 1016 } else if (CurrentToken() == Token::kVAR) {
1015 ConsumeToken(); 1017 ConsumeToken();
1016 var_seen = true; 1018 var_seen = true;
1017 // The parameter type is the 'Dynamic' type. 1019 // The parameter type is the 'dynamic' type.
1018 parameter.type = &Type::ZoneHandle(Type::DynamicType()); 1020 parameter.type = &Type::ZoneHandle(Type::DynamicType());
1019 } 1021 }
1020 if (CurrentToken() == Token::kTHIS) { 1022 if (CurrentToken() == Token::kTHIS) {
1021 ConsumeToken(); 1023 ConsumeToken();
1022 ExpectToken(Token::kPERIOD); 1024 ExpectToken(Token::kPERIOD);
1023 this_seen = true; 1025 this_seen = true;
1024 parameter.is_field_initializer = true; 1026 parameter.is_field_initializer = true;
1025 } 1027 }
1026 if (params->implicitly_final) { 1028 if (params->implicitly_final) {
1027 parameter.is_final = true; 1029 parameter.is_final = true;
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after
2865 } 2867 }
2866 if (CurrentToken() == Token::kVAR) { 2868 if (CurrentToken() == Token::kVAR) {
2867 if (member.has_const) { 2869 if (member.has_const) {
2868 ErrorMsg("identifier expected after 'const'"); 2870 ErrorMsg("identifier expected after 'const'");
2869 } 2871 }
2870 if (member.has_final) { 2872 if (member.has_final) {
2871 ErrorMsg("identifier expected after 'final'"); 2873 ErrorMsg("identifier expected after 'final'");
2872 } 2874 }
2873 ConsumeToken(); 2875 ConsumeToken();
2874 member.has_var = true; 2876 member.has_var = true;
2875 // The member type is the 'Dynamic' type. 2877 // The member type is the 'dynamic' type.
2876 member.type = &Type::ZoneHandle(Type::DynamicType()); 2878 member.type = &Type::ZoneHandle(Type::DynamicType());
2877 } else if (CurrentToken() == Token::kFACTORY) { 2879 } else if (CurrentToken() == Token::kFACTORY) {
2878 ConsumeToken(); 2880 ConsumeToken();
2879 if (member.has_static) { 2881 if (member.has_static) {
2880 ErrorMsg("factory method cannot be explicitly marked static"); 2882 ErrorMsg("factory method cannot be explicitly marked static");
2881 } 2883 }
2882 member.has_factory = true; 2884 member.has_factory = true;
2883 member.has_static = true; 2885 member.has_static = true;
2884 // The result type depends on the name of the factory method. 2886 // The result type depends on the name of the factory method.
2885 } 2887 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2989 (LookaheadToken(1) != Token::kCOMMA) && 2991 (LookaheadToken(1) != Token::kCOMMA) &&
2990 (LookaheadToken(1) != Token::kSEMICOLON)) { 2992 (LookaheadToken(1) != Token::kSEMICOLON)) {
2991 ConsumeToken(); 2993 ConsumeToken();
2992 member.kind = RawFunction::kSetterFunction; 2994 member.kind = RawFunction::kSetterFunction;
2993 member.name_pos = this->TokenPos(); 2995 member.name_pos = this->TokenPos();
2994 member.name = ExpectIdentifier("identifier expected"); 2996 member.name = ExpectIdentifier("identifier expected");
2995 if (CurrentToken() != Token::kLPAREN) { 2997 if (CurrentToken() != Token::kLPAREN) {
2996 ErrorMsg("'(' expected"); 2998 ErrorMsg("'(' expected");
2997 } 2999 }
2998 // The grammar allows a return type, so member.type is not always NULL here. 3000 // The grammar allows a return type, so member.type is not always NULL here.
2999 // If no return type is specified, the return type of the setter is Dynamic. 3001 // If no return type is specified, the return type of the setter is dynamic.
3000 if (member.type == NULL) { 3002 if (member.type == NULL) {
3001 member.type = &Type::ZoneHandle(Type::DynamicType()); 3003 member.type = &Type::ZoneHandle(Type::DynamicType());
3002 } 3004 }
3003 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && 3005 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var &&
3004 (LookaheadToken(1) != Token::kLPAREN) && 3006 (LookaheadToken(1) != Token::kLPAREN) &&
3005 (LookaheadToken(1) != Token::kASSIGN) && 3007 (LookaheadToken(1) != Token::kASSIGN) &&
3006 (LookaheadToken(1) != Token::kCOMMA) && 3008 (LookaheadToken(1) != Token::kCOMMA) &&
3007 (LookaheadToken(1) != Token::kSEMICOLON)) { 3009 (LookaheadToken(1) != Token::kSEMICOLON)) {
3008 ConsumeToken(); 3010 ConsumeToken();
3009 if (!Token::CanBeOverloaded(CurrentToken())) { 3011 if (!Token::CanBeOverloaded(CurrentToken())) {
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 const GrowableObjectArray& types = 3668 const GrowableObjectArray& types =
3667 GrowableObjectArray::Handle(GrowableObjectArray::New()); 3669 GrowableObjectArray::Handle(GrowableObjectArray::New());
3668 AbstractType& type = AbstractType::Handle(); 3670 AbstractType& type = AbstractType::Handle();
3669 do { 3671 do {
3670 ConsumeToken(); 3672 ConsumeToken();
3671 type = ParseType(finalization); 3673 type = ParseType(finalization);
3672 // Only keep the error for the first malformed type argument. 3674 // Only keep the error for the first malformed type argument.
3673 if (malformed_error->IsNull() && type.IsMalformed()) { 3675 if (malformed_error->IsNull() && type.IsMalformed()) {
3674 *malformed_error = type.malformed_error(); 3676 *malformed_error = type.malformed_error();
3675 } 3677 }
3676 // Map a malformed type argument to Dynamic, so that malformed types with 3678 // Map a malformed type argument to dynamic, so that malformed types with
3677 // a resolved type class are handled properly in production mode. 3679 // a resolved type class are handled properly in production mode.
3678 if (type.IsMalformed()) { 3680 if (type.IsMalformed()) {
3679 ASSERT(finalization != ClassFinalizer::kCanonicalizeWellFormed); 3681 ASSERT(finalization != ClassFinalizer::kCanonicalizeWellFormed);
3680 if (finalization == ClassFinalizer::kCanonicalizeForCreation) { 3682 if (finalization == ClassFinalizer::kCanonicalizeForCreation) {
3681 ErrorMsg(*malformed_error); 3683 ErrorMsg(*malformed_error);
3682 } 3684 }
3683 type = Type::DynamicType(); 3685 type = Type::DynamicType();
3684 } 3686 }
3685 types.Add(type); 3687 types.Add(type);
3686 } while (CurrentToken() == Token::kCOMMA); 3688 } while (CurrentToken() == Token::kCOMMA);
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
5156 } 5158 }
5157 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { 5159 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) {
5158 // Not a legal type identifier or const keyword or metadata. 5160 // Not a legal type identifier or const keyword or metadata.
5159 return false; 5161 return false;
5160 } 5162 }
5161 const intptr_t saved_pos = TokenPos(); 5163 const intptr_t saved_pos = TokenPos();
5162 bool is_var_decl = false; 5164 bool is_var_decl = false;
5163 bool have_type = false; 5165 bool have_type = false;
5164 if (CurrentToken() == Token::kCONST) { 5166 if (CurrentToken() == Token::kCONST) {
5165 ConsumeToken(); 5167 ConsumeToken();
5166 have_type = true; // Type is Dynamic. 5168 have_type = true; // Type is dynamic.
5167 } 5169 }
5168 if (IsIdentifier()) { // Type or variable name. 5170 if (IsIdentifier()) { // Type or variable name.
5169 Token::Kind follower = LookaheadToken(1); 5171 Token::Kind follower = LookaheadToken(1);
5170 if ((follower == Token::kLT) || // Parameterized type. 5172 if ((follower == Token::kLT) || // Parameterized type.
5171 (follower == Token::kPERIOD) || // Qualified class name of type. 5173 (follower == Token::kPERIOD) || // Qualified class name of type.
5172 Token::IsIdentifier(follower)) { // Variable name following a type. 5174 Token::IsIdentifier(follower)) { // Variable name following a type.
5173 // We see the beginning of something that could be a type. 5175 // We see the beginning of something that could be a type.
5174 const intptr_t type_pos = TokenPos(); 5176 const intptr_t type_pos = TokenPos();
5175 if (TryParseOptionalType()) { 5177 if (TryParseOptionalType()) {
5176 have_type = true; 5178 have_type = true;
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
6071 exception_param.type = 6073 exception_param.type =
6072 &AbstractType::ZoneHandle(Type::DynamicType()); 6074 &AbstractType::ZoneHandle(Type::DynamicType());
6073 } 6075 }
6074 if (CurrentToken() == Token::kCATCH) { 6076 if (CurrentToken() == Token::kCATCH) {
6075 ConsumeToken(); // Consume the 'catch'. 6077 ConsumeToken(); // Consume the 'catch'.
6076 ExpectToken(Token::kLPAREN); 6078 ExpectToken(Token::kLPAREN);
6077 exception_param.token_pos = TokenPos(); 6079 exception_param.token_pos = TokenPos();
6078 exception_param.var = ExpectIdentifier("identifier expected"); 6080 exception_param.var = ExpectIdentifier("identifier expected");
6079 if (CurrentToken() == Token::kCOMMA) { 6081 if (CurrentToken() == Token::kCOMMA) {
6080 ConsumeToken(); 6082 ConsumeToken();
6081 // TODO(hausner): Make implicit type be StackTrace, not Dynamic. 6083 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
6082 stack_trace_param.type = 6084 stack_trace_param.type =
6083 &AbstractType::ZoneHandle(Type::DynamicType()); 6085 &AbstractType::ZoneHandle(Type::DynamicType());
6084 stack_trace_param.token_pos = TokenPos(); 6086 stack_trace_param.token_pos = TokenPos();
6085 stack_trace_param.var = ExpectIdentifier("identifier expected"); 6087 stack_trace_param.var = ExpectIdentifier("identifier expected");
6086 } 6088 }
6087 ExpectToken(Token::kRPAREN); 6089 ExpectToken(Token::kRPAREN);
6088 } 6090 }
6089 6091
6090 // If a generic "catch all" statement has already been seen then all 6092 // If a generic "catch all" statement has already been seen then all
6091 // subsequent catch statements are dead. We issue an error for now, 6093 // subsequent catch statements are dead. We issue an error for now,
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
6580 CurrentToken() == Token::kIDENT ? 6582 CurrentToken() == Token::kIDENT ?
6581 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); 6583 CurrentLiteral()->ToCString() : Token::Str(CurrentToken()));
6582 } 6584 }
6583 6585
6584 6586
6585 String* Parser::ExpectClassIdentifier(const char* msg) { 6587 String* Parser::ExpectClassIdentifier(const char* msg) {
6586 if (CurrentToken() != Token::kIDENT) { 6588 if (CurrentToken() != Token::kIDENT) {
6587 ErrorMsg("%s", msg); 6589 ErrorMsg("%s", msg);
6588 } 6590 }
6589 String* ident = CurrentLiteral(); 6591 String* ident = CurrentLiteral();
6590 if (ident->Equals("Dynamic")) { 6592 // TODO(hausner): Remove check for 'Dynamic' once support for upper-case
6593 // type dynamic is gone.
6594 if (ident->Equals("Dynamic") || ident->Equals("dynamic")) {
6591 ErrorMsg("%s", msg); 6595 ErrorMsg("%s", msg);
6592 } 6596 }
6593 ConsumeToken(); 6597 ConsumeToken();
6594 return ident; 6598 return ident;
6595 } 6599 }
6596 6600
6597 6601
6598 // Check whether current token is an identifier or a built-in identifier. 6602 // Check whether current token is an identifier or a built-in identifier.
6599 String* Parser::ExpectIdentifier(const char* msg) { 6603 String* Parser::ExpectIdentifier(const char* msg) {
6600 if (!IsIdentifier()) { 6604 if (!IsIdentifier()) {
(...skipping 1764 matching lines...) Expand 10 before | Expand all | Expand 10 after
8365 ClassFinalizer::FinalizationKind finalization) { 8369 ClassFinalizer::FinalizationKind finalization) {
8366 TRACE_PARSER("ParseType"); 8370 TRACE_PARSER("ParseType");
8367 if (CurrentToken() != Token::kIDENT) { 8371 if (CurrentToken() != Token::kIDENT) {
8368 ErrorMsg("type name expected"); 8372 ErrorMsg("type name expected");
8369 } 8373 }
8370 QualIdent type_name; 8374 QualIdent type_name;
8371 if (finalization == ClassFinalizer::kIgnore) { 8375 if (finalization == ClassFinalizer::kIgnore) {
8372 SkipQualIdent(); 8376 SkipQualIdent();
8373 } else { 8377 } else {
8374 ParseQualIdent(&type_name); 8378 ParseQualIdent(&type_name);
8379 // TODO(hausner): Remove this once support for legacy type 'Dynamic'
8380 // is removed.
8381 if ((type_name.lib_prefix == NULL) && type_name.ident->Equals("Dynamic")) {
8382 if (FLAG_warn_legacy_dynamic) {
8383 Warning(type_name.ident_pos,
8384 "legacy type 'Dynamic' found; auto-converting to 'dynamic'");
8385 }
8386 // Replace with lower-case 'dynamic'.
8387 *type_name.ident ^= Symbols::Dynamic();
8388 }
8375 // An identifier cannot be resolved in a local scope when top level parsing. 8389 // An identifier cannot be resolved in a local scope when top level parsing.
8376 if (!is_top_level_ && 8390 if (!is_top_level_ &&
8377 (type_name.lib_prefix == NULL) && 8391 (type_name.lib_prefix == NULL) &&
8378 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { 8392 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) {
8379 ErrorMsg(type_name.ident_pos, "using '%s' in this context is invalid", 8393 ErrorMsg(type_name.ident_pos, "using '%s' in this context is invalid",
8380 type_name.ident->ToCString()); 8394 type_name.ident->ToCString());
8381 } 8395 }
8382 } 8396 }
8383 Object& type_class = Object::Handle(); 8397 Object& type_class = Object::Handle();
8384 // Leave type_class as null if type finalization mode is kIgnore. 8398 // Leave type_class as null if type finalization mode is kIgnore.
8385 if (finalization != ClassFinalizer::kIgnore) { 8399 if (finalization != ClassFinalizer::kIgnore) {
8386 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); 8400 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
8387 if (type_name.lib_prefix != NULL) { 8401 if (type_name.lib_prefix != NULL) {
8388 lib_prefix = type_name.lib_prefix->raw(); 8402 lib_prefix = type_name.lib_prefix->raw();
8389 } 8403 }
8390 type_class = UnresolvedClass::New(lib_prefix, 8404 type_class = UnresolvedClass::New(lib_prefix,
8391 *type_name.ident, 8405 *type_name.ident,
8392 type_name.ident_pos); 8406 type_name.ident_pos);
8393 } 8407 }
8394 Error& malformed_error = Error::Handle(); 8408 Error& malformed_error = Error::Handle();
8395 AbstractTypeArguments& type_arguments = 8409 AbstractTypeArguments& type_arguments =
8396 AbstractTypeArguments::Handle(ParseTypeArguments(&malformed_error, 8410 AbstractTypeArguments::Handle(ParseTypeArguments(&malformed_error,
8397 finalization)); 8411 finalization));
8398 if (finalization == ClassFinalizer::kIgnore) { 8412 if (finalization == ClassFinalizer::kIgnore) {
8399 return Type::DynamicType(); 8413 return Type::DynamicType();
8400 } 8414 }
8401 AbstractType& type = AbstractType::Handle( 8415 AbstractType& type = AbstractType::Handle(
8402 Type::New(type_class, type_arguments, type_name.ident_pos)); 8416 Type::New(type_class, type_arguments, type_name.ident_pos));
8403 // In production mode, malformed type arguments are mapped to Dynamic. 8417 // In production mode, malformed type arguments are mapped to dynamic.
8404 // In checked mode, a type with malformed type arguments is malformed. 8418 // In checked mode, a type with malformed type arguments is malformed.
8405 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { 8419 if (FLAG_enable_type_checks && !malformed_error.IsNull()) {
8406 Type& parameterized_type = Type::Handle(); 8420 Type& parameterized_type = Type::Handle();
8407 parameterized_type ^= type.raw(); 8421 parameterized_type ^= type.raw();
8408 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); 8422 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class()));
8409 parameterized_type.set_arguments(AbstractTypeArguments::Handle()); 8423 parameterized_type.set_arguments(AbstractTypeArguments::Handle());
8410 parameterized_type.set_malformed_error(malformed_error); 8424 parameterized_type.set_malformed_error(malformed_error);
8411 } 8425 }
8412 if (finalization >= ClassFinalizer::kTryResolve) { 8426 if (finalization >= ClassFinalizer::kTryResolve) {
8413 ResolveTypeFromClass(current_class(), finalization, &type); 8427 ResolveTypeFromClass(current_class(), finalization, &type);
(...skipping 30 matching lines...) Expand all
8444 const AbstractTypeArguments& type_arguments) { 8458 const AbstractTypeArguments& type_arguments) {
8445 TRACE_PARSER("ParseListLiteral"); 8459 TRACE_PARSER("ParseListLiteral");
8446 ASSERT(type_pos >= 0); 8460 ASSERT(type_pos >= 0);
8447 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); 8461 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX);
8448 const intptr_t literal_pos = TokenPos(); 8462 const intptr_t literal_pos = TokenPos();
8449 bool is_empty_literal = CurrentToken() == Token::kINDEX; 8463 bool is_empty_literal = CurrentToken() == Token::kINDEX;
8450 ConsumeToken(); 8464 ConsumeToken();
8451 8465
8452 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); 8466 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType());
8453 // If no type argument vector is provided, leave it as null, which is 8467 // If no type argument vector is provided, leave it as null, which is
8454 // equivalent to using Dynamic as the type argument for the element type. 8468 // equivalent to using dynamic as the type argument for the element type.
8455 if (!type_arguments.IsNull()) { 8469 if (!type_arguments.IsNull()) {
8456 ASSERT(type_arguments.Length() > 0); 8470 ASSERT(type_arguments.Length() > 0);
8457 // List literals take a single type argument. 8471 // List literals take a single type argument.
8458 element_type = type_arguments.TypeAt(0); 8472 element_type = type_arguments.TypeAt(0);
8459 if (type_arguments.Length() != 1) { 8473 if (type_arguments.Length() != 1) {
8460 ErrorMsg(type_pos, 8474 ErrorMsg(type_pos,
8461 "a list literal takes one type argument specifying " 8475 "a list literal takes one type argument specifying "
8462 "the element type"); 8476 "the element type");
8463 } 8477 }
8464 if (is_const && !element_type.IsInstantiated()) { 8478 if (is_const && !element_type.IsInstantiated()) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
8614 TRACE_PARSER("ParseMapLiteral"); 8628 TRACE_PARSER("ParseMapLiteral");
8615 ASSERT(type_pos >= 0); 8629 ASSERT(type_pos >= 0);
8616 ASSERT(CurrentToken() == Token::kLBRACE); 8630 ASSERT(CurrentToken() == Token::kLBRACE);
8617 const intptr_t literal_pos = TokenPos(); 8631 const intptr_t literal_pos = TokenPos();
8618 ConsumeToken(); 8632 ConsumeToken();
8619 8633
8620 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); 8634 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType());
8621 AbstractTypeArguments& map_type_arguments = 8635 AbstractTypeArguments& map_type_arguments =
8622 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); 8636 AbstractTypeArguments::ZoneHandle(type_arguments.raw());
8623 // If no type argument vector is provided, leave it as null, which is 8637 // If no type argument vector is provided, leave it as null, which is
8624 // equivalent to using Dynamic as the type argument for the value type. 8638 // equivalent to using dynamic as the type argument for the value type.
8625 if (!map_type_arguments.IsNull()) { 8639 if (!map_type_arguments.IsNull()) {
8626 ASSERT(map_type_arguments.Length() > 0); 8640 ASSERT(map_type_arguments.Length() > 0);
8627 // Map literals take two type arguments. 8641 // Map literals take two type arguments.
8628 if (map_type_arguments.Length() < 2) { 8642 if (map_type_arguments.Length() < 2) {
8629 // TODO(hausner): Remove legacy syntax support. 8643 // TODO(hausner): Remove legacy syntax support.
8630 // We temporarily accept a single type argument. 8644 // We temporarily accept a single type argument.
8631 if (FLAG_warn_legacy_map_literal) { 8645 if (FLAG_warn_legacy_map_literal) {
8632 Warning(type_pos, 8646 Warning(type_pos,
8633 "a map literal takes two type arguments specifying " 8647 "a map literal takes two type arguments specifying "
8634 "the key type and the value type"); 8648 "the key type and the value type");
(...skipping 16 matching lines...) Expand all
8651 } 8665 }
8652 if (is_const && !value_type.IsInstantiated()) { 8666 if (is_const && !value_type.IsInstantiated()) {
8653 ErrorMsg(type_pos, 8667 ErrorMsg(type_pos,
8654 "the type argument of a constant map literal cannot include " 8668 "the type argument of a constant map literal cannot include "
8655 "a type variable"); 8669 "a type variable");
8656 } 8670 }
8657 } 8671 }
8658 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); 8672 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2));
8659 map_type_arguments ^= map_type_arguments.Canonicalize(); 8673 map_type_arguments ^= map_type_arguments.Canonicalize();
8660 8674
8661 // The kv_pair array is temporary and of element type Dynamic. It is passed 8675 // The kv_pair array is temporary and of element type dynamic. It is passed
8662 // to the factory to initialize a properly typed map. 8676 // to the factory to initialize a properly typed map.
8663 ArrayNode* kv_pairs = 8677 ArrayNode* kv_pairs =
8664 new ArrayNode(TokenPos(), Type::ZoneHandle(Type::ListInterface())); 8678 new ArrayNode(TokenPos(), Type::ZoneHandle(Type::ListInterface()));
8665 8679
8666 // Parse the map entries. Note: there may be an optional extra 8680 // Parse the map entries. Note: there may be an optional extra
8667 // comma after the last entry. 8681 // comma after the last entry.
8668 const String& dst_name = String::ZoneHandle(Symbols::ListLiteralElement()); 8682 const String& dst_name = String::ZoneHandle(Symbols::ListLiteralElement());
8669 while (CurrentToken() != Token::kRBRACE) { 8683 while (CurrentToken() != Token::kRBRACE) {
8670 AstNode* key = NULL; 8684 AstNode* key = NULL;
8671 if (CurrentToken() == Token::kSTRING) { 8685 if (CurrentToken() == Token::kSTRING) {
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after
9722 void Parser::SkipQualIdent() { 9736 void Parser::SkipQualIdent() {
9723 ASSERT(IsIdentifier()); 9737 ASSERT(IsIdentifier());
9724 ConsumeToken(); 9738 ConsumeToken();
9725 if (CurrentToken() == Token::kPERIOD) { 9739 if (CurrentToken() == Token::kPERIOD) {
9726 ConsumeToken(); // Consume the kPERIOD token. 9740 ConsumeToken(); // Consume the kPERIOD token.
9727 ExpectIdentifier("identifier expected after '.'"); 9741 ExpectIdentifier("identifier expected after '.'");
9728 } 9742 }
9729 } 9743 }
9730 9744
9731 } // namespace dart 9745 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698