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 6914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6925 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 6925 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
6926 no_args)); | 6926 no_args)); |
6927 } | 6927 } |
6928 | 6928 |
6929 ParseStatementSequence(); // Parse the catch handler code. | 6929 ParseStatementSequence(); // Parse the catch handler code. |
6930 current_block_->statements->Add( | 6930 current_block_->statements->Add( |
6931 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); | 6931 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); |
6932 SequenceNode* catch_handler = CloseBlock(); | 6932 SequenceNode* catch_handler = CloseBlock(); |
6933 ExpectToken(Token::kRBRACE); | 6933 ExpectToken(Token::kRBRACE); |
6934 | 6934 |
6935 if (!exception_param.type->IsDynamicType()) { // Has a type specification. | 6935 const bool is_bad_type = exception_param.type->IsMalformed() || |
6936 // Now form an 'if type check' as an exception type exists in | 6936 exception_param.type->IsMalbounded(); |
6937 // the catch specifier. | 6937 if (!is_bad_type && !exception_param.type->IsDynamicType()) { |
6938 // Has a type specification that is not malformed or malbounded. | |
6939 // Now form an 'if type check' as an exception type exists in the | |
6940 // catch specifier. | |
6938 if (!exception_param.type->IsInstantiated() && | 6941 if (!exception_param.type->IsInstantiated() && |
ricow1
2013/11/06 10:05:18
Ivan: I changed back to -> here, the merge changed
Ivan Posva
2013/11/06 15:54:37
✓
| |
6939 (current_block_->scope->function_level() > 0)) { | 6942 (current_block_->scope->function_level() > 0)) { |
6940 // Make sure that the instantiator is captured. | 6943 // Make sure that the instantiator is captured. |
6941 CaptureInstantiator(); | 6944 CaptureInstantiator(); |
6942 } | 6945 } |
6943 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); | 6946 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); |
6944 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); | 6947 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); |
6945 if (!exception_type->type().IsInstantiated()) { | 6948 if (!exception_type->type().IsInstantiated()) { |
6946 EnsureExpressionTemp(); | 6949 EnsureExpressionTemp(); |
6947 } | 6950 } |
6948 AstNode* type_cond_expr = new ComparisonNode( | 6951 AstNode* type_cond_expr = new ComparisonNode( |
6949 catch_pos, Token::kIS, exception_var, exception_type); | 6952 catch_pos, Token::kIS, exception_var, exception_type); |
6950 current_block_->statements->Add( | 6953 current_block_->statements->Add( |
6951 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); | 6954 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); |
6952 | 6955 |
6953 // Do not add uninstantiated types (e.g. type parameter T or | 6956 // Do not add uninstantiated types (e.g. type parameter T or |
6954 // generic type List<T>), since the debugger won't be able to | 6957 // generic type List<T>), since the debugger won't be able to |
6955 // instantiate it when walking the stack. | 6958 // instantiate it when walking the stack. |
6956 // This means that the debugger is not able to determine whether | 6959 // This means that the debugger is not able to determine whether |
6957 // an exception is caught if the catch clause uses generic types. | 6960 // an exception is caught if the catch clause uses generic types. |
6958 // It will report the exception as uncaught when in fact it might | 6961 // It will report the exception as uncaught when in fact it might |
6959 // be caught and handled when we unwind the stack. | 6962 // be caught and handled when we unwind the stack. |
6960 if (exception_param.type->IsInstantiated()) { | 6963 if (exception_param.type->IsInstantiated()) { |
6961 handler_types.Add(*exception_param.type); | 6964 handler_types.Add(*exception_param.type); |
6962 } | 6965 } |
6963 } else { | 6966 } else { |
6967 if (is_bad_type) { | |
6968 current_block_->statements->Add(ThrowTypeError(catch_pos, | |
6969 *exception_param.type)); | |
ricow1
2013/11/06 10:05:18
Ivan: I added * here to make us compile
Ivan Posva
2013/11/06 15:54:37
✓
| |
6970 // We still add the dead code below to satisfy the code generator. | |
6971 } | |
6964 // No exception type exists in the catch specifier so execute the | 6972 // No exception type exists in the catch specifier so execute the |
6965 // catch handler code unconditionally. | 6973 // catch handler code unconditionally. |
6966 current_block_->statements->Add(catch_handler); | 6974 current_block_->statements->Add(catch_handler); |
6967 generic_catch_seen = true; | 6975 generic_catch_seen = true; |
6968 // This catch clause will handle all exceptions. We can safely forget | 6976 // This catch clause will handle all exceptions. We can safely forget |
6969 // all previous catch clause types. | 6977 // all previous catch clause types. |
6970 handler_types.SetLength(0); | 6978 handler_types.SetLength(0); |
6971 handler_types.Add(*exception_param.type); | 6979 handler_types.Add(*exception_param.type); |
6972 } | 6980 } |
6973 SequenceNode* catch_clause = CloseBlock(); | 6981 SequenceNode* catch_clause = CloseBlock(); |
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8636 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 8644 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
8637 if (!scope_class.IsNull()) { | 8645 if (!scope_class.IsNull()) { |
8638 // First check if the type is a type parameter of the given scope class. | 8646 // First check if the type is a type parameter of the given scope class. |
8639 const TypeParameter& type_parameter = TypeParameter::Handle( | 8647 const TypeParameter& type_parameter = TypeParameter::Handle( |
8640 scope_class.LookupTypeParameter(unresolved_class_name)); | 8648 scope_class.LookupTypeParameter(unresolved_class_name)); |
8641 if (!type_parameter.IsNull()) { | 8649 if (!type_parameter.IsNull()) { |
8642 // A type parameter is considered to be a malformed type when | 8650 // A type parameter is considered to be a malformed type when |
8643 // referenced by a static member. | 8651 // referenced by a static member. |
8644 if (ParsingStaticMember()) { | 8652 if (ParsingStaticMember()) { |
8645 ASSERT(scope_class.raw() == current_class().raw()); | 8653 ASSERT(scope_class.raw() == current_class().raw()); |
8646 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8654 *type = ClassFinalizer::NewFinalizedMalformedType( |
8647 FLAG_error_on_bad_type) { | 8655 Error::Handle(), // No previous error. |
8648 *type = ClassFinalizer::NewFinalizedMalformedType( | 8656 script_, |
8649 Error::Handle(), // No previous error. | 8657 type->token_pos(), |
8650 script_, | 8658 "type parameter '%s' cannot be referenced " |
8651 type->token_pos(), | 8659 "from static member", |
8652 "type parameter '%s' cannot be referenced " | 8660 String::Handle(type_parameter.name()).ToCString()); |
8653 "from static member", | |
8654 String::Handle(type_parameter.name()).ToCString()); | |
8655 } else { | |
8656 // Map the malformed type to dynamic and ignore type arguments. | |
8657 *type = Type::DynamicType(); | |
8658 } | |
8659 return; | 8661 return; |
8660 } | 8662 } |
8661 // A type parameter cannot be parameterized, so make the type | 8663 // A type parameter cannot be parameterized, so make the type |
8662 // malformed if type arguments have previously been parsed. | 8664 // malformed if type arguments have previously been parsed. |
8663 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 8665 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
8664 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8666 *type = ClassFinalizer::NewFinalizedMalformedType( |
8665 FLAG_error_on_bad_type) { | 8667 Error::Handle(), // No previous error. |
8666 *type = ClassFinalizer::NewFinalizedMalformedType( | 8668 script_, |
8667 Error::Handle(), // No previous error. | 8669 type_parameter.token_pos(), |
8668 script_, | 8670 "type parameter '%s' cannot be parameterized", |
8669 type_parameter.token_pos(), | 8671 String::Handle(type_parameter.name()).ToCString()); |
8670 "type parameter '%s' cannot be parameterized", | |
8671 String::Handle(type_parameter.name()).ToCString()); | |
8672 } else { | |
8673 // Map the malformed type to dynamic and ignore type arguments. | |
8674 *type = Type::DynamicType(); | |
8675 } | |
8676 return; | 8672 return; |
8677 } | 8673 } |
8678 *type = type_parameter.raw(); | 8674 *type = type_parameter.raw(); |
8679 return; | 8675 return; |
8680 } | 8676 } |
8681 } | 8677 } |
8682 // The referenced class may not have been parsed yet. It would be wrong | 8678 // The referenced class may not have been parsed yet. It would be wrong |
8683 // to resolve it too early to an imported class of the same name. | 8679 // to resolve it too early to an imported class of the same name. |
8684 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 8680 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
8685 // Resolve classname in the scope of the current library. | 8681 // Resolve classname in the scope of the current library. |
8686 resolved_type_class = ResolveClassInCurrentLibraryScope( | 8682 resolved_type_class = ResolveClassInCurrentLibraryScope( |
8687 unresolved_class_name); | 8683 unresolved_class_name); |
8688 } | 8684 } |
8689 } else { | 8685 } else { |
8690 LibraryPrefix& lib_prefix = | 8686 LibraryPrefix& lib_prefix = |
8691 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 8687 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
8692 // Resolve class name in the scope of the library prefix. | 8688 // Resolve class name in the scope of the library prefix. |
8693 resolved_type_class = | 8689 resolved_type_class = |
8694 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); | 8690 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); |
8695 } | 8691 } |
8696 // At this point, we can only have a parameterized_type. | 8692 // At this point, we can only have a parameterized_type. |
8697 const Type& parameterized_type = Type::Cast(*type); | 8693 const Type& parameterized_type = Type::Cast(*type); |
8698 if (!resolved_type_class.IsNull()) { | 8694 if (!resolved_type_class.IsNull()) { |
8699 // Replace unresolved class with resolved type class. | 8695 // Replace unresolved class with resolved type class. |
8700 parameterized_type.set_type_class(resolved_type_class); | 8696 parameterized_type.set_type_class(resolved_type_class); |
8701 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 8697 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
8702 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8698 ClassFinalizer::FinalizeMalformedType( |
8703 FLAG_error_on_bad_type) { | 8699 Error::Handle(), // No previous error. |
8704 ClassFinalizer::FinalizeMalformedType( | 8700 script_, |
8705 Error::Handle(), // No previous error. | 8701 parameterized_type, |
8706 script_, | 8702 "type '%s' is not loaded", |
8707 parameterized_type, | 8703 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
8708 "type '%s' is not loaded", | |
8709 String::Handle(parameterized_type.UserVisibleName()).ToCString()); | |
8710 } else { | |
8711 // Map the malformed type to dynamic and ignore type arguments. | |
8712 *type = Type::DynamicType(); | |
8713 } | |
8714 return; | 8704 return; |
8715 } | 8705 } |
8716 } | 8706 } |
8717 // Resolve type arguments, if any. | 8707 // Resolve type arguments, if any. |
8718 const AbstractTypeArguments& arguments = | 8708 const AbstractTypeArguments& arguments = |
8719 AbstractTypeArguments::Handle(type->arguments()); | 8709 AbstractTypeArguments::Handle(type->arguments()); |
8720 if (!arguments.IsNull()) { | 8710 if (!arguments.IsNull()) { |
8721 const intptr_t num_arguments = arguments.Length(); | 8711 const intptr_t num_arguments = arguments.Length(); |
8722 for (intptr_t i = 0; i < num_arguments; i++) { | 8712 for (intptr_t i = 0; i < num_arguments; i++) { |
8723 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 8713 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9307 } | 9297 } |
9308 SkipQualIdent(); | 9298 SkipQualIdent(); |
9309 } else { | 9299 } else { |
9310 ParseQualIdent(&type_name); | 9300 ParseQualIdent(&type_name); |
9311 // An identifier cannot be resolved in a local scope when top level parsing. | 9301 // An identifier cannot be resolved in a local scope when top level parsing. |
9312 if (!is_top_level_ && | 9302 if (!is_top_level_ && |
9313 (type_name.lib_prefix == NULL) && | 9303 (type_name.lib_prefix == NULL) && |
9314 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 9304 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
9315 // The type is malformed. Skip over its type arguments. | 9305 // The type is malformed. Skip over its type arguments. |
9316 ParseTypeArguments(ClassFinalizer::kIgnore); | 9306 ParseTypeArguments(ClassFinalizer::kIgnore); |
9317 if (finalization == ClassFinalizer::kCanonicalizeWellFormed) { | 9307 return ClassFinalizer::NewFinalizedMalformedType( |
9318 return ClassFinalizer::NewFinalizedMalformedType( | 9308 Error::Handle(), // No previous error. |
9319 Error::Handle(), // No previous error. | 9309 script_, |
9320 script_, | 9310 type_name.ident_pos, |
9321 type_name.ident_pos, | 9311 "using '%s' in this context is invalid", |
9322 "using '%s' in this context is invalid", | 9312 type_name.ident->ToCString()); |
9323 type_name.ident->ToCString()); | |
9324 } | |
9325 return Type::DynamicType(); | |
9326 } | 9313 } |
9327 } | 9314 } |
9328 Object& type_class = Object::Handle(isolate()); | 9315 Object& type_class = Object::Handle(isolate()); |
9329 // Leave type_class as null if type finalization mode is kIgnore. | 9316 // Leave type_class as null if type finalization mode is kIgnore. |
9330 if (finalization != ClassFinalizer::kIgnore) { | 9317 if (finalization != ClassFinalizer::kIgnore) { |
9331 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); | 9318 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); |
9332 if (type_name.lib_prefix != NULL) { | 9319 if (type_name.lib_prefix != NULL) { |
9333 lib_prefix = type_name.lib_prefix->raw(); | 9320 lib_prefix = type_name.lib_prefix->raw(); |
9334 } | 9321 } |
9335 type_class = UnresolvedClass::New(lib_prefix, | 9322 type_class = UnresolvedClass::New(lib_prefix, |
(...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10779 void Parser::SkipQualIdent() { | 10766 void Parser::SkipQualIdent() { |
10780 ASSERT(IsIdentifier()); | 10767 ASSERT(IsIdentifier()); |
10781 ConsumeToken(); | 10768 ConsumeToken(); |
10782 if (CurrentToken() == Token::kPERIOD) { | 10769 if (CurrentToken() == Token::kPERIOD) { |
10783 ConsumeToken(); // Consume the kPERIOD token. | 10770 ConsumeToken(); // Consume the kPERIOD token. |
10784 ExpectIdentifier("identifier expected after '.'"); | 10771 ExpectIdentifier("identifier expected after '.'"); |
10785 } | 10772 } |
10786 } | 10773 } |
10787 | 10774 |
10788 } // namespace dart | 10775 } // namespace dart |
OLD | NEW |