built_mirrors

This is a library that generates ClassMirror from classes annotated with @reflectable or @Reflectable().

Getting Started

  1. Create a new dart-web project.
  2. add built_mirrors dependency to your pubspec.yaml.
...
dependencies:
  ...
  built_mirrors: any
  ...
  1. create a file in bin folder called models.dart and put next code on it:
library built_mirrors.example;

import 'package:built_mirrors/built_mirrors.dart';

part 'models.g.dart';

class MyAnnotation extends Annotation {
  final String val1;
  final val2;
  const MyAnnotation(this.val1, {this.val2});
}

@reflectable
class Person {
  Person({this.id, this.name, this.myDynamic, this.cars});
  int id;
  @MyAnnotation('hello', val2: null)
  String name;
  var myDynamic;
  List<Car> cars;

  String get myGetter => 'myGetter result';
  set mySetter(String val) => 'setting $val';
}

@reflectable
class Car {
  int id;
  String engine;
  Car([this.id, this.engine]);
}

@reflectable
class EmptyClass {

}

@reflectable
class ExtendedPerson extends Person {
  var extendedName;
  var otherExtended;
}
  1. edit the file main.dart in the folder bin and put next code on it:
// Copyright (c) 2017, luis. All rights reserved. Use of this source code

// is governed by a BSD-style license that can be found in the LICENSE file.

import 'models.dart';
import 'package:built_mirrors/built_mirrors.dart';

main() {

  // Initializes the `Type-ClassMirror` map
  initClassMirrors({
    Person: PersonClassMirror,
    Car: CarClassMirror
  });

  // Gets the PersonClassMirror
  var personClassMirror = reflectType(Person);
  // and then constructs a new person using a map with the
  // needed parameters for the constructor
  var p1 = personClassMirror.constructors[''].call({'id': 1, 'name': 'person 1'});
  // Get the list of DeclarationMirror corresponding to the fields of Person class
  var p1Fields = personClassMirror.fields;

  // prints: `p1Fields['myDynamic'].type: dynamic}\n` in the `result` element
  print("p1Fields['myDynamic'].type: ${p1Fields['myDynamic'].type}\n");
  // prints: `p1Fields['cars'].type: [List, Car]}\n` in the `result` element
  print("p1Fields['cars'].type: ${p1Fields['cars'].type}\n");

  // Gets the CarClassMirror and constructs a new car using the default constructor
  // passing a map containing the required parameters
  Car car1 = reflectType(Car).constructors[''].call({'id': 1, 'engine': 'v8'});
  /* prints:
      car1:
        id: 1
        engine: v8
   */
  print('car1:\n\tid: ${car1.id}\n\tengine: ${car1.engine}\n');
}
  1. create a file in tool folder called build.dart and put next code on it:
import 'package:build_runner/build_runner.dart';
import 'package:built_mirrors/phase.dart';


main() async {
  await build(new PhaseGroup()
    ..addPhase(
    // In next line replace `built_mirrors` for the name of your package
    // and `example/*.dart` for the globs you want to use as input, for example `**/*.dart`
    // to take all the dart files of the project as input.
        builtMirrorsPhase('built_mirrors', const ['example/*.dart'])),
      deleteFilesByDefault: true);
}
  1. run tool/build.dart. Then you will see that the file bin/models.g.darthas been generated and it will contains the next code:
// GENERATED CODE - DO NOT MODIFY BY HAND

part of built_mirrors.example;

// **************************************************************************
// Generator: BuiltMirrorsGenerator
// Target: class Person
// **************************************************************************

_Person__Constructor(params) => new Person(
    id: params['id'],
    name: params['name'],
    myDynamic: params['myDynamic'],
    cars: params['cars']);

const $$Person_fields_id = const DeclarationMirror(type: int);
const $$Person_fields_name = const DeclarationMirror(
    type: String, annotations: const [const MyAnnotation('hello', val2: null)]);
