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

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

Issue 75713002: Distinguish between malformed and malbounded types more efficiently using the (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
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/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 7406 matching lines...) Expand 10 before | Expand all | Expand 10 after
7417 // Location argument. 7417 // Location argument.
7418 arguments->Add(new LiteralNode( 7418 arguments->Add(new LiteralNode(
7419 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); 7419 type_pos, Integer::ZoneHandle(Integer::New(type_pos))));
7420 // Src value argument. 7420 // Src value argument.
7421 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); 7421 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle()));
7422 // Dst type name argument. 7422 // Dst type name argument.
7423 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed())); 7423 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed()));
7424 // Dst name argument. 7424 // Dst name argument.
7425 arguments->Add(new LiteralNode(type_pos, Symbols::Empty())); 7425 arguments->Add(new LiteralNode(type_pos, Symbols::Empty()));
7426 // Malformed type error or malbounded type error. 7426 // Malformed type error or malbounded type error.
7427 Error& error = Error::Handle(); 7427 const Error& error = Error::Handle(type.error());
7428 if (type.IsMalformed()) { 7428 ASSERT(!error.IsNull());
7429 error = type.malformed_error();
7430 } else {
7431 const bool is_malbounded = type.IsMalboundedWithError(&error);
7432 ASSERT(is_malbounded);
7433 }
7434 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( 7429 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
7435 Symbols::New(error.ToErrorCString())))); 7430 Symbols::New(error.ToErrorCString()))));
7436 return MakeStaticCall(Symbols::TypeError(), 7431 return MakeStaticCall(Symbols::TypeError(),
7437 Library::PrivateCoreLibName(Symbols::ThrowNew()), 7432 Library::PrivateCoreLibName(Symbols::ThrowNew()),
7438 arguments); 7433 arguments);
7439 } 7434 }
7440 7435
7441 7436
7442 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, 7437 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos,
7443 const Class& cls, 7438 const Class& cls,
(...skipping 2339 matching lines...) Expand 10 before | Expand all | Expand 10 after
9783 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 9778 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
9784 bool is_const = (op_kind == Token::kCONST); 9779 bool is_const = (op_kind == Token::kCONST);
9785 if (!IsIdentifier()) { 9780 if (!IsIdentifier()) {
9786 ErrorMsg("type name expected"); 9781 ErrorMsg("type name expected");
9787 } 9782 }
9788 intptr_t type_pos = TokenPos(); 9783 intptr_t type_pos = TokenPos();
9789 AbstractType& type = AbstractType::Handle( 9784 AbstractType& type = AbstractType::Handle(
9790 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); 9785 ParseType(ClassFinalizer::kCanonicalizeWellFormed));
9791 // In case the type is malformed, throw a dynamic type error after finishing 9786 // In case the type is malformed, throw a dynamic type error after finishing
9792 // parsing the instance creation expression. 9787 // parsing the instance creation expression.
9793 if (!type.IsMalformed()) { 9788 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
9794 if (type.IsTypeParameter() || type.IsDynamicType()) { 9789 // Replace the type with a malformed type.
9795 // Replace the type with a malformed type. 9790 type = ClassFinalizer::NewFinalizedMalformedType(
9796 type = ClassFinalizer::NewFinalizedMalformedType( 9791 Error::Handle(), // No previous error.
9797 Error::Handle(), // No previous error. 9792 script_,
9798 script_, 9793 type_pos,
9799 type_pos, 9794 "%s'%s' cannot be instantiated",
9800 "%s'%s' cannot be instantiated", 9795 type.IsTypeParameter() ? "type parameter " : "",
9801 type.IsTypeParameter() ? "type parameter " : "", 9796 type.IsTypeParameter() ?
9802 type.IsTypeParameter() ? 9797 String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
9803 String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
9804 } else if (FLAG_enable_type_checks || FLAG_error_on_bad_type) {
9805 Error& bound_error = Error::Handle();
9806 if (type.IsMalboundedWithError(&bound_error)) {
9807 // Replace the type with a malformed type.
9808 type = ClassFinalizer::NewFinalizedMalformedType(
9809 bound_error,
9810 script_,
9811 type_pos,
9812 "malbounded type '%s' cannot be instantiated",
9813 String::Handle(type.UserVisibleName()).ToCString());
9814 }
9815 }
9816 } 9798 }
9817 9799
9818 // The grammar allows for an optional ('.' identifier)? after the type, which 9800 // The grammar allows for an optional ('.' identifier)? after the type, which
9819 // is a named constructor. Note that ParseType() above will not consume it as 9801 // is a named constructor. Note that ParseType() above will not consume it as
9820 // part of a misinterpreted qualified identifier, because only a valid library 9802 // part of a misinterpreted qualified identifier, because only a valid library
9821 // prefix is accepted as qualifier. 9803 // prefix is accepted as qualifier.
9822 String* named_constructor = NULL; 9804 String* named_constructor = NULL;
9823 if (CurrentToken() == Token::kPERIOD) { 9805 if (CurrentToken() == Token::kPERIOD) {
9824 ConsumeToken(); 9806 ConsumeToken();
9825 named_constructor = ExpectIdentifier("name of constructor expected"); 9807 named_constructor = ExpectIdentifier("name of constructor expected");
9826 } 9808 }
9827 9809
9828 // Parse constructor parameters. 9810 // Parse constructor parameters.
9829 CheckToken(Token::kLPAREN); 9811 CheckToken(Token::kLPAREN);
9830 intptr_t call_pos = TokenPos(); 9812 intptr_t call_pos = TokenPos();
9831 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 9813 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const);
9832 9814
9833 // Parsing is complete, so we can return a throw in case of a malformed type 9815 // Parsing is complete, so we can return a throw in case of a malformed or
9834 // or report a compile-time error if the constructor is const. 9816 // malbounded type or report a compile-time error if the constructor is const.
9835 if (type.IsMalformed()) { 9817 if (type.IsMalformedOrMalbounded()) {
9836 if (is_const) { 9818 if (is_const) {
9837 const Error& error = Error::Handle(type.malformed_error()); 9819 const Error& error = Error::Handle(type.error());
9838 ErrorMsg(error); 9820 ErrorMsg(error);
9839 } 9821 }
9840 return ThrowTypeError(type_pos, type); 9822 return ThrowTypeError(type_pos, type);
9841 } 9823 }
9842 9824
9843 // Resolve the type and optional identifier to a constructor or factory. 9825 // Resolve the type and optional identifier to a constructor or factory.
9844 Class& type_class = Class::Handle(type.type_class()); 9826 Class& type_class = Class::Handle(type.type_class());
9845 String& type_class_name = String::Handle(type_class.Name()); 9827 String& type_class_name = String::Handle(type_class.Name());
9846 AbstractTypeArguments& type_arguments = 9828 AbstractTypeArguments& type_arguments =
9847 AbstractTypeArguments::ZoneHandle(type.arguments()); 9829 AbstractTypeArguments::ZoneHandle(type.arguments());
(...skipping 20 matching lines...) Expand all
9868 // Replace the type with a malformed type and compile a throw or report a 9850 // Replace the type with a malformed type and compile a throw or report a
9869 // compile-time error if the constructor is const. 9851 // compile-time error if the constructor is const.
9870 if (is_const) { 9852 if (is_const) {
9871 type = ClassFinalizer::NewFinalizedMalformedType( 9853 type = ClassFinalizer::NewFinalizedMalformedType(
9872 Error::Handle(), // No previous error. 9854 Error::Handle(), // No previous error.
9873 script_, 9855 script_,
9874 call_pos, 9856 call_pos,
9875 "class '%s' has no constructor or factory named '%s'", 9857 "class '%s' has no constructor or factory named '%s'",
9876 String::Handle(type_class.Name()).ToCString(), 9858 String::Handle(type_class.Name()).ToCString(),
9877 external_constructor_name.ToCString()); 9859 external_constructor_name.ToCString());
9878 const Error& error = Error::Handle(type.malformed_error()); 9860 ErrorMsg(Error::Handle(type.error()));
9879 ErrorMsg(error);
9880 } 9861 }
9881 return ThrowNoSuchMethodError(call_pos, 9862 return ThrowNoSuchMethodError(call_pos,
9882 type_class, 9863 type_class,
9883 external_constructor_name, 9864 external_constructor_name,
9884 arguments, 9865 arguments,
9885 InvocationMirror::kConstructor, 9866 InvocationMirror::kConstructor,
9886 InvocationMirror::kMethod, 9867 InvocationMirror::kMethod,
9887 &constructor); 9868 &constructor);
9888 } else if (constructor.IsRedirectingFactory()) { 9869 } else if (constructor.IsRedirectingFactory()) {
9889 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); 9870 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
9890 Type& redirect_type = Type::Handle(constructor.RedirectionType()); 9871 Type& redirect_type = Type::Handle(constructor.RedirectionType());
9891 Error& error = Error::Handle(); 9872 if (!redirect_type.IsMalformedOrMalbounded() &&
9892 if (!redirect_type.IsMalformed() && !redirect_type.IsMalbounded() &&
9893 !redirect_type.IsInstantiated()) { 9873 !redirect_type.IsInstantiated()) {
9894 // The type arguments of the redirection type are instantiated from the 9874 // The type arguments of the redirection type are instantiated from the
9895 // type arguments of the parsed type of the 'new' or 'const' expression. 9875 // type arguments of the parsed type of the 'new' or 'const' expression.
9876 Error& error = Error::Handle();
9896 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); 9877 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error);
9897 if (!error.IsNull()) { 9878 if (!error.IsNull()) {
9898 redirect_type = ClassFinalizer::NewFinalizedMalformedType( 9879 redirect_type = ClassFinalizer::NewFinalizedMalformedType(
9899 error, 9880 error,
9900 script_, 9881 script_,
9901 call_pos, 9882 call_pos,
9902 "redirecting factory type '%s' cannot be instantiated", 9883 "redirecting factory type '%s' cannot be instantiated",
9903 String::Handle(redirect_type.UserVisibleName()).ToCString()); 9884 String::Handle(redirect_type.UserVisibleName()).ToCString());
9904 error = Error::null();
9905 } 9885 }
9906 } 9886 }
9907 if (redirect_type.IsMalformed() || 9887 if (redirect_type.IsMalformedOrMalbounded()) {
9908 redirect_type.IsMalboundedWithError(&error)) {
9909 if (is_const) { 9888 if (is_const) {
9910 if (redirect_type.IsMalformed()) { 9889 ErrorMsg(Error::Handle(redirect_type.error()));
9911 error = type.malformed_error();
9912 }
9913 ErrorMsg(error);
9914 } 9890 }
9915 return ThrowTypeError(redirect_type.token_pos(), redirect_type); 9891 return ThrowTypeError(redirect_type.token_pos(), redirect_type);
9916 } 9892 }
9917 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { 9893 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) {
9918 // Additional type checking of the result is necessary. 9894 // Additional type checking of the result is necessary.
9919 type_bound = type.raw(); 9895 type_bound = type.raw();
9920 } 9896 }
9921 type = redirect_type.raw(); 9897 type = redirect_type.raw();
9922 type_class = type.type_class(); 9898 type_class = type.type_class();
9923 type_class_name = type_class.Name(); 9899 type_class_name = type_class.Name();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
9968 } 9944 }
9969 return ThrowNoSuchMethodError(call_pos, 9945 return ThrowNoSuchMethodError(call_pos,
9970 type_class, 9946 type_class,
9971 external_constructor_name, 9947 external_constructor_name,
9972 arguments, 9948 arguments,
9973 InvocationMirror::kConstructor, 9949 InvocationMirror::kConstructor,
9974 InvocationMirror::kMethod, 9950 InvocationMirror::kMethod,
9975 &constructor); 9951 &constructor);
9976 } 9952 }
9977 9953
9978 // Return a throw in case of a malformed type or report a compile-time error 9954 // Return a throw in case of a malformed or malbounded type or report a
9979 // if the constructor is const. 9955 // compile-time error if the constructor is const.
9980 Error& error = Error::Handle(); 9956 if (type.IsMalformedOrMalbounded()) {
9981 if (type.IsMalformed() || type.IsMalboundedWithError(&error)) {
9982 if (is_const) { 9957 if (is_const) {
9983 if (type.IsMalformed()) { 9958 ErrorMsg(Error::Handle(type.error()));
9984 error = type.malformed_error();
9985 }
9986 ErrorMsg(error);
9987 } 9959 }
9988 return ThrowTypeError(type_pos, type); 9960 return ThrowTypeError(type_pos, type);
9989 } 9961 }
9990 type_arguments ^= type_arguments.Canonicalize(); 9962 type_arguments ^= type_arguments.Canonicalize();
9991 // Make the constructor call. 9963 // Make the constructor call.
9992 AstNode* new_object = NULL; 9964 AstNode* new_object = NULL;
9993 if (is_const) { 9965 if (is_const) {
9994 if (!constructor.is_const()) { 9966 if (!constructor.is_const()) {
9995 const String& external_constructor_name = 9967 const String& external_constructor_name =
9996 (named_constructor ? constructor_name : type_class_name); 9968 (named_constructor ? constructor_name : type_class_name);
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
10699 void Parser::SkipQualIdent() { 10671 void Parser::SkipQualIdent() {
10700 ASSERT(IsIdentifier()); 10672 ASSERT(IsIdentifier());
10701 ConsumeToken(); 10673 ConsumeToken();
10702 if (CurrentToken() == Token::kPERIOD) { 10674 if (CurrentToken() == Token::kPERIOD) {
10703 ConsumeToken(); // Consume the kPERIOD token. 10675 ConsumeToken(); // Consume the kPERIOD token.
10704 ExpectIdentifier("identifier expected after '.'"); 10676 ExpectIdentifier("identifier expected after '.'");
10705 } 10677 }
10706 } 10678 }
10707 10679
10708 } // namespace dart 10680 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698