| 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.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 6894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6905 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 6905 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
| 6906 no_args)); | 6906 no_args)); |
| 6907 } | 6907 } |
| 6908 | 6908 |
| 6909 ParseStatementSequence(); // Parse the catch handler code. | 6909 ParseStatementSequence(); // Parse the catch handler code. |
| 6910 current_block_->statements->Add( | 6910 current_block_->statements->Add( |
| 6911 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); | 6911 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); |
| 6912 SequenceNode* catch_handler = CloseBlock(); | 6912 SequenceNode* catch_handler = CloseBlock(); |
| 6913 ExpectToken(Token::kRBRACE); | 6913 ExpectToken(Token::kRBRACE); |
| 6914 | 6914 |
| 6915 if (!exception_param.type.IsDynamicType()) { // Has a type specification. | 6915 const bool is_bad_type = exception_param.type.IsMalformed() || |
| 6916 exception_param.type.IsMalbounded(); |
| 6917 if (!is_bad_type && !exception_param.type.IsDynamicType()) { |
| 6918 // Has a type specification that is not malformed or malbounded. |
| 6916 // Now form an 'if type check' as an exception type exists in the | 6919 // Now form an 'if type check' as an exception type exists in the |
| 6917 // catch specifier. | 6920 // catch specifier. |
| 6918 if (!exception_param.type.IsInstantiated() && | 6921 if (!exception_param.type.IsInstantiated() && |
| 6919 (current_block_->scope->function_level() > 0)) { | 6922 (current_block_->scope->function_level() > 0)) { |
| 6920 // Make sure that the instantiator is captured. | 6923 // Make sure that the instantiator is captured. |
| 6921 CaptureInstantiator(); | 6924 CaptureInstantiator(); |
| 6922 } | 6925 } |
| 6923 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type); | 6926 TypeNode* exception_type = new TypeNode(catch_pos, exception_param.type); |
| 6924 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var); | 6927 AstNode* exception_value = new LoadLocalNode(catch_pos, exception_var); |
| 6925 if (!exception_type->type().IsInstantiated()) { | 6928 if (!exception_type->type().IsInstantiated()) { |
| 6926 EnsureExpressionTemp(); | 6929 EnsureExpressionTemp(); |
| 6927 } | 6930 } |
| 6928 AstNode* type_cond_expr = new ComparisonNode( | 6931 AstNode* type_cond_expr = new ComparisonNode( |
| 6929 catch_pos, Token::kIS, exception_value, exception_type); | 6932 catch_pos, Token::kIS, exception_value, exception_type); |
| 6930 current_block_->statements->Add( | 6933 current_block_->statements->Add( |
| 6931 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); | 6934 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); |
| 6932 | 6935 |
| 6933 // Do not add uninstantiated types (e.g. type parameter T or generic | 6936 // Do not add uninstantiated types (e.g. type parameter T or generic |
| 6934 // type List<T>), since the debugger won't be able to instantiate it | 6937 // type List<T>), since the debugger won't be able to instantiate it |
| 6935 // when walking the stack. This means that the debugger is not able | 6938 // when walking the stack. This means that the debugger is not able |
| 6936 // to determine whether an exception is caught if the catch clause | 6939 // to determine whether an exception is caught if the catch clause |
| 6937 // uses generic types. It will report the exception as uncaught when | 6940 // uses generic types. It will report the exception as uncaught when |
| 6938 // in fact it might be caught and handled when we unwind the stack. | 6941 // in fact it might be caught and handled when we unwind the stack. |
| 6939 if (exception_param.type.IsInstantiated()) { | 6942 if (exception_param.type.IsInstantiated()) { |
| 6940 handler_types.Add(exception_param.type); | 6943 handler_types.Add(exception_param.type); |
| 6941 } | 6944 } |
| 6942 } else { | 6945 } else { |
| 6946 if (is_bad_type) { |
| 6947 current_block_->statements->Add(ThrowTypeError(catch_pos, |
| 6948 exception_param.type)); |
| 6949 // We still add the dead code below to satisfy the code generator. |
| 6950 } |
| 6943 // No exception type exists in the catch specifier so execute the | 6951 // No exception type exists in the catch specifier so execute the |
| 6944 // catch handler code unconditionally. | 6952 // catch handler code unconditionally. |
| 6945 current_block_->statements->Add(catch_handler); | 6953 current_block_->statements->Add(catch_handler); |
| 6946 generic_catch_seen = true; | 6954 generic_catch_seen = true; |
| 6947 // This catch clause will handle all exceptions. We can safely forget | 6955 // This catch clause will handle all exceptions. We can safely forget |
| 6948 // all previous catch clause types. | 6956 // all previous catch clause types. |
| 6949 handler_types.SetLength(0); | 6957 handler_types.SetLength(0); |
| 6950 handler_types.Add(exception_param.type); | 6958 handler_types.Add(exception_param.type); |
| 6951 } | 6959 } |
| 6952 } | 6960 } |
| (...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8608 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 8616 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 8609 if (!scope_class.IsNull()) { | 8617 if (!scope_class.IsNull()) { |
| 8610 // First check if the type is a type parameter of the given scope class. | 8618 // First check if the type is a type parameter of the given scope class. |
| 8611 const TypeParameter& type_parameter = TypeParameter::Handle( | 8619 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 8612 scope_class.LookupTypeParameter(unresolved_class_name)); | 8620 scope_class.LookupTypeParameter(unresolved_class_name)); |
| 8613 if (!type_parameter.IsNull()) { | 8621 if (!type_parameter.IsNull()) { |
| 8614 // A type parameter is considered to be a malformed type when | 8622 // A type parameter is considered to be a malformed type when |
| 8615 // referenced by a static member. | 8623 // referenced by a static member. |
| 8616 if (ParsingStaticMember()) { | 8624 if (ParsingStaticMember()) { |
| 8617 ASSERT(scope_class.raw() == current_class().raw()); | 8625 ASSERT(scope_class.raw() == current_class().raw()); |
| 8618 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8626 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 8619 FLAG_error_on_bad_type) { | 8627 Error::Handle(), // No previous error. |
| 8620 *type = ClassFinalizer::NewFinalizedMalformedType( | 8628 script_, |
| 8621 Error::Handle(), // No previous error. | 8629 type->token_pos(), |
| 8622 script_, | 8630 "type parameter '%s' cannot be referenced " |
| 8623 type->token_pos(), | 8631 "from static member", |
| 8624 "type parameter '%s' cannot be referenced " | 8632 String::Handle(type_parameter.name()).ToCString()); |
| 8625 "from static member", | |
| 8626 String::Handle(type_parameter.name()).ToCString()); | |
| 8627 } else { | |
| 8628 // Map the malformed type to dynamic and ignore type arguments. | |
| 8629 *type = Type::DynamicType(); | |
| 8630 } | |
| 8631 return; | 8633 return; |
| 8632 } | 8634 } |
| 8633 // A type parameter cannot be parameterized, so make the type | 8635 // A type parameter cannot be parameterized, so make the type |
| 8634 // malformed if type arguments have previously been parsed. | 8636 // malformed if type arguments have previously been parsed. |
| 8635 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 8637 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
| 8636 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8638 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 8637 FLAG_error_on_bad_type) { | 8639 Error::Handle(), // No previous error. |
| 8638 *type = ClassFinalizer::NewFinalizedMalformedType( | 8640 script_, |
| 8639 Error::Handle(), // No previous error. | 8641 type_parameter.token_pos(), |
| 8640 script_, | 8642 "type parameter '%s' cannot be parameterized", |
| 8641 type_parameter.token_pos(), | 8643 String::Handle(type_parameter.name()).ToCString()); |
| 8642 "type parameter '%s' cannot be parameterized", | |
| 8643 String::Handle(type_parameter.name()).ToCString()); | |
| 8644 } else { | |
| 8645 // Map the malformed type to dynamic and ignore type arguments. | |
| 8646 *type = Type::DynamicType(); | |
| 8647 } | |
| 8648 return; | 8644 return; |
| 8649 } | 8645 } |
| 8650 *type = type_parameter.raw(); | 8646 *type = type_parameter.raw(); |
| 8651 return; | 8647 return; |
| 8652 } | 8648 } |
| 8653 } | 8649 } |
| 8654 // The referenced class may not have been parsed yet. It would be wrong | 8650 // The referenced class may not have been parsed yet. It would be wrong |
| 8655 // to resolve it too early to an imported class of the same name. | 8651 // to resolve it too early to an imported class of the same name. |
| 8656 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 8652 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
| 8657 // Resolve classname in the scope of the current library. | 8653 // Resolve classname in the scope of the current library. |
| 8658 resolved_type_class = ResolveClassInCurrentLibraryScope( | 8654 resolved_type_class = ResolveClassInCurrentLibraryScope( |
| 8659 unresolved_class_name); | 8655 unresolved_class_name); |
| 8660 } | 8656 } |
| 8661 } else { | 8657 } else { |
| 8662 LibraryPrefix& lib_prefix = | 8658 LibraryPrefix& lib_prefix = |
| 8663 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 8659 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| 8664 // Resolve class name in the scope of the library prefix. | 8660 // Resolve class name in the scope of the library prefix. |
| 8665 resolved_type_class = | 8661 resolved_type_class = |
| 8666 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); | 8662 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); |
| 8667 } | 8663 } |
| 8668 // At this point, we can only have a parameterized_type. | 8664 // At this point, we can only have a parameterized_type. |
| 8669 const Type& parameterized_type = Type::Cast(*type); | 8665 const Type& parameterized_type = Type::Cast(*type); |
| 8670 if (!resolved_type_class.IsNull()) { | 8666 if (!resolved_type_class.IsNull()) { |
| 8671 // Replace unresolved class with resolved type class. | 8667 // Replace unresolved class with resolved type class. |
| 8672 parameterized_type.set_type_class(resolved_type_class); | 8668 parameterized_type.set_type_class(resolved_type_class); |
| 8673 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 8669 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
| 8674 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || | 8670 ClassFinalizer::FinalizeMalformedType( |
| 8675 FLAG_error_on_bad_type) { | 8671 Error::Handle(), // No previous error. |
| 8676 ClassFinalizer::FinalizeMalformedType( | 8672 script_, |
| 8677 Error::Handle(), // No previous error. | 8673 parameterized_type, |
| 8678 script_, | 8674 "type '%s' is not loaded", |
| 8679 parameterized_type, | 8675 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
| 8680 "type '%s' is not loaded", | |
| 8681 String::Handle(parameterized_type.UserVisibleName()).ToCString()); | |
| 8682 } else { | |
| 8683 // Map the malformed type to dynamic and ignore type arguments. | |
| 8684 *type = Type::DynamicType(); | |
| 8685 } | |
| 8686 return; | 8676 return; |
| 8687 } | 8677 } |
| 8688 } | 8678 } |
| 8689 // Resolve type arguments, if any. | 8679 // Resolve type arguments, if any. |
| 8690 const AbstractTypeArguments& arguments = | 8680 const AbstractTypeArguments& arguments = |
| 8691 AbstractTypeArguments::Handle(type->arguments()); | 8681 AbstractTypeArguments::Handle(type->arguments()); |
| 8692 if (!arguments.IsNull()) { | 8682 if (!arguments.IsNull()) { |
| 8693 const intptr_t num_arguments = arguments.Length(); | 8683 const intptr_t num_arguments = arguments.Length(); |
| 8694 for (intptr_t i = 0; i < num_arguments; i++) { | 8684 for (intptr_t i = 0; i < num_arguments; i++) { |
| 8695 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 8685 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9279 } | 9269 } |
| 9280 SkipQualIdent(); | 9270 SkipQualIdent(); |
| 9281 } else { | 9271 } else { |
| 9282 ParseQualIdent(&type_name); | 9272 ParseQualIdent(&type_name); |
| 9283 // An identifier cannot be resolved in a local scope when top level parsing. | 9273 // An identifier cannot be resolved in a local scope when top level parsing. |
| 9284 if (!is_top_level_ && | 9274 if (!is_top_level_ && |
| 9285 (type_name.lib_prefix == NULL) && | 9275 (type_name.lib_prefix == NULL) && |
| 9286 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 9276 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
| 9287 // The type is malformed. Skip over its type arguments. | 9277 // The type is malformed. Skip over its type arguments. |
| 9288 ParseTypeArguments(ClassFinalizer::kIgnore); | 9278 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 9289 if (finalization == ClassFinalizer::kCanonicalizeWellFormed) { | 9279 return ClassFinalizer::NewFinalizedMalformedType( |
| 9290 return ClassFinalizer::NewFinalizedMalformedType( | 9280 Error::Handle(), // No previous error. |
| 9291 Error::Handle(), // No previous error. | 9281 script_, |
| 9292 script_, | 9282 type_name.ident_pos, |
| 9293 type_name.ident_pos, | 9283 "using '%s' in this context is invalid", |
| 9294 "using '%s' in this context is invalid", | 9284 type_name.ident->ToCString()); |
| 9295 type_name.ident->ToCString()); | |
| 9296 } | |
| 9297 return Type::DynamicType(); | |
| 9298 } | 9285 } |
| 9299 } | 9286 } |
| 9300 Object& type_class = Object::Handle(isolate()); | 9287 Object& type_class = Object::Handle(isolate()); |
| 9301 // Leave type_class as null if type finalization mode is kIgnore. | 9288 // Leave type_class as null if type finalization mode is kIgnore. |
| 9302 if (finalization != ClassFinalizer::kIgnore) { | 9289 if (finalization != ClassFinalizer::kIgnore) { |
| 9303 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); | 9290 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); |
| 9304 if (type_name.lib_prefix != NULL) { | 9291 if (type_name.lib_prefix != NULL) { |
| 9305 lib_prefix = type_name.lib_prefix->raw(); | 9292 lib_prefix = type_name.lib_prefix->raw(); |
| 9306 } | 9293 } |
| 9307 type_class = UnresolvedClass::New(lib_prefix, | 9294 type_class = UnresolvedClass::New(lib_prefix, |
| (...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10751 void Parser::SkipQualIdent() { | 10738 void Parser::SkipQualIdent() { |
| 10752 ASSERT(IsIdentifier()); | 10739 ASSERT(IsIdentifier()); |
| 10753 ConsumeToken(); | 10740 ConsumeToken(); |
| 10754 if (CurrentToken() == Token::kPERIOD) { | 10741 if (CurrentToken() == Token::kPERIOD) { |
| 10755 ConsumeToken(); // Consume the kPERIOD token. | 10742 ConsumeToken(); // Consume the kPERIOD token. |
| 10756 ExpectIdentifier("identifier expected after '.'"); | 10743 ExpectIdentifier("identifier expected after '.'"); |
| 10757 } | 10744 } |
| 10758 } | 10745 } |
| 10759 | 10746 |
| 10760 } // namespace dart | 10747 } // namespace dart |
| OLD | NEW |