Chromium Code Reviews| 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 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2945 ErrorMsg("type parameter name expected"); | 2945 ErrorMsg("type parameter name expected"); |
| 2946 } | 2946 } |
| 2947 String& type_parameter_name = *CurrentLiteral(); | 2947 String& type_parameter_name = *CurrentLiteral(); |
| 2948 type_parameter = TypeParameter::New(index, | 2948 type_parameter = TypeParameter::New(index, |
| 2949 type_parameter_name, | 2949 type_parameter_name, |
| 2950 token_index_); | 2950 token_index_); |
| 2951 ConsumeToken(); | 2951 ConsumeToken(); |
| 2952 bound = Type::DynamicType(); | 2952 bound = Type::DynamicType(); |
| 2953 if (CurrentToken() == Token::kEXTENDS) { | 2953 if (CurrentToken() == Token::kEXTENDS) { |
| 2954 ConsumeToken(); | 2954 ConsumeToken(); |
| 2955 bound = ParseType(ClassFinalizer::kTryResolve); | 2955 // A bound may refer to the owner of the type parameter it applies to, |
| 2956 // i.e. to the class or interface currently being parsed. | |
| 2957 // Postpone resolution in order to avoid resolving the class and its | |
| 2958 // type parameters, as they are not fully parsed yet. | |
| 2959 bound = ParseType(ClassFinalizer::kDoNotResolve); | |
| 2956 } | 2960 } |
| 2957 type_parameters_array.Add(type_parameter); | 2961 type_parameters_array.Add(type_parameter); |
| 2958 bounds_array.Add(bound); | 2962 bounds_array.Add(bound); |
| 2959 index++; | 2963 index++; |
| 2960 } while (CurrentToken() == Token::kCOMMA); | 2964 } while (CurrentToken() == Token::kCOMMA); |
| 2961 Token::Kind token = CurrentToken(); | 2965 Token::Kind token = CurrentToken(); |
| 2962 if ((token == Token::kGT) || (token == Token::kSHR)) { | 2966 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 2963 ConsumeRightAngleBracket(); | 2967 ConsumeRightAngleBracket(); |
| 2964 } else { | 2968 } else { |
| 2965 ErrorMsg("right angle bracket expected"); | 2969 ErrorMsg("right angle bracket expected"); |
| (...skipping 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5531 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { | 5535 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { |
| 5532 ASSERT(type.IsMalformed()); | 5536 ASSERT(type.IsMalformed()); |
| 5533 ArgumentListNode* arguments = new ArgumentListNode(type_pos); | 5537 ArgumentListNode* arguments = new ArgumentListNode(type_pos); |
| 5534 // Location argument. | 5538 // Location argument. |
| 5535 arguments->Add(new LiteralNode( | 5539 arguments->Add(new LiteralNode( |
| 5536 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); | 5540 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); |
| 5537 // Src value argument. | 5541 // Src value argument. |
| 5538 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); | 5542 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); |
| 5539 // Dst type name argument. | 5543 // Dst type name argument. |
| 5540 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5544 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5541 String::NewSymbol("malformed type")))); | 5545 String::NewSymbol("malformed")))); |
| 5542 // Dst type name argument. | 5546 // Dst name argument. |
| 5543 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5547 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5544 String::NewSymbol("")))); | 5548 String::NewSymbol("")))); |
| 5545 // Malformed type error. | 5549 // Malformed type error. |
| 5546 const Error& error = Error::Handle(type.malformed_error()); | 5550 const Error& error = Error::Handle(type.malformed_error()); |
| 5547 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5551 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5548 String::NewSymbol(error.ToErrorCString())))); | 5552 String::NewSymbol(error.ToErrorCString())))); |
| 5549 return MakeStaticCall(kTypeErrorName, kThrowNewName, arguments); | 5553 return MakeStaticCall(kTypeErrorName, kThrowNewName, arguments); |
| 5550 } | 5554 } |
| 5551 | 5555 |
| 5552 | 5556 |
| (...skipping 1781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7334 bool is_const = false; | 7338 bool is_const = false; |
| 7335 if (CurrentToken() == Token::kCONST) { | 7339 if (CurrentToken() == Token::kCONST) { |
| 7336 is_const = true; | 7340 is_const = true; |
| 7337 ConsumeToken(); | 7341 ConsumeToken(); |
| 7338 } | 7342 } |
| 7339 const intptr_t type_pos = token_index_; | 7343 const intptr_t type_pos = token_index_; |
| 7340 Error& malformed_error = Error::Handle(); | 7344 Error& malformed_error = Error::Handle(); |
| 7341 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( | 7345 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( |
| 7342 ParseTypeArguments(&malformed_error, | 7346 ParseTypeArguments(&malformed_error, |
| 7343 ClassFinalizer::kFinalizeWellFormed)); | 7347 ClassFinalizer::kFinalizeWellFormed)); |
| 7348 // Map and List interfaces do not declare bounds on their type parameters, so | |
| 7349 // we should never see a malformed type error here. | |
| 7350 // Note that a bound error is the only possible malformed type error returned | |
| 7351 // 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
| |
| 7352 ASSERT(malformed_error.IsNull()); | |
| 7344 AstNode* primary = NULL; | 7353 AstNode* primary = NULL; |
| 7345 if ((CurrentToken() == Token::kLBRACK) || | 7354 if ((CurrentToken() == Token::kLBRACK) || |
| 7346 (CurrentToken() == Token::kINDEX)) { | 7355 (CurrentToken() == Token::kINDEX)) { |
| 7347 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 7356 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 7348 } else if (CurrentToken() == Token::kLBRACE) { | 7357 } else if (CurrentToken() == Token::kLBRACE) { |
| 7349 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 7358 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 7350 } else { | 7359 } else { |
| 7351 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 7360 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
| 7352 } | 7361 } |
| 7353 return primary; | 7362 return primary; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 7373 AstNode* Parser::ParseNewOperator() { | 7382 AstNode* Parser::ParseNewOperator() { |
| 7374 TRACE_PARSER("ParseNewOperator"); | 7383 TRACE_PARSER("ParseNewOperator"); |
| 7375 const intptr_t new_pos = token_index_; | 7384 const intptr_t new_pos = token_index_; |
| 7376 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7385 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7377 bool is_const = (CurrentToken() == Token::kCONST); | 7386 bool is_const = (CurrentToken() == Token::kCONST); |
| 7378 ConsumeToken(); | 7387 ConsumeToken(); |
| 7379 if (!IsIdentifier()) { | 7388 if (!IsIdentifier()) { |
| 7380 ErrorMsg("type name expected"); | 7389 ErrorMsg("type name expected"); |
| 7381 } | 7390 } |
| 7382 intptr_t type_pos = token_index_; | 7391 intptr_t type_pos = token_index_; |
| 7383 | |
| 7384 // TODO(regis): Bounds error should not result in a compile time error, | |
| 7385 // but in a dynamic type error. Requesting kFinalizeWellFormed below is too | |
| 7386 // strict. See co19 issue 96. | |
| 7387 const AbstractType& type = AbstractType::Handle( | 7392 const AbstractType& type = AbstractType::Handle( |
| 7388 ParseType(ClassFinalizer::kFinalizeWellFormed)); | 7393 ParseType(ClassFinalizer::kFinalizeWellFormed)); |
| 7394 // Malformed bounds never result in a compile time error, therefore, the | |
| 7395 // parsed type may be malformed although we requested kFinalizeWellFormed. | |
| 7396 // In that case, we throw a dynamic type error instead of calling the | |
| 7397 // constructor. | |
| 7389 if (type.IsTypeParameter()) { | 7398 if (type.IsTypeParameter()) { |
| 7390 ErrorMsg(type_pos, | 7399 ErrorMsg(type_pos, |
| 7391 "type parameter '%s' cannot be instantiated", | 7400 "type parameter '%s' cannot be instantiated", |
| 7392 String::Handle(type.Name()).ToCString()); | 7401 String::Handle(type.Name()).ToCString()); |
| 7393 } | 7402 } |
| 7394 Class& type_class = Class::Handle(type.type_class()); | 7403 Class& type_class = Class::Handle(type.type_class()); |
| 7395 String& type_class_name = String::Handle(type_class.Name()); | 7404 String& type_class_name = String::Handle(type_class.Name()); |
| 7396 AbstractTypeArguments& type_arguments = | 7405 AbstractTypeArguments& type_arguments = |
| 7397 AbstractTypeArguments::ZoneHandle(type.arguments()); | 7406 AbstractTypeArguments::ZoneHandle(type.arguments()); |
| 7398 | 7407 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7541 } | 7550 } |
| 7542 | 7551 |
| 7543 type_arguments ^= type_arguments.Canonicalize(); | 7552 type_arguments ^= type_arguments.Canonicalize(); |
| 7544 // Make the constructor call. | 7553 // Make the constructor call. |
| 7545 AstNode* new_object = NULL; | 7554 AstNode* new_object = NULL; |
| 7546 if (is_const) { | 7555 if (is_const) { |
| 7547 if (!constructor.is_const()) { | 7556 if (!constructor.is_const()) { |
| 7548 ErrorMsg("'const' requires const constructor: '%s'", | 7557 ErrorMsg("'const' requires const constructor: '%s'", |
| 7549 String::Handle(constructor.name()).ToCString()); | 7558 String::Handle(constructor.name()).ToCString()); |
| 7550 } | 7559 } |
| 7560 if (type.IsMalformed()) { | |
| 7561 // Compile the throw of a dynamic type error due to a bound error. | |
| 7562 return ThrowTypeError(type_pos, type); | |
| 7563 } | |
| 7551 const Object& constructor_result = Object::Handle( | 7564 const Object& constructor_result = Object::Handle( |
| 7552 EvaluateConstConstructorCall(constructor_class, | 7565 EvaluateConstConstructorCall(constructor_class, |
| 7553 type_arguments, | 7566 type_arguments, |
| 7554 constructor, | 7567 constructor, |
| 7555 arguments)); | 7568 arguments)); |
| 7556 if (constructor_result.IsUnhandledException()) { | 7569 if (constructor_result.IsUnhandledException()) { |
| 7557 new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result); | 7570 new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result); |
| 7558 } else { | 7571 } else { |
| 7559 Instance& const_instance = Instance::ZoneHandle(); | 7572 Instance& const_instance = Instance::ZoneHandle(); |
| 7560 const_instance ^= constructor_result.raw(); | 7573 const_instance ^= constructor_result.raw(); |
| 7561 new_object = new LiteralNode(new_pos, const_instance); | 7574 new_object = new LiteralNode(new_pos, const_instance); |
| 7562 } | 7575 } |
| 7563 } else { | 7576 } else { |
| 7564 CheckFunctionIsCallable(new_pos, constructor); | 7577 CheckFunctionIsCallable(new_pos, constructor); |
| 7565 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7578 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 7566 if (!type_arguments.IsNull() && | 7579 if (!type_arguments.IsNull() && |
| 7567 !type_arguments.IsInstantiated() && | 7580 !type_arguments.IsInstantiated() && |
| 7568 (current_block_->scope->function_level() > 0)) { | 7581 (current_block_->scope->function_level() > 0)) { |
| 7569 // Make sure that the instantiator is captured. | 7582 // Make sure that the instantiator is captured. |
| 7570 CaptureReceiver(); | 7583 CaptureReceiver(); |
| 7571 } | 7584 } |
| 7585 if (type.IsMalformed()) { | |
| 7586 // Compile the throw of a dynamic type error due to a bound error. | |
| 7587 return ThrowTypeError(type_pos, type); | |
| 7588 } | |
| 7572 // TODO(regis): If the type argument vector is not instantiated, we need to | 7589 // TODO(regis): If the type argument vector is not instantiated, we need to |
| 7573 // verify in checked mode at runtime that it is within its declared bounds. | 7590 // verify in checked mode at runtime that it is within its declared bounds. |
| 7574 new_object = new ConstructorCallNode( | 7591 new_object = new ConstructorCallNode( |
| 7575 new_pos, type_arguments, constructor, arguments); | 7592 new_pos, type_arguments, constructor, arguments); |
| 7576 } | 7593 } |
| 7577 return new_object; | 7594 return new_object; |
| 7578 } | 7595 } |
| 7579 | 7596 |
| 7580 | 7597 |
| 7581 String& Parser::Interpolate(ArrayNode* values) { | 7598 String& Parser::Interpolate(ArrayNode* values) { |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8144 void Parser::SkipQualIdent() { | 8161 void Parser::SkipQualIdent() { |
| 8145 ASSERT(IsIdentifier()); | 8162 ASSERT(IsIdentifier()); |
| 8146 ConsumeToken(); | 8163 ConsumeToken(); |
| 8147 if (CurrentToken() == Token::kPERIOD) { | 8164 if (CurrentToken() == Token::kPERIOD) { |
| 8148 ConsumeToken(); // Consume the kPERIOD token. | 8165 ConsumeToken(); // Consume the kPERIOD token. |
| 8149 ExpectIdentifier("identifier expected after '.'"); | 8166 ExpectIdentifier("identifier expected after '.'"); |
| 8150 } | 8167 } |
| 8151 } | 8168 } |
| 8152 | 8169 |
| 8153 } // namespace dart | 8170 } // namespace dart |
| OLD | NEW |