This package provides the data classes for the usage recording feature in the Dart SDK.
During compilation, usages of declarations annotated with @RecordUse() in reachable code are recorded, and information about these usages is made available to post-compile steps (such as link hooks). Usages in unreachable code are not recorded.
const redirecting factory constructors), any non-const generative constructor invocation, and any generative constructor tear-off in reachable code will be recorded. Calls to non-const factory constructors are not recorded directly by annotating the class; rather, any generative constructor invocation within the factory body will be recorded.Only usages in executable code are recorded. Usages appearing within metadata (annotations) are ignored.
[!NOTE] The
@RecordUse()annotation is only allowed on declarations within a package'slib/directory.
void main() { PirateTranslator.speak('Hello'); print(const PirateShip('Black Pearl', 50)); } abstract class PirateTranslator { @RecordUse() static String speak(String english) => 'Ahoy $english'; } @RecordUse() final class PirateShip { final String name; final int cannons; const PirateShip(this.name, this.cannons); }
This code will generate a data file that contains both the field values of the PirateShip instances, as well as the arguments for the speak method annotated with @RecordUse().
This information can then be accessed in a link hook as follows:
void main(List<String> arguments) { link(arguments, (input, output) async { final uses = input.recordedUses; if (uses == null) return; final calls = uses.calls[methodId] ?? []; for (final call in calls) { switch (call) { case CallWithArguments( positionalArguments: [StringConstant(value: final english), ...], ): // Shrink a translations file based on all the different translation // keys. print('Translating to pirate: $english'); case _: print('Cannot determine which translations are used.'); } } final ships = uses.instances[classId] ?? []; for (final ship in ships) { switch (ship) { case InstanceConstantReference( instanceConstant: InstanceConstant( fields: {'name': StringConstant(value: final name)}, ), ): // Include the 3d model for this ship in the application but not // bundle the other ships. print('Pirate ship found: $name'); case _: print('Cannot determine which ships are used.'); } } }); }
Contributions are welcome! Please open an issue or submit a pull request.