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

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
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('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/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 3864 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 ErrorMsg(classname_pos, 3875 ErrorMsg(classname_pos,
3876 "mixin application '%s' may not be a patch class", 3876 "mixin application '%s' may not be a patch class",
3877 class_name.ToCString()); 3877 class_name.ToCString());
3878 } 3878 }
3879 3879
3880 AbstractType& super_type = Type::Handle(); 3880 AbstractType& super_type = Type::Handle();
3881 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { 3881 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) {
3882 ConsumeToken(); // extends or = 3882 ConsumeToken(); // extends or =
3883 const intptr_t type_pos = TokenPos(); 3883 const intptr_t type_pos = TokenPos();
3884 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); 3884 super_type = ParseType(ClassFinalizer::kResolveTypeParameters);
3885 if (super_type.IsMalformed() || super_type.IsDynamicType()) { 3885 if (super_type.IsMalformedOrMalbounded()) {
3886 ErrorMsg(Error::Handle(super_type.error()));
3887 }
3888 if (super_type.IsDynamicType()) {
3886 // Unlikely here, since super type is not resolved yet. 3889 // Unlikely here, since super type is not resolved yet.
3887 ErrorMsg(type_pos, 3890 ErrorMsg(type_pos,
3888 "class '%s' may not extend %s", 3891 "class '%s' may not extend 'dynamic'",
3889 class_name.ToCString(), 3892 class_name.ToCString());
3890 super_type.IsMalformed() ? "a malformed type" : "'dynamic'");
3891 } 3893 }
3892 if (super_type.IsTypeParameter()) { 3894 if (super_type.IsTypeParameter()) {
3893 ErrorMsg(type_pos, 3895 ErrorMsg(type_pos,
3894 "class '%s' may not extend type parameter '%s'", 3896 "class '%s' may not extend type parameter '%s'",
3895 class_name.ToCString(), 3897 class_name.ToCString(),
3896 String::Handle(super_type.UserVisibleName()).ToCString()); 3898 String::Handle(super_type.UserVisibleName()).ToCString());
3897 } 3899 }
3898 // The class finalizer will check whether the super type is malbounded. 3900 // The class finalizer will check whether the super type is malbounded.
3899 if (CurrentToken() == Token::kWITH) { 3901 if (CurrentToken() == Token::kWITH) {
3900 super_type = ParseMixins(super_type); 3902 super_type = ParseMixins(super_type);
(...skipping 3516 matching lines...) Expand 10 before | Expand all | Expand 10 after
7417 // Location argument. 7419 // Location argument.
7418 arguments->Add(new LiteralNode( 7420 arguments->Add(new LiteralNode(
7419 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); 7421 type_pos, Integer::ZoneHandle(Integer::New(type_pos))));
7420 // Src value argument. 7422 // Src value argument.
7421 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); 7423 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle()));
7422 // Dst type name argument. 7424 // Dst type name argument.
7423 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed())); 7425 arguments->Add(new LiteralNode(type_pos, Symbols::Malformed()));
7424 // Dst name argument. 7426 // Dst name argument.
7425 arguments->Add(new LiteralNode(type_pos, Symbols::Empty())); 7427 arguments->Add(new LiteralNode(type_pos, Symbols::Empty()));
7426 // Malformed type error or malbounded type error. 7428 // Malformed type error or malbounded type error.
7427 Error& error = Error::Handle(); 7429 const Error& error = Error::Handle(type.error());
7428 if (type.IsMalformed()) { 7430 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( 7431 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
7435 Symbols::New(error.ToErrorCString())))); 7432 Symbols::New(error.ToErrorCString()))));
7436 return MakeStaticCall(Symbols::TypeError(), 7433 return MakeStaticCall(Symbols::TypeError(),
7437 Library::PrivateCoreLibName(Symbols::ThrowNew()), 7434 Library::PrivateCoreLibName(Symbols::ThrowNew()),
7438 arguments); 7435 arguments);
7439 } 7436 }
7440 7437
7441 7438
7442 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, 7439 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos,
7443 const Class& cls, 7440 const Class& cls,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
7547 if (!type.IsInstantiated() && 7544 if (!type.IsInstantiated() &&
7548 (current_block_->scope->function_level() > 0)) { 7545 (current_block_->scope->function_level() > 0)) {
7549 // Make sure that the instantiator is captured. 7546 // Make sure that the instantiator is captured.
7550 CaptureInstantiator(); 7547 CaptureInstantiator();
7551 } 7548 }
7552 right_operand = new TypeNode(type_pos, type); 7549 right_operand = new TypeNode(type_pos, type);
7553 // In production mode, the type may be malformed. 7550 // In production mode, the type may be malformed.
7554 // In checked mode, the type may be malformed or malbounded. 7551 // In checked mode, the type may be malformed or malbounded.
7555 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || 7552 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) ||
7556 (op_kind == Token::kAS)) && 7553 (op_kind == Token::kAS)) &&
7557 (type.IsMalformed() || type.IsMalbounded())) { 7554 type.IsMalformedOrMalbounded()) {
7558 // Note that a type error is thrown even if the tested value is null 7555 // Note that a type error is thrown even if the tested value is null
7559 // in a type test or in a type cast. 7556 // in a type test or in a type cast.
7560 return ThrowTypeError(type_pos, type); 7557 return ThrowTypeError(type_pos, type);
7561 } 7558 }
7562 } 7559 }
7563 if (Token::IsRelationalOperator(op_kind) 7560 if (Token::IsRelationalOperator(op_kind)
7564 || Token::IsTypeTestOperator(op_kind) 7561 || Token::IsTypeTestOperator(op_kind)
7565 || Token::IsTypeCastOperator(op_kind) 7562 || Token::IsTypeCastOperator(op_kind)
7566 || Token::IsEqualityOperator(op_kind)) { 7563 || Token::IsEqualityOperator(op_kind)) {
7567 if (Token::IsTypeTestOperator(op_kind) || 7564 if (Token::IsTypeTestOperator(op_kind) ||
(...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after
9783 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 9780 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
9784 bool is_const = (op_kind == Token::kCONST); 9781 bool is_const = (op_kind == Token::kCONST);
9785 if (!IsIdentifier()) { 9782 if (!IsIdentifier()) {
9786 ErrorMsg("type name expected"); 9783 ErrorMsg("type name expected");
9787 } 9784 }
9788 intptr_t type_pos = TokenPos(); 9785 intptr_t type_pos = TokenPos();
9789 AbstractType& type = AbstractType::Handle( 9786 AbstractType& type = AbstractType::Handle(
9790 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); 9787 ParseType(ClassFinalizer::kCanonicalizeWellFormed));
9791 // In case the type is malformed, throw a dynamic type error after finishing 9788 // In case the type is malformed, throw a dynamic type error after finishing
9792 // parsing the instance creation expression. 9789 // parsing the instance creation expression.
9793 if (!type.IsMalformed()) { 9790 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
9794 if (type.IsTypeParameter() || type.IsDynamicType()) { 9791 // Replace the type with a malformed type.
9795 // Replace the type with a malformed type. 9792 type = ClassFinalizer::NewFinalizedMalformedType(
9796 type = ClassFinalizer::NewFinalizedMalformedType( 9793 Error::Handle(), // No previous error.
9797 Error::Handle(), // No previous error. 9794 script_,
9798 script_, 9795 type_pos,
9799 type_pos, 9796 "%s'%s' cannot be instantiated",
9800 "%s'%s' cannot be instantiated", 9797 type.IsTypeParameter() ? "type parameter " : "",
9801 type.IsTypeParameter() ? "type parameter " : "", 9798 type.IsTypeParameter() ?
9802 type.IsTypeParameter() ? 9799 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 } 9800 }
9817 9801
9818 // The grammar allows for an optional ('.' identifier)? after the type, which 9802 // 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 9803 // 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 9804 // part of a misinterpreted qualified identifier, because only a valid library
9821 // prefix is accepted as qualifier. 9805 // prefix is accepted as qualifier.
9822 String* named_constructor = NULL; 9806 String* named_constructor = NULL;
9823 if (CurrentToken() == Token::kPERIOD) { 9807 if (CurrentToken() == Token::kPERIOD) {
9824 ConsumeToken(); 9808 ConsumeToken();
9825 named_constructor = ExpectIdentifier("name of constructor expected"); 9809 named_constructor = ExpectIdentifier("name of constructor expected");
9826 } 9810 }
9827 9811
9828 // Parse constructor parameters. 9812 // Parse constructor parameters.
9829 CheckToken(Token::kLPAREN); 9813 CheckToken(Token::kLPAREN);
9830 intptr_t call_pos = TokenPos(); 9814 intptr_t call_pos = TokenPos();
9831 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 9815 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const);
9832 9816
9833 // Parsing is complete, so we can return a throw in case of a malformed type 9817 // 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. 9818 // malbounded type or report a compile-time error if the constructor is const.
9835 if (type.IsMalformed()) { 9819 if (type.IsMalformedOrMalbounded()) {
9836 if (is_const) { 9820 if (is_const) {
9837 const Error& error = Error::Handle(type.malformed_error()); 9821 const Error& error = Error::Handle(type.error());
9838 ErrorMsg(error); 9822 ErrorMsg(error);
9839 } 9823 }
9840 return ThrowTypeError(type_pos, type); 9824 return ThrowTypeError(type_pos, type);
9841 } 9825 }
9842 9826
9843 // Resolve the type and optional identifier to a constructor or factory. 9827 // Resolve the type and optional identifier to a constructor or factory.
9844 Class& type_class = Class::Handle(type.type_class()); 9828 Class& type_class = Class::Handle(type.type_class());
9845 String& type_class_name = String::Handle(type_class.Name()); 9829 String& type_class_name = String::Handle(type_class.Name());
9846 AbstractTypeArguments& type_arguments = 9830 AbstractTypeArguments& type_arguments =
9847 AbstractTypeArguments::ZoneHandle(type.arguments()); 9831 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 9852 // Replace the type with a malformed type and compile a throw or report a
9869 // compile-time error if the constructor is const. 9853 // compile-time error if the constructor is const.
9870 if (is_const) { 9854 if (is_const) {
9871 type = ClassFinalizer::NewFinalizedMalformedType( 9855 type = ClassFinalizer::NewFinalizedMalformedType(
9872 Error::Handle(), // No previous error. 9856 Error::Handle(), // No previous error.
9873 script_, 9857 script_,
9874 call_pos, 9858 call_pos,
9875 "class '%s' has no constructor or factory named '%s'", 9859 "class '%s' has no constructor or factory named '%s'",
9876 String::Handle(type_class.Name()).ToCString(), 9860 String::Handle(type_class.Name()).ToCString(),
9877 external_constructor_name.ToCString()); 9861 external_constructor_name.ToCString());
9878 const Error& error = Error::Handle(type.malformed_error()); 9862 ErrorMsg(Error::Handle(type.error()));
9879 ErrorMsg(error);
9880 } 9863 }
9881 return ThrowNoSuchMethodError(call_pos, 9864 return ThrowNoSuchMethodError(call_pos,
9882 type_class, 9865 type_class,
9883 external_constructor_name, 9866 external_constructor_name,
9884 arguments, 9867 arguments,
9885 InvocationMirror::kConstructor, 9868 InvocationMirror::kConstructor,
9886 InvocationMirror::kMethod, 9869 InvocationMirror::kMethod,
9887 &constructor); 9870 &constructor);
9888 } else if (constructor.IsRedirectingFactory()) { 9871 } else if (constructor.IsRedirectingFactory()) {
9889 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); 9872 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
9890 Type& redirect_type = Type::Handle(constructor.RedirectionType()); 9873 Type& redirect_type = Type::Handle(constructor.RedirectionType());
9891 Error& error = Error::Handle(); 9874 if (!redirect_type.IsMalformedOrMalbounded() &&
9892 if (!redirect_type.IsMalformed() && !redirect_type.IsMalbounded() &&
9893 !redirect_type.IsInstantiated()) { 9875 !redirect_type.IsInstantiated()) {
9894 // The type arguments of the redirection type are instantiated from the 9876 // The type arguments of the redirection type are instantiated from the
9895 // type arguments of the parsed type of the 'new' or 'const' expression. 9877 // type arguments of the parsed type of the 'new' or 'const' expression.
9878 Error& error = Error::Handle();
9896 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); 9879 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error);
9897 if (!error.IsNull()) { 9880 if (!error.IsNull()) {
9898 redirect_type = ClassFinalizer::NewFinalizedMalformedType( 9881 redirect_type = ClassFinalizer::NewFinalizedMalformedType(
9899 error, 9882 error,
9900 script_, 9883 script_,
9901 call_pos, 9884 call_pos,
9902 "redirecting factory type '%s' cannot be instantiated", 9885 "redirecting factory type '%s' cannot be instantiated",
9903 String::Handle(redirect_type.UserVisibleName()).ToCString()); 9886 String::Handle(redirect_type.UserVisibleName()).ToCString());
9904 error = Error::null();
9905 } 9887 }
9906 } 9888 }
9907 if (redirect_type.IsMalformed() || 9889 if (redirect_type.IsMalformedOrMalbounded()) {
9908 redirect_type.IsMalboundedWithError(&error)) {
9909 if (is_const) { 9890 if (is_const) {
9910 if (redirect_type.IsMalformed()) { 9891 ErrorMsg(Error::Handle(redirect_type.error()));
9911 error = type.malformed_error();
9912 }
9913 ErrorMsg(error);
9914 } 9892 }
9915 return ThrowTypeError(redirect_type.token_pos(), redirect_type); 9893 return ThrowTypeError(redirect_type.token_pos(), redirect_type);
9916 } 9894 }
9917 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { 9895 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) {
9918 // Additional type checking of the result is necessary. 9896 // Additional type checking of the result is necessary.
9919 type_bound = type.raw(); 9897 type_bound = type.raw();
9920 } 9898 }
9921 type = redirect_type.raw(); 9899 type = redirect_type.raw();
9922 type_class = type.type_class(); 9900 type_class = type.type_class();
9923 type_class_name = type_class.Name(); 9901 type_class_name = type_class.Name();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
9968 } 9946 }
9969 return ThrowNoSuchMethodError(call_pos, 9947 return ThrowNoSuchMethodError(call_pos,
9970 type_class, 9948 type_class,
9971 external_constructor_name, 9949 external_constructor_name,
9972 arguments, 9950 arguments,
9973 InvocationMirror::kConstructor, 9951 InvocationMirror::kConstructor,
9974 InvocationMirror::kMethod, 9952 InvocationMirror::kMethod,
9975 &constructor); 9953 &constructor);
9976 } 9954 }
9977 9955
9978 // Return a throw in case of a malformed type or report a compile-time error 9956 // Return a throw in case of a malformed or malbounded type or report a
9979 // if the constructor is const. 9957 // compile-time error if the constructor is const.
9980 Error& error = Error::Handle(); 9958 if (type.IsMalformedOrMalbounded()) {
9981 if (type.IsMalformed() || type.IsMalboundedWithError(&error)) {
9982 if (is_const) { 9959 if (is_const) {
9983 if (type.IsMalformed()) { 9960 ErrorMsg(Error::Handle(type.error()));
9984 error = type.malformed_error();
9985 }
9986 ErrorMsg(error);
9987 } 9961 }
9988 return ThrowTypeError(type_pos, type); 9962 return ThrowTypeError(type_pos, type);
9989 } 9963 }
9990 type_arguments ^= type_arguments.Canonicalize(); 9964 type_arguments ^= type_arguments.Canonicalize();
9991 // Make the constructor call. 9965 // Make the constructor call.
9992 AstNode* new_object = NULL; 9966 AstNode* new_object = NULL;
9993 if (is_const) { 9967 if (is_const) {
9994 if (!constructor.is_const()) { 9968 if (!constructor.is_const()) {
9995 const String& external_constructor_name = 9969 const String& external_constructor_name =
9996 (named_constructor ? constructor_name : type_class_name); 9970 (named_constructor ? constructor_name : type_class_name);
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
10699 void Parser::SkipQualIdent() { 10673 void Parser::SkipQualIdent() {
10700 ASSERT(IsIdentifier()); 10674 ASSERT(IsIdentifier());
10701 ConsumeToken(); 10675 ConsumeToken();
10702 if (CurrentToken() == Token::kPERIOD) { 10676 if (CurrentToken() == Token::kPERIOD) {
10703 ConsumeToken(); // Consume the kPERIOD token. 10677 ConsumeToken(); // Consume the kPERIOD token.
10704 ExpectIdentifier("identifier expected after '.'"); 10678 ExpectIdentifier("identifier expected after '.'");
10705 } 10679 }
10706 } 10680 }
10707 10681
10708 } // namespace dart 10682 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698