const $$Person_fields_myDynamic = const DeclarationMirror(type: dynamic);
const $$Person_fields_cars = const DeclarationMirror(type: const [List, Car]);
const $$Person_fields_myGetter = const DeclarationMirror(type: String);
const $$Person_fields_mySetter = const DeclarationMirror(type: String);

const PersonClassMirror = const ClassMirror(constructors: const {
  '': const FunctionMirror(parameters: const {
    'id': const DeclarationMirror(type: int),
    'name': const DeclarationMirror(type: String),
    'myDynamic': const DeclarationMirror(type: dynamic),
    'cars': const DeclarationMirror(type: const [List, Car])
  }, call: _Person__Constructor)
}, fields: const {
  'id': $$Person_fields_id,
  'name': $$Person_fields_name,
  'myDynamic': $$Person_fields_myDynamic,
  'cars': $$Person_fields_cars,
  'myGetter': $$Person_fields_myGetter,
  'mySetter': $$Person_fields_mySetter
}, getters: const [
  'id',
  'name',
  'myDynamic',
  'cars',
  'myGetter'
], setters: const [
  'id',
  'name',
  'myDynamic',
  'cars',
  'mySetter'
]);

// **************************************************************************
// Generator: BuiltMirrorsGenerator
// Target: class Car
// **************************************************************************

_Car__Constructor(params) => new Car(params['id'], params['engine']);

const $$Car_fields_id = const DeclarationMirror(type: int);
const $$Car_fields_engine = const DeclarationMirror(type: String);

const CarClassMirror = const ClassMirror(constructors: const {
  '': const FunctionMirror(parameters: const {
    'id': const DeclarationMirror(type: int),
    'engine': const DeclarationMirror(type: String)
  }, call: _Car__Constructor)
}, fields: const {
  'id': $$Car_fields_id,
  'engine': $$Car_fields_engine
}, getters: const [
  'id',
  'engine'
], setters: const [
  'id',
  'engine'
]);

// **************************************************************************
// Generator: BuiltMirrorsGenerator
// Target: class EmptyClass
// **************************************************************************

_EmptyClass__Constructor(params) => new EmptyClass();

const EmptyClassClassMirror = const ClassMirror(constructors: const {
  '': const FunctionMirror(parameters: const {}, call: _EmptyClass__Constructor)
});

// **************************************************************************
// Generator: BuiltMirrorsGenerator
// Target: class ExtendedPerson
// **************************************************************************

_ExtendedPerson__Constructor(params) => new ExtendedPerson();

const $$ExtendedPerson_fields_extendedName =
    const DeclarationMirror(type: dynamic);
const $$ExtendedPerson_fields_otherExtended =
    const DeclarationMirror(type: dynamic);

const ExtendedPersonClassMirror = const ClassMirror(constructors: const {
  '': const FunctionMirror(
      parameters: const {}, call: _ExtendedPerson__Constructor)
}, fields: const {
  'extendedName': $$ExtendedPerson_fields_extendedName,
  'otherExtended': $$ExtendedPerson_fields_otherExtended,
  'id': $$Person_fields_id,
  'name': $$Person_fields_name,
  'myDynamic': $$Person_fields_myDynamic,
  'cars': $$Person_fields_cars,
  'myGetter': $$Person_fields_myGetter,
  'mySetter': $$Person_fields_mySetter
}, getters: const [
  'id',
  'name',
  'myDynamic',
  'cars',
  'myGetter',
  'extendedName',
  'otherExtended'
], setters: const [
  'id',
  'name',
  'myDynamic',
  'cars',
  'mySetter',
  'extendedName',
  'otherExtended'
]);
  1. Finally you can run the file bin/main.dart. If everything is ok you will see nextoutput in console:
p1Fields['myDynamic'].type: dynamic

p1Fields['cars'].type: [List, Car]

car1:
	id: 1
	engine: v8

Libraries

built_mirrors

generator

phase