| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 5356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5367 va_list args; | 5367 va_list args; |
| 5368 va_start(args, format); | 5368 va_start(args, format); |
| 5369 const Error& error = Error::Handle( | 5369 const Error& error = Error::Handle( |
| 5370 FormatError(script_, token_index_, "Error", format, args)); | 5370 FormatError(script_, token_index_, "Error", format, args)); |
| 5371 va_end(args); | 5371 va_end(args); |
| 5372 Isolate::Current()->long_jump_base()->Jump(1, error); | 5372 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5373 UNREACHABLE(); | 5373 UNREACHABLE(); |
| 5374 } | 5374 } |
| 5375 | 5375 |
| 5376 | 5376 |
| 5377 void Parser::ErrorMsg(const Error& error) { |
| 5378 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5379 UNREACHABLE(); |
| 5380 } |
| 5381 |
| 5382 |
| 5377 void Parser::AppendErrorMsg( | 5383 void Parser::AppendErrorMsg( |
| 5378 const Error& prev_error, intptr_t token_index, const char* format, ...) { | 5384 const Error& prev_error, intptr_t token_index, const char* format, ...) { |
| 5379 va_list args; | 5385 va_list args; |
| 5380 va_start(args, format); | 5386 va_start(args, format); |
| 5381 const Error& error = Error::Handle(FormatErrorWithAppend( | 5387 const Error& error = Error::Handle(FormatErrorWithAppend( |
| 5382 prev_error, script_, token_index, "Error", format, args)); | 5388 prev_error, script_, token_index, "Error", format, args)); |
| 5383 va_end(args); | 5389 va_end(args); |
| 5384 Isolate::Current()->long_jump_base()->Jump(1, error); | 5390 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5385 UNREACHABLE(); | 5391 UNREACHABLE(); |
| 5386 } | 5392 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5547 const intptr_t type_pos = token_index_; | 5553 const intptr_t type_pos = token_index_; |
| 5548 const AbstractType& type = | 5554 const AbstractType& type = |
| 5549 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); | 5555 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); |
| 5550 if (!type.IsInstantiated() && | 5556 if (!type.IsInstantiated() && |
| 5551 (current_block_->scope->function_level() > 0)) { | 5557 (current_block_->scope->function_level() > 0)) { |
| 5552 // Make sure that the instantiator is captured. | 5558 // Make sure that the instantiator is captured. |
| 5553 CaptureReceiver(); | 5559 CaptureReceiver(); |
| 5554 } | 5560 } |
| 5555 right_operand = new TypeNode(type_pos, type); | 5561 right_operand = new TypeNode(type_pos, type); |
| 5556 if (type.IsMalformed()) { | 5562 if (type.IsMalformed()) { |
| 5563 // Note that a type error is thrown even if the tested value is null. |
| 5557 return ThrowTypeError(type_pos, type); | 5564 return ThrowTypeError(type_pos, type); |
| 5558 } | 5565 } |
| 5559 } | 5566 } |
| 5560 if (Token::IsRelationalOperator(op_kind) | 5567 if (Token::IsRelationalOperator(op_kind) |
| 5561 || Token::IsInstanceofOperator(op_kind) | 5568 || Token::IsInstanceofOperator(op_kind) |
| 5562 || Token::IsEqualityOperator(op_kind)) { | 5569 || Token::IsEqualityOperator(op_kind)) { |
| 5563 left_operand = new ComparisonNode( | 5570 left_operand = new ComparisonNode( |
| 5564 op_pos, op_kind, left_operand, right_operand); | 5571 op_pos, op_kind, left_operand, right_operand); |
| 5565 break; // Equality and relational operators cannot be chained. | 5572 break; // Equality and relational operators cannot be chained. |
| 5566 } else { | 5573 } else { |
| (...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6421 // At this point, we can only have a parameterized_type. | 6428 // At this point, we can only have a parameterized_type. |
| 6422 Type& parameterized_type = Type::Handle(); | 6429 Type& parameterized_type = Type::Handle(); |
| 6423 parameterized_type ^= type->raw(); | 6430 parameterized_type ^= type->raw(); |
| 6424 if (!resolved_type_class.IsNull()) { | 6431 if (!resolved_type_class.IsNull()) { |
| 6425 Object& type_class = Object::Handle(resolved_type_class.raw()); | 6432 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 6426 // Replace unresolved class with resolved type class. | 6433 // Replace unresolved class with resolved type class. |
| 6427 parameterized_type.set_type_class(type_class); | 6434 parameterized_type.set_type_class(type_class); |
| 6428 } else if (finalization >= ClassFinalizer::kFinalize) { | 6435 } else if (finalization >= ClassFinalizer::kFinalize) { |
| 6429 // The type is malformed. | 6436 // The type is malformed. |
| 6430 ClassFinalizer::FinalizeMalformedType( | 6437 ClassFinalizer::FinalizeMalformedType( |
| 6438 Error::Handle(), // No previous error. |
| 6431 current_class(), parameterized_type, finalization, | 6439 current_class(), parameterized_type, finalization, |
| 6432 "type '%s' is not loaded", | 6440 "type '%s' is not loaded", |
| 6433 String::Handle(parameterized_type.Name()).ToCString()); | 6441 String::Handle(parameterized_type.Name()).ToCString()); |
| 6434 } | 6442 } |
| 6435 } | 6443 } |
| 6436 // Resolve type arguments, if any. | 6444 // Resolve type arguments, if any. |
| 6437 const AbstractTypeArguments& arguments = | 6445 const AbstractTypeArguments& arguments = |
| 6438 AbstractTypeArguments::Handle(type->arguments()); | 6446 AbstractTypeArguments::Handle(type->arguments()); |
| 6439 if (!arguments.IsNull()) { | 6447 if (!arguments.IsNull()) { |
| 6440 const intptr_t num_arguments = arguments.Length(); | 6448 const intptr_t num_arguments = arguments.Length(); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6995 String::NewSymbol("list literal element")); | 7003 String::NewSymbol("list literal element")); |
| 6996 while (CurrentToken() != Token::kRBRACK) { | 7004 while (CurrentToken() != Token::kRBRACK) { |
| 6997 const intptr_t element_pos = token_index_; | 7005 const intptr_t element_pos = token_index_; |
| 6998 AstNode* element = ParseExpr(is_const); | 7006 AstNode* element = ParseExpr(is_const); |
| 6999 if (FLAG_enable_type_checks && | 7007 if (FLAG_enable_type_checks && |
| 7000 !is_const && | 7008 !is_const && |
| 7001 !element_type.IsDynamicType()) { | 7009 !element_type.IsDynamicType()) { |
| 7002 // The expression needs to be type checked at runtime. | 7010 // The expression needs to be type checked at runtime. |
| 7003 // Eliminate the type check if it can be performed at compile time and | 7011 // Eliminate the type check if it can be performed at compile time and |
| 7004 // if it succeeds. | 7012 // if it succeeds. |
| 7013 Error& malformed_error = Error::Handle(); |
| 7005 if (!element_type.IsInstantiated() || | 7014 if (!element_type.IsInstantiated() || |
| 7006 !element->IsLiteralNode() || | 7015 !element->IsLiteralNode() || |
| 7007 !element->AsLiteralNode()->literal(). | 7016 !element->AsLiteralNode()->literal(). |
| 7008 IsAssignableTo(element_type, TypeArguments::Handle())) { | 7017 IsAssignableTo(element_type, |
| 7018 TypeArguments::Handle(), |
| 7019 &malformed_error)) { |
| 7009 element = new AssignableNode(element_pos, | 7020 element = new AssignableNode(element_pos, |
| 7010 element, | 7021 element, |
| 7011 element_type, | 7022 element_type, |
| 7012 dst_name); | 7023 dst_name); |
| 7013 } | 7024 } |
| 7014 } | 7025 } |
| 7015 list->AddElement(element); | 7026 list->AddElement(element); |
| 7016 if (CurrentToken() == Token::kCOMMA) { | 7027 if (CurrentToken() == Token::kCOMMA) { |
| 7017 ConsumeToken(); | 7028 ConsumeToken(); |
| 7018 } else if (CurrentToken() != Token::kRBRACK) { | 7029 } else if (CurrentToken() != Token::kRBRACK) { |
| 7019 ErrorMsg("comma or ']' expected"); | 7030 ErrorMsg("comma or ']' expected"); |
| 7020 } | 7031 } |
| 7021 } | 7032 } |
| 7022 ExpectToken(Token::kRBRACK); | 7033 ExpectToken(Token::kRBRACK); |
| 7023 SetAllowFunctionLiterals(saved_mode); | 7034 SetAllowFunctionLiterals(saved_mode); |
| 7024 } | 7035 } |
| 7025 | 7036 |
| 7026 if (is_const) { | 7037 if (is_const) { |
| 7027 // Allocate and initialize the const list at compile time. | 7038 // Allocate and initialize the const list at compile time. |
| 7028 Array& const_list = | 7039 Array& const_list = |
| 7029 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); | 7040 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); |
| 7030 const_list.SetTypeArguments(type_arguments); | 7041 const_list.SetTypeArguments(type_arguments); |
| 7031 | 7042 Error& malformed_error = Error::Handle(); |
| 7032 for (int i = 0; i < list->length(); i++) { | 7043 for (int i = 0; i < list->length(); i++) { |
| 7033 AstNode* elem = list->ElementAt(i); | 7044 AstNode* elem = list->ElementAt(i); |
| 7034 // Arguments have been evaluated to a literal value already. | 7045 // Arguments have been evaluated to a literal value already. |
| 7035 ASSERT(elem->IsLiteralNode()); | 7046 ASSERT(elem->IsLiteralNode()); |
| 7036 if (FLAG_enable_type_checks && | 7047 if (FLAG_enable_type_checks && |
| 7037 !element_type.IsDynamicType() && | 7048 !element_type.IsDynamicType() && |
| 7038 !elem->AsLiteralNode()->literal(). | 7049 !elem->AsLiteralNode()->literal().IsAssignableTo( |
| 7039 IsAssignableTo(element_type, TypeArguments::Handle())) { | 7050 element_type, TypeArguments::Handle(), &malformed_error)) { |
| 7040 ErrorMsg(elem->AsLiteralNode()->token_index(), | 7051 // If the failure is due to a malformed type error, display it instead. |
| 7041 "list literal element at index %d must be " | 7052 if (!malformed_error.IsNull()) { |
| 7042 "a constant of type '%s'", | 7053 ErrorMsg(malformed_error); |
| 7043 i, | 7054 } else { |
| 7044 String::Handle(element_type.Name()).ToCString()); | 7055 ErrorMsg(elem->AsLiteralNode()->token_index(), |
| 7056 "list literal element at index %d must be " |
| 7057 "a constant of type '%s'", |
| 7058 i, |
| 7059 String::Handle(element_type.Name()).ToCString()); |
| 7060 } |
| 7045 } | 7061 } |
| 7046 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 7062 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 7047 } | 7063 } |
| 7048 const_list ^= const_list.Canonicalize(); | 7064 const_list ^= const_list.Canonicalize(); |
| 7049 const_list.MakeImmutable(); | 7065 const_list.MakeImmutable(); |
| 7050 return new LiteralNode(literal_pos, const_list); | 7066 return new LiteralNode(literal_pos, const_list); |
| 7051 } else { | 7067 } else { |
| 7052 // Factory call at runtime. | 7068 // Factory call at runtime. |
| 7053 String& list_literal_factory_class_name = String::Handle( | 7069 String& list_literal_factory_class_name = String::Handle( |
| 7054 String::NewSymbol(kListLiteralFactoryClassName)); | 7070 String::NewSymbol(kListLiteralFactoryClassName)); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7172 const bool saved_mode = SetAllowFunctionLiterals(true); | 7188 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7173 const intptr_t value_pos = token_index_; | 7189 const intptr_t value_pos = token_index_; |
| 7174 AstNode* value = ParseExpr(is_const); | 7190 AstNode* value = ParseExpr(is_const); |
| 7175 SetAllowFunctionLiterals(saved_mode); | 7191 SetAllowFunctionLiterals(saved_mode); |
| 7176 if (FLAG_enable_type_checks && | 7192 if (FLAG_enable_type_checks && |
| 7177 !is_const && | 7193 !is_const && |
| 7178 !value_type.IsDynamicType()) { | 7194 !value_type.IsDynamicType()) { |
| 7179 // The expression needs to be type checked at runtime. | 7195 // The expression needs to be type checked at runtime. |
| 7180 // Eliminate the type check if it can be performed at compile time and | 7196 // Eliminate the type check if it can be performed at compile time and |
| 7181 // if it succeeds. | 7197 // if it succeeds. |
| 7198 Error& malformed_error = Error::Handle(); |
| 7182 if (!value_type.IsInstantiated() || | 7199 if (!value_type.IsInstantiated() || |
| 7183 !value->IsLiteralNode() || | 7200 !value->IsLiteralNode() || |
| 7184 !value->AsLiteralNode()->literal(). | 7201 !value->AsLiteralNode()->literal().IsAssignableTo( |
| 7185 IsAssignableTo(value_type, TypeArguments::Handle())) { | 7202 value_type, TypeArguments::Handle(), &malformed_error)) { |
| 7186 value = new AssignableNode(value_pos, | 7203 value = new AssignableNode(value_pos, |
| 7187 value, | 7204 value, |
| 7188 value_type, | 7205 value_type, |
| 7189 dst_name); | 7206 dst_name); |
| 7190 } | 7207 } |
| 7191 } | 7208 } |
| 7192 AddKeyValuePair(kv_pairs, is_const, key, value); | 7209 AddKeyValuePair(kv_pairs, is_const, key, value); |
| 7193 | 7210 |
| 7194 if (CurrentToken() == Token::kCOMMA) { | 7211 if (CurrentToken() == Token::kCOMMA) { |
| 7195 ConsumeToken(); | 7212 ConsumeToken(); |
| 7196 } else if (CurrentToken() != Token::kRBRACE) { | 7213 } else if (CurrentToken() != Token::kRBRACE) { |
| 7197 ErrorMsg("comma or '}' expected"); | 7214 ErrorMsg("comma or '}' expected"); |
| 7198 } | 7215 } |
| 7199 } | 7216 } |
| 7200 ASSERT(kv_pairs->length() % 2 == 0); | 7217 ASSERT(kv_pairs->length() % 2 == 0); |
| 7201 ExpectToken(Token::kRBRACE); | 7218 ExpectToken(Token::kRBRACE); |
| 7202 | 7219 |
| 7203 if (is_const) { | 7220 if (is_const) { |
| 7204 // Create the key-value pair array, canonicalize it and then create | 7221 // Create the key-value pair array, canonicalize it and then create |
| 7205 // the immutable map object with it. This all happens at compile time. | 7222 // the immutable map object with it. This all happens at compile time. |
| 7206 // The resulting immutable map object is returned as a literal. | 7223 // The resulting immutable map object is returned as a literal. |
| 7207 | 7224 |
| 7208 // First, create the canonicalized key-value pair array. | 7225 // First, create the canonicalized key-value pair array. |
| 7209 Array& key_value_array = | 7226 Array& key_value_array = |
| 7210 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); | 7227 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); |
| 7228 Error& malformed_error = Error::Handle(); |
| 7211 for (int i = 0; i < kv_pairs->length(); i++) { | 7229 for (int i = 0; i < kv_pairs->length(); i++) { |
| 7212 AstNode* arg = kv_pairs->ElementAt(i); | 7230 AstNode* arg = kv_pairs->ElementAt(i); |
| 7213 // Arguments have been evaluated to a literal value already. | 7231 // Arguments have been evaluated to a literal value already. |
| 7214 ASSERT(arg->IsLiteralNode()); | 7232 ASSERT(arg->IsLiteralNode()); |
| 7215 if (FLAG_enable_type_checks && | 7233 if (FLAG_enable_type_checks && |
| 7216 ((i % 2) == 1) && // Check values only, not keys. | 7234 ((i % 2) == 1) && // Check values only, not keys. |
| 7217 !value_type.IsDynamicType() && | 7235 !value_type.IsDynamicType() && |
| 7218 !arg->AsLiteralNode()->literal(). | 7236 !arg->AsLiteralNode()->literal().IsAssignableTo( |
| 7219 IsAssignableTo(value_type, TypeArguments::Handle())) { | 7237 value_type, TypeArguments::Handle(), &malformed_error)) { |
| 7220 ErrorMsg(arg->AsLiteralNode()->token_index(), | 7238 // If the failure is due to a malformed type error, display it instead. |
| 7221 "map literal value at index %d must be " | 7239 if (!malformed_error.IsNull()) { |
| 7222 "a constant of type '%s'", | 7240 ErrorMsg(malformed_error); |
| 7223 i >> 1, | 7241 } else { |
| 7224 String::Handle(value_type.Name()).ToCString()); | 7242 ErrorMsg(arg->AsLiteralNode()->token_index(), |
| 7243 "map literal value at index %d must be " |
| 7244 "a constant of type '%s'", |
| 7245 i >> 1, |
| 7246 String::Handle(value_type.Name()).ToCString()); |
| 7247 } |
| 7225 } | 7248 } |
| 7226 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 7249 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 7227 } | 7250 } |
| 7228 key_value_array ^= key_value_array.Canonicalize(); | 7251 key_value_array ^= key_value_array.Canonicalize(); |
| 7229 key_value_array.MakeImmutable(); | 7252 key_value_array.MakeImmutable(); |
| 7230 | 7253 |
| 7231 // Construct the map object. | 7254 // Construct the map object. |
| 7232 const String& immutable_map_class_name = | 7255 const String& immutable_map_class_name = |
| 7233 String::Handle(String::NewSymbol(kImmutableMapName)); | 7256 String::Handle(String::NewSymbol(kImmutableMapName)); |
| 7234 const Class& immutable_map_class = | 7257 const Class& immutable_map_class = |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7326 TRACE_PARSER("ParseNewOperator"); | 7349 TRACE_PARSER("ParseNewOperator"); |
| 7327 const intptr_t new_pos = token_index_; | 7350 const intptr_t new_pos = token_index_; |
| 7328 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7351 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7329 bool is_const = (CurrentToken() == Token::kCONST); | 7352 bool is_const = (CurrentToken() == Token::kCONST); |
| 7330 ConsumeToken(); | 7353 ConsumeToken(); |
| 7331 if (!IsIdentifier()) { | 7354 if (!IsIdentifier()) { |
| 7332 ErrorMsg("type name expected"); | 7355 ErrorMsg("type name expected"); |
| 7333 } | 7356 } |
| 7334 intptr_t type_pos = token_index_; | 7357 intptr_t type_pos = token_index_; |
| 7335 | 7358 |
| 7359 // TODO(regis): Bounds error should not result in a compile time error, |
| 7360 // but in a dynamic type error. Requesting kFinalizeWellFormed below is too |
| 7361 // strict. See co19 issue 96. |
| 7336 const AbstractType& type = AbstractType::Handle( | 7362 const AbstractType& type = AbstractType::Handle( |
| 7337 ParseType(ClassFinalizer::kFinalizeWellFormed)); | 7363 ParseType(ClassFinalizer::kFinalizeWellFormed)); |
| 7338 if (type.IsTypeParameter()) { | 7364 if (type.IsTypeParameter()) { |
| 7339 ErrorMsg(type_pos, | 7365 ErrorMsg(type_pos, |
| 7340 "type parameter '%s' cannot be instantiated", | 7366 "type parameter '%s' cannot be instantiated", |
| 7341 String::Handle(type.Name()).ToCString()); | 7367 String::Handle(type.Name()).ToCString()); |
| 7342 } | 7368 } |
| 7343 Class& type_class = Class::Handle(type.type_class()); | 7369 Class& type_class = Class::Handle(type.type_class()); |
| 7344 String& type_class_name = String::Handle(type_class.Name()); | 7370 String& type_class_name = String::Handle(type_class.Name()); |
| 7345 AbstractTypeArguments& type_arguments = | 7371 AbstractTypeArguments& type_arguments = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7403 if (!type_class.HasResolvedFactoryClass()) { | 7429 if (!type_class.HasResolvedFactoryClass()) { |
| 7404 // This error can occur only with bootstrap classes. | 7430 // This error can occur only with bootstrap classes. |
| 7405 const UnresolvedClass& unresolved = | 7431 const UnresolvedClass& unresolved = |
| 7406 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); | 7432 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); |
| 7407 const String& missing_class_name = String::Handle(unresolved.ident()); | 7433 const String& missing_class_name = String::Handle(unresolved.ident()); |
| 7408 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); | 7434 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); |
| 7409 } | 7435 } |
| 7410 // Only change the class of the constructor to the factory class if the | 7436 // Only change the class of the constructor to the factory class if the |
| 7411 // factory class implements the interface 'type'. | 7437 // factory class implements the interface 'type'. |
| 7412 const Class& factory_class = Class::Handle(type_class.FactoryClass()); | 7438 const Class& factory_class = Class::Handle(type_class.FactoryClass()); |
| 7439 Error& malformed_error = Error::Handle(); |
| 7413 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), | 7440 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), |
| 7414 type_class, | 7441 type_class, |
| 7415 TypeArguments::Handle())) { | 7442 TypeArguments::Handle(), |
| 7443 &malformed_error)) { |
| 7416 // Class finalization verifies that the factory class has identical type | 7444 // Class finalization verifies that the factory class has identical type |
| 7417 // parameters as the interface. | 7445 // parameters as the interface. |
| 7418 constructor_class_name = factory_class.Name(); | 7446 constructor_class_name = factory_class.Name(); |
| 7419 } | 7447 } |
| 7420 // Always change the result type of the constructor to the factory type. | 7448 // Always change the result type of the constructor to the factory type. |
| 7421 constructor_class = factory_class.raw(); | 7449 constructor_class = factory_class.raw(); |
| 7422 // The finalized type_arguments are still those of the interface type. | 7450 // The finalized type_arguments are still those of the interface type. |
| 7423 ASSERT(!constructor_class.is_interface()); | 7451 ASSERT(!constructor_class.is_interface()); |
| 7424 } | 7452 } |
| 7425 | 7453 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7509 } | 7537 } |
| 7510 } else { | 7538 } else { |
| 7511 CheckFunctionIsCallable(new_pos, constructor); | 7539 CheckFunctionIsCallable(new_pos, constructor); |
| 7512 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7540 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 7513 if (!type_arguments.IsNull() && | 7541 if (!type_arguments.IsNull() && |
| 7514 !type_arguments.IsInstantiated() && | 7542 !type_arguments.IsInstantiated() && |
| 7515 (current_block_->scope->function_level() > 0)) { | 7543 (current_block_->scope->function_level() > 0)) { |
| 7516 // Make sure that the instantiator is captured. | 7544 // Make sure that the instantiator is captured. |
| 7517 CaptureReceiver(); | 7545 CaptureReceiver(); |
| 7518 } | 7546 } |
| 7547 // TODO(regis): If the type argument vector is not instantiated, we need to |
| 7548 // verify in checked mode at runtime that it is within its declared bounds. |
| 7519 new_object = new ConstructorCallNode( | 7549 new_object = new ConstructorCallNode( |
| 7520 new_pos, type_arguments, constructor, arguments); | 7550 new_pos, type_arguments, constructor, arguments); |
| 7521 } | 7551 } |
| 7522 return new_object; | 7552 return new_object; |
| 7523 } | 7553 } |
| 7524 | 7554 |
| 7525 | 7555 |
| 7526 String& Parser::Interpolate(ArrayNode* values) { | 7556 String& Parser::Interpolate(ArrayNode* values) { |
| 7527 const String& class_name = | 7557 const String& class_name = |
| 7528 String::Handle(String::NewSymbol(kStringClassName)); | 7558 String::Handle(String::NewSymbol(kStringClassName)); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8089 void Parser::SkipQualIdent() { | 8119 void Parser::SkipQualIdent() { |
| 8090 ASSERT(IsIdentifier()); | 8120 ASSERT(IsIdentifier()); |
| 8091 ConsumeToken(); | 8121 ConsumeToken(); |
| 8092 if (CurrentToken() == Token::kPERIOD) { | 8122 if (CurrentToken() == Token::kPERIOD) { |
| 8093 ConsumeToken(); // Consume the kPERIOD token. | 8123 ConsumeToken(); // Consume the kPERIOD token. |
| 8094 ExpectIdentifier("identifier expected after '.'"); | 8124 ExpectIdentifier("identifier expected after '.'"); |
| 8095 } | 8125 } |
| 8096 } | 8126 } |
| 8097 | 8127 |
| 8098 } // namespace dart | 8128 } // namespace dart |
| OLD | NEW |