zengen 0.3.0 copy "zengen: ^0.3.0" to clipboard
zengen: ^0.3.0 copied to clipboard

outdatedDart 1 only

A package to generate boilerplate code.

ZenGen #

Build Status

This project provides a source_gen generator to generate boilerplate code.

This library is inspired from the project Lombok in the Java world.

Features #

@ToString() #

Annotating a class with @ToString() will generate an implementation of String toString() built by default with its public getters.

For instance :

@ToString()
class _A {
  final a;
  final int b;
  _A(this.a, this.b);
}

will generate :

@GeneratedFrom(_A)
class A {
  final a;
  final int b;
  A(this.a, this.b);
  @override String toString() => "A(a=$a, b=$b)";
}

The code generated can be customized with the following optional parameters:

  • callSuper: if set to true the result of toString will contains the result of super.toString().
  • exclude: a list of getter names can be exclude with this argument.
  • includePrivate: if set to true the generation will include private getters.

@EqualsAndHashCode() #

Annotating a class with @EqualsAndHashCode() will generate an implementation of bool operator ==(o) and int get hashCode built by default with its public getters.

For instance :

@EqualsAndHashCode()
class _A {
  final a;
  final int b;
  _A(this.a, this.b);
}

will generate :

@GeneratedFrom(_A)
class A {
  final a;
  final int b;
  A(this.a, this.b);
  @override bool operator ==(o) => identical(this, o) ||
      o.runtimeType == runtimeType && o.a == a && o.b == b;
  @override int get hashCode => hashObjects([a, b]);
}

The code generated can be customize with the following optional parameters:

  • callSuper: if set to true the generated code will use additionnally super.hashCode and super == o.
  • exclude: a list of getter names can be exclude with this argument.
  • includePrivate: if set to true the generation will include private getters.

@DefaultConstructor() #

Annotating an external constructor with @DefaultConstructor() will generate a default constructor with uninitialized final fields as required parameters and mutable fields as optional named parameters. You can use the useConst parameter to generate a const constructor.

For instance :

class _A {
  var a;
  final b;
  @DefaultConstructor() external _A();
}

will generate :

@GeneratedFrom(_A)
class A {
  var a;
  final b;
  A(this.b, {this.a});
}

The external _A(); is used to make the analyzer happy and will be removed in the generated A.

@Value() #

Annotating a class with @Value() is the same as annotating the class with @DefaultConstructor(), @EqualsAndHashCode() and @ToString().

For instance :

@Value()
class _A {
  final int a;
  final b, c;
  external _A();
}

will generate :

@GeneratedFrom(_A)
class A {
  final int a;
  final b, c;
  A(this.a, this.b, this.c);
  @override bool operator ==(o) => identical(this, o) ||
      o.runtimeType == runtimeType && o.a == a && o.b == b && o.c == c;
  @override int get hashCode => hashObjects([a, b, c]);
  @override String toString() => "A(a=$a, b=$b, c=$c)";
}

Note that you can customize @EqualsAndHashCode() and @ToString() by using the annotation with the custom parameters. You can use the useConst parameter to generate a const constructor.

@Delegate() #

Annotating a field/getter with @Delegate() will add to the enclosing class all the public methods available on the type of the field/getter.

For instance :

abstract class A {
  m1();
}
class _B {
  @Delegate() A _a;
}

will generate :

@GeneratedFrom(_B)
class B {
  @Delegate() A _a;
  m1() => _a.m1();
}

The code generated can be customize with the following optional parameters:

  • exclude: a list of members can be exclude with this argument.

@Lazy() #

Annotating a field with @Lazy() will make it lazy computed.

For instance :

class _A {
  @Lazy() var a = "String";
}

will generate :

@GeneratedFrom(_A)
class A {
  dynamic get a => _lazyFields.putIfAbsent(#a, () => "String");
  set a(dynamic v) => _lazyFields[#a] = v;
  final _lazyFields = <Symbol, dynamic>{};
}

The lazy fields are stored into _lazyFields by field names. If the field is final no setter will be generated.

@Cached() #

Annotating a method with @Cached() will make its result managed by a cache. By default the cache used is a forever cache that will compute the result once and keep it forever in memory.

For instance :

class _A {
  @Cached() int fib(int n) => (n < 2) ? n : fib(n - 1) + fib(n - 2);
}

will generate :

@GeneratedFrom(_A)
class A {
  int fib(int n) => _caches
      .putIfAbsent(
          #fib,
          () => _createCache(
              #fib, (int n) => (n < 2) ? n : fib(n - 1) + fib(n - 2)))
      .getValue([n]);
  final _caches = <Symbol, Cache>{};
  Cache _createCache(Symbol methodName, Function compute) => new Cache(compute);
}

The caches for each method are stored into _caches. You can implement your own Cache _createCache(Symbol methodName, Function compute) to customize the cache policy.

@Implementation() #

Annotating a method with @Implementation() will make it the method called by all abstract members. The method annotated must have exactly one parameter of type StringInvocation. This type is the same as Invocation from dart:core except that the Symbol are replaced by String. This allows to avoid dart:mirrors.

For instance :

abstract class _A {
  m1();
  String get g;
  void set s(String s);
  @Implementation() _noSuchMethod(i) => print(i);
}

will generate :

@GeneratedFrom(_A)
class A {
  m1() => _noSuchMethod(new StringInvocation('m1', isMethod: true));
  String get g => _noSuchMethod(new StringInvocation('g', isGetter: true));
  void set s(String s) {
    _noSuchMethod(
        new StringInvocation('s', isSetter: true, positionalArguments: [s]));
  }

  _noSuchMethod(i) => print(i);
}

Usage #

To use this library in your code :

  • add a dependency in your pubspec.yaml :
dependencies:
  zengen: any
  • add import in your dart code :
import 'package:zengen/zengen.dart';
  • create a script build.dart that run the generator
import 'package:zengen/generator.dart';
import 'package:source_gen/source_gen.dart' show build;

main(List<String> args) async {
  print(await build(args, [new ZengenGenerator()],
      librarySearchPaths: ['example/', 'lib/', 'web/', 'test/']));
}

You can use the build_system package to allow the generator to be run on every file changes.

License #

Apache 2.0

0
likes
0
pub points
6%
popularity

Publisher

unverified uploader

A package to generate boilerplate code.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

quiver, source_gen

More

Packages that depend on zengen