Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: runtime/vm/parser.cc

Issue 57133004: Complete latest spec changes regarding malformed types (see issue 14006). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.cc ('k') | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698