| 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 2527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2538 } | 2538 } |
| 2539 | 2539 |
| 2540 // Parse redirecting factory constructor. | 2540 // Parse redirecting factory constructor. |
| 2541 Type& redirection_type = Type::Handle(); | 2541 Type& redirection_type = Type::Handle(); |
| 2542 String& redirection_identifier = String::Handle(); | 2542 String& redirection_identifier = String::Handle(); |
| 2543 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 2543 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 2544 ConsumeToken(); | 2544 ConsumeToken(); |
| 2545 const intptr_t type_pos = TokenPos(); | 2545 const intptr_t type_pos = TokenPos(); |
| 2546 const AbstractType& type = AbstractType::Handle( | 2546 const AbstractType& type = AbstractType::Handle( |
| 2547 ParseType(ClassFinalizer::kTryResolve)); | 2547 ParseType(ClassFinalizer::kTryResolve)); |
| 2548 if (type.IsTypeParameter() || type.IsDynamicType()) { | 2548 if (!type.IsMalformed() && |
| 2549 (type.IsTypeParameter() || type.IsDynamicType())) { |
| 2549 // Replace the type with a malformed type and compile a throw when called. | 2550 // Replace the type with a malformed type and compile a throw when called. |
| 2550 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 2551 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 2551 Error::Handle(), // No previous error. | 2552 Error::Handle(), // No previous error. |
| 2552 current_class(), | 2553 current_class(), |
| 2553 type_pos, | 2554 type_pos, |
| 2554 ClassFinalizer::kTryResolve, // No compile-time error. | 2555 ClassFinalizer::kTryResolve, // No compile-time error. |
| 2555 "factory '%s' may not redirect to %s'%s'", | 2556 "factory '%s' may not redirect to %s'%s'", |
| 2556 method->name->ToCString(), | 2557 method->name->ToCString(), |
| 2557 type.IsTypeParameter() ? "type parameter " : "", | 2558 type.IsTypeParameter() ? "type parameter " : "", |
| 2558 type.IsTypeParameter() ? | 2559 type.IsTypeParameter() ? |
| (...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3734 do { | 3735 do { |
| 3735 ConsumeToken(); | 3736 ConsumeToken(); |
| 3736 type = ParseType(finalization); | 3737 type = ParseType(finalization); |
| 3737 // Only keep the error for the first malformed type argument. | 3738 // Only keep the error for the first malformed type argument. |
| 3738 if (malformed_error->IsNull() && type.IsMalformed()) { | 3739 if (malformed_error->IsNull() && type.IsMalformed()) { |
| 3739 *malformed_error = type.malformed_error(); | 3740 *malformed_error = type.malformed_error(); |
| 3740 } | 3741 } |
| 3741 // Map a malformed type argument to dynamic, so that malformed types with | 3742 // Map a malformed type argument to dynamic, so that malformed types with |
| 3742 // a resolved type class are handled properly in production mode. | 3743 // a resolved type class are handled properly in production mode. |
| 3743 if (type.IsMalformed()) { | 3744 if (type.IsMalformed()) { |
| 3744 ASSERT(finalization != ClassFinalizer::kCanonicalizeWellFormed); | 3745 ASSERT(finalization < ClassFinalizer::kCanonicalizeWellFormed); |
| 3745 if (finalization == ClassFinalizer::kCanonicalizeForCreation) { | |
| 3746 ErrorMsg(*malformed_error); | |
| 3747 } | |
| 3748 type = Type::DynamicType(); | 3746 type = Type::DynamicType(); |
| 3749 } | 3747 } |
| 3750 types.Add(type); | 3748 types.Add(type); |
| 3751 } while (CurrentToken() == Token::kCOMMA); | 3749 } while (CurrentToken() == Token::kCOMMA); |
| 3752 Token::Kind token = CurrentToken(); | 3750 Token::Kind token = CurrentToken(); |
| 3753 if ((token == Token::kGT) || (token == Token::kSHR)) { | 3751 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 3754 ConsumeRightAngleBracket(); | 3752 ConsumeRightAngleBracket(); |
| 3755 } else { | 3753 } else { |
| 3756 ErrorMsg("right angle bracket expected"); | 3754 ErrorMsg("right angle bracket expected"); |
| 3757 } | 3755 } |
| (...skipping 2423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6181 const intptr_t handler_pos = TokenPos(); | 6179 const intptr_t handler_pos = TokenPos(); |
| 6182 OpenBlock(); // Start the catch block sequence. | 6180 OpenBlock(); // Start the catch block sequence. |
| 6183 current_block_->scope->AddLabel(end_catch_label); | 6181 current_block_->scope->AddLabel(end_catch_label); |
| 6184 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6182 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
| 6185 const intptr_t catch_pos = TokenPos(); | 6183 const intptr_t catch_pos = TokenPos(); |
| 6186 CatchParamDesc exception_param; | 6184 CatchParamDesc exception_param; |
| 6187 CatchParamDesc stack_trace_param; | 6185 CatchParamDesc stack_trace_param; |
| 6188 catch_seen = true; | 6186 catch_seen = true; |
| 6189 if (IsLiteral("on")) { | 6187 if (IsLiteral("on")) { |
| 6190 ConsumeToken(); | 6188 ConsumeToken(); |
| 6189 // TODO(regis): The spec may change in the way a malformed 'on' type is |
| 6190 // treated. For now, we require the type to be wellformed. |
| 6191 exception_param.type = &AbstractType::ZoneHandle( | 6191 exception_param.type = &AbstractType::ZoneHandle( |
| 6192 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); | 6192 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); |
| 6193 } else { | 6193 } else { |
| 6194 exception_param.type = | 6194 exception_param.type = |
| 6195 &AbstractType::ZoneHandle(Type::DynamicType()); | 6195 &AbstractType::ZoneHandle(Type::DynamicType()); |
| 6196 } | 6196 } |
| 6197 if (CurrentToken() == Token::kCATCH) { | 6197 if (CurrentToken() == Token::kCATCH) { |
| 6198 ConsumeToken(); // Consume the 'catch'. | 6198 ConsumeToken(); // Consume the 'catch'. |
| 6199 ExpectToken(Token::kLPAREN); | 6199 ExpectToken(Token::kLPAREN); |
| 6200 exception_param.token_pos = TokenPos(); | 6200 exception_param.token_pos = TokenPos(); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6837 AstNode* right_operand = NULL; | 6837 AstNode* right_operand = NULL; |
| 6838 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 6838 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
| 6839 right_operand = ParseBinaryExpr(current_preced + 1); | 6839 right_operand = ParseBinaryExpr(current_preced + 1); |
| 6840 } else { | 6840 } else { |
| 6841 // For 'is' and 'as' we expect the right operand to be a type. | 6841 // For 'is' and 'as' we expect the right operand to be a type. |
| 6842 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 6842 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
| 6843 ConsumeToken(); | 6843 ConsumeToken(); |
| 6844 op_kind = Token::kISNOT; | 6844 op_kind = Token::kISNOT; |
| 6845 } | 6845 } |
| 6846 const intptr_t type_pos = TokenPos(); | 6846 const intptr_t type_pos = TokenPos(); |
| 6847 const AbstractType& type = | 6847 const AbstractType& type = AbstractType::ZoneHandle( |
| 6848 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kCanonicalize)); | 6848 ParseType(ClassFinalizer::kCanonicalizeExpression)); |
| 6849 if (!type.IsInstantiated() && | 6849 if (!type.IsInstantiated() && |
| 6850 (current_block_->scope->function_level() > 0)) { | 6850 (current_block_->scope->function_level() > 0)) { |
| 6851 // Make sure that the instantiator is captured. | 6851 // Make sure that the instantiator is captured. |
| 6852 CaptureInstantiator(); | 6852 CaptureInstantiator(); |
| 6853 } | 6853 } |
| 6854 right_operand = new TypeNode(type_pos, type); | 6854 right_operand = new TypeNode(type_pos, type); |
| 6855 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && | 6855 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && |
| 6856 type.IsMalformed()) { | 6856 type.IsMalformed()) { |
| 6857 // Note that a type error is thrown even if the tested value is null | 6857 // Note that a type error is thrown even if the tested value is null |
| 6858 // in a type test. However, no cast exception is thrown if the value | 6858 // in a type test. However, no cast exception is thrown if the value |
| (...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7804 "type parameter '%s' cannot be parameterized", | 7804 "type parameter '%s' cannot be parameterized", |
| 7805 String::Handle(type_parameter.name()).ToCString()); | 7805 String::Handle(type_parameter.name()).ToCString()); |
| 7806 return; | 7806 return; |
| 7807 } | 7807 } |
| 7808 *type = type_parameter.raw(); | 7808 *type = type_parameter.raw(); |
| 7809 return; | 7809 return; |
| 7810 } | 7810 } |
| 7811 } | 7811 } |
| 7812 // Resolve classname in the scope of the current library. | 7812 // Resolve classname in the scope of the current library. |
| 7813 Error& error = Error::Handle(); | 7813 Error& error = Error::Handle(); |
| 7814 resolved_type_class = | 7814 // If we finalize a type expression, as opposed to a type annotation, we |
| 7815 ResolveClassInCurrentLibraryScope(unresolved_class.token_pos(), | 7815 // tell the resolver (by passing NULL) to immediately report an ambiguous |
| 7816 unresolved_class_name, | 7816 // type as a compile time error. |
| 7817 &error); | 7817 resolved_type_class = ResolveClassInCurrentLibraryScope( |
| 7818 unresolved_class.token_pos(), |
| 7819 unresolved_class_name, |
| 7820 finalization >= ClassFinalizer::kCanonicalizeExpression ? |
| 7821 NULL : &error); |
| 7818 if (!error.IsNull()) { | 7822 if (!error.IsNull()) { |
| 7819 *type = ClassFinalizer::NewFinalizedMalformedType( | 7823 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 7820 error, | 7824 error, |
| 7821 scope_class, | 7825 scope_class, |
| 7822 unresolved_class.token_pos(), | 7826 unresolved_class.token_pos(), |
| 7823 finalization, | 7827 finalization, |
| 7824 "cannot resolve class '%s'", | 7828 "cannot resolve class '%s'", |
| 7825 unresolved_class_name.ToCString()); | 7829 unresolved_class_name.ToCString()); |
| 7826 return; | 7830 return; |
| 7827 } | 7831 } |
| 7828 } else { | 7832 } else { |
| 7829 LibraryPrefix& lib_prefix = | 7833 LibraryPrefix& lib_prefix = |
| 7830 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 7834 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| 7831 // Resolve class name in the scope of the library prefix. | 7835 // Resolve class name in the scope of the library prefix. |
| 7832 Error& error = Error::Handle(); | 7836 Error& error = Error::Handle(); |
| 7833 resolved_type_class = | 7837 // If we finalize a type expression, as opposed to a type annotation, we |
| 7834 ResolveClassInPrefixScope(unresolved_class.token_pos(), | 7838 // tell the resolver (by passing NULL) to immediately report an ambiguous |
| 7835 lib_prefix, | 7839 // type as a compile time error. |
| 7836 unresolved_class_name, | 7840 resolved_type_class = ResolveClassInPrefixScope( |
| 7837 &error); | 7841 unresolved_class.token_pos(), |
| 7842 lib_prefix, |
| 7843 unresolved_class_name, |
| 7844 finalization >= ClassFinalizer::kCanonicalizeExpression ? |
| 7845 NULL : &error); |
| 7838 if (!error.IsNull()) { | 7846 if (!error.IsNull()) { |
| 7839 *type = ClassFinalizer::NewFinalizedMalformedType( | 7847 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 7840 error, | 7848 error, |
| 7841 scope_class, | 7849 scope_class, |
| 7842 unresolved_class.token_pos(), | 7850 unresolved_class.token_pos(), |
| 7843 finalization, | 7851 finalization, |
| 7844 "cannot resolve class '%s'", | 7852 "cannot resolve class '%s'", |
| 7845 unresolved_class_name.ToCString()); | 7853 unresolved_class_name.ToCString()); |
| 7846 return; | 7854 return; |
| 7847 } | 7855 } |
| (...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9100 TRACE_PARSER("ParseNewOperator"); | 9108 TRACE_PARSER("ParseNewOperator"); |
| 9101 const intptr_t new_pos = TokenPos(); | 9109 const intptr_t new_pos = TokenPos(); |
| 9102 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 9110 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 9103 bool is_const = (CurrentToken() == Token::kCONST); | 9111 bool is_const = (CurrentToken() == Token::kCONST); |
| 9104 ConsumeToken(); | 9112 ConsumeToken(); |
| 9105 if (!IsIdentifier()) { | 9113 if (!IsIdentifier()) { |
| 9106 ErrorMsg("type name expected"); | 9114 ErrorMsg("type name expected"); |
| 9107 } | 9115 } |
| 9108 intptr_t type_pos = TokenPos(); | 9116 intptr_t type_pos = TokenPos(); |
| 9109 AbstractType& type = AbstractType::Handle( | 9117 AbstractType& type = AbstractType::Handle( |
| 9110 ParseType(ClassFinalizer::kCanonicalizeForCreation)); | 9118 ParseType(ClassFinalizer::kCanonicalizeExpression)); |
| 9111 // In case the type is malformed, throw a dynamic type error after finishing | 9119 // In case the type is malformed, throw a dynamic type error after finishing |
| 9112 // parsing the instance creation expression. | 9120 // parsing the instance creation expression. |
| 9113 if (type.IsTypeParameter() || type.IsDynamicType()) { | 9121 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
| 9114 ASSERT(!type.IsMalformed()); | |
| 9115 // Replace the type with a malformed type. | 9122 // Replace the type with a malformed type. |
| 9116 type = ClassFinalizer::NewFinalizedMalformedType( | 9123 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9117 Error::Handle(), // No previous error. | 9124 Error::Handle(), // No previous error. |
| 9118 current_class(), | 9125 current_class(), |
| 9119 type_pos, | 9126 type_pos, |
| 9120 ClassFinalizer::kTryResolve, // No compile-time error. | 9127 ClassFinalizer::kTryResolve, // No compile-time error. |
| 9121 "%s'%s' cannot be instantiated", | 9128 "%s'%s' cannot be instantiated", |
| 9122 type.IsTypeParameter() ? "type parameter " : "", | 9129 type.IsTypeParameter() ? "type parameter " : "", |
| 9123 type.IsTypeParameter() ? | 9130 type.IsTypeParameter() ? |
| 9124 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 9131 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10038 void Parser::SkipQualIdent() { | 10045 void Parser::SkipQualIdent() { |
| 10039 ASSERT(IsIdentifier()); | 10046 ASSERT(IsIdentifier()); |
| 10040 ConsumeToken(); | 10047 ConsumeToken(); |
| 10041 if (CurrentToken() == Token::kPERIOD) { | 10048 if (CurrentToken() == Token::kPERIOD) { |
| 10042 ConsumeToken(); // Consume the kPERIOD token. | 10049 ConsumeToken(); // Consume the kPERIOD token. |
| 10043 ExpectIdentifier("identifier expected after '.'"); | 10050 ExpectIdentifier("identifier expected after '.'"); |
| 10044 } | 10051 } |
| 10045 } | 10052 } |
| 10046 | 10053 |
| 10047 } // namespace dart | 10054 } // namespace dart |
| OLD | NEW |