need Dart mirror instantiate() function

Issue

to add some sanity to my life, looking for instantiate() function as syntactic sugar to Dart’s mirror library: instantiate( class|type|instance, argArray )

class Klass {
  int i1;
  Klass( int i1 ) {
    this.i1 = (i1 is int) ? i1 : 0;
  }
}
type ktype = Klass;
Klass kinstance = new Klass( 5 );

Klass test1 = instantiate( Klass, [5] );
Klass test2 = instantiate( ktype, [5] );
Klass test3 = instantiate( kinstance, [5] );

currently 90% of my interaction with mirrors would be covered by this one function. currently blindly cutting and copying out of sheer stupidity. certainly someone smarter than me has done this already!


here is instantiate( type, [constructor, positional, named] ) for all occassions:

  • arguments of constructor, positional and named are all optional
  • type can be Type, in instantiated type, or a string representation of the type
  • constructor: eg, new Map.from(…) – ‘from’ is the constructor, either ‘from’ or #from
  • positional: positional arguments in a List
  • named: names arguments in Map, keys may be ‘key’ or #key
dynamic instantiate( dynamic v_type, [dynamic v_constructorName, List v_positional, Map v_named] ) {
  Type type =
    ( _type is Type ) ? v_type
    : (v_type is String ) ? str2Type( v_type )
    : reflect(v_type).type.reflectedType;
  Map v_named2 =
    (v_named is Map) ? v_named
    : (v_positional is Map) ? v_positional
    : (v_constructorName is Map) ? v_constructorName
    : {};
  Map named = {};
  v_named2.keys.forEach( (k) => named[(k is Symbol)?k:new Symbol(k)] = v_named2[k] );
  List positional =
    (v_positional is List) ? v_positional
    : (v_constructorName is List) ? v_constructorName : [];
  Symbol constructorName =
    (v_constructorName is Symbol) ? v_constructorName
    : (v_constructorName is String) ? Symbol(v_constructorName)
    : const Symbol('');
  return reflectClass(type).newInstance(constructorName, positional, named).reflectee;
}

Solution

import 'dart:mirrors';

void main() {
  Type ktype = Klass;
  Klass kinstance = new Klass( 5 );
  // Constructor name
  var ctor = const Symbol("");

  Klass test1 = instantiate(Klass, ctor, [1]);
  Klass test2 = instantiate(ktype, ctor, [2]);
  Klass test3 = instantiate(reflect(kinstance).type.reflectedType, ctor, [3]);
  Klass test4 = instantiate(Klass, #fromString, ["4"]);

  print(test1.i1);
  print(test2.i1);
  print(test3.i1);
  print(test4.i1);
}

dynamic instantiate(Type type, Symbol constructorName, List positional, [Map named]) {
  return reflectClass(type).newInstance(constructorName, positional, named).reflectee;
}

class Klass {
  int i1;
  Klass( int i1 ) {
    this.i1 = (i1 is int) ? i1 : 0;
  }

  Klass.fromString(String i) {
    i1 = int.parse(i, onError : (s) => i1 = 0);
  }
}

Output:

1
2
3
4

Answered By – mezoni

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *