This commit is contained in:
crusader 2017-12-24 17:29:11 +09:00
parent 795b91d4f8
commit ca017516a1
19 changed files with 109 additions and 100 deletions

View File

@ -89,6 +89,10 @@ export class Class extends AccessibleObject {
return method;
}
public getType(): ClassType {
return this._clazzType;
}
public getConstructor(): Constructor {
return this._constructor;
}

View File

@ -1,17 +1,23 @@
import {
PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type';
import {Class} from './class';
import {Executable} from './executable';
export class Constructor extends Executable {
private _rawConstructor: Function;
public constructor(declaringClazz: Class, parameterTypes: any[]) {
super(declaringClazz, parameterTypes);
super(declaringClazz, CONSTRUCTOR_NAME, parameterTypes);
this._rawConstructor = TypeUtil.getPrototype(declaringClazz.getType())[CONSTRUCTOR_NAME];
}
public getName(): PropertyKeyType {
return '';
public newInstance(...args: any[]): any {
let ctor = this.getDeclaringClass().getType();
return new (ctor.bind.apply(ctor, [null].concat(args)))();
}
}
const CONSTRUCTOR_NAME = 'constructor';

View File

@ -1,12 +1,3 @@
import {
Annotation,
Class,
Constructor,
Field,
Method,
Parameter,
} from '@overflow/commons/core/reflect';
import {
ClassType,
DecoratorType,
@ -15,8 +6,14 @@ import {
TypeUtil,
} from '@overflow/commons/core/type';
import * as Constants from './constants';
import {Annotation} from './annotation';
import {Class} from './class';
import {Constructor} from './constructor';
import {Field} from './field';
import {Method} from './method';
import {Parameter} from './parameter';
import * as Constants from './constants';
export class Decorator {
public static create = (AnnotationClass: ClassType<Annotation>) => {

View File

@ -1,5 +1,6 @@
import {
PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type';
import {AccessibleObject} from './accessible_object';
@ -9,20 +10,26 @@ import {Parameter} from './parameter';
export abstract class Executable extends AccessibleObject implements Member {
private _clazz: Class;
private _name: PropertyKeyType;
private _parameters: Parameter[];
protected constructor(declaringClazz: Class, parameterTypes: any[]) {
protected constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[]) {
super();
this._clazz = declaringClazz;
this._name = name;
if (null === parameterTypes) {
return;
}
let parameterNames = TypeUtil.getParameterNames(declaringClazz.getType(), name);
this._parameters = [];
for (let i = 0; i < parameterTypes.length; i++) {
const parameterType = parameterTypes[i];
let parameter: Parameter = new Parameter(this, parameterType, i);
const parameterName = parameterNames[i];
let parameter: Parameter = new Parameter(this, parameterType, parameterName, i);
this._parameters.push(parameter);
}
}
@ -31,7 +38,10 @@ export abstract class Executable extends AccessibleObject implements Member {
return this._clazz;
}
public abstract getName(): PropertyKeyType;
public getName(): PropertyKeyType {
return this._name;
}
/**
* getParameterCount
*/

View File

@ -1,8 +1,9 @@
export * from './accessible_object';
export * from './annotated_element';
export * from './annotation';
export * from './constructor';
export * from './class';
export * from './constructor';
export * from './decorator';
export * from './executable';
export * from './field';
export * from './member';

View File

@ -1,25 +1,26 @@
import {
PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type';
import {Class} from './class';
import {Executable} from './executable';
export class Method extends Executable {
private _name: PropertyKeyType;
private _returnType: any;
private _rawMethod: Function;
public constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[], returnType: any) {
super(declaringClazz, parameterTypes);
this._name = name;
super(declaringClazz, name, parameterTypes);
this._returnType = returnType;
}
public getName(): PropertyKeyType {
return this._name;
this._rawMethod = TypeUtil.getPrototype(declaringClazz.getType())[name];
}
public getReturnType(): any {
return this._returnType;
}
public invoke(instance: Object, ...args: any[]): any {
return this._rawMethod.apply(instance, args);
}
}

View File

@ -5,11 +5,13 @@ export class Parameter extends AccessibleObject {
private _executable: Executable;
private _type: any;
private _index: number;
private _name: string;
public constructor(executable: Executable, parameterType: any, index: number) {
public constructor(executable: Executable, parameterType: any, name: string, index: number) {
super();
this._executable = executable;
this._type = parameterType;
this._name = name;
this._index = index;
}
@ -21,6 +23,10 @@ export class Parameter extends AccessibleObject {
return this._type;
}
public getName(): string {
return this._name;
}
public getIndex(): number {
return this._index;
}

View File

@ -27,6 +27,17 @@ export class TypeUtil {
return target.prototype ? target : target.constructor;
}
/**
* Get the provide prototype if target is an instance.
* @param target
* @returns {*}
*/
public static getPrototype(target: any): Object {
return typeof target === 'function'
? target.prototype
: target;
}
/**
*
* @param target
@ -336,6 +347,28 @@ export class TypeUtil {
return Object.getOwnPropertyDescriptor(target && target.prototype || target, propertyKey)!;
}
/**
*
* @param target
* @param {PropertyKeyType} propertyKey
* @returns {string[]}
*/
public static getParameterNames(target: any, propertyKey: PropertyKeyType): string[] {
let rawType = TypeUtil.getPrototype(target);
let fn: Function = rawType[propertyKey];
let code = fn.toString()
.replace(COMMENTS, '')
.replace(FAT_ARROWS, '')
.replace(DEFAULT_PARAMS, '');
let result = code.slice(code.indexOf('(') + 1, code.indexOf(')')).match(/([^\s,]+)/g);
return result === null
? []
: result;
}
/**
*
* @param target
@ -406,3 +439,7 @@ export class TypeUtil {
}
}
const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
const DEFAULT_PARAMS = /=[^,]+/mg;
const FAT_ARROWS = /=>.*$/mg;

View File

@ -1,2 +0,0 @@
export * from './constants';
export * from './decorator';

View File

@ -1,5 +1,6 @@
import {
Annotation,
Decorator,
} from '@overflow/commons/core/reflect';
import {
@ -8,18 +9,15 @@ import {
TypeUtil,
} from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface ActionMappingAnnotationAttributes {
value: string;
value: string[];
}
export class ActionMappingAnnotation implements Annotation {
public readonly attributes: ActionMappingAnnotationAttributes;
public constructor(value: string | ActionMappingAnnotationAttributes) {
public constructor(value: string | string[] | ActionMappingAnnotationAttributes) {
if (undefined === value) {
throw new Error(`value attribute must be specified.`);
@ -27,7 +25,11 @@ export class ActionMappingAnnotation implements Annotation {
if (TypeUtil.isString(value)) {
this.attributes = {
value: <string>value,
value: [<string>value],
};
} else if (TypeUtil.isArray(value)) {
this.attributes = {
value: <string[]>value,
};
} else {
this.attributes = <ActionMappingAnnotationAttributes>value;

View File

@ -1,5 +1,4 @@
export * from './action_mapping';
export * from './parameter';
export * from './reducer';
export * from './rest_api';
export * from './rpc_api';

View File

@ -1,43 +0,0 @@
import {
Annotation,
} from '@overflow/commons/core/reflect';
import {
PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface ParameterAnnotationAttributes {
name?: string;
}
export class ParameterAnnotation implements Annotation {
public readonly attributes: ParameterAnnotationAttributes;
public constructor(name: string | ParameterAnnotationAttributes) {
if (undefined === name) {
this.attributes = {
name: '',
};
return;
}
if (TypeUtil.isString(name)) {
this.attributes = {
name: <string>name,
};
} else {
this.attributes = <ParameterAnnotationAttributes>name;
}
}
public parameterDecorator?(target: Object, propertyKey: PropertyKeyType, parameterIndex: number): void {
console.log('Parameter');
}
}
export const Parameter = Decorator.create(ParameterAnnotation);

View File

@ -1,5 +1,6 @@
import {
Annotation,
Decorator,
} from '@overflow/commons/core/reflect';
import {
@ -7,9 +8,6 @@ import {
TypeUtil,
} from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface ReducerAnnotationAttributes {
name?: string;

View File

@ -1,5 +1,6 @@
import {
Annotation,
Decorator,
} from '@overflow/commons/core/reflect';
import {
@ -8,10 +9,6 @@ import {
TypeUtil,
} from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface RestAPIAnnotationAttributes {
entryPath: string;
}

View File

@ -1,5 +1,6 @@
import {
Annotation,
Decorator,
} from '@overflow/commons/core/reflect';
import {
@ -8,10 +9,6 @@ import {
TypeUtil,
} from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface RpcAPIAnnotationAttributes {
method: string;
}

View File

@ -2,6 +2,11 @@
import {
ClassType,
} from '@overflow/commons/core/type';
import {
Method,
} from '@overflow/commons/core/reflect';
import {
ActionMappingAnnotation,
ReducerAnnotation,
@ -64,10 +69,6 @@ export default class LPCReducer {
let reducerMapping: string = null;
let ama: ActionMappingAnnotation = clazz.getOwnAnnotation(ActionMappingAnnotation);
if (undefined !== ama) {
reducerMapping = ama.attributes.value;
}
console.log(`actionMapping-value: ${ama.attributes.value}`);
clazz.getOwnMethods().forEach(method => {
let restAPIAnnotation: RestAPIAnnotation = method.getOwnAnnotation(RestAPIAnnotation);
@ -79,6 +80,9 @@ export default class LPCReducer {
console.log(`restAPI: ${rpcAPIAnnotation.attributes.method}`);
}
});
}
}
// protected registerReducerMethod(ama: ActionMappingAnnotation, method: Method): void {
// }
}

View File

@ -1,6 +1,5 @@
import {
ActionMapping,
Parameter,
Reducer,
RestAPI,
} from '@overflow/commons/redux/decorators';
@ -8,18 +7,14 @@ import {
@Reducer()
@ActionMapping('@overflow/modules/member/MemberReducer')
export default class MemberReducer {
private name: string;
public constructor(count: number, @Parameter() name: string) {
this.name = name;
}
/**
* signin
*/
@RestAPI('/account/signin')
@ActionMapping('/signin')
public signin(state: any, @Parameter() result: any, error: any): any {
public signin(state: any, result: any, error: any): any {
console.log(`signin`);
return state;
}
}