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 |