Chromium Code Reviews| Index: lib/message_generator.dart |
| diff --git a/lib/message_generator.dart b/lib/message_generator.dart |
| index 4dd64bba2066d855bef896a69e4a1f39d2dc033c..4a07bba78d36072aa97bfd8a9efba1605de5e2db 100644 |
| --- a/lib/message_generator.dart |
| +++ b/lib/message_generator.dart |
| @@ -5,18 +5,46 @@ |
| part of protoc; |
| class MessageGenerator extends ProtobufContainer { |
| - // Returns the mixin for this message, or null if none. |
| - static PbMixin _getMixin(DescriptorProto desc, PbMixin defaultValue) { |
| - if (!desc.hasOptions()) return defaultValue; |
| - if (!desc.options.hasExtension(Dart_options.mixin)) return defaultValue; |
| + /// Returns the mixin for this message, or null if none. |
| + /// |
| + /// First searches [declaredMixins], then internal mixins declared by |
| + /// [findMixin]. |
| + static PbMixin _getMixin(DescriptorProto desc, |
| + Map<String, DartMixin> declaredMixins, String defaultMixin) { |
| + PbMixin resolveMixin(String name, {List<String> children: const []}) { |
| + if (name.isEmpty) return null; // don't use a mixin (override any default) |
| + |
| + if (declaredMixins.containsKey(name)) { |
| + var dartMixin = declaredMixins[name]; |
| + |
| + PbMixin parent; |
| + if (dartMixin.hasParent()) { |
| + var parentName = dartMixin.parent; |
| + if (children.contains(parentName)) { |
|
skybrian
2016/06/22 20:29:52
Seems better to check for cycles sooner? The error
frederikmutzel
2016/06/23 12:30:16
Moved to file_generator.
I also moved the convers
|
| + var chain = children.join('->') + '->$name'; |
| + throw ('cycle in mixin parents: $chain'); |
| + } |
| + children.add(name); |
| + var parent = resolveMixin(dartMixin.parent, children: children); |
| + if (parent == null) { |
| + throw ('unknown mixin parent: $parent of $name'); |
| + } |
| + } |
| + return new PbMixin(dartMixin.name, |
| + importFrom: dartMixin.importFrom, parent: parent); |
| + } |
| - String name = desc.options.getExtension(Dart_options.mixin); |
| - if (name.isEmpty) return null; // don't use a mixin (override any default) |
| - var mixin = findMixin(name); |
| - if (mixin == null) { |
| - throw ("unknown mixin class: ${name}"); |
| + var internalMixin = findMixin(name); |
| + if (internalMixin == null) throw ("unknown mixin class: ${name}"); |
| + return internalMixin; |
| } |
| - return mixin; |
| + |
| + if (!desc.hasOptions() || !desc.options.hasExtension(Dart_options.mixin)) { |
| + return resolveMixin(defaultMixin); |
| + } |
| + |
| + String name = desc.options.getExtension(Dart_options.mixin); |
| + return resolveMixin(name); |
| } |
| final String classname; |
| @@ -33,7 +61,7 @@ class MessageGenerator extends ProtobufContainer { |
| List<ProtobufField> _fieldList; |
| MessageGenerator(DescriptorProto descriptor, ProtobufContainer parent, |
| - PbMixin defaultMixin) |
| + Map<String, DartMixin> declaredMixins, String defaultMixin) |
| : _descriptor = descriptor, |
| _parent = parent, |
| classname = (parent.classname == '') |
| @@ -44,13 +72,14 @@ class MessageGenerator extends ProtobufContainer { |
| : (parent.fqname == '.' |
| ? '.${descriptor.name}' |
| : '${parent.fqname}.${descriptor.name}'), |
| - mixin = _getMixin(descriptor, defaultMixin) { |
| + mixin = _getMixin(descriptor, declaredMixins, defaultMixin ?? '') { |
| for (EnumDescriptorProto e in _descriptor.enumType) { |
| _enumGenerators.add(new EnumGenerator(e, this)); |
| } |
| for (DescriptorProto n in _descriptor.nestedType) { |
| - _messageGenerators.add(new MessageGenerator(n, this, defaultMixin)); |
| + _messageGenerators |
| + .add(new MessageGenerator(n, this, declaredMixins, defaultMixin)); |
| } |
| for (FieldDescriptorProto x in _descriptor.extension) { |