2015-06-16 16:13:31 -07:00
|
|
|
import {
|
|
|
|
|
Type,
|
|
|
|
|
isPresent,
|
|
|
|
|
isFunction,
|
|
|
|
|
global,
|
|
|
|
|
stringify,
|
|
|
|
|
BaseException
|
|
|
|
|
} from 'angular2/src/facade/lang';
|
2015-04-24 13:17:36 -07:00
|
|
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
2015-05-18 17:19:54 -07:00
|
|
|
import {GetterFn, SetterFn, MethodFn} from './types';
|
|
|
|
|
import {PlatformReflectionCapabilities} from 'platform_reflection_capabilities';
|
2015-04-24 13:17:36 -07:00
|
|
|
|
2015-05-18 17:19:54 -07:00
|
|
|
export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
2015-05-01 14:05:19 -07:00
|
|
|
private _reflect: any;
|
|
|
|
|
|
|
|
|
|
constructor(reflect?: any) { this._reflect = isPresent(reflect) ? reflect : global.Reflect; }
|
|
|
|
|
|
|
|
|
|
factory(t: Type): Function {
|
|
|
|
|
switch (t.length) {
|
2015-04-24 13:17:36 -07:00
|
|
|
case 0:
|
2015-06-11 11:25:40 -07:00
|
|
|
return () => new t();
|
2015-04-24 13:17:36 -07:00
|
|
|
case 1:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1) => new t(a1);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 2:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2) => new t(a1, a2);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 3:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3) => new t(a1, a2, a3);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 4:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4) => new t(a1, a2, a3, a4);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 5:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5) => new t(a1, a2, a3, a4, a5);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 6:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5, a6) => new t(a1, a2, a3, a4, a5, a6);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 7:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5, a6, a7) => new t(a1, a2, a3, a4, a5, a6, a7);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 8:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8) => new t(a1, a2, a3, a4, a5, a6, a7, a8);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 9:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9) => new t(a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
2015-04-24 13:17:36 -07:00
|
|
|
case 10:
|
2015-06-11 11:25:40 -07:00
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
|
|
|
|
case 11:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
|
|
|
|
case 12:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
|
|
|
|
case 13:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
|
|
|
|
|
case 14:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
|
|
|
|
|
case 15:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
|
|
|
|
case 16:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16);
|
|
|
|
|
case 17:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
|
|
|
|
|
a17);
|
|
|
|
|
case 18:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) =>
|
|
|
|
|
new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17,
|
|
|
|
|
a18);
|
|
|
|
|
case 19:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
|
|
|
|
|
a19) => new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
|
|
|
|
|
a17, a18, a19);
|
|
|
|
|
case 20:
|
|
|
|
|
return (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
|
|
|
|
|
a19, a20) => new t(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
|
|
|
|
|
a16, a17, a18, a19, a20);
|
2015-04-24 13:17:36 -07:00
|
|
|
};
|
|
|
|
|
|
2015-05-19 14:29:10 -07:00
|
|
|
throw new Error(
|
2015-06-11 11:25:40 -07:00
|
|
|
`Cannot create a factory for '${stringify(t)}' because its constructor has more than 20 arguments`);
|
2015-04-24 13:17:36 -07:00
|
|
|
}
|
|
|
|
|
|
2015-04-29 16:22:38 -07:00
|
|
|
_zipTypesAndAnnotaions(paramTypes, paramAnnotations): List<List<any>> {
|
2015-05-18 08:11:13 +02:00
|
|
|
var result;
|
|
|
|
|
|
|
|
|
|
if (typeof paramTypes === 'undefined') {
|
|
|
|
|
result = ListWrapper.createFixedSize(paramAnnotations.length);
|
|
|
|
|
} else {
|
|
|
|
|
result = ListWrapper.createFixedSize(paramTypes.length);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-29 16:22:38 -07:00
|
|
|
for (var i = 0; i < result.length; i++) {
|
|
|
|
|
// TS outputs Object for parameters without types, while Traceur omits
|
|
|
|
|
// the annotations. For now we preserve the Traceur behavior to aid
|
|
|
|
|
// migration, but this can be revisited.
|
2015-05-18 08:11:13 +02:00
|
|
|
if (typeof paramTypes === 'undefined') {
|
|
|
|
|
result[i] = [];
|
|
|
|
|
} else if (paramTypes[i] != Object) {
|
2015-04-29 16:22:38 -07:00
|
|
|
result[i] = [paramTypes[i]];
|
|
|
|
|
} else {
|
|
|
|
|
result[i] = [];
|
|
|
|
|
}
|
2015-05-06 10:06:30 -07:00
|
|
|
if (isPresent(paramAnnotations) && isPresent(paramAnnotations[i])) {
|
2015-04-29 16:22:38 -07:00
|
|
|
result[i] = result[i].concat(paramAnnotations[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-24 13:17:36 -07:00
|
|
|
parameters(typeOfFunc): List<List<any>> {
|
2015-04-28 18:17:00 -07:00
|
|
|
// Prefer the direct API.
|
|
|
|
|
if (isPresent(typeOfFunc.parameters)) {
|
|
|
|
|
return typeOfFunc.parameters;
|
|
|
|
|
}
|
2015-05-01 14:05:19 -07:00
|
|
|
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
|
|
|
|
var paramAnnotations = this._reflect.getMetadata('parameters', typeOfFunc);
|
|
|
|
|
var paramTypes = this._reflect.getMetadata('design:paramtypes', typeOfFunc);
|
2015-04-29 16:22:38 -07:00
|
|
|
if (isPresent(paramTypes) || isPresent(paramAnnotations)) {
|
|
|
|
|
return this._zipTypesAndAnnotaions(paramTypes, paramAnnotations);
|
2015-04-28 18:17:00 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ListWrapper.createFixedSize(typeOfFunc.length);
|
2015-04-24 13:17:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
annotations(typeOfFunc): List<any> {
|
2015-04-28 18:17:00 -07:00
|
|
|
// Prefer the direct API.
|
|
|
|
|
if (isPresent(typeOfFunc.annotations)) {
|
2015-06-16 16:13:31 -07:00
|
|
|
var annotations = typeOfFunc.annotations;
|
|
|
|
|
if (isFunction(annotations) && annotations.annotations) {
|
|
|
|
|
annotations = annotations.annotations;
|
|
|
|
|
}
|
|
|
|
|
return annotations;
|
2015-04-28 18:17:00 -07:00
|
|
|
}
|
2015-05-01 14:05:19 -07:00
|
|
|
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
|
|
|
|
var annotations = this._reflect.getMetadata('annotations', typeOfFunc);
|
2015-04-28 18:17:00 -07:00
|
|
|
if (isPresent(annotations)) return annotations;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
2015-04-24 13:17:36 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 08:08:14 -07:00
|
|
|
interfaces(type): List<any> { throw new BaseException("JavaScript does not support interfaces"); }
|
2015-05-27 08:07:11 -07:00
|
|
|
|
2015-05-18 16:09:09 -07:00
|
|
|
getter(name: string): GetterFn { return <GetterFn>new Function('o', 'return o.' + name + ';'); }
|
2015-04-24 13:17:36 -07:00
|
|
|
|
2015-05-18 16:09:09 -07:00
|
|
|
setter(name: string): SetterFn {
|
|
|
|
|
return <SetterFn>new Function('o', 'v', 'return o.' + name + ' = v;');
|
|
|
|
|
}
|
2015-04-24 13:17:36 -07:00
|
|
|
|
|
|
|
|
method(name: string): MethodFn {
|
|
|
|
|
let functionBody = `if (!o.${name}) throw new Error('"${name}" is undefined');
|
|
|
|
|
return o.${name}.apply(o, args);`;
|
2015-05-18 16:09:09 -07:00
|
|
|
return <MethodFn>new Function('o', 'args', functionBody);
|
2015-04-24 13:17:36 -07:00
|
|
|
}
|
|
|
|
|
}
|