Index: pkg/observe/lib/transform.dart |
diff --git a/pkg/observe/lib/transform.dart b/pkg/observe/lib/transform.dart |
index 3e0aac25cae17c265ee72ac98f27439296be9f82..d8396b9a4983637465ffb4033eeda31185115b46 100644 |
--- a/pkg/observe/lib/transform.dart |
+++ b/pkg/observe/lib/transform.dart |
@@ -135,19 +135,20 @@ void _transformClass(ClassDeclaration cls, TextEditTransaction code, |
// report a warning later below. Because we don't have type analysis (only |
// syntactic understanding of the code), we only report warnings that are |
// known to be true. |
- var declaresObservable = false; |
+ var explicitObservable = false; |
+ var implicitObservable = false; |
if (cls.extendsClause != null) { |
var id = _getSimpleIdentifier(cls.extendsClause.superclass.name); |
if (id.name == 'Observable') { |
code.edit(id.offset, id.end, 'ChangeNotifier'); |
- declaresObservable = true; |
+ explicitObservable = true; |
} else if (id.name == 'ChangeNotifier') { |
- declaresObservable = true; |
+ explicitObservable = true; |
} else if (id.name != 'HtmlElement' && id.name != 'CustomElement' |
&& id.name != 'Object') { |
// TODO(sigmund): this is conservative, consider using type-resolution to |
// improve this check. |
- declaresObservable = true; |
+ implicitObservable = true; |
} |
} |
@@ -156,25 +157,27 @@ void _transformClass(ClassDeclaration cls, TextEditTransaction code, |
var id = _getSimpleIdentifier(type.name); |
if (id.name == 'Observable') { |
code.edit(id.offset, id.end, 'ChangeNotifier'); |
- declaresObservable = true; |
+ explicitObservable = true; |
break; |
} else if (id.name == 'ChangeNotifier') { |
- declaresObservable = true; |
+ explicitObservable = true; |
break; |
} else { |
// TODO(sigmund): this is conservative, consider using type-resolution |
// to improve this check. |
- declaresObservable = true; |
+ implicitObservable = true; |
} |
} |
} |
- if (!declaresObservable && cls.implementsClause != null) { |
+ if (cls.implementsClause != null) { |
// TODO(sigmund): consider adding type-resolution to give a more precise |
// answer. |
- declaresObservable = true; |
+ implicitObservable = true; |
} |
+ var declaresObservable = explicitObservable || implicitObservable; |
+ |
// Track fields that were transformed. |
var instanceFields = new Set<String>(); |
var getters = new List<String>(); |
@@ -223,6 +226,8 @@ void _transformClass(ClassDeclaration cls, TextEditTransaction code, |
// If nothing was @observable, bail. |
if (instanceFields.length == 0) return; |
+ if (!explicitObservable) _mixinObservable(cls, code); |
+ |
// Fix initializers, because they aren't allowed to call the setter. |
for (var member in cls.members) { |
if (member is ConstructorDeclaration) { |
@@ -231,6 +236,23 @@ void _transformClass(ClassDeclaration cls, TextEditTransaction code, |
} |
} |
+/** Adds "with ChangeNotifier" and associated implementation. */ |
+void _mixinObservable(ClassDeclaration cls, TextEditTransaction code) { |
+ // Note: we need to be careful to put the with clause after extends, but |
+ // before implements clause. |
+ if (cls.withClause != null) { |
+ var pos = cls.withClause.end; |
+ code.edit(pos, pos, ', ChangeNotifier'); |
+ } else if (cls.extendsClause != null) { |
+ var pos = cls.extendsClause.end; |
+ code.edit(pos, pos, ' with ChangeNotifier '); |
+ } else { |
+ var params = cls.typeParameters; |
+ var pos = params != null ? params.end : cls.name.end; |
+ code.edit(pos, pos, ' extends ChangeNotifier '); |
+ } |
+} |
+ |
SimpleIdentifier _getSimpleIdentifier(Identifier id) => |
id is PrefixedIdentifier ? (id as PrefixedIdentifier).identifier : id; |