chore(packaging): move files to match target file structure

This commit is contained in:
Yegor Jbanov
2015-02-04 23:05:13 -08:00
parent 7ce4f66cdc
commit 3820609f24
149 changed files with 0 additions and 77 deletions

92
modules/angular2/src/di/annotations.js vendored Normal file
View File

@ -0,0 +1,92 @@
import {CONST} from "facade/src/lang";
/**
* A parameter annotation that creates a synchronous eager dependency.
*
* ```
* class AComponent {
* constructor(@Inject('aServiceToken') aService) {}
* }
* ```
*
*/
export class Inject {
token;
@CONST()
constructor(token) {
this.token = token;
}
}
/**
* A parameter annotation that creates an asynchronous eager dependency.
*
* ```
* class AComponent {
* constructor(@InjectPromise('aServiceToken') aServicePromise) {
* aServicePromise.then(aService => ...);
* }
* }
* ```
*
*/
export class InjectPromise {
token;
@CONST()
constructor(token) {
this.token = token;
}
}
/**
* A parameter annotation that creates a synchronous lazy dependency.
*
* ```
* class AComponent {
* constructor(@InjectLazy('aServiceToken') aServiceFn) {
* aService = aServiceFn();
* }
* }
* ```
*
*/
export class InjectLazy {
token;
@CONST()
constructor(token) {
this.token = token;
}
}
/**
* `DependencyAnnotation` is used by the framework to extend DI.
*
* Only annotations implementing `DependencyAnnotation` will be added
* to the list of dependency properties.
*
* For example:
*
* ```
* class Parent extends DependencyAnnotation {}
* class NotDependencyProperty {}
*
* class AComponent {
* constructor(@Parent @NotDependencyProperty aService:AService) {}
* }
* ```
*
* will create the following dependency:
*
* ```
* new Dependency(Key.get(AService), [new Parent()])
* ```
*
* The framework can use `new Parent()` to handle the `aService` dependency
* in a specific way.
*
*/
export class DependencyAnnotation {
@CONST()
constructor() {
}
}

128
modules/angular2/src/di/binding.js vendored Normal file
View File

@ -0,0 +1,128 @@
import {FIELD, Type, isBlank, isPresent} from 'facade/src/lang';
import {List, MapWrapper, ListWrapper} from 'facade/src/collection';
import {reflector} from 'reflection/src/reflection';
import {Key} from './key';
import {Inject, InjectLazy, InjectPromise, DependencyAnnotation} from './annotations';
import {NoAnnotationError} from './exceptions';
export class Dependency {
key:Key;
asPromise:boolean;
lazy:boolean;
properties:List;
constructor(key:Key, asPromise:boolean, lazy:boolean, properties:List) {
this.key = key;
this.asPromise = asPromise;
this.lazy = lazy;
this.properties = properties;
}
}
export class Binding {
key:Key;
factory:Function;
dependencies:List;
providedAsPromise:boolean;
constructor(key:Key, factory:Function, dependencies:List, providedAsPromise:boolean) {
this.key = key;
this.factory = factory;
this.dependencies = dependencies;
this.providedAsPromise = providedAsPromise;
}
}
export function bind(token):BindingBuilder {
return new BindingBuilder(token);
}
export class BindingBuilder {
token;
constructor(token) {
this.token = token;
}
toClass(type:Type):Binding {
return new Binding(
Key.get(this.token),
reflector.factory(type),
_dependenciesFor(type),
false
);
}
toValue(value):Binding {
return new Binding(
Key.get(this.token),
() => value,
[],
false
);
}
toFactory(factoryFunction:Function, dependencies:List = null):Binding {
return new Binding(
Key.get(this.token),
factoryFunction,
this._constructDependencies(factoryFunction, dependencies),
false
);
}
toAsyncFactory(factoryFunction:Function, dependencies:List = null):Binding {
return new Binding(
Key.get(this.token),
factoryFunction,
this._constructDependencies(factoryFunction, dependencies),
true
);
}
_constructDependencies(factoryFunction:Function, dependencies:List) {
return isBlank(dependencies) ?
_dependenciesFor(factoryFunction) :
ListWrapper.map(dependencies, (t) => new Dependency(Key.get(t), false, false, []));
}
}
function _dependenciesFor(typeOrFunc):List {
var params = reflector.parameters(typeOrFunc);
if (isBlank(params)) return [];
if (ListWrapper.any(params, (p) => isBlank(p))) throw new NoAnnotationError(typeOrFunc);
return ListWrapper.map(params, (p) => _extractToken(typeOrFunc, p));
}
function _extractToken(typeOrFunc, annotations) {
var type;
var depProps = [];
for (var i = 0; i < annotations.length; ++i) {
var paramAnnotation = annotations[i];
if (paramAnnotation instanceof Type) {
type = paramAnnotation;
} else if (paramAnnotation instanceof Inject) {
return _createDependency(paramAnnotation.token, false, false, []);
} else if (paramAnnotation instanceof InjectPromise) {
return _createDependency(paramAnnotation.token, true, false, []);
} else if (paramAnnotation instanceof InjectLazy) {
return _createDependency(paramAnnotation.token, false, true, []);
} else if (paramAnnotation instanceof DependencyAnnotation) {
ListWrapper.push(depProps, paramAnnotation);
}
}
if (isPresent(type)) {
return _createDependency(type, false, false, depProps);
} else {
throw new NoAnnotationError(typeOrFunc);
}
}
function _createDependency(token, asPromise, lazy, depProps):Dependency {
return new Dependency(Key.get(token), asPromise, lazy, depProps);
}

