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

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

Issue 53583003: Implement latest spec changes regarding malformed types (see issue 14006): (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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/intermediate_language_x64.cc ('k') | runtime/vm/symbols.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 "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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698