| OLD | NEW |
| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 3730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3741 ErrorMsg(classname_pos, | 3741 ErrorMsg(classname_pos, |
| 3742 "mixin application '%s' may not be a patch class", | 3742 "mixin application '%s' may not be a patch class", |
| 3743 class_name.ToCString()); | 3743 class_name.ToCString()); |
| 3744 } | 3744 } |
| 3745 | 3745 |
| 3746 AbstractType& super_type = Type::Handle(); | 3746 AbstractType& super_type = Type::Handle(); |
| 3747 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 3747 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 3748 ConsumeToken(); // extends or = | 3748 ConsumeToken(); // extends or = |
| 3749 const intptr_t type_pos = TokenPos(); | 3749 const intptr_t type_pos = TokenPos(); |
| 3750 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 3750 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 3751 if (super_type.IsDynamicType()) { | 3751 if (super_type.IsMalformed() || super_type.IsDynamicType()) { |
| 3752 // The string 'dynamic' is not resolved yet at this point, but a malformed | 3752 // Unlikely here, since super type is not resolved yet. |
| 3753 // type mapped to dynamic can be encountered here. | |
| 3754 ErrorMsg(type_pos, | 3753 ErrorMsg(type_pos, |
| 3755 "class '%s' may not extend a malformed type", | 3754 "class '%s' may not extend %s", |
| 3756 class_name.ToCString()); | 3755 class_name.ToCString(), |
| 3756 super_type.IsMalformed() ? "a malformed type" : "'dynamic'"); |
| 3757 } | 3757 } |
| 3758 if (super_type.IsTypeParameter()) { | 3758 if (super_type.IsTypeParameter()) { |
| 3759 ErrorMsg(type_pos, | 3759 ErrorMsg(type_pos, |
| 3760 "class '%s' may not extend type parameter '%s'", | 3760 "class '%s' may not extend type parameter '%s'", |
| 3761 class_name.ToCString(), | 3761 class_name.ToCString(), |
| 3762 String::Handle(super_type.UserVisibleName()).ToCString()); | 3762 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3763 } | 3763 } |
| 3764 // The class finalizer will check whether the super type is malbounded. |
| 3764 if (CurrentToken() == Token::kWITH) { | 3765 if (CurrentToken() == Token::kWITH) { |
| 3765 super_type = ParseMixins(super_type); | 3766 super_type = ParseMixins(super_type); |
| 3766 } | 3767 } |
| 3767 if (is_mixin_declaration) { | 3768 if (is_mixin_declaration) { |
| 3768 cls.set_is_mixin_typedef(); | 3769 cls.set_is_mixin_typedef(); |
| 3769 cls.set_is_synthesized_class(); | 3770 cls.set_is_synthesized_class(); |
| 3770 } | 3771 } |
| 3771 } else { | 3772 } else { |
| 3772 // No extends clause: implicitly extend Object, unless Object itself. | 3773 // No extends clause: implicitly extend Object, unless Object itself. |
| 3773 if (!cls.IsObjectClass()) { | 3774 if (!cls.IsObjectClass()) { |
| (...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7423 } | 7424 } |
| 7424 const intptr_t type_pos = TokenPos(); | 7425 const intptr_t type_pos = TokenPos(); |
| 7425 const AbstractType& type = AbstractType::ZoneHandle( | 7426 const AbstractType& type = AbstractType::ZoneHandle( |
| 7426 ParseType(ClassFinalizer::kCanonicalize)); | 7427 ParseType(ClassFinalizer::kCanonicalize)); |
| 7427 if (!type.IsInstantiated() && | 7428 if (!type.IsInstantiated() && |
| 7428 (current_block_->scope->function_level() > 0)) { | 7429 (current_block_->scope->function_level() > 0)) { |
| 7429 // Make sure that the instantiator is captured. | 7430 // Make sure that the instantiator is captured. |
| 7430 CaptureInstantiator(); | 7431 CaptureInstantiator(); |
| 7431 } | 7432 } |
| 7432 right_operand = new TypeNode(type_pos, type); | 7433 right_operand = new TypeNode(type_pos, type); |
| 7433 // The type is never malformed (mapped to dynamic), but it can be | 7434 // In production mode, the type may be malformed. |
| 7434 // malbounded in checked mode. | 7435 // In checked mode, the type may be malformed or malbounded. |
| 7435 ASSERT(!type.IsMalformed()); | |
| 7436 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || | 7436 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || |
| 7437 (op_kind == Token::kAS)) && | 7437 (op_kind == Token::kAS)) && |
| 7438 type.IsMalbounded()) { | 7438 (type.IsMalformed() || type.IsMalbounded())) { |
| 7439 // Note that a type error is thrown even if the tested value is null | 7439 // Note that a type error is thrown even if the tested value is null |
| 7440 // in a type test or in a type cast. | 7440 // in a type test or in a type cast. |
| 7441 return ThrowTypeError(type_pos, type); | 7441 return ThrowTypeError(type_pos, type); |
| 7442 } | 7442 } |
| 7443 } | 7443 } |
| 7444 if (Token::IsRelationalOperator(op_kind) | 7444 if (Token::IsRelationalOperator(op_kind) |
| 7445 || Token::IsTypeTestOperator(op_kind) | 7445 || Token::IsTypeTestOperator(op_kind) |
| 7446 || Token::IsTypeCastOperator(op_kind) | 7446 || Token::IsTypeCastOperator(op_kind) |
| 7447 || Token::IsEqualityOperator(op_kind)) { | 7447 || Token::IsEqualityOperator(op_kind)) { |
| 7448 if (Token::IsTypeTestOperator(op_kind) || | 7448 if (Token::IsTypeTestOperator(op_kind) || |
| (...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9186 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); | 9186 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); |
| 9187 AbstractTypeArguments& list_type_arguments = | 9187 AbstractTypeArguments& list_type_arguments = |
| 9188 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 9188 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
| 9189 // If no type argument vector is provided, leave it as null, which is | 9189 // If no type argument vector is provided, leave it as null, which is |
| 9190 // equivalent to using dynamic as the type argument for the element type. | 9190 // equivalent to using dynamic as the type argument for the element type. |
| 9191 if (!list_type_arguments.IsNull()) { | 9191 if (!list_type_arguments.IsNull()) { |
| 9192 ASSERT(list_type_arguments.Length() > 0); | 9192 ASSERT(list_type_arguments.Length() > 0); |
| 9193 // List literals take a single type argument. | 9193 // List literals take a single type argument. |
| 9194 if (list_type_arguments.Length() == 1) { | 9194 if (list_type_arguments.Length() == 1) { |
| 9195 element_type = list_type_arguments.TypeAt(0); | 9195 element_type = list_type_arguments.TypeAt(0); |
| 9196 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
| 9197 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
| 9198 if (is_const && !element_type.IsInstantiated()) { |
| 9199 ErrorMsg(type_pos, |
| 9200 "the type argument of a constant list literal cannot include " |
| 9201 "a type variable"); |
| 9202 } |
| 9196 } else { | 9203 } else { |
| 9197 if (FLAG_error_on_bad_type) { | 9204 if (FLAG_error_on_bad_type) { |
| 9198 ErrorMsg(type_pos, | 9205 ErrorMsg(type_pos, |
| 9199 "a list literal takes one type argument specifying " | 9206 "a list literal takes one type argument specifying " |
| 9200 "the element type"); | 9207 "the element type"); |
| 9201 } | 9208 } |
| 9202 // Ignore type arguments. | 9209 // Ignore type arguments. |
| 9203 list_type_arguments = AbstractTypeArguments::null(); | 9210 list_type_arguments = AbstractTypeArguments::null(); |
| 9204 } | 9211 } |
| 9205 if (is_const && !element_type.IsInstantiated()) { | |
| 9206 ErrorMsg(type_pos, | |
| 9207 "the type argument of a constant list literal cannot include " | |
| 9208 "a type variable"); | |
| 9209 } | |
| 9210 } | 9212 } |
| 9211 ASSERT((list_type_arguments.IsNull() && element_type.IsDynamicType()) || | 9213 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
| 9212 ((list_type_arguments.Length() == 1) && !element_type.IsNull())); | |
| 9213 const Class& array_class = Class::Handle( | 9214 const Class& array_class = Class::Handle( |
| 9214 isolate()->object_store()->array_class()); | 9215 isolate()->object_store()->array_class()); |
| 9215 Type& type = Type::ZoneHandle( | 9216 Type& type = Type::ZoneHandle( |
| 9216 Type::New(array_class, list_type_arguments, type_pos)); | 9217 Type::New(array_class, list_type_arguments, type_pos)); |
| 9217 type ^= ClassFinalizer::FinalizeType( | 9218 type ^= ClassFinalizer::FinalizeType( |
| 9218 current_class(), type, ClassFinalizer::kCanonicalize); | 9219 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9219 GrowableArray<AstNode*> element_list; | 9220 GrowableArray<AstNode*> element_list; |
| 9220 // Parse the list elements. Note: there may be an optional extra | 9221 // Parse the list elements. Note: there may be an optional extra |
| 9221 // comma after the last element. | 9222 // comma after the last element. |
| 9222 if (!is_empty_literal) { | 9223 if (!is_empty_literal) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9379 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 9380 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
| 9380 // If no type argument vector is provided, leave it as null, which is | 9381 // If no type argument vector is provided, leave it as null, which is |
| 9381 // equivalent to using dynamic as the type argument for the both key and value | 9382 // equivalent to using dynamic as the type argument for the both key and value |
| 9382 // types. | 9383 // types. |
| 9383 if (!map_type_arguments.IsNull()) { | 9384 if (!map_type_arguments.IsNull()) { |
| 9384 ASSERT(map_type_arguments.Length() > 0); | 9385 ASSERT(map_type_arguments.Length() > 0); |
| 9385 // Map literals take two type arguments. | 9386 // Map literals take two type arguments. |
| 9386 if (map_type_arguments.Length() == 2) { | 9387 if (map_type_arguments.Length() == 2) { |
| 9387 key_type = map_type_arguments.TypeAt(0); | 9388 key_type = map_type_arguments.TypeAt(0); |
| 9388 value_type = map_type_arguments.TypeAt(1); | 9389 value_type = map_type_arguments.TypeAt(1); |
| 9390 // Malformed type arguments are mapped to dynamic. |
| 9391 ASSERT(!key_type.IsMalformed() && !value_type.IsMalformed()); |
| 9392 // No declared bounds in Map. |
| 9393 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); |
| 9389 if (is_const && !type_arguments.IsInstantiated()) { | 9394 if (is_const && !type_arguments.IsInstantiated()) { |
| 9390 ErrorMsg(type_pos, | 9395 ErrorMsg(type_pos, |
| 9391 "the type arguments of a constant map literal cannot include " | 9396 "the type arguments of a constant map literal cannot include " |
| 9392 "a type variable"); | 9397 "a type variable"); |
| 9393 } | 9398 } |
| 9394 if (key_type.IsMalformed()) { | |
| 9395 if (FLAG_error_on_bad_type) { | |
| 9396 ErrorMsg(Error::Handle(key_type.malformed_error())); | |
| 9397 } | |
| 9398 // Map malformed key type to dynamic. | |
| 9399 key_type = Type::DynamicType(); | |
| 9400 map_type_arguments.SetTypeAt(0, key_type); | |
| 9401 } | |
| 9402 if (value_type.IsMalformed()) { | |
| 9403 if (FLAG_error_on_bad_type) { | |
| 9404 ErrorMsg(Error::Handle(value_type.malformed_error())); | |
| 9405 } | |
| 9406 // Map malformed value type to dynamic. | |
| 9407 value_type = Type::DynamicType(); | |
| 9408 map_type_arguments.SetTypeAt(1, value_type); | |
| 9409 } | |
| 9410 } else { | 9399 } else { |
| 9411 if (FLAG_error_on_bad_type) { | 9400 if (FLAG_error_on_bad_type) { |
| 9412 ErrorMsg(type_pos, | 9401 ErrorMsg(type_pos, |
| 9413 "a map literal takes two type arguments specifying " | 9402 "a map literal takes two type arguments specifying " |
| 9414 "the key type and the value type"); | 9403 "the key type and the value type"); |
| 9415 } | 9404 } |
| 9416 // Ignore type arguments. | 9405 // Ignore type arguments. |
| 9417 map_type_arguments = AbstractTypeArguments::null(); | 9406 map_type_arguments = AbstractTypeArguments::null(); |
| 9418 } | 9407 } |
| 9419 } | 9408 } |
| 9420 ASSERT((map_type_arguments.IsNull() && | 9409 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 9421 key_type.IsDynamicType() && value_type.IsDynamicType()) || | |
| 9422 ((map_type_arguments.Length() == 2) && | |
| 9423 !key_type.IsMalformed() && !value_type.IsMalformed())); | |
| 9424 map_type_arguments ^= map_type_arguments.Canonicalize(); | 9410 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 9425 | 9411 |
| 9426 GrowableArray<AstNode*> kv_pairs_list; | 9412 GrowableArray<AstNode*> kv_pairs_list; |
| 9427 // Parse the map entries. Note: there may be an optional extra | 9413 // Parse the map entries. Note: there may be an optional extra |
| 9428 // comma after the last entry. | 9414 // comma after the last entry. |
| 9429 while (CurrentToken() != Token::kRBRACE) { | 9415 while (CurrentToken() != Token::kRBRACE) { |
| 9430 const bool saved_mode = SetAllowFunctionLiterals(true); | 9416 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 9431 const intptr_t key_pos = TokenPos(); | 9417 const intptr_t key_pos = TokenPos(); |
| 9432 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 9418 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 9433 if (FLAG_enable_type_checks && | 9419 if (FLAG_enable_type_checks && |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9597 AstNode* Parser::ParseCompoundLiteral() { | 9583 AstNode* Parser::ParseCompoundLiteral() { |
| 9598 TRACE_PARSER("ParseCompoundLiteral"); | 9584 TRACE_PARSER("ParseCompoundLiteral"); |
| 9599 bool is_const = false; | 9585 bool is_const = false; |
| 9600 if (CurrentToken() == Token::kCONST) { | 9586 if (CurrentToken() == Token::kCONST) { |
| 9601 is_const = true; | 9587 is_const = true; |
| 9602 ConsumeToken(); | 9588 ConsumeToken(); |
| 9603 } | 9589 } |
| 9604 const intptr_t type_pos = TokenPos(); | 9590 const intptr_t type_pos = TokenPos(); |
| 9605 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle( | 9591 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle( |
| 9606 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 9592 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
| 9593 // Malformed type arguments are mapped to dynamic, so we will not encounter |
| 9594 // them here. |
| 9607 // Map and List interfaces do not declare bounds on their type parameters, so | 9595 // Map and List interfaces do not declare bounds on their type parameters, so |
| 9608 // we should never see a malformed type argument mapped to dynamic here. | 9596 // we will not see malbounded type arguments here. |
| 9609 AstNode* primary = NULL; | 9597 AstNode* primary = NULL; |
| 9610 if ((CurrentToken() == Token::kLBRACK) || | 9598 if ((CurrentToken() == Token::kLBRACK) || |
| 9611 (CurrentToken() == Token::kINDEX)) { | 9599 (CurrentToken() == Token::kINDEX)) { |
| 9612 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 9600 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 9613 } else if (CurrentToken() == Token::kLBRACE) { | 9601 } else if (CurrentToken() == Token::kLBRACE) { |
| 9614 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 9602 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 9615 } else { | 9603 } else { |
| 9616 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 9604 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
| 9617 } | 9605 } |
| 9618 return primary; | 9606 return primary; |
| (...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10588 void Parser::SkipQualIdent() { | 10576 void Parser::SkipQualIdent() { |
| 10589 ASSERT(IsIdentifier()); | 10577 ASSERT(IsIdentifier()); |
| 10590 ConsumeToken(); | 10578 ConsumeToken(); |
| 10591 if (CurrentToken() == Token::kPERIOD) { | 10579 if (CurrentToken() == Token::kPERIOD) { |
| 10592 ConsumeToken(); // Consume the kPERIOD token. | 10580 ConsumeToken(); // Consume the kPERIOD token. |
| 10593 ExpectIdentifier("identifier expected after '.'"); | 10581 ExpectIdentifier("identifier expected after '.'"); |
| 10594 } | 10582 } |
| 10595 } | 10583 } |
| 10596 | 10584 |
| 10597 } // namespace dart | 10585 } // namespace dart |
| OLD | NEW |