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

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

Issue 23190035: Distinguish between malformed and malbounded types (fix issues 12552 and 12554). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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') | tests/language/f_bounded_quantification5_test.dart » ('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 2978 matching lines...) Expand 10 before | Expand all | Expand 10 after
2989 if (!type.IsMalformed() && type.IsTypeParameter()) { 2989 if (!type.IsMalformed() && type.IsTypeParameter()) {
2990 // Replace the type with a malformed type and compile a throw when called. 2990 // Replace the type with a malformed type and compile a throw when called.
2991 redirection_type = ClassFinalizer::NewFinalizedMalformedType( 2991 redirection_type = ClassFinalizer::NewFinalizedMalformedType(
2992 Error::Handle(), // No previous error. 2992 Error::Handle(), // No previous error.
2993 current_class(), 2993 current_class(),
2994 type_pos, 2994 type_pos,
2995 "factory '%s' may not redirect to type parameter '%s'", 2995 "factory '%s' may not redirect to type parameter '%s'",
2996 method->name->ToCString(), 2996 method->name->ToCString(),
2997 String::Handle(type.UserVisibleName()).ToCString()); 2997 String::Handle(type.UserVisibleName()).ToCString());
2998 } else { 2998 } else {
2999 // TODO(regis): What if the redirection type is malbounded?
2999 redirection_type ^= type.raw(); 3000 redirection_type ^= type.raw();
3000 } 3001 }
3001 if (CurrentToken() == Token::kPERIOD) { 3002 if (CurrentToken() == Token::kPERIOD) {
3002 // Named constructor or factory. 3003 // Named constructor or factory.
3003 ConsumeToken(); 3004 ConsumeToken();
3004 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); 3005 redirection_identifier = ExpectIdentifier("identifier expected")->raw();
3005 } 3006 }
3006 } else if (CurrentToken() == Token::kCOLON) { 3007 } else if (CurrentToken() == Token::kCOLON) {
3007 // Parse initializers. 3008 // Parse initializers.
3008 if (!method->IsConstructor()) { 3009 if (!method->IsConstructor()) {
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after
5445 if (variable_name != NULL) { 5446 if (variable_name != NULL) {
5446 // Patch the function type of the variable now that the signature is known. 5447 // Patch the function type of the variable now that the signature is known.
5447 function_type.set_type_class(signature_class); 5448 function_type.set_type_class(signature_class);
5448 function_type.set_arguments(signature_type_arguments); 5449 function_type.set_arguments(signature_type_arguments);
5449 5450
5450 // Mark the function type as malformed if the signature type is malformed. 5451 // Mark the function type as malformed if the signature type is malformed.
5451 if (signature_type.IsMalformed()) { 5452 if (signature_type.IsMalformed()) {
5452 const Error& error = Error::Handle(signature_type.malformed_error()); 5453 const Error& error = Error::Handle(signature_type.malformed_error());
5453 function_type.set_malformed_error(error); 5454 function_type.set_malformed_error(error);
5454 } 5455 }
5456 // TODO(regis): What if the signature is malbounded?
5455 5457
5456 // The function type was initially marked as instantiated, but it may 5458 // The function type was initially marked as instantiated, but it may
5457 // actually be uninstantiated. 5459 // actually be uninstantiated.
5458 function_type.ResetIsFinalized(); 5460 function_type.ResetIsFinalized();
5459 5461
5460 // The function variable type should have been patched above. 5462 // The function variable type should have been patched above.
5461 ASSERT((function_variable == NULL) || 5463 ASSERT((function_variable == NULL) ||
5462 (function_variable->type().raw() == function_type.raw())); 5464 (function_variable->type().raw() == function_type.raw()));
5463 } 5465 }
5464 5466
(...skipping 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after
7119 if (node != NULL) { 7121 if (node != NULL) {
7120 sequence->Add(node); 7122 sequence->Add(node);
7121 } 7123 }
7122 return sequence; 7124 return sequence;
7123 } 7125 }
7124 return node->AsSequenceNode(); 7126 return node->AsSequenceNode();
7125 } 7127 }
7126 7128
7127 7129
7128 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { 7130 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) {
7129 ASSERT(type.IsMalformed());
7130 ArgumentListNode* arguments = new ArgumentListNode(type_pos); 7131 ArgumentListNode* arguments = new ArgumentListNode(type_pos);
7131 // Location argument. 7132 // Location argument.
7132 arguments->Add(new LiteralNode( 7133 arguments->Add(new LiteralNode(
7133 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); 7134 type_pos, Integer::ZoneHandle(Integer::New(type_pos))));
7134 // Src value argument. 7135 // Src value argument.
7135 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); 7136 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle()));
7136 // Dst type name argument. 7137 // Dst type name argument.
7137 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed())); 7138 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed()));
7138 // Dst name argument. 7139 // Dst name argument.
7139 arguments->Add(new LiteralNode(type_pos, Symbols::Empty())); 7140 arguments->Add(new LiteralNode(type_pos, Symbols::Empty()));
7140 // Malformed type error. 7141 // Malformed type error or malbounded type error.
7141 const Error& error = Error::Handle(type.malformed_error()); 7142 Error& error = Error::Handle();
7143 if (type.IsMalformed()) {
7144 error = type.malformed_error();
7145 } else {
7146 const bool is_malbounded = type.IsMalboundedWithError(&error);
7147 ASSERT(is_malbounded);
7148 }
7142 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( 7149 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
7143 Symbols::New(error.ToErrorCString())))); 7150 Symbols::New(error.ToErrorCString()))));
7144 return MakeStaticCall(Symbols::TypeError(), 7151 return MakeStaticCall(Symbols::TypeError(),
7145 PrivateCoreLibName(Symbols::ThrowNew()), 7152 PrivateCoreLibName(Symbols::ThrowNew()),
7146 arguments); 7153 arguments);
7147 } 7154 }
7148 7155
7149 7156
7150 // TODO(regis): Providing the argument values is not always feasible, since 7157 // TODO(regis): Providing the argument values is not always feasible, since
7151 // evaluating them could throw an error. 7158 // evaluating them could throw an error.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
7231 } 7238 }
7232 const intptr_t type_pos = TokenPos(); 7239 const intptr_t type_pos = TokenPos();
7233 const AbstractType& type = AbstractType::ZoneHandle( 7240 const AbstractType& type = AbstractType::ZoneHandle(
7234 ParseType(ClassFinalizer::kCanonicalize)); 7241 ParseType(ClassFinalizer::kCanonicalize));
7235 if (!type.IsInstantiated() && 7242 if (!type.IsInstantiated() &&
7236 (current_block_->scope->function_level() > 0)) { 7243 (current_block_->scope->function_level() > 0)) {
7237 // Make sure that the instantiator is captured. 7244 // Make sure that the instantiator is captured.
7238 CaptureInstantiator(); 7245 CaptureInstantiator();
7239 } 7246 }
7240 right_operand = new TypeNode(type_pos, type); 7247 right_operand = new TypeNode(type_pos, type);
7241 // If the type is malformed, it is actually malbounded in checked mode. 7248 // The type is never malformed (mapped to dynamic), but it can be
7242 ASSERT(!type.IsMalformed() || FLAG_enable_type_checks); 7249 // malbounded in checked mode.
7250 ASSERT(!type.IsMalformed());
7243 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && 7251 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) &&
7244 type.IsMalformed()) { 7252 type.IsMalbounded()) {
7245 // Note that a type error is thrown even if the tested value is null 7253 // Note that a type error is thrown even if the tested value is null
7246 // in a type test. However, no cast exception is thrown if the value 7254 // in a type test. However, no cast exception is thrown if the value
7247 // is null in a type cast. 7255 // is null in a type cast.
7248 return ThrowTypeError(type_pos, type); 7256 return ThrowTypeError(type_pos, type);
7249 } 7257 }
7250 } 7258 }
7251 if (Token::IsRelationalOperator(op_kind) 7259 if (Token::IsRelationalOperator(op_kind)
7252 || Token::IsTypeTestOperator(op_kind) 7260 || Token::IsTypeTestOperator(op_kind)
7253 || Token::IsTypeCastOperator(op_kind) 7261 || Token::IsTypeCastOperator(op_kind)
7254 || Token::IsEqualityOperator(op_kind)) { 7262 || Token::IsEqualityOperator(op_kind)) {
(...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after
9599 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 9607 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
9600 bool is_const = (op_kind == Token::kCONST); 9608 bool is_const = (op_kind == Token::kCONST);
9601 if (!IsIdentifier()) { 9609 if (!IsIdentifier()) {
9602 ErrorMsg("type name expected"); 9610 ErrorMsg("type name expected");
9603 } 9611 }
9604 intptr_t type_pos = TokenPos(); 9612 intptr_t type_pos = TokenPos();
9605 AbstractType& type = AbstractType::Handle( 9613 AbstractType& type = AbstractType::Handle(
9606 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); 9614 ParseType(ClassFinalizer::kCanonicalizeWellFormed));
9607 // In case the type is malformed, throw a dynamic type error after finishing 9615 // In case the type is malformed, throw a dynamic type error after finishing
9608 // parsing the instance creation expression. 9616 // parsing the instance creation expression.
9609 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { 9617 if (!type.IsMalformed()) {
9610 // Replace the type with a malformed type. 9618 if (type.IsTypeParameter() || type.IsDynamicType()) {
9611 type = ClassFinalizer::NewFinalizedMalformedType( 9619 // Replace the type with a malformed type.
9612 Error::Handle(), // No previous error. 9620 type = ClassFinalizer::NewFinalizedMalformedType(
9613 current_class(), 9621 Error::Handle(), // No previous error.
9614 type_pos, 9622 current_class(),
9615 "%s'%s' cannot be instantiated", 9623 type_pos,
9616 type.IsTypeParameter() ? "type parameter " : "", 9624 "%s'%s' cannot be instantiated",
9617 type.IsTypeParameter() ? 9625 type.IsTypeParameter() ? "type parameter " : "",
9618 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); 9626 type.IsTypeParameter() ?
9627 String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
9628 } else if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
9629 Error& bound_error = Error::Handle();
9630 if (type.IsMalboundedWithError(&bound_error)) {
9631 // Replace the type with a malformed type.
9632 type = ClassFinalizer::NewFinalizedMalformedType(
9633 bound_error,
9634 current_class(),
9635 type_pos,
9636 "malbounded type '%s' cannot be instantiated",
9637 String::Handle(type.UserVisibleName()).ToCString());
9638 }
9639 }
9619 } 9640 }
9620 9641
9621 // The grammar allows for an optional ('.' identifier)? after the type, which 9642 // The grammar allows for an optional ('.' identifier)? after the type, which
9622 // is a named constructor. Note that ParseType() above will not consume it as 9643 // is a named constructor. Note that ParseType() above will not consume it as
9623 // part of a misinterpreted qualified identifier, because only a valid library 9644 // part of a misinterpreted qualified identifier, because only a valid library
9624 // prefix is accepted as qualifier. 9645 // prefix is accepted as qualifier.
9625 String* named_constructor = NULL; 9646 String* named_constructor = NULL;
9626 if (CurrentToken() == Token::kPERIOD) { 9647 if (CurrentToken() == Token::kPERIOD) {
9627 ConsumeToken(); 9648 ConsumeToken();
9628 named_constructor = ExpectIdentifier("name of constructor expected"); 9649 named_constructor = ExpectIdentifier("name of constructor expected");
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
10399 void Parser::SkipQualIdent() { 10420 void Parser::SkipQualIdent() {
10400 ASSERT(IsIdentifier()); 10421 ASSERT(IsIdentifier());
10401 ConsumeToken(); 10422 ConsumeToken();
10402 if (CurrentToken() == Token::kPERIOD) { 10423 if (CurrentToken() == Token::kPERIOD) {
10403 ConsumeToken(); // Consume the kPERIOD token. 10424 ConsumeToken(); // Consume the kPERIOD token.
10404 ExpectIdentifier("identifier expected after '.'"); 10425 ExpectIdentifier("identifier expected after '.'");
10405 } 10426 }
10406 } 10427 }
10407 10428
10408 } // namespace dart 10429 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | tests/language/f_bounded_quantification5_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698