| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2960 if (!type.IsMalformed() && type.IsTypeParameter()) { | 2960 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 2961 // Replace the type with a malformed type and compile a throw when called. | 2961 // Replace the type with a malformed type and compile a throw when called. |
| 2962 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 2962 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 2963 Error::Handle(), // No previous error. | 2963 Error::Handle(), // No previous error. |
| 2964 current_class(), | 2964 current_class(), |
| 2965 type_pos, | 2965 type_pos, |
| 2966 "factory '%s' may not redirect to type parameter '%s'", | 2966 "factory '%s' may not redirect to type parameter '%s'", |
| 2967 method->name->ToCString(), | 2967 method->name->ToCString(), |
| 2968 String::Handle(type.UserVisibleName()).ToCString()); | 2968 String::Handle(type.UserVisibleName()).ToCString()); |
| 2969 } else { | 2969 } else { |
| 2970 // TODO(regis): What if the redirection type is malbounded? |
| 2970 redirection_type ^= type.raw(); | 2971 redirection_type ^= type.raw(); |
| 2971 } | 2972 } |
| 2972 if (CurrentToken() == Token::kPERIOD) { | 2973 if (CurrentToken() == Token::kPERIOD) { |
| 2973 // Named constructor or factory. | 2974 // Named constructor or factory. |
| 2974 ConsumeToken(); | 2975 ConsumeToken(); |
| 2975 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 2976 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 2976 } | 2977 } |
| 2977 } else if (CurrentToken() == Token::kCOLON) { | 2978 } else if (CurrentToken() == Token::kCOLON) { |
| 2978 // Parse initializers. | 2979 // Parse initializers. |
| 2979 if (!method->IsConstructor()) { | 2980 if (!method->IsConstructor()) { |
| (...skipping 2430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5410 if (variable_name != NULL) { | 5411 if (variable_name != NULL) { |
| 5411 // Patch the function type of the variable now that the signature is known. | 5412 // Patch the function type of the variable now that the signature is known. |
| 5412 function_type.set_type_class(signature_class); | 5413 function_type.set_type_class(signature_class); |
| 5413 function_type.set_arguments(signature_type_arguments); | 5414 function_type.set_arguments(signature_type_arguments); |
| 5414 | 5415 |
| 5415 // Mark the function type as malformed if the signature type is malformed. | 5416 // Mark the function type as malformed if the signature type is malformed. |
| 5416 if (signature_type.IsMalformed()) { | 5417 if (signature_type.IsMalformed()) { |
| 5417 const Error& error = Error::Handle(signature_type.malformed_error()); | 5418 const Error& error = Error::Handle(signature_type.malformed_error()); |
| 5418 function_type.set_malformed_error(error); | 5419 function_type.set_malformed_error(error); |
| 5419 } | 5420 } |
| 5421 // TODO(regis): What if the signature is malbounded? |
| 5420 | 5422 |
| 5421 // The function type was initially marked as instantiated, but it may | 5423 // The function type was initially marked as instantiated, but it may |
| 5422 // actually be uninstantiated. | 5424 // actually be uninstantiated. |
| 5423 function_type.ResetIsFinalized(); | 5425 function_type.ResetIsFinalized(); |
| 5424 | 5426 |
| 5425 // The function variable type should have been patched above. | 5427 // The function variable type should have been patched above. |
| 5426 ASSERT((function_variable == NULL) || | 5428 ASSERT((function_variable == NULL) || |
| 5427 (function_variable->type().raw() == function_type.raw())); | 5429 (function_variable->type().raw() == function_type.raw())); |
| 5428 } | 5430 } |
| 5429 | 5431 |
| (...skipping 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7084 if (node != NULL) { | 7086 if (node != NULL) { |
| 7085 sequence->Add(node); | 7087 sequence->Add(node); |
| 7086 } | 7088 } |
| 7087 return sequence; | 7089 return sequence; |
| 7088 } | 7090 } |
| 7089 return node->AsSequenceNode(); | 7091 return node->AsSequenceNode(); |
| 7090 } | 7092 } |
| 7091 | 7093 |
| 7092 | 7094 |
| 7093 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { | 7095 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { |
| 7094 ASSERT(type.IsMalformed()); | |
| 7095 ArgumentListNode* arguments = new ArgumentListNode(type_pos); | 7096 ArgumentListNode* arguments = new ArgumentListNode(type_pos); |
| 7096 // Location argument. | 7097 // Location argument. |
| 7097 arguments->Add(new LiteralNode( | 7098 arguments->Add(new LiteralNode( |
| 7098 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); | 7099 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); |
| 7099 // Src value argument. | 7100 // Src value argument. |
| 7100 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); | 7101 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); |
| 7101 // Dst type name argument. | 7102 // Dst type name argument. |
| 7102 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed())); | 7103 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed())); |
| 7103 // Dst name argument. | 7104 // Dst name argument. |
| 7104 arguments->Add(new LiteralNode(type_pos, Symbols::Empty())); | 7105 arguments->Add(new LiteralNode(type_pos, Symbols::Empty())); |
| 7105 // Malformed type error. | 7106 // Malformed type error or malbounded type error. |
| 7106 const Error& error = Error::Handle(type.malformed_error()); | 7107 Error& error = Error::Handle(); |
| 7108 if (type.IsMalformed()) { |
| 7109 error = type.malformed_error(); |
| 7110 } else { |
| 7111 const bool is_malbounded = type.IsMalbounded(&error); |
| 7112 ASSERT(is_malbounded); |
| 7113 } |
| 7107 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 7114 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 7108 Symbols::New(error.ToErrorCString())))); | 7115 Symbols::New(error.ToErrorCString())))); |
| 7109 return MakeStaticCall(Symbols::TypeError(), | 7116 return MakeStaticCall(Symbols::TypeError(), |
| 7110 PrivateCoreLibName(Symbols::ThrowNew()), | 7117 PrivateCoreLibName(Symbols::ThrowNew()), |
| 7111 arguments); | 7118 arguments); |
| 7112 } | 7119 } |
| 7113 | 7120 |
| 7114 | 7121 |
| 7115 // TODO(regis): Providing the argument values is not always feasible, since | 7122 // TODO(regis): Providing the argument values is not always feasible, since |
| 7116 // evaluating them could throw an error. | 7123 // evaluating them could throw an error. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7196 } | 7203 } |
| 7197 const intptr_t type_pos = TokenPos(); | 7204 const intptr_t type_pos = TokenPos(); |
| 7198 const AbstractType& type = AbstractType::ZoneHandle( | 7205 const AbstractType& type = AbstractType::ZoneHandle( |
| 7199 ParseType(ClassFinalizer::kCanonicalize)); | 7206 ParseType(ClassFinalizer::kCanonicalize)); |
| 7200 if (!type.IsInstantiated() && | 7207 if (!type.IsInstantiated() && |
| 7201 (current_block_->scope->function_level() > 0)) { | 7208 (current_block_->scope->function_level() > 0)) { |
| 7202 // Make sure that the instantiator is captured. | 7209 // Make sure that the instantiator is captured. |
| 7203 CaptureInstantiator(); | 7210 CaptureInstantiator(); |
| 7204 } | 7211 } |
| 7205 right_operand = new TypeNode(type_pos, type); | 7212 right_operand = new TypeNode(type_pos, type); |
| 7206 // If the type is malformed, it is actually malbounded in checked mode. | 7213 // The type is never malformed (mapped to dynamic), but it can be |
| 7207 ASSERT(!type.IsMalformed() || FLAG_enable_type_checks); | 7214 // malbounded in checked mode. |
| 7215 ASSERT(!type.IsMalformed()); |
| 7208 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && | 7216 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && |
| 7209 type.IsMalformed()) { | 7217 type.IsMalbounded(NULL)) { |
| 7210 // Note that a type error is thrown even if the tested value is null | 7218 // Note that a type error is thrown even if the tested value is null |
| 7211 // in a type test. However, no cast exception is thrown if the value | 7219 // in a type test. However, no cast exception is thrown if the value |
| 7212 // is null in a type cast. | 7220 // is null in a type cast. |
| 7213 return ThrowTypeError(type_pos, type); | 7221 return ThrowTypeError(type_pos, type); |
| 7214 } | 7222 } |
| 7215 } | 7223 } |
| 7216 if (Token::IsRelationalOperator(op_kind) | 7224 if (Token::IsRelationalOperator(op_kind) |
| 7217 || Token::IsTypeTestOperator(op_kind) | 7225 || Token::IsTypeTestOperator(op_kind) |
| 7218 || Token::IsTypeCastOperator(op_kind) | 7226 || Token::IsTypeCastOperator(op_kind) |
| 7219 || Token::IsEqualityOperator(op_kind)) { | 7227 || Token::IsEqualityOperator(op_kind)) { |
| (...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9564 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 9572 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 9565 bool is_const = (op_kind == Token::kCONST); | 9573 bool is_const = (op_kind == Token::kCONST); |
| 9566 if (!IsIdentifier()) { | 9574 if (!IsIdentifier()) { |
| 9567 ErrorMsg("type name expected"); | 9575 ErrorMsg("type name expected"); |
| 9568 } | 9576 } |
| 9569 intptr_t type_pos = TokenPos(); | 9577 intptr_t type_pos = TokenPos(); |
| 9570 AbstractType& type = AbstractType::Handle( | 9578 AbstractType& type = AbstractType::Handle( |
| 9571 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); | 9579 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); |
| 9572 // In case the type is malformed, throw a dynamic type error after finishing | 9580 // In case the type is malformed, throw a dynamic type error after finishing |
| 9573 // parsing the instance creation expression. | 9581 // parsing the instance creation expression. |
| 9574 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 9582 if (!type.IsMalformed()) { |
| 9575 // Replace the type with a malformed type. | 9583 if (type.IsTypeParameter() || type.IsDynamicType()) { |
| 9576 type = ClassFinalizer::NewFinalizedMalformedType( | 9584 // Replace the type with a malformed type. |
| 9577 Error::Handle(), // No previous error. | 9585 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9578 current_class(), | 9586 Error::Handle(), // No previous error. |
| 9579 type_pos, | 9587 current_class(), |
| 9580 "%s'%s' cannot be instantiated", | 9588 type_pos, |
| 9581 type.IsTypeParameter() ? "type parameter " : "", | 9589 "%s'%s' cannot be instantiated", |
| 9582 type.IsTypeParameter() ? | 9590 type.IsTypeParameter() ? "type parameter " : "", |
| 9583 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 9591 type.IsTypeParameter() ? |
| 9592 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
| 9593 } else if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { |
| 9594 Error& bound_error = Error::Handle(); |
| 9595 if (type.IsMalbounded(&bound_error)) { |
| 9596 // Replace the type with a malformed type. |
| 9597 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9598 bound_error, |
| 9599 current_class(), |
| 9600 type_pos, |
| 9601 "malbounded type '%s' cannot be instantiated", |
| 9602 String::Handle(type.UserVisibleName()).ToCString()); |
| 9603 } |
| 9604 } |
| 9584 } | 9605 } |
| 9585 | 9606 |
| 9586 // The grammar allows for an optional ('.' identifier)? after the type, which | 9607 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 9587 // is a named constructor. Note that ParseType() above will not consume it as | 9608 // is a named constructor. Note that ParseType() above will not consume it as |
| 9588 // part of a misinterpreted qualified identifier, because only a valid library | 9609 // part of a misinterpreted qualified identifier, because only a valid library |
| 9589 // prefix is accepted as qualifier. | 9610 // prefix is accepted as qualifier. |
| 9590 String* named_constructor = NULL; | 9611 String* named_constructor = NULL; |
| 9591 if (CurrentToken() == Token::kPERIOD) { | 9612 if (CurrentToken() == Token::kPERIOD) { |
| 9592 ConsumeToken(); | 9613 ConsumeToken(); |
| 9593 named_constructor = ExpectIdentifier("name of constructor expected"); | 9614 named_constructor = ExpectIdentifier("name of constructor expected"); |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10364 void Parser::SkipQualIdent() { | 10385 void Parser::SkipQualIdent() { |
| 10365 ASSERT(IsIdentifier()); | 10386 ASSERT(IsIdentifier()); |
| 10366 ConsumeToken(); | 10387 ConsumeToken(); |
| 10367 if (CurrentToken() == Token::kPERIOD) { | 10388 if (CurrentToken() == Token::kPERIOD) { |
| 10368 ConsumeToken(); // Consume the kPERIOD token. | 10389 ConsumeToken(); // Consume the kPERIOD token. |
| 10369 ExpectIdentifier("identifier expected after '.'"); | 10390 ExpectIdentifier("identifier expected after '.'"); |
| 10370 } | 10391 } |
| 10371 } | 10392 } |
| 10372 | 10393 |
| 10373 } // namespace dart | 10394 } // namespace dart |
| OLD | NEW |