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 |