| 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;
|
|
|
|
|