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 "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3566 method->name->ToCString()); | 3566 method->name->ToCString()); |
3567 } | 3567 } |
3568 ConsumeToken(); | 3568 ConsumeToken(); |
3569 const intptr_t type_pos = TokenPos(); | 3569 const intptr_t type_pos = TokenPos(); |
3570 is_redirecting = true; | 3570 is_redirecting = true; |
3571 const bool consume_unresolved_prefix = | 3571 const bool consume_unresolved_prefix = |
3572 (LookaheadToken(3) == Token::kLT) || | 3572 (LookaheadToken(3) == Token::kLT) || |
3573 (LookaheadToken(3) == Token::kPERIOD); | 3573 (LookaheadToken(3) == Token::kPERIOD); |
3574 const AbstractType& type = AbstractType::Handle(Z, | 3574 const AbstractType& type = AbstractType::Handle(Z, |
3575 ParseType(ClassFinalizer::kResolveTypeParameters, | 3575 ParseType(ClassFinalizer::kResolveTypeParameters, |
3576 false, // Deferred types not allowed. | 3576 true, |
3577 consume_unresolved_prefix)); | 3577 consume_unresolved_prefix)); |
3578 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3578 if (!type.IsMalformed() && type.IsTypeParameter()) { |
3579 // Replace the type with a malformed type and compile a throw when called. | 3579 // Replace the type with a malformed type and compile a throw when called. |
3580 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 3580 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
3581 Error::Handle(Z), // No previous error. | 3581 Error::Handle(Z), // No previous error. |
3582 script_, | 3582 script_, |
3583 type_pos, | 3583 type_pos, |
3584 "factory '%s' may not redirect to type parameter '%s'", | 3584 "factory '%s' may not redirect to type parameter '%s'", |
3585 method->name->ToCString(), | 3585 method->name->ToCString(), |
3586 String::Handle(Z, type.UserVisibleName()).ToCString()); | 3586 String::Handle(Z, type.UserVisibleName()).ToCString()); |
(...skipping 8425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12012 Error::Handle(Z), // No previous error. | 12012 Error::Handle(Z), // No previous error. |
12013 script_, | 12013 script_, |
12014 ident_pos, | 12014 ident_pos, |
12015 "using '%s' in this context is invalid", | 12015 "using '%s' in this context is invalid", |
12016 type_name.ToCString()); | 12016 type_name.ToCString()); |
12017 } | 12017 } |
12018 if (!prefix.IsNull() && prefix.is_deferred_load()) { | 12018 if (!prefix.IsNull() && prefix.is_deferred_load()) { |
12019 // If deferred prefixes are allowed but it is not yet loaded, | 12019 // If deferred prefixes are allowed but it is not yet loaded, |
12020 // remember that this function depends on the prefix. | 12020 // remember that this function depends on the prefix. |
12021 if (allow_deferred_type && !prefix.is_loaded()) { | 12021 if (allow_deferred_type && !prefix.is_loaded()) { |
12022 ASSERT(parsed_function() != NULL); | 12022 if (parsed_function() != NULL) { |
12023 parsed_function()->AddDeferredPrefix(prefix); | 12023 parsed_function()->AddDeferredPrefix(prefix); |
| 12024 } |
12024 } | 12025 } |
12025 // If the deferred prefixes are not allowed, or if the prefix | 12026 // If the deferred prefixes are not allowed, or if the prefix is not yet |
12026 // is not yet loaded, return a malformed type. Otherwise, handle | 12027 // loaded when finalization is requested, return a malformed type. |
12027 // resolution below, as needed. | 12028 // Otherwise, handle resolution below, as needed. |
12028 if (!prefix.is_loaded() || !allow_deferred_type) { | 12029 if (!allow_deferred_type || |
| 12030 (!prefix.is_loaded() |
| 12031 && (finalization > ClassFinalizer::kResolveTypeParameters))) { |
12029 ParseTypeArguments(ClassFinalizer::kIgnore); | 12032 ParseTypeArguments(ClassFinalizer::kIgnore); |
12030 return ClassFinalizer::NewFinalizedMalformedType( | 12033 return ClassFinalizer::NewFinalizedMalformedType( |
12031 Error::Handle(Z), // No previous error. | 12034 Error::Handle(Z), // No previous error. |
12032 script_, | 12035 script_, |
12033 ident_pos, | 12036 ident_pos, |
12034 !prefix.is_loaded() | 12037 !prefix.is_loaded() |
12035 ? "deferred type '%s.%s' is not yet loaded" | 12038 ? "deferred type '%s.%s' is not yet loaded" |
12036 : "using deferred type '%s.%s' is invalid", | 12039 : "using deferred type '%s.%s' is invalid", |
12037 String::Handle(Z, prefix.name()).ToCString(), | 12040 String::Handle(Z, prefix.name()).ToCString(), |
12038 type_name.ToCString()); | 12041 type_name.ToCString()); |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12695 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 12698 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); |
12696 if (!error.IsNull()) { | 12699 if (!error.IsNull()) { |
12697 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 12700 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
12698 error, | 12701 error, |
12699 script_, | 12702 script_, |
12700 call_pos, | 12703 call_pos, |
12701 "redirecting factory type '%s' cannot be instantiated", | 12704 "redirecting factory type '%s' cannot be instantiated", |
12702 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 12705 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
12703 } | 12706 } |
12704 } | 12707 } |
| 12708 if (!redirect_type.HasResolvedTypeClass()) { |
| 12709 // If the redirection type is unresolved, we convert the allocation |
| 12710 // into throwing a type error. |
| 12711 const UnresolvedClass& cls = |
| 12712 UnresolvedClass::Handle(Z, redirect_type.unresolved_class()); |
| 12713 const LibraryPrefix& prefix = |
| 12714 LibraryPrefix::Handle(Z, cls.library_prefix()); |
| 12715 if (!prefix.IsNull() && !prefix.is_loaded()) { |
| 12716 // If the redirection type is unresolved because it refers to |
| 12717 // an unloaded deferred prefix, mark this function as depending |
| 12718 // on the library prefix. It will then get invalidated when the |
| 12719 // prefix is loaded. |
| 12720 parsed_function()->AddDeferredPrefix(prefix); |
| 12721 } |
| 12722 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
| 12723 Error::Handle(Z), |
| 12724 script_, |
| 12725 call_pos, |
| 12726 "redirection type '%s' is not loaded", |
| 12727 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
| 12728 } |
| 12729 |
12705 if (redirect_type.IsMalformedOrMalbounded()) { | 12730 if (redirect_type.IsMalformedOrMalbounded()) { |
12706 if (is_const) { | 12731 if (is_const) { |
12707 ReportError(Error::Handle(Z, redirect_type.error())); | 12732 ReportError(Error::Handle(Z, redirect_type.error())); |
12708 } | 12733 } |
12709 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 12734 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
12710 } | 12735 } |
12711 if (I->flags().type_checks() && !redirect_type.IsSubtypeOf(type, NULL)) { | 12736 if (I->flags().type_checks() && !redirect_type.IsSubtypeOf(type, NULL)) { |
12712 // Additional type checking of the result is necessary. | 12737 // Additional type checking of the result is necessary. |
12713 type_bound = type.raw(); | 12738 type_bound = type.raw(); |
12714 } | 12739 } |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13526 void Parser::SkipQualIdent() { | 13551 void Parser::SkipQualIdent() { |
13527 ASSERT(IsIdentifier()); | 13552 ASSERT(IsIdentifier()); |
13528 ConsumeToken(); | 13553 ConsumeToken(); |
13529 if (CurrentToken() == Token::kPERIOD) { | 13554 if (CurrentToken() == Token::kPERIOD) { |
13530 ConsumeToken(); // Consume the kPERIOD token. | 13555 ConsumeToken(); // Consume the kPERIOD token. |
13531 ExpectIdentifier("identifier expected after '.'"); | 13556 ExpectIdentifier("identifier expected after '.'"); |
13532 } | 13557 } |
13533 } | 13558 } |
13534 | 13559 |
13535 } // namespace dart | 13560 } // namespace dart |
OLD | NEW |