|
| 1 | +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file |
| 2 | +// for details. All rights reserved. Use of this source code is governed by a |
| 3 | +// BSD-style license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +// There is no public API exposed yet, the in progress api lives here. |
| 6 | +import 'dart:async'; |
| 7 | + |
| 8 | +import 'package:_fe_analyzer_shared/src/macros/api.dart'; |
| 9 | + |
| 10 | +macro class Observable implements FieldDeclarationsMacro { |
| 11 | + const Observable(); |
| 12 | + |
| 13 | + @override |
| 14 | + Future<void> buildDeclarationsForField( |
| 15 | + FieldDeclaration field, ClassMemberDeclarationBuilder builder) async { |
| 16 | + final name = field.identifier.name; |
| 17 | + if (!name.startsWith('_')) { |
| 18 | + throw ArgumentError( |
| 19 | + '@observable can only annotate private fields, and it will create ' |
| 20 | + 'public getters and setters for them, but the public field ' |
| 21 | + '$name was annotated.'); |
| 22 | + } |
| 23 | + var publicName = name.substring(1); |
| 24 | + var getter = DeclarationCode.fromParts( |
| 25 | + [field.type.code, ' get $publicName => ', field.identifier, ';']); |
| 26 | + builder.declareInClass(getter); |
| 27 | + |
| 28 | + var print = |
| 29 | + // ignore: deprecated_member_use |
| 30 | + await builder.resolveIdentifier(Uri.parse('dart:core'), 'print'); |
| 31 | + var setter = DeclarationCode.fromParts([ |
| 32 | + 'set $publicName(', |
| 33 | + field.type.code, |
| 34 | + ' val) {\n', |
| 35 | + print, |
| 36 | + "('Setting $publicName to \${val}');\n", |
| 37 | + field.identifier, |
| 38 | + ' = val;\n}', |
| 39 | + ]); |
| 40 | + builder.declareInClass(setter); |
| 41 | + } |
| 42 | +} |
0 commit comments