nameof 0.2.2 nameof: ^0.2.2 copied to clipboard
Generator for Dart class member's names, such as fields, properties, methods, constructors
Motivation #
Sometimes there is a need to access the names of programming language entities, such as methods, properties, constructors, etc. Unfortunately, Flutter does not have a reflection mechanism designed for this purpose. But there is code generation! It is all you need for access to names of code entities with this package.
Index #
How to use #
Install #
To use Nameof
, you will need your typical build_runner code-generator setup.
First, install build_runner and Nameof
by adding them to your pubspec.yaml
file:
If you are using creating a Flutter project:
$ flutter pub add nameof_annotation
$ flutter pub add --dev build_runner
$ flutter pub add --dev nameof
If you are using creating a Dart project:
$ dart pub add nameof_annotation
$ dart pub add --dev build_runner
$ dart pub add --dev nameof
This installs three packages:
- build_runner, the tool to run code-generators
- nameof, the code generator
- nameof_annotation, a package containing annotations for
Nameof
.
Run the generator #
To run the code generator, execute the following command:
dart run build_runner build
For Flutter projects, you can also run:
flutter pub run build_runner build
Note that like most code-generators, nameof will need you to both import the annotation (nameof_annotation)
and use the part
keyword on the top of your files.
As such, a file that wants to use nameof will start with:
import 'package:nameof_annotation/nameof_annotation.dart';
part 'my_file.nameof.dart';
Using Nameof #
Simple usage #
For example we have a class Car
. For names generation of this class you need to tell generator some instructions with nameof
annotation:
@nameof
class Car {
final double price;
final double weigth;
final int year;
final String model;
Car(this.price, this.weigth, this.year, this.model);
Car.sedan(double price, double weigth, int year)
: this(price, weigth, year, 'Sedan');
}
Then you need to run generator Run the generator
It will generate next code:
/// Container for names of elements belonging to the [Car] class
abstract class NameofCar {
static const String className = 'Car';
static const String constructor = '';
static const String constructorSedan = 'sedan';
static const String fieldPrice = 'price';
static const String fieldWeigth = 'weigth';
static const String fieldYear = 'year';
static const String fieldModel = 'model';
}
Then use it in your code:
print(NameofCar.fieldPrice);
It is simple!
Also you may to use nameof
annotation for abstract classes and mixins.
Models coverage #
You can have very precision setting of coverage of model's members with use coverage settings and @NameofIgnore
annotation. For example two next configurations will lead to one output.
- First configuration:
@Nameof(coverage: Coverage.excludeImplicit)
class Itinerary {
final double longStart;
final double latStart;
final double longEnd;
final double latEnd;
@nameofKey
final String name;
@nameofKey
final double length;
Itinerary(this.longStart, this.latStart, this.longEnd, this.latEnd, this.name,
this.length);
}
- Second configuration:
@Nameof(coverage: Coverage.includeImplicit)
class Itinerary {
@nameofIgnore
final double longStart;
@nameofIgnore
final double latStart;
@nameofIgnore
final double longEnd;
@nameofIgnore
final double latEnd;
final String name;
final double length;
@nameofIgnore
Itinerary(this.longStart, this.latStart, this.longEnd, this.latEnd, this.name,
this.length);
}
Output:
/// Container for names of elements belonging to the [Itinerary] class
abstract class NameofItinerary {
static const String className = 'Itinerary';
static const String fieldName = 'name';
static const String fieldLength = 'length';
}
Take an attention for coverage
setting, @nameofKey
and @nameofIgnore
annotations.
If you do not set coverage, generator will use includeImplicit
setting by default.
Override names #
If you want override name of element you can do it! Code:
@nameof
class Ephemeral {
@NameofKey(name: 'AbRaCadabra')
String get flushLight => 'Purple';
}
Generator output:
/// Container for names of elements belonging to the [Ephemeral] class
abstract class NameofEphemeral {
static const String className = 'Ephemeral';
static const String constructor = '';
static const String propertyGetFlushLight = 'AbRaCadabra';
}
As can you see property was renamed. Output has AbRaCadabra
not flushLight
.
NameofKey targets #
@NameofKey
annotatition applyed for public fields, methods, properties and constructors.
Configurations #
Nameof offers various options to customize the generated code. For example, you may want to change coverage behaviour of model.
To do so, there are two possibilities:
Changing the behavior for a specific model #
If you want to customize the generated code for only one specific class, you can do so by using annotation setting:
@Nameof(coverage: Coverage.excludeImplicit)
class Empoyee {...}
Changing the behavior for the entire project #
Instead of applying your modification to a single class, you may want to apply it to all Nameof models at the same time.
You can do so by customizing a file called build.yaml
This file is an optional configuration file that should be placed next to your pubspec.yaml
:
project_folder/
pubspec.yaml
build.yaml
lib/
There, you will be able to change the same options as the options found in @Nameof
(see above)
by writing:
targets:
$default:
builders:
nameof:
options:
coverage: includeImplicit
Two settings for coverage is available: includeImplicit
(default) and excludeImplicit