Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 28595) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -30,6 +30,7 @@ |
| DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
| DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| +DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef"); |
| DECLARE_FLAG(bool, error_on_bad_type); |
| DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| @@ -3800,9 +3801,24 @@ |
| } |
| cls.set_type_parameters(orig_type_parameters); |
| } |
| + |
| + if (is_abstract) { |
| + cls.set_is_abstract(); |
| + } |
| + if (metadata_pos >= 0) { |
| + library_.AddClassMetadata(cls, metadata_pos); |
| + } |
| + |
| + const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| + if (is_mixin_declaration && is_patch) { |
| + ErrorMsg(classname_pos, |
| + "mixin application '%s' may not be a patch class", |
| + class_name.ToCString()); |
| + } |
| + |
| AbstractType& super_type = Type::Handle(); |
| - if (CurrentToken() == Token::kEXTENDS) { |
| - ConsumeToken(); |
| + if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| + ConsumeToken(); // extends or = |
| const intptr_t type_pos = TokenPos(); |
| super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| if (super_type.IsDynamicType()) { |
| @@ -3821,6 +3837,10 @@ |
| if (CurrentToken() == Token::kWITH) { |
| super_type = ParseMixins(pending_classes, super_type); |
| } |
| + if (is_mixin_declaration) { |
| + cls.set_is_mixin_typedef(); |
| + 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
|
| + } |
| } else { |
| // No extends clause: implicitly extend Object, unless Object itself. |
| if (!cls.IsObjectClass()) { |
| @@ -3828,15 +3848,18 @@ |
| } |
| } |
| ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
| + // TODO(12773): Treat a mixin application as an alias, not as a base |
| + // class whose super class is the mixin application! This is difficult |
| + // 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.
|
| cls.set_super_type(super_type); |
| if (CurrentToken() == Token::kIMPLEMENTS) { |
| + // At this point, a mixin applicaton class already has an interface, but |
| + // ParseInterfaceList will add to the list and not lose the one already |
| + // present. |
|
regis
2013/10/15 00:19:41
This comment is actually not correct anymore. The
hausner
2013/10/15 15:57:06
Done.
|
| ParseInterfaceList(cls); |
| } |
| - if (is_abstract) { |
| - cls.set_is_abstract(); |
| - } |
| if (is_patch) { |
| // Apply the changes to the patched class looked up above. |
| ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
| @@ -3847,15 +3870,16 @@ |
| cls.set_is_patch(); |
| } |
| pending_classes.Add(cls, Heap::kOld); |
| - if (metadata_pos >= 0) { |
| - library_.AddClassMetadata(cls, metadata_pos); |
| - } |
| - if (CurrentToken() != Token::kLBRACE) { |
| - ErrorMsg("{ expected"); |
| + if (is_mixin_declaration) { |
| + ExpectSemicolon(); |
| + } else { |
| + if (CurrentToken() != Token::kLBRACE) { |
| + ErrorMsg("{ expected"); |
| + } |
| + SkipBlock(); |
| + ExpectToken(Token::kRBRACE); |
| } |
| - SkipBlock(); |
| - ExpectToken(Token::kRBRACE); |
| } |
| @@ -4100,6 +4124,9 @@ |
| ExpectToken(Token::kTYPEDEF); |
| if (IsMixinTypedef()) { |
| + if (FLAG_warn_mixin_typedef) { |
| + Warning("deprecated mixin typedef"); |
| + } |
| ParseMixinTypedef(pending_classes, metadata_pos); |
| return; |
| } |