built_mirrors 0.6.0+1

built_mirrors

Build Status

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.models;

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});
}

const myOtherAnnotation = const _MyOtherAnnotation();
class _MyOtherAnnotation extends Annotation {
  const _MyOtherAnnotation();
}

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

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

@reflectable
@myOtherAnnotation
class Car {
  int id;
  @MyAnnotation(r'\uabcd', val2: null)
  String engine;
  Car([this.id, this.engine]);
}

@reflectable
class EmptyClass {

}

@reflectable
class ExtendedPerson extends Person {
  var extendedName;
  var otherExtended;
}

@reflectable
class ClassWithMethod {

  @myOtherAnnotation
  someMethod(@myOtherAnnotation String someParameter) {
    return 'someMethod';
  }

  @myOtherAnnotation
  someMethodWithNamedParams({@myOtherAnnotation String someParameter}) {
    return 'someMethod';
  }
}

  1. edit the file main.dart in the folder bin and put next code on it:
library built_mirrors.example.main;

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

part 'main.g.dart';

@reflectable
@AnnotationWithFunction(otherFunction)
String someFunction(@myOtherAnnotation int p1, int p0, int p2) {
  return '';
}

otherFunction() {}

class AnnotationWithFunction extends Annotation {
  const AnnotationWithFunction(this.function);

  final Function function;
}

