Chromium Code Reviews| 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 |