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 |