| 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 5355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5366 va_list args; | 5366 va_list args; |
| 5367 va_start(args, format); | 5367 va_start(args, format); |
| 5368 const Error& error = Error::Handle( | 5368 const Error& error = Error::Handle( |
| 5369 FormatError(script_, token_index_, "Error", format, args)); | 5369 FormatError(script_, token_index_, "Error", format, args)); |
| 5370 va_end(args); | 5370 va_end(args); |
| 5371 Isolate::Current()->long_jump_base()->Jump(1, error); | 5371 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5372 UNREACHABLE(); | 5372 UNREACHABLE(); |
| 5373 } | 5373 } |
| 5374 | 5374 |
| 5375 | 5375 |
| 5376 void Parser::ErrorMsg(const Error& error) { |
| 5377 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5378 UNREACHABLE(); |
| 5379 } |
| 5380 |
| 5381 |
| 5376 void Parser::AppendErrorMsg( | 5382 void Parser::AppendErrorMsg( |
| 5377 const Error& prev_error, intptr_t token_index, const char* format, ...) { | 5383 const Error& prev_error, intptr_t token_index, const char* format, ...) { |
| 5378 va_list args; | 5384 va_list args; |
| 5379 va_start(args, format); | 5385 va_start(args, format); |
| 5380 const Error& error = Error::Handle(FormatErrorWithAppend( | 5386 const Error& error = Error::Handle(FormatErrorWithAppend( |
| 5381 prev_error, script_, token_index, "Error", format, args)); | 5387 prev_error, script_, token_index, "Error", format, args)); |
| 5382 va_end(args); | 5388 va_end(args); |
| 5383 Isolate::Current()->long_jump_base()->Jump(1, error); | 5389 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5384 UNREACHABLE(); | 5390 UNREACHABLE(); |
| 5385 } | 5391 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5546 const intptr_t type_pos = token_index_; | 5552 const intptr_t type_pos = token_index_; |
| 5547 const AbstractType& type = | 5553 const AbstractType& type = |
| 5548 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); | 5554 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); |
| 5549 if (!type.IsInstantiated() && | 5555 if (!type.IsInstantiated() && |
| 5550 (current_block_->scope->function_level() > 0)) { | 5556 (current_block_->scope->function_level() > 0)) { |
| 5551 // Make sure that the instantiator is captured. | 5557 // Make sure that the instantiator is captured. |
| 5552 CaptureReceiver(); | 5558 CaptureReceiver(); |
| 5553 } | 5559 } |
| 5554 right_operand = new TypeNode(type_pos, type); | 5560 right_operand = new TypeNode(type_pos, type); |
| 5555 if (type.IsMalformed()) { | 5561 if (type.IsMalformed()) { |
| 5562 // Note that a type error is thrown even if the tested value is null. |
| 5556 return ThrowTypeError(type_pos, type); | 5563 return ThrowTypeError(type_pos, type); |
| 5557 } | 5564 } |
| 5558 } | 5565 } |
| 5559 if (Token::IsRelationalOperator(op_kind) | 5566 if (Token::IsRelationalOperator(op_kind) |
| 5560 || Token::IsInstanceofOperator(op_kind) | 5567 || Token::IsInstanceofOperator(op_kind) |
| 5561 || Token::IsEqualityOperator(op_kind)) { | 5568 || Token::IsEqualityOperator(op_kind)) { |
| 5562 left_operand = new ComparisonNode( | 5569 left_operand = new ComparisonNode( |
| 5563 op_pos, op_kind, left_operand, right_operand); | 5570 op_pos, op_kind, left_operand, right_operand); |
| 5564 break; // Equality and relational operators cannot be chained. | 5571 break; // Equality and relational operators cannot be chained. |
| 5565 } else { | 5572 } else { |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6386 // At this point, we can only have a parameterized_type. | 6393 // At this point, we can only have a parameterized_type. |
| 6387 Type& parameterized_type = Type::Handle(); | 6394 Type& parameterized_type = Type::Handle(); |
| 6388 parameterized_type ^= type->raw(); | 6395 parameterized_type ^= type->raw(); |
| 6389 if (!resolved_type_class.IsNull()) { | 6396 if (!resolved_type_class.IsNull()) { |
| 6390 Object& type_class = Object::Handle(resolved_type_class.raw()); | 6397 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 6391 // Replace unresolved class with resolved type class. | 6398 // Replace unresolved class with resolved type class. |
| 6392 parameterized_type.set_type_class(type_class); | 6399 parameterized_type.set_type_class(type_class); |
| 6393 } else if (finalization >= ClassFinalizer::kFinalize) { | 6400 } else if (finalization >= ClassFinalizer::kFinalize) { |
| 6394 // The type is malformed. | 6401 // The type is malformed. |
| 6395 ClassFinalizer::FinalizeMalformedType( | 6402 ClassFinalizer::FinalizeMalformedType( |
| 6403 Error::Handle(), // No previous error. |
| 6396 current_class(), parameterized_type, finalization, | 6404 current_class(), parameterized_type, finalization, |
| 6397 "type '%s' is not loaded", | 6405 "type '%s' is not loaded", |
| 6398 String::Handle(parameterized_type.Name()).ToCString()); | 6406 String::Handle(parameterized_type.Name()).ToCString()); |
| 6399 } | 6407 } |
| 6400 } | 6408 } |
| 6401 // Resolve type arguments, if any. | 6409 // Resolve type arguments, if any. |
| 6402 const AbstractTypeArguments& arguments = | 6410 const AbstractTypeArguments& arguments = |
| 6403 AbstractTypeArguments::Handle(type->arguments()); | 6411 AbstractTypeArguments::Handle(type->arguments()); |
| 6404 if (!arguments.IsNull()) { | 6412 if (!arguments.IsNull()) { |
| 6405 const intptr_t num_arguments = arguments.Length(); | 6413 const intptr_t num_arguments = arguments.Length(); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6960 String::NewSymbol("list literal element")); | 6968 String::NewSymbol("list literal element")); |
| 6961 while (CurrentToken() != Token::kRBRACK) { | 6969 while (CurrentToken() != Token::kRBRACK) { |
| 6962 const intptr_t element_pos = token_index_; | 6970 const intptr_t element_pos = token_index_; |
| 6963 AstNode* element = ParseExpr(is_const); | 6971 AstNode* element = ParseExpr(is_const); |
| 6964 if (FLAG_enable_type_checks && | 6972 if (FLAG_enable_type_checks && |
| 6965 !is_const && | 6973 !is_const && |
| 6966 !element_type.IsDynamicType()) { | 6974 !element_type.IsDynamicType()) { |
| 6967 // The expression needs to be type checked at runtime. | 6975 // The expression needs to be type checked at runtime. |
| 6968 // Eliminate the type check if it can be performed at compile time and | 6976 // Eliminate the type check if it can be performed at compile time and |
| 6969 // if it succeeds. | 6977 // if it succeeds. |
| 6978 Error& malformed_error = Error::Handle(); |
| 6970 if (!element_type.IsInstantiated() || | 6979 if (!element_type.IsInstantiated() || |
| 6971 !element->IsLiteralNode() || | 6980 !element->IsLiteralNode() || |
| 6972 !element->AsLiteralNode()->literal(). | 6981 !element->AsLiteralNode()->literal(). |
| 6973 IsAssignableTo(element_type, TypeArguments::Handle())) { | 6982 IsAssignableTo(element_type, |
| 6983 TypeArguments::Handle(), |
| 6984 &malformed_error)) { |
| 6974 element = new AssignableNode(element_pos, | 6985 element = new AssignableNode(element_pos, |
| 6975 element, | 6986 element, |
| 6976 element_type, | 6987 element_type, |
| 6977 dst_name); | 6988 dst_name); |
| 6978 } | 6989 } |
| 6979 } | 6990 } |
| 6980 list->AddElement(element); | 6991 list->AddElement(element); |
| 6981 if (CurrentToken() == Token::kCOMMA) { | 6992 if (CurrentToken() == Token::kCOMMA) { |
| 6982 ConsumeToken(); | 6993 ConsumeToken(); |
| 6983 } else if (CurrentToken() != Token::kRBRACK) { | 6994 } else if (CurrentToken() != Token::kRBRACK) { |
| 6984 ErrorMsg("comma or ']' expected"); | 6995 ErrorMsg("comma or ']' expected"); |
| 6985 } | 6996 } |
| 6986 } | 6997 } |
| 6987 ExpectToken(Token::kRBRACK); | 6998 ExpectToken(Token::kRBRACK); |
| 6988 SetAllowFunctionLiterals(saved_mode); | 6999 SetAllowFunctionLiterals(saved_mode); |
| 6989 } | 7000 } |
| 6990 | 7001 |
| 6991 if (is_const) { | 7002 if (is_const) { |
| 6992 // Allocate and initialize the const list at compile time. | 7003 // Allocate and initialize the const list at compile time. |
| 6993 Array& const_list = | 7004 Array& const_list = |
| 6994 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); | 7005 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); |
| 6995 const_list.SetTypeArguments(type_arguments); | 7006 const_list.SetTypeArguments(type_arguments); |
| 6996 | 7007 Error& malformed_error = Error::Handle(); |
| 6997 for (int i = 0; i < list->length(); i++) { | 7008 for (int i = 0; i < list->length(); i++) { |
| 6998 AstNode* elem = list->ElementAt(i); | 7009 AstNode* elem = list->ElementAt(i); |
| 6999 // Arguments have been evaluated to a literal value already. | 7010 // Arguments have been evaluated to a literal value already. |
| 7000 ASSERT(elem->IsLiteralNode()); | 7011 ASSERT(elem->IsLiteralNode()); |
| 7001 if (FLAG_enable_type_checks && | 7012 if (FLAG_enable_type_checks && |
| 7002 !element_type.IsDynamicType() && | 7013 !element_type.IsDynamicType() && |
| 7003 !elem->AsLiteralNode()->literal(). | 7014 !elem->AsLiteralNode()->literal().IsAssignableTo( |
| 7004 IsAssignableTo(element_type, TypeArguments::Handle())) { | 7015 element_type, TypeArguments::Handle(), &malformed_error)) { |
| 7005 ErrorMsg(elem->AsLiteralNode()->token_index(), | 7016 // If the failure is due to a malformed type error, display it instead. |
| 7006 "list literal element at index %d must be " | 7017 if (!malformed_error.IsNull()) { |
| 7007 "a constant of type '%s'", | 7018 ErrorMsg(malformed_error); |
| 7008 i, | 7019 } else { |
| 7009 String::Handle(element_type.Name()).ToCString()); | 7020 ErrorMsg(elem->AsLiteralNode()->token_index(), |
| 7021 "list literal element at index %d must be " |
| 7022 "a constant of type '%s'", |
| 7023 i, |
| 7024 String::Handle(element_type.Name()).ToCString()); |
| 7025 } |
| 7010 } | 7026 } |
| 7011 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 7027 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 7012 } | 7028 } |
| 7013 const_list ^= const_list.Canonicalize(); | 7029 const_list ^= const_list.Canonicalize(); |
| 7014 const_list.MakeImmutable(); | 7030 const_list.MakeImmutable(); |
| 7015 return new LiteralNode(literal_pos, const_list); | 7031 return new LiteralNode(literal_pos, const_list); |
| 7016 } else { | 7032 } else { |
| 7017 // Factory call at runtime. | 7033 // Factory call at runtime. |
| 7018 String& list_literal_factory_class_name = String::Handle( | 7034 String& list_literal_factory_class_name = String::Handle( |
| 7019 String::NewSymbol(kListLiteralFactoryClassName)); | 7035 String::NewSymbol(kListLiteralFactoryClassName)); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7137 const bool saved_mode = SetAllowFunctionLiterals(true); | 7153 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7138 const intptr_t value_pos = token_index_; | 7154 const intptr_t value_pos = token_index_; |
| 7139 AstNode* value = ParseExpr(is_const); | 7155 AstNode* value = ParseExpr(is_const); |
| 7140 SetAllowFunctionLiterals(saved_mode); | 7156 SetAllowFunctionLiterals(saved_mode); |
| 7141 if (FLAG_enable_type_checks && | 7157 if (FLAG_enable_type_checks && |
| 7142 !is_const && | 7158 !is_const && |
| 7143 !value_type.IsDynamicType()) { | 7159 !value_type.IsDynamicType()) { |
| 7144 // The expression needs to be type checked at runtime. | 7160 // The expression needs to be type checked at runtime. |
| 7145 // Eliminate the type check if it can be performed at compile time and | 7161 // Eliminate the type check if it can be performed at compile time and |
| 7146 // if it succeeds. | 7162 // if it succeeds. |
| 7163 Error& malformed_error = Error::Handle(); |
| 7147 if (!value_type.IsInstantiated() || | 7164 if (!value_type.IsInstantiated() || |
| 7148 !value->IsLiteralNode() || | 7165 !value->IsLiteralNode() || |
| 7149 !value->AsLiteralNode()->literal(). | 7166 !value->AsLiteralNode()->literal().IsAssignableTo( |
| 7150 IsAssignableTo(value_type, TypeArguments::Handle())) { | 7167 value_type, TypeArguments::Handle(), &malformed_error)) { |
| 7151 value = new AssignableNode(value_pos, | 7168 value = new AssignableNode(value_pos, |
| 7152 value, | 7169 value, |
| 7153 value_type, | 7170 value_type, |
| 7154 dst_name); | 7171 dst_name); |
| 7155 } | 7172 } |
| 7156 } | 7173 } |
| 7157 AddKeyValuePair(kv_pairs, is_const, key, value); | 7174 AddKeyValuePair(kv_pairs, is_const, key, value); |
| 7158 | 7175 |
| 7159 if (CurrentToken() == Token::kCOMMA) { | 7176 if (CurrentToken() == Token::kCOMMA) { |
| 7160 ConsumeToken(); | 7177 ConsumeToken(); |
| 7161 } else if (CurrentToken() != Token::kRBRACE) { | 7178 } else if (CurrentToken() != Token::kRBRACE) { |
| 7162 ErrorMsg("comma or '}' expected"); | 7179 ErrorMsg("comma or '}' expected"); |
| 7163 } | 7180 } |
| 7164 } | 7181 } |
| 7165 ASSERT(kv_pairs->length() % 2 == 0); | 7182 ASSERT(kv_pairs->length() % 2 == 0); |
| 7166 ExpectToken(Token::kRBRACE); | 7183 ExpectToken(Token::kRBRACE); |
| 7167 | 7184 |
| 7168 if (is_const) { | 7185 if (is_const) { |
| 7169 // Create the key-value pair array, canonicalize it and then create | 7186 // Create the key-value pair array, canonicalize it and then create |
| 7170 // the immutable map object with it. This all happens at compile time. | 7187 // the immutable map object with it. This all happens at compile time. |
| 7171 // The resulting immutable map object is returned as a literal. | 7188 // The resulting immutable map object is returned as a literal. |
| 7172 | 7189 |
| 7173 // First, create the canonicalized key-value pair array. | 7190 // First, create the canonicalized key-value pair array. |
| 7174 Array& key_value_array = | 7191 Array& key_value_array = |
| 7175 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); | 7192 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); |
| 7193 Error& malformed_error = Error::Handle(); |
| 7176 for (int i = 0; i < kv_pairs->length(); i++) { | 7194 for (int i = 0; i < kv_pairs->length(); i++) { |
| 7177 AstNode* arg = kv_pairs->ElementAt(i); | 7195 AstNode* arg = kv_pairs->ElementAt(i); |
| 7178 // Arguments have been evaluated to a literal value already. | 7196 // Arguments have been evaluated to a literal value already. |
| 7179 ASSERT(arg->IsLiteralNode()); | 7197 ASSERT(arg->IsLiteralNode()); |
| 7180 if (FLAG_enable_type_checks && | 7198 if (FLAG_enable_type_checks && |
| 7181 ((i % 2) == 1) && // Check values only, not keys. | 7199 ((i % 2) == 1) && // Check values only, not keys. |
| 7182 !value_type.IsDynamicType() && | 7200 !value_type.IsDynamicType() && |
| 7183 !arg->AsLiteralNode()->literal(). | 7201 !arg->AsLiteralNode()->literal().IsAssignableTo( |
| 7184 IsAssignableTo(value_type, TypeArguments::Handle())) { | 7202 value_type, TypeArguments::Handle(), &malformed_error)) { |
| 7185 ErrorMsg(arg->AsLiteralNode()->token_index(), | 7203 // If the failure is due to a malformed type error, display it instead. |
| 7186 "map literal value at index %d must be " | 7204 if (!malformed_error.IsNull()) { |
| 7187 "a constant of type '%s'", | 7205 ErrorMsg(malformed_error); |
| 7188 i >> 1, | 7206 } else { |
| 7189 String::Handle(value_type.Name()).ToCString()); | 7207 ErrorMsg(arg->AsLiteralNode()->token_index(), |
| 7208 "map literal value at index %d must be " |
| 7209 "a constant of type '%s'", |
| 7210 i >> 1, |
| 7211 String::Handle(value_type.Name()).ToCString()); |
| 7212 } |
| 7190 } | 7213 } |
| 7191 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 7214 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 7192 } | 7215 } |
| 7193 key_value_array ^= key_value_array.Canonicalize(); | 7216 key_value_array ^= key_value_array.Canonicalize(); |
| 7194 key_value_array.MakeImmutable(); | 7217 key_value_array.MakeImmutable(); |
| 7195 | 7218 |
| 7196 // Construct the map object. | 7219 // Construct the map object. |
| 7197 const String& immutable_map_class_name = | 7220 const String& immutable_map_class_name = |
| 7198 String::Handle(String::NewSymbol(kImmutableMapName)); | 7221 String::Handle(String::NewSymbol(kImmutableMapName)); |
| 7199 const Class& immutable_map_class = | 7222 const Class& immutable_map_class = |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7291 TRACE_PARSER("ParseNewOperator"); | 7314 TRACE_PARSER("ParseNewOperator"); |
| 7292 const intptr_t new_pos = token_index_; | 7315 const intptr_t new_pos = token_index_; |
| 7293 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7316 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7294 bool is_const = (CurrentToken() == Token::kCONST); | 7317 bool is_const = (CurrentToken() == Token::kCONST); |
| 7295 ConsumeToken(); | 7318 ConsumeToken(); |
| 7296 if (!IsIdentifier()) { | 7319 if (!IsIdentifier()) { |
| 7297 ErrorMsg("type name expected"); | 7320 ErrorMsg("type name expected"); |
| 7298 } | 7321 } |
| 7299 intptr_t type_pos = token_index_; | 7322 intptr_t type_pos = token_index_; |
| 7300 | 7323 |
| 7324 // TODO(regis): Bounds error should not result in a compile time error, |
| 7325 // but in a dynamic type error. Requesting kFinalizeWellFormed below is too |
| 7326 // strict. See co19 issue 96. |
| 7301 const AbstractType& type = AbstractType::Handle( | 7327 const AbstractType& type = AbstractType::Handle( |
| 7302 ParseType(ClassFinalizer::kFinalizeWellFormed)); | 7328 ParseType(ClassFinalizer::kFinalizeWellFormed)); |
| 7303 if (type.IsTypeParameter()) { | 7329 if (type.IsTypeParameter()) { |
| 7304 ErrorMsg(type_pos, | 7330 ErrorMsg(type_pos, |
| 7305 "type parameter '%s' cannot be instantiated", | 7331 "type parameter '%s' cannot be instantiated", |
| 7306 String::Handle(type.Name()).ToCString()); | 7332 String::Handle(type.Name()).ToCString()); |
| 7307 } | 7333 } |
| 7308 Class& type_class = Class::Handle(type.type_class()); | 7334 Class& type_class = Class::Handle(type.type_class()); |
| 7309 String& type_class_name = String::Handle(type_class.Name()); | 7335 String& type_class_name = String::Handle(type_class.Name()); |
| 7310 AbstractTypeArguments& type_arguments = | 7336 AbstractTypeArguments& type_arguments = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7368 if (!type_class.HasResolvedFactoryClass()) { | 7394 if (!type_class.HasResolvedFactoryClass()) { |
| 7369 // This error can occur only with bootstrap classes. | 7395 // This error can occur only with bootstrap classes. |
| 7370 const UnresolvedClass& unresolved = | 7396 const UnresolvedClass& unresolved = |
| 7371 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); | 7397 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); |
| 7372 const String& missing_class_name = String::Handle(unresolved.ident()); | 7398 const String& missing_class_name = String::Handle(unresolved.ident()); |
| 7373 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); | 7399 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); |
| 7374 } | 7400 } |
| 7375 // Only change the class of the constructor to the factory class if the | 7401 // Only change the class of the constructor to the factory class if the |
| 7376 // factory class implements the interface 'type'. | 7402 // factory class implements the interface 'type'. |
| 7377 const Class& factory_class = Class::Handle(type_class.FactoryClass()); | 7403 const Class& factory_class = Class::Handle(type_class.FactoryClass()); |
| 7404 Error& malformed_error = Error::Handle(); |
| 7378 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), | 7405 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), |
| 7379 type_class, | 7406 type_class, |
| 7380 TypeArguments::Handle())) { | 7407 TypeArguments::Handle(), |
| 7408 &malformed_error)) { |
| 7381 // Class finalization verifies that the factory class has identical type | 7409 // Class finalization verifies that the factory class has identical type |
| 7382 // parameters as the interface. | 7410 // parameters as the interface. |
| 7383 constructor_class_name = factory_class.Name(); | 7411 constructor_class_name = factory_class.Name(); |
| 7384 } | 7412 } |
| 7385 // Always change the result type of the constructor to the factory type. | 7413 // Always change the result type of the constructor to the factory type. |
| 7386 constructor_class = factory_class.raw(); | 7414 constructor_class = factory_class.raw(); |
| 7387 // The finalized type_arguments are still those of the interface type. | 7415 // The finalized type_arguments are still those of the interface type. |
| 7388 ASSERT(!constructor_class.is_interface()); | 7416 ASSERT(!constructor_class.is_interface()); |
| 7389 } | 7417 } |
| 7390 | 7418 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7474 } | 7502 } |
| 7475 } else { | 7503 } else { |
| 7476 CheckFunctionIsCallable(new_pos, constructor); | 7504 CheckFunctionIsCallable(new_pos, constructor); |
| 7477 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7505 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 7478 if (!type_arguments.IsNull() && | 7506 if (!type_arguments.IsNull() && |
| 7479 !type_arguments.IsInstantiated() && | 7507 !type_arguments.IsInstantiated() && |
| 7480 (current_block_->scope->function_level() > 0)) { | 7508 (current_block_->scope->function_level() > 0)) { |
| 7481 // Make sure that the instantiator is captured. | 7509 // Make sure that the instantiator is captured. |
| 7482 CaptureReceiver(); | 7510 CaptureReceiver(); |
| 7483 } | 7511 } |
| 7512 // TODO(regis): If the type argument vector is not instantiated, we need to |
| 7513 // verify in checked mode at runtime that it is within its declared bounds. |
| 7484 new_object = new ConstructorCallNode( | 7514 new_object = new ConstructorCallNode( |
| 7485 new_pos, type_arguments, constructor, arguments); | 7515 new_pos, type_arguments, constructor, arguments); |
| 7486 } | 7516 } |
| 7487 return new_object; | 7517 return new_object; |
| 7488 } | 7518 } |
| 7489 | 7519 |
| 7490 | 7520 |
| 7491 String& Parser::Interpolate(ArrayNode* values) { | 7521 String& Parser::Interpolate(ArrayNode* values) { |
| 7492 const String& class_name = | 7522 const String& class_name = |
| 7493 String::Handle(String::NewSymbol(kStringClassName)); | 7523 String::Handle(String::NewSymbol(kStringClassName)); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8054 void Parser::SkipQualIdent() { | 8084 void Parser::SkipQualIdent() { |
| 8055 ASSERT(IsIdentifier()); | 8085 ASSERT(IsIdentifier()); |
| 8056 ConsumeToken(); | 8086 ConsumeToken(); |
| 8057 if (CurrentToken() == Token::kPERIOD) { | 8087 if (CurrentToken() == Token::kPERIOD) { |
| 8058 ConsumeToken(); // Consume the kPERIOD token. | 8088 ConsumeToken(); // Consume the kPERIOD token. |
| 8059 ExpectIdentifier("identifier expected after '.'"); | 8089 ExpectIdentifier("identifier expected after '.'"); |
| 8060 } | 8090 } |
| 8061 } | 8091 } |
| 8062 | 8092 |
| 8063 } // namespace dart | 8093 } // namespace dart |
| OLD | NEW |