Chromium Code Reviews| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "vm/stack_frame.h" | 23 #include "vm/stack_frame.h" |
| 24 #include "vm/symbols.h" | 24 #include "vm/symbols.h" |
| 25 | 25 |
| 26 namespace dart { | 26 namespace dart { |
| 27 | 27 |
| 28 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 28 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 29 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 29 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 30 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 30 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 31 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 31 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
| 32 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 32 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| 33 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef"); | |
| 33 DECLARE_FLAG(bool, error_on_bad_type); | 34 DECLARE_FLAG(bool, error_on_bad_type); |
| 34 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 35 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 35 | 36 |
| 36 static void CheckedModeHandler(bool value) { | 37 static void CheckedModeHandler(bool value) { |
| 37 FLAG_enable_asserts = value; | 38 FLAG_enable_asserts = value; |
| 38 FLAG_enable_type_checks = value; | 39 FLAG_enable_type_checks = value; |
| 39 } | 40 } |
| 40 | 41 |
| 41 // --enable-checked-mode and --checked both enable checked mode which is | 42 // --enable-checked-mode and --checked both enable checked mode which is |
| 42 // equivalent to setting --enable-asserts and --enable-type-checks. | 43 // equivalent to setting --enable-asserts and --enable-type-checks. |
| (...skipping 3750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3793 "original type parameter '%s'", | 3794 "original type parameter '%s'", |
| 3794 new_name.ToCString(), | 3795 new_name.ToCString(), |
| 3795 class_name.ToCString(), | 3796 class_name.ToCString(), |
| 3796 orig_name.ToCString()); | 3797 orig_name.ToCString()); |
| 3797 } | 3798 } |
| 3798 // We do not check that the bounds are repeated. We use the original ones. | 3799 // We do not check that the bounds are repeated. We use the original ones. |
| 3799 // TODO(regis): Should we check? | 3800 // TODO(regis): Should we check? |
| 3800 } | 3801 } |
| 3801 cls.set_type_parameters(orig_type_parameters); | 3802 cls.set_type_parameters(orig_type_parameters); |
| 3802 } | 3803 } |
| 3804 | |
| 3805 if (is_abstract) { | |
| 3806 cls.set_is_abstract(); | |
| 3807 } | |
| 3808 if (metadata_pos >= 0) { | |
| 3809 library_.AddClassMetadata(cls, metadata_pos); | |
| 3810 } | |
| 3811 | |
| 3812 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | |
| 3813 if (is_mixin_declaration && is_patch) { | |
| 3814 ErrorMsg(classname_pos, | |
| 3815 "mixin application '%s' may not be a patch class", | |
| 3816 class_name.ToCString()); | |
| 3817 } | |
| 3818 | |
| 3803 AbstractType& super_type = Type::Handle(); | 3819 AbstractType& super_type = Type::Handle(); |
| 3804 if (CurrentToken() == Token::kEXTENDS) { | 3820 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 3805 ConsumeToken(); | 3821 ConsumeToken(); // extends or = |
| 3806 const intptr_t type_pos = TokenPos(); | 3822 const intptr_t type_pos = TokenPos(); |
| 3807 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 3823 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 3808 if (super_type.IsDynamicType()) { | 3824 if (super_type.IsDynamicType()) { |
| 3809 // The string 'dynamic' is not resolved yet at this point, but a malformed | 3825 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 3810 // type mapped to dynamic can be encountered here. | 3826 // type mapped to dynamic can be encountered here. |
| 3811 ErrorMsg(type_pos, | 3827 ErrorMsg(type_pos, |
| 3812 "class '%s' may not extend a malformed type", | 3828 "class '%s' may not extend a malformed type", |
| 3813 class_name.ToCString()); | 3829 class_name.ToCString()); |
| 3814 } | 3830 } |
| 3815 if (super_type.IsTypeParameter()) { | 3831 if (super_type.IsTypeParameter()) { |
| 3816 ErrorMsg(type_pos, | 3832 ErrorMsg(type_pos, |
| 3817 "class '%s' may not extend type parameter '%s'", | 3833 "class '%s' may not extend type parameter '%s'", |
| 3818 class_name.ToCString(), | 3834 class_name.ToCString(), |
| 3819 String::Handle(super_type.UserVisibleName()).ToCString()); | 3835 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3820 } | 3836 } |
| 3821 if (CurrentToken() == Token::kWITH) { | 3837 if (CurrentToken() == Token::kWITH) { |
| 3822 super_type = ParseMixins(pending_classes, super_type); | 3838 super_type = ParseMixins(pending_classes, super_type); |
| 3823 } | 3839 } |
| 3840 if (is_mixin_declaration) { | |
| 3841 cls.set_is_mixin_typedef(); | |
| 3842 cls.set_is_synthesized_class(); | |
|
regis
2013/10/15 00:19:41
I am wondering if this synthesized class marker is
hausner
2013/10/15 15:57:06
I can look at this for a separate change. The debu
| |
| 3843 } | |
| 3824 } else { | 3844 } else { |
| 3825 // No extends clause: implicitly extend Object, unless Object itself. | 3845 // No extends clause: implicitly extend Object, unless Object itself. |
| 3826 if (!cls.IsObjectClass()) { | 3846 if (!cls.IsObjectClass()) { |
| 3827 super_type = Type::ObjectType(); | 3847 super_type = Type::ObjectType(); |
| 3828 } | 3848 } |
| 3829 } | 3849 } |
| 3830 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); | 3850 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
| 3851 // TODO(12773): Treat a mixin application as an alias, not as a base | |
| 3852 // class whose super class is the mixin application! This is difficult | |
| 3853 // because of issues involving subsitution of type parameters | |
|
regis
2013/10/15 00:19:41
This is not a TODO. The issue 12773 is marked as f
hausner
2013/10/15 15:57:06
Done.
| |
| 3831 cls.set_super_type(super_type); | 3854 cls.set_super_type(super_type); |
| 3832 | 3855 |
| 3833 if (CurrentToken() == Token::kIMPLEMENTS) { | 3856 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3857 // At this point, a mixin applicaton class already has an interface, but | |
| 3858 // ParseInterfaceList will add to the list and not lose the one already | |
| 3859 // present. | |
|
regis
2013/10/15 00:19:41
This comment is actually not correct anymore. The
hausner
2013/10/15 15:57:06
Done.
| |
| 3834 ParseInterfaceList(cls); | 3860 ParseInterfaceList(cls); |
| 3835 } | 3861 } |
| 3836 | 3862 |
| 3837 if (is_abstract) { | |
| 3838 cls.set_is_abstract(); | |
| 3839 } | |
| 3840 if (is_patch) { | 3863 if (is_patch) { |
| 3841 // Apply the changes to the patched class looked up above. | 3864 // Apply the changes to the patched class looked up above. |
| 3842 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); | 3865 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
| 3843 // The patched class must not be finalized yet. | 3866 // The patched class must not be finalized yet. |
| 3844 const Class& orig_class = Class::Cast(obj); | 3867 const Class& orig_class = Class::Cast(obj); |
| 3845 ASSERT(!orig_class.is_finalized()); | 3868 ASSERT(!orig_class.is_finalized()); |
| 3846 orig_class.set_patch_class(cls); | 3869 orig_class.set_patch_class(cls); |
| 3847 cls.set_is_patch(); | 3870 cls.set_is_patch(); |
| 3848 } | 3871 } |
| 3849 pending_classes.Add(cls, Heap::kOld); | 3872 pending_classes.Add(cls, Heap::kOld); |
| 3850 if (metadata_pos >= 0) { | 3873 |
| 3851 library_.AddClassMetadata(cls, metadata_pos); | 3874 if (is_mixin_declaration) { |
| 3875 ExpectSemicolon(); | |
| 3876 } else { | |
| 3877 if (CurrentToken() != Token::kLBRACE) { | |
| 3878 ErrorMsg("{ expected"); | |
| 3879 } | |
| 3880 SkipBlock(); | |
| 3881 ExpectToken(Token::kRBRACE); | |
| 3852 } | 3882 } |
| 3853 | |
| 3854 if (CurrentToken() != Token::kLBRACE) { | |
| 3855 ErrorMsg("{ expected"); | |
| 3856 } | |
| 3857 SkipBlock(); | |
| 3858 ExpectToken(Token::kRBRACE); | |
| 3859 } | 3883 } |
| 3860 | 3884 |
| 3861 | 3885 |
| 3862 void Parser::ParseClassDefinition(const Class& cls) { | 3886 void Parser::ParseClassDefinition(const Class& cls) { |
| 3863 TRACE_PARSER("ParseClassDefinition"); | 3887 TRACE_PARSER("ParseClassDefinition"); |
| 3864 set_current_class(cls); | 3888 set_current_class(cls); |
| 3865 is_top_level_ = true; | 3889 is_top_level_ = true; |
| 3866 String& class_name = String::Handle(cls.Name()); | 3890 String& class_name = String::Handle(cls.Name()); |
| 3867 const intptr_t class_pos = TokenPos(); | 3891 const intptr_t class_pos = TokenPos(); |
| 3868 ClassDesc members(cls, class_name, false, class_pos); | 3892 ClassDesc members(cls, class_name, false, class_pos); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4026 String::Handle(type.UserVisibleName()).ToCString()); | 4050 String::Handle(type.UserVisibleName()).ToCString()); |
| 4027 } | 4051 } |
| 4028 | 4052 |
| 4029 if (CurrentToken() != Token::kWITH) { | 4053 if (CurrentToken() != Token::kWITH) { |
| 4030 ErrorMsg("mixin application 'with Type' expected"); | 4054 ErrorMsg("mixin application 'with Type' expected"); |
| 4031 } | 4055 } |
| 4032 type = ParseMixins(pending_classes, type); | 4056 type = ParseMixins(pending_classes, type); |
| 4033 | 4057 |
| 4034 // TODO(12773): Treat the mixin application as an alias, not as a base | 4058 // TODO(12773): Treat the mixin application as an alias, not as a base |
| 4035 // class whose super class is the mixin application! This is difficult because | 4059 // class whose super class is the mixin application! This is difficult because |
| 4036 // of issues involving subsitution of type parameters | 4060 // of issues involving subsitution of type parameters |
|
regis
2013/10/15 00:19:41
ditto, although this ParseMixinTypedef will be rem
hausner
2013/10/15 15:57:06
Done.
| |
| 4037 mixin_application.set_super_type(type); | 4061 mixin_application.set_super_type(type); |
| 4038 mixin_application.set_is_synthesized_class(); | 4062 mixin_application.set_is_synthesized_class(); |
| 4039 | 4063 |
| 4040 // This mixin application typedef needs an implicit constructor, but it is | 4064 // This mixin application typedef needs an implicit constructor, but it is |
| 4041 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4065 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 4042 // because this class should be lazily compiled. | 4066 // because this class should be lazily compiled. |
| 4043 if (CurrentToken() == Token::kIMPLEMENTS) { | 4067 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 4044 // At this point, the mixin_application alias already has an interface, but | 4068 // At this point, the mixin_application alias already has an interface, but |
| 4045 // ParseInterfaceList will add to the list and not lose the one already | 4069 // ParseInterfaceList will add to the list and not lose the one already |
| 4046 // there. | 4070 // there. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4093 return is_mixin_def; | 4117 return is_mixin_def; |
| 4094 } | 4118 } |
| 4095 | 4119 |
| 4096 | 4120 |
| 4097 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4121 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 4098 intptr_t metadata_pos) { | 4122 intptr_t metadata_pos) { |
| 4099 TRACE_PARSER("ParseTypedef"); | 4123 TRACE_PARSER("ParseTypedef"); |
| 4100 ExpectToken(Token::kTYPEDEF); | 4124 ExpectToken(Token::kTYPEDEF); |
| 4101 | 4125 |
| 4102 if (IsMixinTypedef()) { | 4126 if (IsMixinTypedef()) { |
| 4127 if (FLAG_warn_mixin_typedef) { | |
| 4128 Warning("deprecated mixin typedef"); | |
| 4129 } | |
| 4103 ParseMixinTypedef(pending_classes, metadata_pos); | 4130 ParseMixinTypedef(pending_classes, metadata_pos); |
| 4104 return; | 4131 return; |
| 4105 } | 4132 } |
| 4106 | 4133 |
| 4107 // Parse the result type of the function type. | 4134 // Parse the result type of the function type. |
| 4108 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 4135 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 4109 if (CurrentToken() == Token::kVOID) { | 4136 if (CurrentToken() == Token::kVOID) { |
| 4110 ConsumeToken(); | 4137 ConsumeToken(); |
| 4111 result_type = Type::VoidType(); | 4138 result_type = Type::VoidType(); |
| 4112 } else if (!IsFunctionTypeAliasName()) { | 4139 } else if (!IsFunctionTypeAliasName()) { |
| (...skipping 6517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10630 void Parser::SkipQualIdent() { | 10657 void Parser::SkipQualIdent() { |
| 10631 ASSERT(IsIdentifier()); | 10658 ASSERT(IsIdentifier()); |
| 10632 ConsumeToken(); | 10659 ConsumeToken(); |
| 10633 if (CurrentToken() == Token::kPERIOD) { | 10660 if (CurrentToken() == Token::kPERIOD) { |
| 10634 ConsumeToken(); // Consume the kPERIOD token. | 10661 ConsumeToken(); // Consume the kPERIOD token. |
| 10635 ExpectIdentifier("identifier expected after '.'"); | 10662 ExpectIdentifier("identifier expected after '.'"); |
| 10636 } | 10663 } |
| 10637 } | 10664 } |
| 10638 | 10665 |
| 10639 } // namespace dart | 10666 } // namespace dart |
| OLD | NEW |