feat(injector): initial implementaion of dynamic injector
This commit is contained in:
14
modules/facade/src/async.dart
Normal file
14
modules/facade/src/async.dart
Normal file
@ -0,0 +1,14 @@
|
||||
library angular.core.facade.async;
|
||||
|
||||
import 'dart:async';
|
||||
export 'dart:async' show Future;
|
||||
|
||||
class FutureWrapper {
|
||||
static Future value(obj) {
|
||||
return new Future.value(obj);
|
||||
}
|
||||
|
||||
static Future wait(List<Future> futures){
|
||||
return Future.wait(futures);
|
||||
}
|
||||
}
|
12
modules/facade/src/async.es6
Normal file
12
modules/facade/src/async.es6
Normal file
@ -0,0 +1,12 @@
|
||||
export var Future = Promise;
|
||||
|
||||
export class FutureWrapper {
|
||||
static value(obj):Future {
|
||||
return Future.resolve(obj);
|
||||
}
|
||||
|
||||
static wait(futures):Future {
|
||||
if (futures.length == 0) return Future.resolve([]);
|
||||
return Future.all(futures);
|
||||
}
|
||||
}
|
@ -8,14 +8,25 @@ class MapWrapper {
|
||||
static get(m, k) => m[k];
|
||||
static void set(m, k, v){ m[k] = v; }
|
||||
static contains(m, k) => m.containsKey(k);
|
||||
static forEach(m, fn) {
|
||||
m.forEach(fn);
|
||||
}
|
||||
}
|
||||
|
||||
class ListWrapper {
|
||||
static List clone(List l) => new List.from(l);
|
||||
static List create() => new List();
|
||||
static List createFixedSize(int size) => new List(size);
|
||||
static get(m, k) => m[k];
|
||||
static void set(m, k, v) { m[k] = v; }
|
||||
static contains(m, k) => m.containsKey(k);
|
||||
static map(list, fn) => list.map(fn).toList();
|
||||
static forEach(list, fn) {
|
||||
list.forEach(fn);
|
||||
}
|
||||
static last(list) {
|
||||
return list.last;
|
||||
}
|
||||
static void push(List l, e) { l.add(e); }
|
||||
}
|
||||
|
||||
|
@ -6,21 +6,41 @@ export class MapWrapper {
|
||||
static create():HashMap { return new HashMap(); }
|
||||
static get(m, k) { return m[k]; }
|
||||
static set(m, k, v) { m[k] = v; }
|
||||
static contains(m, k) { return m.containsKey(k); }
|
||||
static contains(m, k) { return m[k] != undefined; }
|
||||
static forEach(m, fn) {
|
||||
for(var k in m) {
|
||||
fn(k, m[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class ListWrapper {
|
||||
static create():List { return new List(); }
|
||||
static createFixedSize(size):List { return new List(); }
|
||||
static get(m, k) { return m[k]; }
|
||||
static set(m, k, v) { m[k] = v; }
|
||||
static clone(array) {
|
||||
return Array.prototype.slice.call(array, 0);
|
||||
}
|
||||
static push(l, e) { l.push(e); }
|
||||
static map(array, fn) {
|
||||
return array.map(fn);
|
||||
}
|
||||
static forEach(array, fn) {
|
||||
for(var p of array) {
|
||||
fn(p);
|
||||
}
|
||||
}
|
||||
static push(array, el) {
|
||||
array.push(el);
|
||||
}
|
||||
static last(array) {
|
||||
if (!array || array.length == 0) return null;
|
||||
return array[array.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
export class SetWrapper {
|
||||
static createFromList(lst:List) { return new Set(lst); }
|
||||
static has(s:Set, key):boolean { return s.has(key); }
|
||||
}
|
||||
}
|
57
modules/facade/src/di/reflector.dart
Normal file
57
modules/facade/src/di/reflector.dart
Normal file
@ -0,0 +1,57 @@
|
||||
library facade.di.reflector;
|
||||
|
||||
import 'dart:mirrors';
|
||||
|
||||
class Inject {
|
||||
final Object token;
|
||||
const Inject(this.token);
|
||||
}
|
||||
|
||||
class Reflector {
|
||||
factoryFor(Type type) {
|
||||
return _generateFactory(type);
|
||||
}
|
||||
|
||||
convertToFactory(Function factory) {
|
||||
return (args) => Function.apply(factory, args);
|
||||
}
|
||||
|
||||
Function _generateFactory(Type type) {
|
||||
ClassMirror classMirror = reflectType(type);
|
||||
MethodMirror ctor = classMirror.declarations[classMirror.simpleName];
|
||||
Function create = classMirror.newInstance;
|
||||
Symbol name = ctor.constructorName;
|
||||
return (args) => create(name, args).reflectee;
|
||||
}
|
||||
|
||||
dependencies(Type type) {
|
||||
ClassMirror classMirror = reflectType(type);
|
||||
MethodMirror ctor = classMirror.declarations[classMirror.simpleName];
|
||||
|
||||
return new List.generate(ctor.parameters.length, (int pos) {
|
||||
ParameterMirror p = ctor.parameters[pos];
|
||||
|
||||
if (p.type.qualifiedName == #dynamic) {
|
||||
var name = MirrorSystem.getName(p.simpleName);
|
||||
throw "Error getting params for '$type': "
|
||||
"The '$name' parameter must be typed";
|
||||
}
|
||||
|
||||
if (p.type is TypedefMirror) {
|
||||
throw "Typedef '${p.type}' in constructor "
|
||||
"'${classMirror.simpleName}' is not supported.";
|
||||
}
|
||||
|
||||
ClassMirror pTypeMirror = (p.type as ClassMirror);
|
||||
var pType = pTypeMirror.reflectedType;
|
||||
|
||||
final inject = p.metadata.map((m) => m.reflectee).where((m) => m is Inject);
|
||||
|
||||
if (inject.isNotEmpty) {
|
||||
return inject.first.token;
|
||||
} else {
|
||||
return pType;
|
||||
}
|
||||
}, growable:false);
|
||||
}
|
||||
}
|
41
modules/facade/src/di/reflector.es6
Normal file
41
modules/facade/src/di/reflector.es6
Normal file
@ -0,0 +1,41 @@
|
||||
import {Type} from 'facade/lang';
|
||||
|
||||
//TODO: vsvakin: remove when const constructors are implemented
|
||||
export class Inject {
|
||||
constructor(token){
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
|
||||
export class Reflector {
|
||||
factoryFor(type:Type) {
|
||||
return (args) => new type(...args);
|
||||
}
|
||||
|
||||
convertToFactory(factoryFunction:Function) {
|
||||
return (args) => factoryFunction(...args);
|
||||
}
|
||||
|
||||
dependencies(type:Type) {
|
||||
var p = type.parameters;
|
||||
if (p == undefined) return [];
|
||||
return type.parameters.map((p) => this._extractToken(p));
|
||||
}
|
||||
|
||||
_extractToken(annotations) {
|
||||
var type, inject;
|
||||
for (var paramAnnotation of annotations) {
|
||||
if (isFunction(paramAnnotation)) {
|
||||
type = paramAnnotation;
|
||||
|
||||
} else if (paramAnnotation instanceof Inject) {
|
||||
inject = paramAnnotation.token;
|
||||
}
|
||||
}
|
||||
return inject != undefined ? inject : type;
|
||||
}
|
||||
}
|
||||
|
||||
function isFunction(value) {
|
||||
return typeof value === 'function';
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
library angular.core.facade.async;
|
||||
library angular.core.facade.lang;
|
||||
|
||||
export 'dart:async' show Future;
|
||||
export 'dart:core' show Type, int;
|
||||
export 'dart:core' show Type;
|
||||
|
||||
class FIELD {
|
||||
final String definition;
|
||||
@ -19,6 +18,10 @@ class IMPLEMENTS {
|
||||
const IMPLEMENTS(this.interfaceClass);
|
||||
}
|
||||
|
||||
bool isPresent(obj) => obj != null;
|
||||
bool isBlank(obj) => obj == null;
|
||||
|
||||
String humanize(obj) => obj.toString();
|
||||
|
||||
class StringWrapper {
|
||||
static String fromCharCode(int code) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
export var Future = Promise;
|
||||
export var Type = Function;
|
||||
|
||||
export class FIELD {
|
||||
@ -12,6 +11,30 @@ export class ABSTRACT {}
|
||||
export class IMPLEMENTS {}
|
||||
|
||||
|
||||
export function isPresent(obj){
|
||||
return obj != undefined && obj != null;
|
||||
}
|
||||
|
||||
export function isBlank(obj){
|
||||
return obj == undefined || obj == null;
|
||||
}
|
||||
|
||||
export function humanize(token) {
|
||||
if (typeof token === 'string') {
|
||||
return token;
|
||||
}
|
||||
|
||||
if (token === undefined || token === null) {
|
||||
return '' + token;
|
||||
}
|
||||
|
||||
if (token.name) {
|
||||
return token.name;
|
||||
}
|
||||
|
||||
return token.toString();
|
||||
}
|
||||
|
||||
export class StringWrapper {
|
||||
static fromCharCode(code:int) {
|
||||
return String.fromCharCode(code);
|
||||
|
Reference in New Issue
Block a user