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

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

Issue 27223005: Implement new mixin application syntax (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months 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 | « no previous file | tests/co19/co19-runtime.status » ('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 "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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698