built_mirrors 0.7.1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 84

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(name: 'id', type: int);
const $$Person_fields_name = const DeclarationMirror(
    name: 'name',
    type: String,
    annotations: const [const MyAnnotation(r'helloꯍ', val2: null)]);
const $$Person_fields_myDynamic =
    const DeclarationMirror(name: 'myDynamic', type: dynamic);
const $$Person_fields_cars =
    const DeclarationMirror(name: 'cars', type: const [List, Car]);
const $$Person_fields_myGetter =
    const DeclarationMirror(name: 'myGetter', type: String, isFinal: true);
const $$Person_fields_mySetter =
    const DeclarationMirror(name: 'mySetter', type: String);

const PersonClassMirror =
    const ClassMirror(name: 'Person', constructors: const {
  '': const FunctionMirror(
      name: '',
      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(name: 'id', type: int);
const $$Car_fields_engine = const DeclarationMirror(
    name: 'engine',
    type: String,
    annotations: const [const MyAnnotation(r'\uabcd', val2: null)]);

const CarClassMirror = const ClassMirror(name: 'Car', constructors: const {
  '': const FunctionMirror(
      name: '',
      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(name: '', $call: _EmptyClass__Constructor)
    });
_ExtendedPerson__Constructor([positionalParams, namedParams]) =>
    new ExtendedPerson();

const $$ExtendedPerson_fields_extendedName =
    const DeclarationMirror(name: 'extendedName', type: dynamic);
const $$ExtendedPerson_fields_otherExtended =
    const DeclarationMirror(name: 'otherExtended', type: dynamic);

const ExtendedPersonClassMirror = const ClassMirror(
    name: 'ExtendedPerson',
    constructors: const {
      '': const FunctionMirror(name: '', $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(name: '', $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.7.1

  • add name param to fields and constructors

0.7.0

  • fixed the null issue
  • upgrade build package to ^0.11.1
  • upgrade build_runner to version ^0.6.0

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.7.1"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or packages 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';
        
Version Uploaded Documentation Archive
0.7.1 Dec 4, 2017 Go to the documentation of built_mirrors 0.7.1 Download built_mirrors 0.7.1 archive
0.7.0 Dec 4, 2017 Go to the documentation of built_mirrors 0.7.0 Download built_mirrors 0.7.0 archive
0.6.1 Dec 4, 2017 Go to the documentation of built_mirrors 0.6.1 Download built_mirrors 0.6.1 archive
0.6.0+1 Sep 20, 2017 Go to the documentation of built_mirrors 0.6.0+1 Download built_mirrors 0.6.0+1 archive
0.6.0 Sep 20, 2017 Go to the documentation of built_mirrors 0.6.0 Download built_mirrors 0.6.0 archive
0.5.2 Aug 31, 2017 Go to the documentation of built_mirrors 0.5.2 Download built_mirrors 0.5.2 archive
0.5.1 Aug 29, 2017 Go to the documentation of built_mirrors 0.5.1 Download built_mirrors 0.5.1 archive
0.5.0 Aug 17, 2017 Go to the documentation of built_mirrors 0.5.0 Download built_mirrors 0.5.0 archive
0.4.0 Aug 11, 2017 Go to the documentation of built_mirrors 0.4.0 Download built_mirrors 0.4.0 archive
0.3.0 Jul 28, 2017 Go to the documentation of built_mirrors 0.3.0 Download built_mirrors 0.3.0 archive

All 27 versions...

Analysis

This feature is new.
We welcome feedback.

We analyzed this package, and provided a score, details, and suggestions below.

  • completed on Dec 6, 2017
  • Dart: 2.0.0-dev.8.0
  • pana: 0.7.3+1

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
69
Health:
Code health derived from static analysis. [more]
99
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
99
Overall score:
Weighted score of the above. [more]
84

Platforms

Detected platforms: Flutter, server, web

primary library - package:built_mirrors/built_mirrors.dart

Dependencies

Package Constraint Resolved Available
Direct dependencies
analyzer ^0.30.0 0.30.0+4 0.31.0-alpha.2
build ^0.11.1 0.11.1
build_runner ^0.6.0 0.6.1
source_gen ^0.7.0 0.7.2+1
Transitive dependencies
args 1.2.0
async 1.13.3 2.0.1
barback 0.15.2+13
bazel_worker 0.1.8
build_barback 0.4.0+2
build_compilers 0.1.0
build_config 0.1.1
built_collection 1.6.2 2.1.0
built_value 4.3.3 4.4.1
charcode 1.1.1
cli_util 0.1.2+1
code_builder 2.3.0
code_transformers 0.5.1+3
collection 1.14.3
convert 2.0.1
crypto 2.0.2+1
csslib 0.14.1
dart_style 1.0.8
fixnum 0.10.6
front_end 0.1.0-alpha.4.1 0.1.0-alpha.7
glob 1.1.5
html 0.13.2
http_parser 3.1.1
io 0.3.1
isolate 1.1.0
json_annotation 0.2.1
kernel 0.3.0-alpha.1.1 0.3.0-alpha.4
logging 0.11.3+1
matcher 0.12.1+4
meta 1.1.2
mime 0.9.4
package_config 1.0.3
path 1.5.1
plugin 0.2.0+2
pool 1.3.3
protobuf 0.6.0
quiver 0.26.2
scratch_space 0.0.1+2
shelf 0.7.1
source_maps 0.10.4
source_span 1.4.0
stack_trace 1.9.1
stream_channel 1.6.2
stream_transform 0.0.9
string_scanner 1.0.2
typed_data 1.1.5
utf 0.9.0+3
watcher 0.9.7+4
yaml 2.1.13
Dev dependencies
build_test ^0.9.1
test ^0.12.0