107
modules/angular2/src/di/exceptions.js vendored Normal file
View File

@ -0,0 +1,107 @@
import {ListWrapper, List} from 'facade/src/collection';
import {stringify} from 'facade/src/lang';
import {Key} from './key';
function findFirstClosedCycle(keys:List) {
var res = [];
for(var i = 0; i < keys.length; ++i) {
if (ListWrapper.contains(res, keys[i])) {
ListWrapper.push(res, keys[i]);
return res;
} else {
ListWrapper.push(res, keys[i]);
}
}
return res;
}
function constructResolvingPath(keys:List) {
if (keys.length > 1) {
var reversed = findFirstClosedCycle(ListWrapper.reversed(keys));
var tokenStrs = ListWrapper.map(reversed, (k) => stringify(k.token));
return " (" + tokenStrs.join(' -> ') + ")";
} else {
return "";
}
}
export class KeyMetadataError extends Error {}
export class ProviderError extends Error {
keys:List;
constructResolvingMessage:Function;
message;
constructor(key:Key, constructResolvingMessage:Function) {
this.keys = [key];
this.constructResolvingMessage = constructResolvingMessage;
this.message = this.constructResolvingMessage(this.keys);
}
addKey(key:Key) {
ListWrapper.push(this.keys, key);
this.message = this.constructResolvingMessage(this.keys);
}
toString() {
return this.message;
}
}
export class NoProviderError extends ProviderError {
constructor(key:Key) {
super(key, function (keys:List) {
var first = stringify(ListWrapper.first(keys).token);
return `No provider for ${first}!${constructResolvingPath(keys)}`;
});
}
}
export class AsyncBindingError extends ProviderError {
constructor(key:Key) {
super(key, function (keys:List) {
var first = stringify(ListWrapper.first(keys).token);
return `Cannot instantiate ${first} synchronously. ` +
`It is provided as a promise!${constructResolvingPath(keys)}`;
});
}
}
export class CyclicDependencyError extends ProviderError {
constructor(key:Key) {
super(key, function (keys:List) {
return `Cannot instantiate cyclic dependency!${constructResolvingPath(keys)}`;
});
}
}
export class InstantiationError extends ProviderError {
constructor(originalException, key:Key) {
super(key, function (keys:List) {
var first = stringify(ListWrapper.first(keys).token);
return `Error during instantiation of ${first}!${constructResolvingPath(keys)}.` +
` ORIGINAL ERROR: ${originalException}`;
});
}
}
export class InvalidBindingError extends Error {
message:string;
constructor(binding) {
this.message = `Invalid binding ${binding}`;
}
toString() {
return this.message;
}
}
export class NoAnnotationError extends Error {
message:string;
constructor(typeOrFunc) {
this.message = `Cannot resolve all parameters for ${stringify(typeOrFunc)}`;
}
toString() {
return this.message;
}
}

258
modules/angular2/src/di/injector.js vendored Normal file
View File

@ -0,0 +1,258 @@
import {Map, List, MapWrapper, ListWrapper} from 'facade/src/collection';
import {Binding, BindingBuilder, bind} from './binding';
import {ProviderError, NoProviderError, InvalidBindingError,
AsyncBindingError, CyclicDependencyError, InstantiationError} from './exceptions';
import {FunctionWrapper, Type, isPresent, isBlank} from 'facade/src/lang';
import {Promise, PromiseWrapper} from 'facade/src/async';
import {Key} from './key';
var _constructing = new Object();
class _Waiting {
promise:Promise;
constructor(promise:Promise) {
this.promise = promise;
}
}
function _isWaiting(obj):boolean {
return obj instanceof _Waiting;
}
export class Injector {
_bindings:List;
_instances:List;
_parent:Injector;
_defaultBindings:boolean;
_asyncStrategy: _AsyncInjectorStrategy;
_syncStrategy:_SyncInjectorStrategy;
constructor(bindings:List, {parent=null, defaultBindings=false}={}) {
var flatten = _flattenBindings(bindings, MapWrapper.create());
this._bindings = this._createListOfBindings(flatten);
this._instances = this._createInstances();
this._parent = parent;
this._defaultBindings = defaultBindings;
this._asyncStrategy = new _AsyncInjectorStrategy(this);
this._syncStrategy = new _SyncInjectorStrategy(this);
}
get(token) {
return this._getByKey(Key.get(token), false, false);
}
asyncGet(token) {
return this._getByKey(Key.get(token), true, false);
}
createChild(bindings:List):Injector {
return new Injector(bindings, {parent: this});
}
_createListOfBindings(flattenBindings):List {
var bindings = ListWrapper.createFixedSize(Key.numberOfKeys + 1);
MapWrapper.forEach(flattenBindings, (v, keyId) => bindings[keyId] = v);
return bindings;
}
_createInstances():List {
return ListWrapper.createFixedSize(Key.numberOfKeys + 1);
}
_getByKey(key:Key, returnPromise:boolean, returnLazy:boolean) {
if (returnLazy) {
return () => this._getByKey(key, returnPromise, false);
}
var strategy = returnPromise ? this._asyncStrategy : this._syncStrategy;
var instance = strategy.readFromCache(key);
if (isPresent(instance)) return instance;
instance = strategy.instantiate(key);
if (isPresent(instance)) return instance;
if (isPresent(this._parent)) {
return this._parent._getByKey(key, returnPromise, returnLazy);
}
throw new NoProviderError(key);
}
_resolveDependencies(key:Key, binding:Binding, forceAsync:boolean):List {
try {
var getDependency = d => this._getByKey(d.key, forceAsync || d.asPromise, d.lazy);
return ListWrapper.map(binding.dependencies, getDependency);
} catch (e) {
this._clear(key);
if (e instanceof ProviderError) e.addKey(key);
throw e;
}
}
_getInstance(key:Key) {
if (this._instances.length <= key.id) return null;
return ListWrapper.get(this._instances, key.id);
}
_setInstance(key:Key, obj) {
ListWrapper.set(this._instances, key.id, obj);
}
_getBinding(key:Key) {
var binding = this._bindings.length <= key.id ?
null :
ListWrapper.get(this._bindings, key.id);
if (isBlank(binding) && this._defaultBindings) {
return bind(key.token).toClass(key.token);
} else {
return binding;
}
}
_markAsConstructing(key:Key) {
this._setInstance(key, _constructing);
}
_clear(key:Key) {
this._setInstance(key, null);
}
}
class _SyncInjectorStrategy {
injector:Injector;
constructor(injector:Injector) {
this.injector = injector;
}
readFromCache(key:Key) {
if (key.token === Injector) {
return this.injector;
}
var instance = this.injector._getInstance(key);
if (instance === _constructing) {
throw new CyclicDependencyError(key);
} else if (isPresent(instance) && !_isWaiting(instance)) {
return instance;
} else {
return null;
}
}
instantiate(key:Key) {
var binding = this.injector._getBinding(key);
if (isBlank(binding)) return null;
if (binding.providedAsPromise) throw new AsyncBindingError(key);
//add a marker so we can detect cyclic dependencies
this.injector._markAsConstructing(key);
var deps = this.injector._resolveDependencies(key, binding, false);
return this._createInstance(key, binding, deps);
}
_createInstance(key:Key, binding:Binding, deps:List) {
try {
var instance = FunctionWrapper.apply(binding.factory, deps);
this.injector._setInstance(key, instance);
return instance;
} catch (e) {
this.injector._clear(key);
throw new InstantiationError(e, key);
}
}
}
class _AsyncInjectorStrategy {
injector:Injector;
constructor(injector:Injector) {
this.injector = injector;
}
readFromCache(key:Key) {
if (key.token === Injector) {
return PromiseWrapper.resolve(this.injector);
}
var instance = this.injector._getInstance(key);
if (instance === _constructing) {
throw new CyclicDependencyError(key);
} else if (_isWaiting(instance)) {
return instance.promise;
} else if (isPresent(instance)) {
return PromiseWrapper.resolve(instance);
} else {
return null;
}
}
instantiate(key:Key) {
var binding = this.injector._getBinding(key);
if (isBlank(binding)) return null;
//add a marker so we can detect cyclic dependencies
this.injector._markAsConstructing(key);
var deps = this.injector._resolveDependencies(key, binding, true);
var depsPromise = PromiseWrapper.all(deps);
var promise = PromiseWrapper
.then(depsPromise, null, (e) => this._errorHandler(key, e))
.then(deps => this._findOrCreate(key, binding, deps))
.then(instance => this._cacheInstance(key, instance));
this.injector._setInstance(key, new _Waiting(promise));
return promise;
}
_errorHandler(key:Key, e):Promise {
if (e instanceof ProviderError) e.addKey(key);
return PromiseWrapper.reject(e);
}
_findOrCreate(key:Key, binding:Binding, deps:List) {
try {
var instance = this.injector._getInstance(key);
if (!_isWaiting(instance)) return instance;
return FunctionWrapper.apply(binding.factory, deps);
} catch (e) {
this.injector._clear(key);
throw new InstantiationError(e, key);
}
}
_cacheInstance(key, instance) {
this.injector._setInstance(key, instance);
return instance
}
}
function _flattenBindings(bindings:List, res:Map) {
ListWrapper.forEach(bindings, function (b) {
if (b instanceof Binding) {
MapWrapper.set(res, b.key.id, b);
} else if (b instanceof Type) {
var s = bind(b).toClass(b);
MapWrapper.set(res, s.key.id, s);
} else if (b instanceof List) {
_flattenBindings(b, res);
} else if (b instanceof BindingBuilder) {
throw new InvalidBindingError(b.token);
} else {
throw new InvalidBindingError(b);
}
});
return res;
}

