| 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 9061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9072 AstNode* Parser::ParseNewOperator() { | 9072 AstNode* Parser::ParseNewOperator() { |
| 9073 TRACE_PARSER("ParseNewOperator"); | 9073 TRACE_PARSER("ParseNewOperator"); |
| 9074 const intptr_t new_pos = TokenPos(); | 9074 const intptr_t new_pos = TokenPos(); |
| 9075 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 9075 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 9076 bool is_const = (CurrentToken() == Token::kCONST); | 9076 bool is_const = (CurrentToken() == Token::kCONST); |
| 9077 ConsumeToken(); | 9077 ConsumeToken(); |
| 9078 if (!IsIdentifier()) { | 9078 if (!IsIdentifier()) { |
| 9079 ErrorMsg("type name expected"); | 9079 ErrorMsg("type name expected"); |
| 9080 } | 9080 } |
| 9081 intptr_t type_pos = TokenPos(); | 9081 intptr_t type_pos = TokenPos(); |
| 9082 AbstractType& type = AbstractType::ZoneHandle( | 9082 AbstractType& type = AbstractType::Handle( |
| 9083 ParseType(ClassFinalizer::kCanonicalizeForCreation)); | 9083 ParseType(ClassFinalizer::kCanonicalizeForCreation)); |
| 9084 // In case the type is malformed, throw a dynamic type error after finishing | 9084 // In case the type is malformed, throw a dynamic type error after finishing |
| 9085 // parsing the instance creation expression. | 9085 // parsing the instance creation expression. |
| 9086 if (type.IsTypeParameter() || type.IsDynamicType()) { | 9086 if (type.IsTypeParameter() || type.IsDynamicType()) { |
| 9087 ASSERT(!type.IsMalformed()); | 9087 ASSERT(!type.IsMalformed()); |
| 9088 // Replace the type with a malformed type. | 9088 // Replace the type with a malformed type. |
| 9089 type = ClassFinalizer::NewFinalizedMalformedType( | 9089 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9090 Error::Handle(), // No previous error. | 9090 Error::Handle(), // No previous error. |
| 9091 current_class(), | 9091 current_class(), |
| 9092 type_pos, | 9092 type_pos, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9206 constructor_class_name = factory_class.Name(); | 9206 constructor_class_name = factory_class.Name(); |
| 9207 } | 9207 } |
| 9208 // Always change the result type of the constructor to the factory type. | 9208 // Always change the result type of the constructor to the factory type. |
| 9209 constructor_class = factory_class.raw(); | 9209 constructor_class = factory_class.raw(); |
| 9210 // The finalized type_arguments are still those of the interface type. | 9210 // The finalized type_arguments are still those of the interface type. |
| 9211 ASSERT(!constructor_class.is_interface()); | 9211 ASSERT(!constructor_class.is_interface()); |
| 9212 } | 9212 } |
| 9213 | 9213 |
| 9214 // An additional type check of the result of a redirecting factory may be | 9214 // An additional type check of the result of a redirecting factory may be |
| 9215 // required. | 9215 // required. |
| 9216 bool check_result_type = false; | 9216 AbstractType& type_bound = AbstractType::ZoneHandle(); |
| 9217 | 9217 |
| 9218 // Make sure that an appropriate constructor exists. | 9218 // Make sure that an appropriate constructor exists. |
| 9219 const String& constructor_name = | 9219 const String& constructor_name = |
| 9220 BuildConstructorName(constructor_class_name, named_constructor); | 9220 BuildConstructorName(constructor_class_name, named_constructor); |
| 9221 Function& constructor = Function::ZoneHandle( | 9221 Function& constructor = Function::ZoneHandle( |
| 9222 constructor_class.LookupConstructor(constructor_name)); | 9222 constructor_class.LookupConstructor(constructor_name)); |
| 9223 if (constructor.IsNull()) { | 9223 if (constructor.IsNull()) { |
| 9224 constructor = constructor_class.LookupFactory(constructor_name); | 9224 constructor = constructor_class.LookupFactory(constructor_name); |
| 9225 if (constructor.IsNull()) { | 9225 if (constructor.IsNull()) { |
| 9226 const String& external_constructor_name = | 9226 const String& external_constructor_name = |
| (...skipping 20 matching lines...) Expand all Loading... |
| 9247 // type arguments of the parsed type of the 'new' or 'const' expression. | 9247 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 9248 redirect_type ^= redirect_type.InstantiateFrom(type_arguments); | 9248 redirect_type ^= redirect_type.InstantiateFrom(type_arguments); |
| 9249 } | 9249 } |
| 9250 if (redirect_type.IsMalformed()) { | 9250 if (redirect_type.IsMalformed()) { |
| 9251 if (is_const) { | 9251 if (is_const) { |
| 9252 const Error& error = Error::Handle(redirect_type.malformed_error()); | 9252 const Error& error = Error::Handle(redirect_type.malformed_error()); |
| 9253 ErrorMsg(error); | 9253 ErrorMsg(error); |
| 9254 } | 9254 } |
| 9255 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 9255 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 9256 } | 9256 } |
| 9257 check_result_type = | 9257 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 9258 FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL); | 9258 // Additional type checking of the result is necessary. |
| 9259 type_bound = type.raw(); |
| 9260 } |
| 9259 type = redirect_type.raw(); | 9261 type = redirect_type.raw(); |
| 9260 type_class = type.type_class(); | 9262 type_class = type.type_class(); |
| 9261 type_arguments = type.arguments(); | 9263 type_arguments = type.arguments(); |
| 9262 constructor = constructor.RedirectionTarget(); | 9264 constructor = constructor.RedirectionTarget(); |
| 9263 ASSERT(!constructor.IsNull()); | 9265 ASSERT(!constructor.IsNull()); |
| 9264 constructor_class = constructor.Owner(); | 9266 constructor_class = constructor.Owner(); |
| 9265 ASSERT(type_class.raw() == constructor_class.raw()); | 9267 ASSERT(type_class.raw() == constructor_class.raw()); |
| 9266 } | 9268 } |
| 9267 if (constructor.IsFactory()) { | 9269 if (constructor.IsFactory()) { |
| 9268 // A factory does not have the implicit 'phase' parameter. | 9270 // A factory does not have the implicit 'phase' parameter. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9364 EvaluateConstConstructorCall(constructor_class, | 9366 EvaluateConstConstructorCall(constructor_class, |
| 9365 type_arguments, | 9367 type_arguments, |
| 9366 constructor, | 9368 constructor, |
| 9367 arguments)); | 9369 arguments)); |
| 9368 if (constructor_result.IsUnhandledException()) { | 9370 if (constructor_result.IsUnhandledException()) { |
| 9369 new_object = GenerateRethrow(new_pos, constructor_result); | 9371 new_object = GenerateRethrow(new_pos, constructor_result); |
| 9370 } else { | 9372 } else { |
| 9371 const Instance& const_instance = Instance::Cast(constructor_result); | 9373 const Instance& const_instance = Instance::Cast(constructor_result); |
| 9372 new_object = new LiteralNode(new_pos, | 9374 new_object = new LiteralNode(new_pos, |
| 9373 Instance::ZoneHandle(const_instance.raw())); | 9375 Instance::ZoneHandle(const_instance.raw())); |
| 9374 if (check_result_type) { | 9376 if (!type_bound.IsNull()) { |
| 9375 ASSERT(!type.IsMalformed()); | 9377 ASSERT(!type_bound.IsMalformed()); |
| 9376 Error& malformed_error = Error::Handle(); | 9378 Error& malformed_error = Error::Handle(); |
| 9377 if (!const_instance.IsInstanceOf(type, | 9379 if (!const_instance.IsInstanceOf(type_bound, |
| 9378 TypeArguments::Handle(), | 9380 TypeArguments::Handle(), |
| 9379 &malformed_error)) { | 9381 &malformed_error)) { |
| 9380 type = ClassFinalizer::NewFinalizedMalformedType( | 9382 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 9381 malformed_error, | 9383 malformed_error, |
| 9382 current_class(), | 9384 current_class(), |
| 9383 new_pos, | 9385 new_pos, |
| 9384 ClassFinalizer::kTryResolve, // No compile-time error. | 9386 ClassFinalizer::kTryResolve, // No compile-time error. |
| 9385 "const factory result is not an instance of '%s'", | 9387 "const factory result is not an instance of '%s'", |
| 9386 String::Handle(type.UserVisibleName()).ToCString()); | 9388 String::Handle(type_bound.UserVisibleName()).ToCString()); |
| 9387 new_object = ThrowTypeError(new_pos, type); | 9389 new_object = ThrowTypeError(new_pos, type_bound); |
| 9388 } | 9390 } |
| 9389 check_result_type = false; | 9391 type_bound = AbstractType::null(); |
| 9390 } | 9392 } |
| 9391 } | 9393 } |
| 9392 } else { | 9394 } else { |
| 9393 CheckFunctionIsCallable(new_pos, constructor); | 9395 CheckFunctionIsCallable(new_pos, constructor); |
| 9394 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 9396 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 9395 if (!type_arguments.IsNull() && | 9397 if (!type_arguments.IsNull() && |
| 9396 !type_arguments.IsInstantiated() && | 9398 !type_arguments.IsInstantiated() && |
| 9397 (current_block_->scope->function_level() > 0)) { | 9399 (current_block_->scope->function_level() > 0)) { |
| 9398 // Make sure that the instantiator is captured. | 9400 // Make sure that the instantiator is captured. |
| 9399 CaptureInstantiator(); | 9401 CaptureInstantiator(); |
| 9400 } | 9402 } |
| 9401 // If the type argument vector is not instantiated, we verify in checked | 9403 // If the type argument vector is not instantiated, we verify in checked |
| 9402 // mode at runtime that it is within its declared bounds. | 9404 // mode at runtime that it is within its declared bounds. |
| 9403 new_object = CreateConstructorCallNode( | 9405 new_object = CreateConstructorCallNode( |
| 9404 new_pos, type_arguments, constructor, arguments); | 9406 new_pos, type_arguments, constructor, arguments); |
| 9405 } | 9407 } |
| 9406 if (check_result_type) { | 9408 if (!type_bound.IsNull()) { |
| 9407 const String& dst_name = String::ZoneHandle(Symbols::FactoryResult()); | 9409 const String& dst_name = String::ZoneHandle(Symbols::FactoryResult()); |
| 9408 new_object = new AssignableNode(new_pos, new_object, type, dst_name); | 9410 new_object = new AssignableNode(new_pos, new_object, type_bound, dst_name); |
| 9409 } | 9411 } |
| 9410 return new_object; | 9412 return new_object; |
| 9411 } | 9413 } |
| 9412 | 9414 |
| 9413 | 9415 |
| 9414 String& Parser::Interpolate(ArrayNode* values) { | 9416 String& Parser::Interpolate(ArrayNode* values) { |
| 9415 const String& class_name = String::Handle(Symbols::StringBase()); | 9417 const String& class_name = String::Handle(Symbols::StringBase()); |
| 9416 const Class& cls = Class::Handle(LookupCoreClass(class_name)); | 9418 const Class& cls = Class::Handle(LookupCoreClass(class_name)); |
| 9417 ASSERT(!cls.IsNull()); | 9419 ASSERT(!cls.IsNull()); |
| 9418 const String& func_name = String::Handle(Symbols::Interpolate()); | 9420 const String& func_name = String::Handle(Symbols::Interpolate()); |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10009 void Parser::SkipQualIdent() { | 10011 void Parser::SkipQualIdent() { |
| 10010 ASSERT(IsIdentifier()); | 10012 ASSERT(IsIdentifier()); |
| 10011 ConsumeToken(); | 10013 ConsumeToken(); |
| 10012 if (CurrentToken() == Token::kPERIOD) { | 10014 if (CurrentToken() == Token::kPERIOD) { |
| 10013 ConsumeToken(); // Consume the kPERIOD token. | 10015 ConsumeToken(); // Consume the kPERIOD token. |
| 10014 ExpectIdentifier("identifier expected after '.'"); | 10016 ExpectIdentifier("identifier expected after '.'"); |
| 10015 } | 10017 } |
| 10016 } | 10018 } |
| 10017 | 10019 |
| 10018 } // namespace dart | 10020 } // namespace dart |
| OLD | NEW |