main() {

  // Initializes the mirrors map
  _initMirrors();

  // 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['']([], {'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['']([1, 'v8']);
  /* prints:
      car1:
        id: 1
        engine: v8
   */
  print('car1:\n\tid: ${car1.id}\n\tengine: ${car1.engine}\n');

  // adds car1 to p1.cars
  p1.cars = [car1];

  print('\n--------------------------');
  print('reflecting "ClassWithMethod"');
  print('--------------------------');
  var methods = reflectType(ClassWithMethod).methods;
  print(methods.keys); // prints: 'someFunction'
  print(methods['someMethod'].returnType); // prints: String
  print(methods['someMethod'].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(methods['someMethod'].positionalParameters); // prints: {p1: Instance of 'DeclarationMirror'}
  print(methods['someMethod'].positionalParameters[0].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(methods['someMethod'].positionalParameters[0].type); // prints: int

  print('\n--------------------------');
  print('reflecting "someFunction"');
  print('--------------------------');
  var sfMirror = reflectFunction(someFunction);
  print(sfMirror.name); // prints: '(someMethod)'
  print(sfMirror.returnType); // prints: dynamic
  print(sfMirror.annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(sfMirror.positionalParameters); // prints: {someParameter: Instance of 'DeclarationMirror'}
  print(sfMirror.positionalParameters[0].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(sfMirror.positionalParameters[0].type); // prints: String
  print(sfMirror.positionalParameters[0].name);
  print(sfMirror.positionalParameters[1].name);
  print(sfMirror.positionalParameters[2].name);
}

  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/action.dart';


main() async {
  // In next line replace `example/*.dart` for the globs you want to use as input, for example `**/*.dart`
  // or leave it empty to take all the dart files of the project as input.
  await build([builtMirrorsAction(const ['example/*.dart'])], deleteFilesByDefault: true);
}

  1. run tool/build.dart. Then you will see that the file bin/models.g.dart has been generated and it will contains the next code:
// GENERATED CODE - DO NOT MODIFY BY HAND

part of built_mirrors.example.models;

// **************************************************************************
// Generator: MirrorsGenerator
// **************************************************************************

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

const $$Person_fields_id = const DeclarationMirror(type: int);
const $$Person_fields_name = const DeclarationMirror(
    type: String,
    annotations: const [const MyAnnotation(r'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, isFinal: true);
const $$Person_fields_mySetter = const DeclarationMirror(type: String);

const PersonClassMirror =
    const ClassMirror(name: 'Person', constructors: const {
  '': const FunctionMirror(namedParameters: const {
    'id': const DeclarationMirror(name: 'id', type: int, isNamed: true),
    'name': const DeclarationMirror(name: 'name', type: String, isNamed: true),
    'myDynamic': const DeclarationMirror(
        name: 'myDynamic', type: dynamic, isNamed: true),
    'cars': const DeclarationMirror(
        name: 'cars', type: const [List, Car], isNamed: true)
  }, $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'
]);
_Car__Constructor([positionalParams, namedParams]) =>
    new Car(positionalParams[0], positionalParams[1]);

const $$Car_fields_id = const DeclarationMirror(type: int);
const $$Car_fields_engine = const DeclarationMirror(
    type: String,
    annotations: const [const MyAnnotation(r'\uabcd', val2: null)]);

const CarClassMirror = const ClassMirror(name: 'Car', constructors: const {
  '': const FunctionMirror(positionalParameters: const [
    const DeclarationMirror(name: 'id', type: int),
    const DeclarationMirror(name: 'engine', type: String)
  ], $call: _Car__Constructor)
}, annotations: const [
  myOtherAnnotation
], fields: const {
  'id': $$Car_fields_id,
  'engine': $$Car_fields_engine
}, getters: const [
  'id',
  'engine'
], setters: const [
  'id',
  'engine'
]);
_EmptyClass__Constructor([positionalParams, namedParams]) => new EmptyClass();

const EmptyClassClassMirror = const ClassMirror(
    name: 'EmptyClass',
    constructors: const {
      '': const FunctionMirror($call: _EmptyClass__Constructor)
    });
_ExtendedPerson__Constructor([positionalParams, namedParams]) =>
    new ExtendedPerson();

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

const ExtendedPersonClassMirror = const ClassMirror(
    name: 'ExtendedPerson',
    constructors: const {
      '': const FunctionMirror($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 [
      'extendedName',
      'otherExtended',
      'id',
      'name',
      'myDynamic',
      'cars',
      'myGetter'
    ],
    setters: const [
      'extendedName',
      'otherExtended',
      'id',
      'name',
      'myDynamic',
      'cars',
      'mySetter'
    ],
    superclass: Person);
_ClassWithMethod__Constructor([positionalParams, namedParams]) =>
    new ClassWithMethod();

const ClassWithMethodClassMirror =
    const ClassMirror(name: 'ClassWithMethod', constructors: const {
  '': const FunctionMirror($call: _ClassWithMethod__Constructor)
}, methods: const {
  'someMethod': const FunctionMirror(
      positionalParameters: const [
        const DeclarationMirror(
            name: 'someParameter',
            type: String,
            isRequired: true,
            annotations: const [myOtherAnnotation])
      ],
      name: 'someMethod',
      returnType: dynamic,
      annotations: const [myOtherAnnotation]),
  'someMethodWithNamedParams': const FunctionMirror(
      namedParameters: const {
        'someParameter': const DeclarationMirror(
            name: 'someParameter',
            type: String,
            isNamed: true,
            annotations: const [myOtherAnnotation])
      },
      name: 'someMethodWithNamedParams',
      returnType: dynamic,
      annotations: const [myOtherAnnotation])
});

  1. Finally you can run the file bin/main.dart. If everything is ok you will see next output in console:
p1Fields['myDynamic'].type: dynamic

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

car1:
	id: 1
	engine: v8


--------------------------
reflecting "ClassWithMethod"
--------------------------
(someMethod)
dynamic
[Instance of '_MyOtherAnnotation']
{someParameter: Instance of 'DeclarationMirror'}
[Instance of '_MyOtherAnnotation']
String

--------------------------
reflecting "someFunction"
--------------------------
someFunction
String
[Instance of 'AnnotationWithFunction']
{p1: Instance of 'DeclarationMirror', p0: Instance of 'DeclarationMirror', p2: Instance of 'DeclarationMirror'}
[Instance of '_MyOtherAnnotation']
int
p1
p0
p2

0.6.0

  • split function parameters into positional and named
  • rename phase.dart to action.dart

0.5.2

  • add generators for annotations with List, Map and other constants

0.5.1

  • add name to DeclarationMirror generator

0.5.0

  • upgrade build_runner to version ^0.4.0
  • upgrade build to version ^0.10.0

0.4.0

  • upgrade build_runner to version ^0.4.0
  • upgrade build to version ^0.10.0

0.3.0

  • upgrade source_gen pacakge to version ^0.6.0
  • change a.constanValue to a.computeConstantValue()

0.2.4

  • allow multiple initMirrors functions

0.2.3

  • correct default values for dartdoc

0.2.2

  • upgrade build package to version ^0.9.0

0.2.1

  • make generated strings raw

0.2.0

  • remove packageName parameter from phase
  • upgrade build_test to version ^0.5.0

0.1.3

  • correct _getExtensionLevel when processing non-reflectable classes
  • correct mirror_generator for generating function values in annotations parameters

0.1.2

  • enable strong-mode in .analysys_options
  • correct getter functionMirrors

0.1.1

  • add scanners

0.1.0

  • add FunctionMirrors

  • add MethodMirrors generation to ClassMirror

0.0.8

  • make ClassMirror.name public again

0.0.7

  • add enum to InitClassMirrorsGenerator

0.0.6

  • reinitialize static variables from InitClassMirrorsGenerator to avoid multiple adding mirrors from other modules

0.0.5

  • add init_class_mirrors_generator
  • rename generator.dart to class_mirrors_generator _ rename BuiltMirrorsGenerator to ClassMirrorsGenerator

0.0.4

  • ClassMirror:
    • add name and toString to have better logging.
    • add isEnum and values to support enum types
  • Add FunctionCall Typedef to enhance the type of FunctionMirror.call
  • DeclarationMirror:
    • add isFinal to handel if a field is final
    • add isOptional to handle if a parameter is optional
  • BuiltMirrorsGenerator:
    • add enum-ClassMirror template
    • add isOptional template for optional parameters
    • add isFinal template for final fields

8fc2109 Luis Vargas <luisvargastijerino@gmail.com> on 1/28/17 at 1:05 PM

0.0.3

  • support annotations in classes
  • support shorthand annotations

0.0.2

  • Remove getSymbolName function

0.0.1

  • Initial version

example/main.dart

library built_mirrors.example.main;

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

part 'main.g.dart';

@reflectable
@AnnotationWithFunction(otherFunction)
String someFunction(@myOtherAnnotation int p1, int p0, int p2) {
  return '';
}

otherFunction() {}

class AnnotationWithFunction extends Annotation {
  const AnnotationWithFunction(this.function);

  final Function function;
}

main() {

  // Initializes the mirrors map
  _initMirrors();

  // 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['']([], {'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['']([1, 'v8']);
  /* prints:
      car1:
        id: 1
        engine: v8
   */
  print('car1:\n\tid: ${car1.id}\n\tengine: ${car1.engine}\n');

  // adds car1 to p1.cars
  p1.cars = [car1];

  print('\n--------------------------');
  print('reflecting "ClassWithMethod"');
  print('--------------------------');
  var methods = reflectType(ClassWithMethod).methods;
  print(methods.keys); // prints: 'someFunction'
  print(methods['someMethod'].returnType); // prints: String
  print(methods['someMethod'].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(methods['someMethod'].positionalParameters); // prints: {p1: Instance of 'DeclarationMirror'}
  print(methods['someMethod'].positionalParameters[0].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(methods['someMethod'].positionalParameters[0].type); // prints: int

  print('\n--------------------------');
  print('reflecting "someFunction"');
  print('--------------------------');
  var sfMirror = reflectFunction(someFunction);
  print(sfMirror.name); // prints: '(someMethod)'
  print(sfMirror.returnType); // prints: dynamic
  print(sfMirror.annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(sfMirror.positionalParameters); // prints: {someParameter: Instance of 'DeclarationMirror'}
  print(sfMirror.positionalParameters[0].annotations); // prints: [Instance of '_MyOtherAnnotation']
  print(sfMirror.positionalParameters[0].type); // prints: String
  print(sfMirror.positionalParameters[0].name);
  print(sfMirror.positionalParameters[1].name);
  print(sfMirror.positionalParameters[2].name);
}

1. Depend on it

Add this to your package's pubspec.yaml file:

dependencies:
  built_mirrors: "^0.6.0+1"

2. Install it

You can install packages from the command line:

$ pub get

Alternatively, your editor might support 'pub get'. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:built_mirrors/built_mirrors.dart';

Platforms

Server

About

generates `ClassMirror` from classes annotated with `@reflectable` or `@Reflectable()`

Author

Email luisvargastijerino@gmail.com Luis Vargas

Homepage

github.com/dart-league/built_mirrors

Documentation

www.dartdocs.org/documentation/built_mirrors/0.6.0%2B1/

Uploader

luisvargastijerino@gmail.com

License

BSD

Published

Sep 20, 2017

Share