ing
This commit is contained in:
parent
a5e0efff15
commit
da4e5c50a8
5884
package-lock.json
generated
5884
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,11 @@ export interface Decorator<Attribute = {}> {
|
|||
parameterDecorator?: (target: Object, propertyKey: PropertyKeyType, parameterIndex: number) => void;
|
||||
}
|
||||
|
||||
export abstract class Decorator<Attribute = {}> extends Annotation<Attribute> {
|
||||
export abstract class Decorator<Attribute = {}> extends Annotation {
|
||||
public readonly attribute: Attribute;
|
||||
|
||||
public constructor(attribute?: Attribute) {
|
||||
super(attribute);
|
||||
super();
|
||||
this.attribute = attribute;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
import {
|
||||
Type,
|
||||
} from '@loafer/core';
|
||||
|
||||
import {
|
||||
Class,
|
||||
Constructor,
|
||||
Field,
|
||||
Method,
|
||||
Parameter,
|
||||
Metadata,
|
||||
} from '@loafer/core/reflect';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '@loafer/core/util/TypeUtil';
|
||||
|
||||
import { Decorator } from './Decorator';
|
||||
import { DecoratorUtil } from './util';
|
||||
import { DecoratorType } from './type';
|
||||
import { NotSupportedDecoratorError } from './error';
|
||||
|
||||
|
||||
export class DecoratorFactory {
|
||||
public static create = <Attribute = {}>(DecoratorClass: Type<Decorator<Attribute>>) => {
|
||||
return (attribute: Attribute) => {
|
||||
const annotation: Decorator<Attribute> = new DecoratorClass(attribute);
|
||||
const name: string = DecoratorClass.name;
|
||||
|
||||
return (...decoratorArgs: any[]) => {
|
||||
const decoratorType: DecoratorType = DecoratorUtil.getDecoratorType(decoratorArgs);
|
||||
|
||||
const [target, propertyKey, descriptorOrParameterIndex] = decoratorArgs;
|
||||
|
||||
const clazz: Class = Class._defineClass(TypeUtil.getType(target));
|
||||
let field: Field = null;
|
||||
let method: Method = null;
|
||||
let parameter: Parameter = null;
|
||||
let cons: Constructor = null;
|
||||
|
||||
switch (decoratorType) {
|
||||
case DecoratorType.CLASS:
|
||||
try {
|
||||
cons = clazz._defineConstructor(Metadata.getOwnParamTypes(target));
|
||||
clazz._addAnnotation(annotation);
|
||||
return annotation.classDecorator.call(annotation, target);
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Class.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
case DecoratorType.PROPERTY:
|
||||
try {
|
||||
field = clazz._defineField(propertyKey, Metadata.getOwnType(target, propertyKey));
|
||||
field._addAnnotation(annotation);
|
||||
return annotation.propertyDecorator.call(annotation, target, propertyKey);
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Property.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
case DecoratorType.METHOD:
|
||||
try {
|
||||
method = clazz._defineMethod(propertyKey,
|
||||
Metadata.getOwnParamTypes(target, propertyKey),
|
||||
Metadata.getOwnReturnType(target, propertyKey));
|
||||
method._addAnnotation(annotation);
|
||||
|
||||
return annotation.methodDecorator.call(annotation, target, propertyKey, descriptorOrParameterIndex);
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Method.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
case DecoratorType.PARAMETER:
|
||||
try {
|
||||
if (undefined === propertyKey) {
|
||||
cons = clazz.getConstructor();
|
||||
parameter = cons.getParameter(descriptorOrParameterIndex);
|
||||
} else {
|
||||
method = clazz._defineMethod(propertyKey,
|
||||
Metadata.getOwnParamTypes(target, propertyKey),
|
||||
Metadata.getOwnReturnType(target, propertyKey));
|
||||
parameter = method.getParameter(descriptorOrParameterIndex);
|
||||
}
|
||||
parameter._addAnnotation(annotation);
|
||||
|
||||
return annotation.parameterDecorator.call(annotation, target, propertyKey, descriptorOrParameterIndex);
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Parameter.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
default:
|
||||
throw new NotSupportedDecoratorError(`Cannot determine decorator[@${name}] type.`);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
}
|
160
src/DecoratorHelper.ts
Normal file
160
src/DecoratorHelper.ts
Normal file
|
@ -0,0 +1,160 @@
|
|||
import {
|
||||
Type,
|
||||
PropertyKeyType,
|
||||
} from '@loafer/core';
|
||||
|
||||
import {
|
||||
Annotation,
|
||||
Class,
|
||||
Constructor,
|
||||
Field,
|
||||
Method,
|
||||
Parameter,
|
||||
Metadata,
|
||||
} from '@loafer/core/reflect';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '@loafer/core/util/TypeUtil';
|
||||
|
||||
import { Decorator } from './Decorator';
|
||||
import { DecoratorType, DecoratorParametersType } from './type';
|
||||
import { NotSupportedDecoratorError } from './error';
|
||||
|
||||
export class DecoratorHelper {
|
||||
|
||||
public static register<AnnotationType extends Annotation>(annotation: AnnotationType, ...decoratorArgs: any[]) {
|
||||
const annotationClass = TypeUtil.getType(annotation);
|
||||
const name: string = annotationClass.name;
|
||||
|
||||
DecoratorHelper.registerAnnotation(name, annotation, decoratorArgs);
|
||||
}
|
||||
|
||||
public static create = <Attribute = {}>(DecoratorClass: Type<Decorator<Attribute>>) => {
|
||||
return (attribute: Attribute) => {
|
||||
const annotation: Decorator<Attribute> = new DecoratorClass(attribute);
|
||||
const name: string = DecoratorClass.name;
|
||||
|
||||
return (...decoratorArgs: any[]) => {
|
||||
return DecoratorHelper.registerAnnotation(name, annotation, decoratorArgs);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
private static registerAnnotation(name: string, annotation: any, decoratorArgs: any[]) {
|
||||
const decoratorType: DecoratorType = DecoratorHelper.getDecoratorType(decoratorArgs);
|
||||
|
||||
const [target, propertyKey, descriptorOrParameterIndex] = decoratorArgs;
|
||||
|
||||
const clazz: Class = Class._defineClass(TypeUtil.getType(target));
|
||||
let field: Field = null;
|
||||
let method: Method = null;
|
||||
let parameter: Parameter = null;
|
||||
let cons: Constructor = null;
|
||||
|
||||
switch (decoratorType) {
|
||||
case DecoratorType.CLASS:
|
||||
try {
|
||||
cons = clazz._defineConstructor(Metadata.getOwnParamTypes(target));
|
||||
clazz._addAnnotation(annotation);
|
||||
if (annotation instanceof Decorator) {
|
||||
return annotation.classDecorator.call(annotation, target);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Class.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case DecoratorType.PROPERTY:
|
||||
try {
|
||||
field = clazz._defineField(propertyKey, Metadata.getOwnType(target, propertyKey));
|
||||
field._addAnnotation(annotation);
|
||||
if (annotation instanceof Decorator) {
|
||||
return annotation.propertyDecorator.call(annotation, target, propertyKey);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Property.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case DecoratorType.METHOD:
|
||||
try {
|
||||
method = clazz._defineMethod(propertyKey,
|
||||
Metadata.getOwnParamTypes(target, propertyKey),
|
||||
Metadata.getOwnReturnType(target, propertyKey));
|
||||
method._addAnnotation(annotation);
|
||||
|
||||
if (annotation instanceof Decorator) {
|
||||
return annotation.methodDecorator.call(annotation, target, propertyKey, descriptorOrParameterIndex);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Method.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case DecoratorType.PARAMETER:
|
||||
try {
|
||||
if (undefined === propertyKey) {
|
||||
cons = clazz.getConstructor();
|
||||
parameter = cons.getParameter(descriptorOrParameterIndex);
|
||||
} else {
|
||||
method = clazz._defineMethod(propertyKey,
|
||||
Metadata.getOwnParamTypes(target, propertyKey),
|
||||
Metadata.getOwnReturnType(target, propertyKey));
|
||||
parameter = method.getParameter(descriptorOrParameterIndex);
|
||||
}
|
||||
parameter._addAnnotation(annotation);
|
||||
|
||||
if (annotation instanceof Decorator) {
|
||||
return annotation.parameterDecorator.call(annotation, target, propertyKey, descriptorOrParameterIndex);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof NotSupportedDecoratorError) {
|
||||
throw new NotSupportedDecoratorError(`Cannot apply @${name} decorator on Parameter.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedDecoratorError(`Cannot determine decorator[@${name}] type.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any[]} args
|
||||
* @returns {DecoratorType}
|
||||
*/
|
||||
public static getDecoratorType(args: any[]): DecoratorType {
|
||||
const [, propertyKey, descriptor] = args;
|
||||
|
||||
if (typeof descriptor === 'number') {
|
||||
return DecoratorType.PARAMETER;
|
||||
}
|
||||
|
||||
if (propertyKey && descriptor === undefined || descriptor && (descriptor.get || descriptor.set)) {
|
||||
return DecoratorType.PROPERTY;
|
||||
}
|
||||
return (descriptor && descriptor.value) ? DecoratorType.METHOD : DecoratorType.CLASS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param {string} propertyKey
|
||||
* @returns {DecoratorParametersType}
|
||||
*/
|
||||
public static decoratorArgs(target: any, propertyKey: PropertyKeyType): DecoratorParametersType {
|
||||
return [
|
||||
target,
|
||||
propertyKey,
|
||||
TypeUtil.descriptorOf(target, propertyKey),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
export * from './Decorator';
|
||||
export * from './DecoratorFactory';
|
||||
export * from './DecoratorHelper';
|
||||
export * from './error';
|
||||
export * from './type';
|
||||
export * from './util';
|
||||
|
|
48
src/util.ts
48
src/util.ts
|
@ -1,48 +0,0 @@
|
|||
import {
|
||||
PropertyKeyType,
|
||||
} from '@loafer/core';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '@loafer/core/util/TypeUtil';
|
||||
|
||||
|
||||
import {
|
||||
DecoratorType,
|
||||
DecoratorParametersType,
|
||||
} from './type';
|
||||
|
||||
export class DecoratorUtil {
|
||||
/**
|
||||
*
|
||||
* @param {any[]} args
|
||||
* @returns {DecoratorType}
|
||||
*/
|
||||
public static getDecoratorType(args: any[]): DecoratorType {
|
||||
const [, propertyKey, descriptor] = args;
|
||||
|
||||
if (typeof descriptor === 'number') {
|
||||
return DecoratorType.PARAMETER;
|
||||
}
|
||||
|
||||
if (propertyKey && descriptor === undefined || descriptor && (descriptor.get || descriptor.set)) {
|
||||
return DecoratorType.PROPERTY;
|
||||
}
|
||||
return (descriptor && descriptor.value) ? DecoratorType.METHOD : DecoratorType.CLASS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param {string} propertyKey
|
||||
* @returns {DecoratorParametersType}
|
||||
*/
|
||||
public static decoratorArgs(target: any, propertyKey: PropertyKeyType): DecoratorParametersType {
|
||||
return [
|
||||
target,
|
||||
propertyKey,
|
||||
TypeUtil.descriptorOf(target, propertyKey),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user