refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from '../type';
|
||||
import {GetterFn, MethodFn, SetterFn} from './types';
|
||||
|
||||
export interface PlatformReflectionCapabilities {
|
||||
isReflectionEnabled(): boolean;
|
||||
factory(type: Type<any>): Function;
|
||||
hasLifecycleHook(type: any, lcProperty: string): boolean;
|
||||
parameters(type: Type<any>): any[][];
|
||||
annotations(type: Type<any>): any[];
|
||||
propMetadata(typeOrFunc: Type<any>): {[key: string]: any[]};
|
||||
getter(name: string): GetterFn;
|
||||
setter(name: string): SetterFn;
|
||||
method(name: string): MethodFn;
|
||||
importUri(type: Type<any>): string;
|
||||
resolveIdentifier(name: string, moduleUrl: string, members: string[], runtime: any): any;
|
||||
resolveEnum(enumIdentifier: any, name: string): any;
|
||||
}
|
18
packages/core/src/reflection/reflection.ts
Normal file
18
packages/core/src/reflection/reflection.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ReflectionCapabilities} from './reflection_capabilities';
|
||||
import {Reflector} from './reflector';
|
||||
|
||||
export {Reflector} from './reflector';
|
||||
|
||||
/**
|
||||
* The {@link Reflector} used internally in Angular to access metadata
|
||||
* about symbols.
|
||||
*/
|
||||
export const reflector = new Reflector(new ReflectionCapabilities());
|
253
packages/core/src/reflection/reflection_capabilities.ts
Normal file
253
packages/core/src/reflection/reflection_capabilities.ts
Normal file
@ -0,0 +1,253 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type, isType} from '../type';
|
||||
import {global, stringify} from '../util';
|
||||
import {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
|
||||
import {GetterFn, MethodFn, SetterFn} from './types';
|
||||
|
||||
/**
|
||||
* Attention: This regex has to hold even if the code is minified!
|
||||
*/
|
||||
export const DELEGATE_CTOR =
|
||||
/^function\s+\S+\(\)\s*{\s*("use strict";)?\s*(return\s+)?(\S+\s+!==\s+null\s+&&\s+)?\S+\.apply\(this,\s*arguments\)/;
|
||||
|
||||
export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
private _reflect: any;
|
||||
|
||||
constructor(reflect?: any) { this._reflect = reflect || global['Reflect']; }
|
||||
|
||||
isReflectionEnabled(): boolean { return true; }
|
||||
|
||||
factory<T>(t: Type<T>): (args: any[]) => T { return (...args: any[]) => new t(...args); }
|
||||
|
||||
/** @internal */
|
||||
_zipTypesAndAnnotations(paramTypes: any[], paramAnnotations: any[]): any[][] {
|
||||
let result: any[][];
|
||||
|
||||
if (typeof paramTypes === 'undefined') {
|
||||
result = new Array(paramAnnotations.length);
|
||||
} else {
|
||||
result = new Array(paramTypes.length);
|
||||
}
|
||||
|
||||
for (let 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.
|
||||
if (typeof paramTypes === 'undefined') {
|
||||
result[i] = [];
|
||||
} else if (paramTypes[i] != Object) {
|
||||
result[i] = [paramTypes[i]];
|
||||
} else {
|
||||
result[i] = [];
|
||||
}
|
||||
if (paramAnnotations && paramAnnotations[i] != null) {
|
||||
result[i] = result[i].concat(paramAnnotations[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private _ownParameters(type: Type<any>, parentCtor: any): any[][] {
|
||||
// If we have no decorators, we only have function.length as metadata.
|
||||
// In that case, to detect whether a child class declared an own constructor or not,
|
||||
// we need to look inside of that constructor to check whether it is
|
||||
// just calling the parent.
|
||||
// This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
|
||||
// that sets 'design:paramtypes' to []
|
||||
// if a class inherits from another class but has no ctor declared itself.
|
||||
if (DELEGATE_CTOR.exec(type.toString())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Prefer the direct API.
|
||||
if ((<any>type).parameters && (<any>type).parameters !== parentCtor.parameters) {
|
||||
return (<any>type).parameters;
|
||||
}
|
||||
|
||||
// API of tsickle for lowering decorators to properties on the class.
|
||||
const tsickleCtorParams = (<any>type).ctorParameters;
|
||||
if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
|
||||
// Newer tsickle uses a function closure
|
||||
// Retain the non-function case for compatibility with older tsickle
|
||||
const ctorParameters =
|
||||
typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
|
||||
const paramTypes = ctorParameters.map((ctorParam: any) => ctorParam && ctorParam.type);
|
||||
const paramAnnotations = ctorParameters.map(
|
||||
(ctorParam: any) =>
|
||||
ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));
|
||||
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
||||
}
|
||||
|
||||
// API for metadata created by invoking the decorators.
|
||||
if (this._reflect != null && this._reflect.getOwnMetadata != null) {
|
||||
const paramAnnotations = this._reflect.getOwnMetadata('parameters', type);
|
||||
const paramTypes = this._reflect.getOwnMetadata('design:paramtypes', type);
|
||||
if (paramTypes || paramAnnotations) {
|
||||
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
// If a class has no decorators, at least create metadata
|
||||
// based on function.length.
|
||||
// Note: We know that this is a real constructor as we checked
|
||||
// the content of the constructor above.
|
||||
return new Array((<any>type.length)).fill(undefined);
|
||||
}
|
||||
|
||||
parameters(type: Type<any>): any[][] {
|
||||
// Note: only report metadata if we have at least one class decorator
|
||||
// to stay in sync with the static reflector.
|
||||
if (!isType(type)) {
|
||||
return [];
|
||||
}
|
||||
const parentCtor = getParentCtor(type);
|
||||
let parameters = this._ownParameters(type, parentCtor);
|
||||
if (!parameters && parentCtor !== Object) {
|
||||
parameters = this.parameters(parentCtor);
|
||||
}
|
||||
return parameters || [];
|
||||
}
|
||||
|
||||
private _ownAnnotations(typeOrFunc: Type<any>, parentCtor: any): any[] {
|
||||
// Prefer the direct API.
|
||||
if ((<any>typeOrFunc).annotations && (<any>typeOrFunc).annotations !== parentCtor.annotations) {
|
||||
let annotations = (<any>typeOrFunc).annotations;
|
||||
if (typeof annotations === 'function' && annotations.annotations) {
|
||||
annotations = annotations.annotations;
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
// API of tsickle for lowering decorators to properties on the class.
|
||||
if ((<any>typeOrFunc).decorators && (<any>typeOrFunc).decorators !== parentCtor.decorators) {
|
||||
return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
|
||||
}
|
||||
|
||||
// API for metadata created by invoking the decorators.
|
||||
if (this._reflect && this._reflect.getOwnMetadata) {
|
||||
return this._reflect.getOwnMetadata('annotations', typeOrFunc);
|
||||
}
|
||||
}
|
||||
|
||||
annotations(typeOrFunc: Type<any>): any[] {
|
||||
if (!isType(typeOrFunc)) {
|
||||
return [];
|
||||
}
|
||||
const parentCtor = getParentCtor(typeOrFunc);
|
||||
const ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
|
||||
const parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
|
||||
return parentAnnotations.concat(ownAnnotations);
|
||||
}
|
||||
|
||||
private _ownPropMetadata(typeOrFunc: any, parentCtor: any): {[key: string]: any[]} {
|
||||
// Prefer the direct API.
|
||||
if ((<any>typeOrFunc).propMetadata &&
|
||||
(<any>typeOrFunc).propMetadata !== parentCtor.propMetadata) {
|
||||
let propMetadata = (<any>typeOrFunc).propMetadata;
|
||||
if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
|
||||
propMetadata = propMetadata.propMetadata;
|
||||
}
|
||||
return propMetadata;
|
||||
}
|
||||
|
||||
// API of tsickle for lowering decorators to properties on the class.
|
||||
if ((<any>typeOrFunc).propDecorators &&
|
||||
(<any>typeOrFunc).propDecorators !== parentCtor.propDecorators) {
|
||||
const propDecorators = (<any>typeOrFunc).propDecorators;
|
||||
const propMetadata = <{[key: string]: any[]}>{};
|
||||
Object.keys(propDecorators).forEach(prop => {
|
||||
propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);
|
||||
});
|
||||
return propMetadata;
|
||||
}
|
||||
|
||||
// API for metadata created by invoking the decorators.
|
||||
if (this._reflect && this._reflect.getOwnMetadata) {
|
||||
return this._reflect.getOwnMetadata('propMetadata', typeOrFunc);
|
||||
}
|
||||
}
|
||||
|
||||
propMetadata(typeOrFunc: any): {[key: string]: any[]} {
|
||||
if (!isType(typeOrFunc)) {
|
||||
return {};
|
||||
}
|
||||
const parentCtor = getParentCtor(typeOrFunc);
|
||||
const propMetadata: {[key: string]: any[]} = {};
|
||||
if (parentCtor !== Object) {
|
||||
const parentPropMetadata = this.propMetadata(parentCtor);
|
||||
Object.keys(parentPropMetadata).forEach((propName) => {
|
||||
propMetadata[propName] = parentPropMetadata[propName];
|
||||
});
|
||||
}
|
||||
const ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
|
||||
if (ownPropMetadata) {
|
||||
Object.keys(ownPropMetadata).forEach((propName) => {
|
||||
const decorators: any[] = [];
|
||||
if (propMetadata.hasOwnProperty(propName)) {
|
||||
decorators.push(...propMetadata[propName]);
|
||||
}
|
||||
decorators.push(...ownPropMetadata[propName]);
|
||||
propMetadata[propName] = decorators;
|
||||
});
|
||||
}
|
||||
return propMetadata;
|
||||
}
|
||||
|
||||
hasLifecycleHook(type: any, lcProperty: string): boolean {
|
||||
return type instanceof Type && lcProperty in type.prototype;
|
||||
}
|
||||
|
||||
getter(name: string): GetterFn { return <GetterFn>new Function('o', 'return o.' + name + ';'); }
|
||||
|
||||
setter(name: string): SetterFn {
|
||||
return <SetterFn>new Function('o', 'v', 'return o.' + name + ' = v;');
|
||||
}
|
||||
|
||||
method(name: string): MethodFn {
|
||||
const functionBody = `if (!o.${name}) throw new Error('"${name}" is undefined');
|
||||
return o.${name}.apply(o, args);`;
|
||||
return <MethodFn>new Function('o', 'args', functionBody);
|
||||
}
|
||||
|
||||
// There is not a concept of import uri in Js, but this is useful in developing Dart applications.
|
||||
importUri(type: any): string {
|
||||
// StaticSymbol
|
||||
if (typeof type === 'object' && type['filePath']) {
|
||||
return type['filePath'];
|
||||
}
|
||||
// Runtime type
|
||||
return `./${stringify(type)}`;
|
||||
}
|
||||
|
||||
resolveIdentifier(name: string, moduleUrl: string, members: string[], runtime: any): any {
|
||||
return runtime;
|
||||
}
|
||||
resolveEnum(enumIdentifier: any, name: string): any { return enumIdentifier[name]; }
|
||||
}
|
||||
|
||||
function convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
|
||||
if (!decoratorInvocations) {
|
||||
return [];
|
||||
}
|
||||
return decoratorInvocations.map(decoratorInvocation => {
|
||||
const decoratorType = decoratorInvocation.type;
|
||||
const annotationCls = decoratorType.annotationCls;
|
||||
const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
|
||||
return new annotationCls(...annotationArgs);
|
||||
});
|
||||
}
|
||||
|
||||
function getParentCtor(ctor: Function): Type<any> {
|
||||
const parentProto = Object.getPrototypeOf(ctor.prototype);
|
||||
const parentCtor = parentProto ? parentProto.constructor : null;
|
||||
// Note: We always use `Object` as the null value
|
||||
// to simplify checking later on.
|
||||
return parentCtor || Object;
|
||||
}
|
59
packages/core/src/reflection/reflector.ts
Normal file
59
packages/core/src/reflection/reflector.ts
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from '../type';
|
||||
import {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
|
||||
import {ReflectorReader} from './reflector_reader';
|
||||
import {GetterFn, MethodFn, SetterFn} from './types';
|
||||
|
||||
export {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
|
||||
export {GetterFn, MethodFn, SetterFn} from './types';
|
||||
|
||||
/**
|
||||
* Provides access to reflection data about symbols. Used internally by Angular
|
||||
* to power dependency injection and compilation.
|
||||
*/
|
||||
export class Reflector extends ReflectorReader {
|
||||
constructor(public reflectionCapabilities: PlatformReflectionCapabilities) { super(); }
|
||||
|
||||
updateCapabilities(caps: PlatformReflectionCapabilities) { this.reflectionCapabilities = caps; }
|
||||
|
||||
factory(type: Type<any>): Function { return this.reflectionCapabilities.factory(type); }
|
||||
|
||||
parameters(typeOrFunc: Type<any>): any[][] {
|
||||
return this.reflectionCapabilities.parameters(typeOrFunc);
|
||||
}
|
||||
|
||||
annotations(typeOrFunc: Type<any>): any[] {
|
||||
return this.reflectionCapabilities.annotations(typeOrFunc);
|
||||
}
|
||||
|
||||
propMetadata(typeOrFunc: Type<any>): {[key: string]: any[]} {
|
||||
return this.reflectionCapabilities.propMetadata(typeOrFunc);
|
||||
}
|
||||
|
||||
hasLifecycleHook(type: any, lcProperty: string): boolean {
|
||||
return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
|
||||
}
|
||||
|
||||
getter(name: string): GetterFn { return this.reflectionCapabilities.getter(name); }
|
||||
|
||||
setter(name: string): SetterFn { return this.reflectionCapabilities.setter(name); }
|
||||
|
||||
method(name: string): MethodFn { return this.reflectionCapabilities.method(name); }
|
||||
|
||||
importUri(type: any): string { return this.reflectionCapabilities.importUri(type); }
|
||||
|
||||
resolveIdentifier(name: string, moduleUrl: string, members: string[], runtime: any): any {
|
||||
return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
|
||||
}
|
||||
|
||||
resolveEnum(identifier: any, name: string): any {
|
||||
return this.reflectionCapabilities.resolveEnum(identifier, name);
|
||||
}
|
||||
}
|
20
packages/core/src/reflection/reflector_reader.ts
Normal file
20
packages/core/src/reflection/reflector_reader.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides read-only access to reflection data about symbols. Used internally by Angular
|
||||
* to power dependency injection and compilation.
|
||||
*/
|
||||
export abstract class ReflectorReader {
|
||||
abstract parameters(typeOrFunc: /*Type*/ any): any[][];
|
||||
abstract annotations(typeOrFunc: /*Type*/ any): any[];
|
||||
abstract propMetadata(typeOrFunc: /*Type*/ any): {[key: string]: any[]};
|
||||
abstract importUri(typeOrFunc: /*Type*/ any): string;
|
||||
abstract resolveIdentifier(name: string, moduleUrl: string, members: string[], runtime: any): any;
|
||||
abstract resolveEnum(identifier: any, name: string): any;
|
||||
}
|
11
packages/core/src/reflection/types.ts
Normal file
11
packages/core/src/reflection/types.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export type SetterFn = (obj: any, value: any) => void;
|
||||
export type GetterFn = (obj: any) => any;
|
||||
export type MethodFn = (obj: any, args: any[]) => any;
|
Reference in New Issue
Block a user