55
modules/angular2/src/di/key.js vendored Normal file
View File

@ -0,0 +1,55 @@
import {KeyMetadataError} from './exceptions';
import {MapWrapper, Map} from 'facade/src/collection';
import {FIELD, int, isPresent} from 'facade/src/lang';
export class Key {
token;
id:int;
metadata:any;
constructor(token, id:int) {
this.token = token;
this.id = id;
this.metadata = null;
}
static setMetadata(key:Key, metadata):Key {
if (isPresent(key.metadata) && key.metadata !== metadata) {
throw new KeyMetadataError();
}
key.metadata = metadata;
return key;
}
static get(token):Key {
return _globalKeyRegistry.get(token);
}
static get numberOfKeys():int {
return _globalKeyRegistry.numberOfKeys;
}
}
export class KeyRegistry {
_allKeys:Map;
constructor() {
this._allKeys = MapWrapper.create();
}
get(token):Key {
if (token instanceof Key) return token;
if (MapWrapper.contains(this._allKeys, token)) {
return MapWrapper.get(this._allKeys, token);
}
var newKey = new Key(token, Key.numberOfKeys);
MapWrapper.set(this._allKeys, token, newKey);
return newKey;
}
get numberOfKeys():int {
return MapWrapper.size(this._allKeys);
}
}
var _globalKeyRegistry = new KeyRegistry();

11
modules/angular2/src/di/opaque_token.js vendored Normal file
View File

@ -0,0 +1,11 @@
export class OpaqueToken {
_desc:string;
constructor(desc:string){
this._desc = `Token(${desc})`;
}
toString() {
return this._desc;
}
}