fix: Improve error message on missing dependency

This commit is contained in:
Misko Hevery
2015-05-18 17:19:54 -07:00
parent 7501ad11ca
commit 2ccc65d7fd
16 changed files with 85 additions and 48 deletions

View File

@ -1,4 +1,4 @@
import {CONST} from "angular2/src/facade/lang";
import {CONST, stringify} from "angular2/src/facade/lang";
/**
* A parameter annotation that specifies a dependency.
@ -15,6 +15,7 @@ import {CONST} from "angular2/src/facade/lang";
@CONST()
export class Inject {
constructor(public token) {}
toString() { return `@Inject(${stringify(this.token)})`; }
}
/**
@ -33,6 +34,7 @@ export class Inject {
@CONST()
export class InjectPromise {
constructor(public token) {}
toString() { return `@InjectPromise(${stringify(this.token)})`; }
}
/**
@ -51,6 +53,7 @@ export class InjectPromise {
@CONST()
export class InjectLazy {
constructor(public token) {}
toString() { return `@InjectLazy(${stringify(this.token)})`; }
}
/**
@ -69,6 +72,7 @@ export class InjectLazy {
*/
@CONST()
export class Optional {
toString() { return `@Optional()`; }
}
/**

View File

@ -437,22 +437,27 @@ export class BindingBuilder {
}
}
function _constructDependencies(factoryFunction: Function, dependencies: List<any>) {
return isBlank(dependencies) ?
_dependenciesFor(factoryFunction) :
ListWrapper.map(dependencies, (t) => _extractToken(factoryFunction, t));
function _constructDependencies(factoryFunction: Function,
dependencies: List<any>): List<Dependency> {
if (isBlank(dependencies)) {
return _dependenciesFor(factoryFunction);
} else {
var params: List<List<any>> = ListWrapper.map(dependencies, (t) => [t]);
return ListWrapper.map(dependencies, (t) => _extractToken(factoryFunction, t, params));
}
}
function _dependenciesFor(typeOrFunc): List<any> {
function _dependenciesFor(typeOrFunc): List<Dependency> {
var params = reflector.parameters(typeOrFunc);
if (isBlank(params)) return [];
if (ListWrapper.any(params, (p) => isBlank(p))) {
throw new NoAnnotationError(typeOrFunc);
throw new NoAnnotationError(typeOrFunc, params);
}
return ListWrapper.map(params, (p) => _extractToken(typeOrFunc, p));
return ListWrapper.map(params, (p: List<any>) => _extractToken(typeOrFunc, p, params));
}
function _extractToken(typeOrFunc, annotations) {
function _extractToken(typeOrFunc, annotations /*List<any> | any*/,
params: List<List<any>>): Dependency {
var depProps = [];
var token = null;
var optional = false;
@ -496,7 +501,7 @@ function _extractToken(typeOrFunc, annotations) {
if (isPresent(token)) {
return _createDependency(token, asPromise, lazy, optional, depProps);
} else {
throw new NoAnnotationError(typeOrFunc);
throw new NoAnnotationError(typeOrFunc, params);
}
}

View File

@ -1,5 +1,5 @@
import {ListWrapper, List} from 'angular2/src/facade/collection';
import {stringify, BaseException} from 'angular2/src/facade/lang';
import {stringify, BaseException, isBlank} from 'angular2/src/facade/lang';
function findFirstClosedCycle(keys: List<any>): List<any> {
var res = [];
@ -179,9 +179,19 @@ export class InvalidBindingError extends BaseException {
export class NoAnnotationError extends BaseException {
name: string;
message: string;
constructor(typeOrFunc) {
constructor(typeOrFunc, params: List<List<any>>) {
super();
this.message = "Cannot resolve all parameters for " + stringify(typeOrFunc) + ". " +
var signature = ListWrapper.create();
for (var i = 0, ii = params.length; i < ii; i++) {
var parameter = params[i];
if (isBlank(parameter) || parameter.length == 0) {
ListWrapper.push(signature, '?');
} else {
ListWrapper.push(signature, ListWrapper.map(parameter, stringify).join(' '));
}
}
this.message = "Cannot resolve all parameters for " + stringify(typeOrFunc) + "(" +
signature.join(', ') + "). " +
'Make sure they all have valid type or annotations.';
}

View File

@ -1,4 +1,4 @@
import {Type} from 'angular2/src/facade/lang';
import {Type, stringify} from 'angular2/src/facade/lang';
export interface ForwardRefFn { (): any; }
@ -30,6 +30,7 @@ export interface ForwardRefFn { (): any; }
*/
export function forwardRef(forwardRefFn: ForwardRefFn): Type {
(<any>forwardRefFn).__forward_ref__ = forwardRef;
(<any>forwardRefFn).toString = function() { return stringify(this()); };
return (<Type><any>forwardRefFn);
}

View File

@ -0,0 +1,4 @@
library angular2.di.type_info;
// In dart always return empty, as we can get the co
argsLength(Type type) => 0;

View File