| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |