refactor(core): simplify Reflector code, add types (#12099)
This commit is contained in:
parent
c9b765f5c0
commit
0254ce1f6c
|
@ -16,4 +16,4 @@ export {ReflectionInfo, Reflector} from './reflector';
|
||||||
* The {@link Reflector} used internally in Angular to access metadata
|
* The {@link Reflector} used internally in Angular to access metadata
|
||||||
* about symbols.
|
* about symbols.
|
||||||
*/
|
*/
|
||||||
export var reflector = new Reflector(new ReflectionCapabilities());
|
export const reflector = new Reflector(new ReflectionCapabilities());
|
||||||
|
|
|
@ -19,19 +19,11 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
|
|
||||||
isReflectionEnabled(): boolean { return true; }
|
isReflectionEnabled(): boolean { return true; }
|
||||||
|
|
||||||
factory(t: Type<any>): Function {
|
factory<T>(t: Type<T>): (args: any[]) => T { return (...args: any[]) => new t(...args); }
|
||||||
var prototype = t.prototype;
|
|
||||||
return function(...args: any[]) {
|
|
||||||
var instance = Object.create(prototype);
|
|
||||||
t.apply(instance, args);
|
|
||||||
return instance;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_zipTypesAndAnnotations(
|
_zipTypesAndAnnotations(paramTypes: any[], paramAnnotations: any[]): any[][] {
|
||||||
paramTypes: any /** TODO #9100 */, paramAnnotations: any /** TODO #9100 */): any[][] {
|
var result: any[][];
|
||||||
var result: any /** TODO #9100 */;
|
|
||||||
|
|
||||||
if (typeof paramTypes === 'undefined') {
|
if (typeof paramTypes === 'undefined') {
|
||||||
result = new Array(paramAnnotations.length);
|
result = new Array(paramAnnotations.length);
|
||||||
|
@ -50,48 +42,45 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
} else {
|
} else {
|
||||||
result[i] = [];
|
result[i] = [];
|
||||||
}
|
}
|
||||||
if (isPresent(paramAnnotations) && isPresent(paramAnnotations[i])) {
|
if (paramAnnotations && isPresent(paramAnnotations[i])) {
|
||||||
result[i] = result[i].concat(paramAnnotations[i]);
|
result[i] = result[i].concat(paramAnnotations[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters(typeOrFunc: Type<any>): any[][] {
|
parameters(type: Type<any>): any[][] {
|
||||||
// Prefer the direct API.
|
// Prefer the direct API.
|
||||||
if (isPresent((<any>typeOrFunc).parameters)) {
|
if ((<any>type).parameters) {
|
||||||
return (<any>typeOrFunc).parameters;
|
return (<any>type).parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
// API of tsickle for lowering decorators to properties on the class.
|
// API of tsickle for lowering decorators to properties on the class.
|
||||||
if (isPresent((<any>typeOrFunc).ctorParameters)) {
|
if ((<any>type).ctorParameters) {
|
||||||
let ctorParameters = (<any>typeOrFunc).ctorParameters;
|
const ctorParameters = (<any>type).ctorParameters;
|
||||||
let paramTypes =
|
const paramTypes = ctorParameters.map((ctorParam: any) => ctorParam && ctorParam.type);
|
||||||
ctorParameters.map((ctorParam: any /** TODO #9100 */) => ctorParam && ctorParam.type);
|
const paramAnnotations = ctorParameters.map(
|
||||||
let paramAnnotations = ctorParameters.map(
|
(ctorParam: any) =>
|
||||||
(ctorParam: any /** TODO #9100 */) =>
|
|
||||||
ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));
|
ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));
|
||||||
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
// API for metadata created by invoking the decorators.
|
// API for metadata created by invoking the decorators.
|
||||||
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
||||||
var paramAnnotations = this._reflect.getMetadata('parameters', typeOrFunc);
|
const paramAnnotations = this._reflect.getMetadata('parameters', type);
|
||||||
var paramTypes = this._reflect.getMetadata('design:paramtypes', typeOrFunc);
|
const paramTypes = this._reflect.getMetadata('design:paramtypes', type);
|
||||||
if (isPresent(paramTypes) || isPresent(paramAnnotations)) {
|
if (paramTypes || paramAnnotations) {
|
||||||
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The array has to be filled with `undefined` because holes would be skipped by `some`
|
// The array has to be filled with `undefined` because holes would be skipped by `some`
|
||||||
let parameters = new Array((<any>typeOrFunc.length));
|
return new Array((<any>type.length)).fill(undefined);
|
||||||
parameters.fill(undefined);
|
|
||||||
return parameters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
annotations(typeOrFunc: Type<any>): any[] {
|
annotations(typeOrFunc: Type<any>): any[] {
|
||||||
// Prefer the direct API.
|
// Prefer the direct API.
|
||||||
if (isPresent((<any>typeOrFunc).annotations)) {
|
if ((<any>typeOrFunc).annotations) {
|
||||||
var annotations = (<any>typeOrFunc).annotations;
|
let annotations = (<any>typeOrFunc).annotations;
|
||||||
if (isFunction(annotations) && annotations.annotations) {
|
if (isFunction(annotations) && annotations.annotations) {
|
||||||
annotations = annotations.annotations;
|
annotations = annotations.annotations;
|
||||||
}
|
}
|
||||||
|
@ -99,22 +88,22 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
// API of tsickle for lowering decorators to properties on the class.
|
// API of tsickle for lowering decorators to properties on the class.
|
||||||
if (isPresent((<any>typeOrFunc).decorators)) {
|
if ((<any>typeOrFunc).decorators) {
|
||||||
return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
|
return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
|
||||||
}
|
}
|
||||||
|
|
||||||
// API for metadata created by invoking the decorators.
|
// API for metadata created by invoking the decorators.
|
||||||
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
if (this._reflect && this._reflect.getMetadata) {
|
||||||
var annotations = this._reflect.getMetadata('annotations', typeOrFunc);
|
const annotations = this._reflect.getMetadata('annotations', typeOrFunc);
|
||||||
if (isPresent(annotations)) return annotations;
|
if (annotations) return annotations;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
propMetadata(typeOrFunc: any): {[key: string]: any[]} {
|
propMetadata(typeOrFunc: any): {[key: string]: any[]} {
|
||||||
// Prefer the direct API.
|
// Prefer the direct API.
|
||||||
if (isPresent((<any>typeOrFunc).propMetadata)) {
|
if ((<any>typeOrFunc).propMetadata) {
|
||||||
var propMetadata = (<any>typeOrFunc).propMetadata;
|
let propMetadata = (<any>typeOrFunc).propMetadata;
|
||||||
if (isFunction(propMetadata) && propMetadata.propMetadata) {
|
if (isFunction(propMetadata) && propMetadata.propMetadata) {
|
||||||
propMetadata = propMetadata.propMetadata;
|
propMetadata = propMetadata.propMetadata;
|
||||||
}
|
}
|
||||||
|
@ -122,9 +111,9 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
// API of tsickle for lowering decorators to properties on the class.
|
// API of tsickle for lowering decorators to properties on the class.
|
||||||
if (isPresent((<any>typeOrFunc).propDecorators)) {
|
if ((<any>typeOrFunc).propDecorators) {
|
||||||
let propDecorators = (<any>typeOrFunc).propDecorators;
|
const propDecorators = (<any>typeOrFunc).propDecorators;
|
||||||
let propMetadata = <{[key: string]: any[]}>{};
|
const propMetadata = <{[key: string]: any[]}>{};
|
||||||
Object.keys(propDecorators).forEach(prop => {
|
Object.keys(propDecorators).forEach(prop => {
|
||||||
propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);
|
propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);
|
||||||
});
|
});
|
||||||
|
@ -132,9 +121,9 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
// API for metadata created by invoking the decorators.
|
// API for metadata created by invoking the decorators.
|
||||||
if (isPresent(this._reflect) && isPresent(this._reflect.getMetadata)) {
|
if (this._reflect && this._reflect.getMetadata) {
|
||||||
var propMetadata = this._reflect.getMetadata('propMetadata', typeOrFunc);
|
const propMetadata = this._reflect.getMetadata('propMetadata', typeOrFunc);
|
||||||
if (isPresent(propMetadata)) return propMetadata;
|
if (propMetadata) return propMetadata;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -147,7 +136,7 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
hasLifecycleHook(type: any, lcInterface: Type<any>, lcProperty: string): boolean {
|
hasLifecycleHook(type: any, lcInterface: Type<any>, lcProperty: string): boolean {
|
||||||
if (!(type instanceof Type)) return false;
|
if (!(type instanceof Type)) return false;
|
||||||
|
|
||||||
var proto = (<any>type).prototype;
|
const proto = (<any>type).prototype;
|
||||||
return !!proto[lcProperty];
|
return !!proto[lcProperty];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +147,7 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
method(name: string): MethodFn {
|
method(name: string): MethodFn {
|
||||||
let functionBody = `if (!o.${name}) throw new Error('"${name}" is undefined');
|
const functionBody = `if (!o.${name}) throw new Error('"${name}" is undefined');
|
||||||
return o.${name}.apply(o, args);`;
|
return o.${name}.apply(o, args);`;
|
||||||
return <MethodFn>new Function('o', 'args', functionBody);
|
return <MethodFn>new Function('o', 'args', functionBody);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {MapWrapper} from '../facade/collection';
|
import {MapWrapper} from '../facade/collection';
|
||||||
import {isPresent} from '../facade/lang';
|
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
import {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
|
import {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
|
||||||
import {ReflectorReader} from './reflector_reader';
|
import {ReflectorReader} from './reflector_reader';
|
||||||
|
@ -60,10 +59,10 @@ export class Reflector extends ReflectorReader {
|
||||||
* potential dead code.
|
* potential dead code.
|
||||||
*/
|
*/
|
||||||
listUnusedKeys(): any[] {
|
listUnusedKeys(): any[] {
|
||||||
if (this._usedKeys == null) {
|
if (!this._usedKeys) {
|
||||||
throw new Error('Usage tracking is disabled');
|
throw new Error('Usage tracking is disabled');
|
||||||
}
|
}
|
||||||
var allTypes = MapWrapper.keys(this._injectableInfo);
|
const allTypes = MapWrapper.keys(this._injectableInfo);
|
||||||
return allTypes.filter(key => !this._usedKeys.has(key));
|
return allTypes.filter(key => !this._usedKeys.has(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,87 +82,73 @@ export class Reflector extends ReflectorReader {
|
||||||
|
|
||||||
factory(type: Type<any>): Function {
|
factory(type: Type<any>): Function {
|
||||||
if (this._containsReflectionInfo(type)) {
|
if (this._containsReflectionInfo(type)) {
|
||||||
var res = this._getReflectionInfo(type).factory;
|
return this._getReflectionInfo(type).factory || null;
|
||||||
return isPresent(res) ? res : null;
|
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.factory(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.factory(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters(typeOrFunc: Type<any>): any[][] {
|
parameters(typeOrFunc: Type<any>): any[][] {
|
||||||
if (this._injectableInfo.has(typeOrFunc)) {
|
if (this._injectableInfo.has(typeOrFunc)) {
|
||||||
var res = this._getReflectionInfo(typeOrFunc).parameters;
|
return this._getReflectionInfo(typeOrFunc).parameters || [];
|
||||||
return isPresent(res) ? res : [];
|
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.parameters(typeOrFunc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.parameters(typeOrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
annotations(typeOrFunc: Type<any>): any[] {
|
annotations(typeOrFunc: Type<any>): any[] {
|
||||||
if (this._injectableInfo.has(typeOrFunc)) {
|
if (this._injectableInfo.has(typeOrFunc)) {
|
||||||
var res = this._getReflectionInfo(typeOrFunc).annotations;
|
return this._getReflectionInfo(typeOrFunc).annotations || [];
|
||||||
return isPresent(res) ? res : [];
|
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.annotations(typeOrFunc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.annotations(typeOrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
propMetadata(typeOrFunc: Type<any>): {[key: string]: any[]} {
|
propMetadata(typeOrFunc: Type<any>): {[key: string]: any[]} {
|
||||||
if (this._injectableInfo.has(typeOrFunc)) {
|
if (this._injectableInfo.has(typeOrFunc)) {
|
||||||
var res = this._getReflectionInfo(typeOrFunc).propMetadata;
|
return this._getReflectionInfo(typeOrFunc).propMetadata || {};
|
||||||
return isPresent(res) ? res : {};
|
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.propMetadata(typeOrFunc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.propMetadata(typeOrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces(type: Type<any>): any[] {
|
interfaces(type: Type<any>): any[] {
|
||||||
if (this._injectableInfo.has(type)) {
|
if (this._injectableInfo.has(type)) {
|
||||||
var res = this._getReflectionInfo(type).interfaces;
|
return this._getReflectionInfo(type).interfaces || [];
|
||||||
return isPresent(res) ? res : [];
|
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.interfaces(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.interfaces(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasLifecycleHook(type: any, lcInterface: Type<any>, lcProperty: string): boolean {
|
hasLifecycleHook(type: any, lcInterface: Type<any>, lcProperty: string): boolean {
|
||||||
var interfaces = this.interfaces(type);
|
if (this.interfaces(type).indexOf(lcInterface) !== -1) {
|
||||||
if (interfaces.indexOf(lcInterface) !== -1) {
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.hasLifecycleHook(type, lcInterface, lcProperty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.reflectionCapabilities.hasLifecycleHook(type, lcInterface, lcProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
getter(name: string): GetterFn {
|
getter(name: string): GetterFn {
|
||||||
if (this._getters.has(name)) {
|
return this._getters.has(name) ? this._getters.get(name) :
|
||||||
return this._getters.get(name);
|
this.reflectionCapabilities.getter(name);
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.getter(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setter(name: string): SetterFn {
|
setter(name: string): SetterFn {
|
||||||
if (this._setters.has(name)) {
|
return this._setters.has(name) ? this._setters.get(name) :
|
||||||
return this._setters.get(name);
|
this.reflectionCapabilities.setter(name);
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.setter(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method(name: string): MethodFn {
|
method(name: string): MethodFn {
|
||||||
if (this._methods.has(name)) {
|
return this._methods.has(name) ? this._methods.get(name) :
|
||||||
return this._methods.get(name);
|
this.reflectionCapabilities.method(name);
|
||||||
} else {
|
|
||||||
return this.reflectionCapabilities.method(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_getReflectionInfo(typeOrFunc: any): ReflectionInfo {
|
_getReflectionInfo(typeOrFunc: any): ReflectionInfo {
|
||||||
if (isPresent(this._usedKeys)) {
|
if (this._usedKeys) {
|
||||||
this._usedKeys.add(typeOrFunc);
|
this._usedKeys.add(typeOrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._injectableInfo.get(typeOrFunc);
|
return this._injectableInfo.get(typeOrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue