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; return method;
} }
public getType(): ClassType {
return this._clazzType;
}
public getConstructor(): Constructor { public getConstructor(): Constructor {
return this._constructor; return this._constructor;
} }

View File

@ -1,17 +1,23 @@
import { import {
PropertyKeyType, PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
import {Class} from './class'; import {Class} from './class';
import {Executable} from './executable'; import {Executable} from './executable';
export class Constructor extends Executable { export class Constructor extends Executable {
private _rawConstructor: Function;
public constructor(declaringClazz: Class, parameterTypes: any[]) { 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 { public newInstance(...args: any[]): any {
return ''; 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 { import {
ClassType, ClassType,
DecoratorType, DecoratorType,
@ -15,8 +6,14 @@ import {
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } 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 { export class Decorator {
public static create = (AnnotationClass: ClassType<Annotation>) => { public static create = (AnnotationClass: ClassType<Annotation>) => {

View File

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

View File

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

View File

@ -1,25 +1,26 @@
import { import {
PropertyKeyType, PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
import {Class} from './class'; import {Class} from './class';
import {Executable} from './executable'; import {Executable} from './executable';
export class Method extends Executable { export class Method extends Executable {
private _name: PropertyKeyType;
private _returnType: any; private _returnType: any;
private _rawMethod: Function;
public constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[], returnType: any) { public constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[], returnType: any) {
super(declaringClazz, parameterTypes); super(declaringClazz, name, parameterTypes);
this._name = name;
this._returnType = returnType; this._returnType = returnType;
} this._rawMethod = TypeUtil.getPrototype(declaringClazz.getType())[name];
public getName(): PropertyKeyType {
return this._name;
} }
public getReturnType(): any { public getReturnType(): any {
return this._returnType; 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 _executable: Executable;
private _type: any; private _type: any;
private _index: number; 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(); super();
this._executable = executable; this._executable = executable;
this._type = parameterType; this._type = parameterType;
this._name = name;
this._index = index; this._index = index;
} }
@ -21,6 +23,10 @@ export class Parameter extends AccessibleObject {
return this._type; return this._type;
} }
public getName(): string {
return this._name;
}
public getIndex(): number { public getIndex(): number {
return this._index; return this._index;
} }

View File

@ -27,6 +27,17 @@ export class TypeUtil {
return target.prototype ? target : target.constructor; 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 * @param target
@ -336,6 +347,28 @@ export class TypeUtil {
return Object.getOwnPropertyDescriptor(target && target.prototype || target, propertyKey)!; 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 * @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 { import {
Annotation, Annotation,
Decorator,
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
@ -8,18 +9,15 @@ import {
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface ActionMappingAnnotationAttributes { export interface ActionMappingAnnotationAttributes {
value: string; value: string[];
} }
export class ActionMappingAnnotation implements Annotation { export class ActionMappingAnnotation implements Annotation {
public readonly attributes: ActionMappingAnnotationAttributes; public readonly attributes: ActionMappingAnnotationAttributes;
public constructor(value: string | ActionMappingAnnotationAttributes) { public constructor(value: string | string[] | ActionMappingAnnotationAttributes) {
if (undefined === value) { if (undefined === value) {
throw new Error(`value attribute must be specified.`); throw new Error(`value attribute must be specified.`);
@ -27,7 +25,11 @@ export class ActionMappingAnnotation implements Annotation {
if (TypeUtil.isString(value)) { if (TypeUtil.isString(value)) {
this.attributes = { this.attributes = {
value: <string>value, value: [<string>value],
};
} else if (TypeUtil.isArray(value)) {
this.attributes = {
value: <string[]>value,
}; };
} else { } else {
this.attributes = <ActionMappingAnnotationAttributes>value; this.attributes = <ActionMappingAnnotationAttributes>value;

View File

@ -1,5 +1,4 @@
export * from './action_mapping'; export * from './action_mapping';
export * from './parameter';
export * from './reducer'; export * from './reducer';
export * from './rest_api'; export * from './rest_api';
export * from './rpc_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 { import {
Annotation, Annotation,
Decorator,
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
@ -7,9 +8,6 @@ import {
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
import {
Decorator,
} from '@overflow/commons/decorator';
export interface ReducerAnnotationAttributes { export interface ReducerAnnotationAttributes {
name?: string; name?: string;

View File

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

View File

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

View File

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

View File

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