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) { |