Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 5247) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -2952,7 +2952,11 @@ |
| bound = Type::DynamicType(); |
| if (CurrentToken() == Token::kEXTENDS) { |
| ConsumeToken(); |
| - bound = ParseType(ClassFinalizer::kTryResolve); |
| + // A bound may refer to the owner of the type parameter it applies to, |
| + // i.e. to the class or interface currently being parsed. |
| + // Postpone resolution in order to avoid resolving the class and its |
| + // type parameters, as they are not fully parsed yet. |
| + bound = ParseType(ClassFinalizer::kDoNotResolve); |
| } |
| type_parameters_array.Add(type_parameter); |
| bounds_array.Add(bound); |
| @@ -5538,8 +5542,8 @@ |
| arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); |
| // Dst type name argument. |
| arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| - String::NewSymbol("malformed type")))); |
| - // Dst type name argument. |
| + String::NewSymbol("malformed")))); |
| + // Dst name argument. |
| arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| String::NewSymbol("")))); |
| // Malformed type error. |
| @@ -7341,6 +7345,11 @@ |
| AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( |
| ParseTypeArguments(&malformed_error, |
| ClassFinalizer::kFinalizeWellFormed)); |
| + // Map and List interfaces do not declare bounds on their type parameters, so |
| + // we should never see a malformed type error here. |
| + // Note that a bound error is the only possible malformed type error returned |
| + // when requesting kFinalizeWellFormed type finalization. |
|
srdjan
2012/03/09 20:48:28
What if we change the libraries? Can we check some
regis
2012/03/09 21:08:37
We would need to add debug code here to resolve Ma
|
| + ASSERT(malformed_error.IsNull()); |
| AstNode* primary = NULL; |
| if ((CurrentToken() == Token::kLBRACK) || |
| (CurrentToken() == Token::kINDEX)) { |
| @@ -7380,12 +7389,12 @@ |
| ErrorMsg("type name expected"); |
| } |
| intptr_t type_pos = token_index_; |
| - |
| - // TODO(regis): Bounds error should not result in a compile time error, |
| - // but in a dynamic type error. Requesting kFinalizeWellFormed below is too |
| - // strict. See co19 issue 96. |
| const AbstractType& type = AbstractType::Handle( |
| ParseType(ClassFinalizer::kFinalizeWellFormed)); |
| + // Malformed bounds never result in a compile time error, therefore, the |
| + // parsed type may be malformed although we requested kFinalizeWellFormed. |
| + // In that case, we throw a dynamic type error instead of calling the |
| + // constructor. |
| if (type.IsTypeParameter()) { |
| ErrorMsg(type_pos, |
| "type parameter '%s' cannot be instantiated", |
| @@ -7548,6 +7557,10 @@ |
| ErrorMsg("'const' requires const constructor: '%s'", |
| String::Handle(constructor.name()).ToCString()); |
| } |
| + if (type.IsMalformed()) { |
| + // Compile the throw of a dynamic type error due to a bound error. |
| + return ThrowTypeError(type_pos, type); |
| + } |
| const Object& constructor_result = Object::Handle( |
| EvaluateConstConstructorCall(constructor_class, |
| type_arguments, |
| @@ -7569,6 +7582,10 @@ |
| // Make sure that the instantiator is captured. |
| CaptureReceiver(); |
| } |
| + if (type.IsMalformed()) { |
| + // Compile the throw of a dynamic type error due to a bound error. |
| + return ThrowTypeError(type_pos, type); |
| + } |
| // TODO(regis): If the type argument vector is not instantiated, we need to |
| // verify in checked mode at runtime that it is within its declared bounds. |
| new_object = new ConstructorCallNode( |