UNPKG

node-web-mvc

Version:
161 lines (160 loc) 6.5 kB
"use strict"; /** * 注解索引,用于快速获取指定类下相关注解 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Javascript_1 = __importDefault(require("../../../interface/Javascript")); const ElementType_1 = __importDefault(require("./ElementType")); const annotationsSymbol = Symbol('annotations'); const mapAnnotationsSymbol = Symbol('allAnnotations'); class AnnotationIndexer { static createIndexerIfNeed(ctor) { if (!this.getIndexer(ctor)) { const indexer = new AnnotationIndexer(); Javascript_1.default.defineHiddenProperty(ctor, annotationsSymbol, indexer); indexer.owner = ctor; } return ctor[annotationsSymbol]; } static getIndexer(ctor) { if (!ctor || !ctor.hasOwnProperty(annotationsSymbol)) { return null; } // 这里为了防止从原型链上找annotationsSymbol 所以采用hasOwnProperty return ctor[annotationsSymbol]; } static getMethodIndexer(clazz, method) { var _a, _b, _c; const indexer = this.getIndexer(clazz); const key = typeof method == 'string' ? (_a = clazz.prototype) === null || _a === void 0 ? void 0 : _a[method] : method; return (_c = (_b = indexer === null || indexer === void 0 ? void 0 : indexer.methods) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.call(_b, key); } constructor() { this.clazz = new Map(); this.properties = {}; this.methods = new Map(); } createMethodIndexer(methodKey) { let method = this.methods.get(methodKey); if (!method) { method = { annotations: new Map(), parameters: {}, }; this.methods.set(methodKey, method); } return method; } cacheAnnotation(map, key, annotation) { let annotations = map.get(key); let allAnnotations = map[mapAnnotationsSymbol]; if (!annotations) { annotations = []; map.set(key, annotations); } if (!allAnnotations) { allAnnotations = []; Javascript_1.default.defineHiddenProperty(map, mapAnnotationsSymbol, allAnnotations); } allAnnotations.push(annotation); annotations.push(annotation); } addAnnotation(annotation) { const cacheKey = annotation.nativeAnnotation.constructor; switch (annotation.elementType) { case ElementType_1.default.TYPE: this.cacheAnnotation(this.clazz, cacheKey, annotation); break; case ElementType_1.default.METHOD: this.cacheAnnotation(this.createMethodIndexer(annotation.method).annotations, cacheKey, annotation); break; case ElementType_1.default.PROPERTY: { const name = annotation.name; let properties = this.properties[name]; if (!properties) { properties = this.properties[name] = new Map(); } this.cacheAnnotation(properties, cacheKey, annotation); } case ElementType_1.default.PARAMETER: { const paramName = annotation.paramName; const method = this.createMethodIndexer(annotation.method); let parameter = method.parameters[paramName]; if (!parameter) { parameter = method.parameters[paramName] = new Map(); } this.cacheAnnotation(parameter, cacheKey, annotation); } } } static getClazzAnnotation(clazz, annotationType) { const indexer = this.getIndexer(clazz); if (indexer) { return this.findAnnotation(indexer.clazz, annotationType); } } static getMethodAnnotation(clazz, methodKey, annotationType) { const indexer = this.getMethodIndexer(clazz, methodKey); if (indexer) { return this.findAnnotation(indexer.annotations, annotationType); } } static getPropertyAnnotation(clazz, name, annotationType) { var _a; const indexer = this.getIndexer(clazz); const property = (_a = indexer === null || indexer === void 0 ? void 0 : indexer.properties) === null || _a === void 0 ? void 0 : _a[name]; if (property) { return this.findAnnotation(property, annotationType); } } static getParameterAnnotation(clazz, methodKey, paramName, annotationType) { var _a, _b; const parameter = (_b = (_a = this.getMethodIndexer(clazz, methodKey)) === null || _a === void 0 ? void 0 : _a.parameters) === null || _b === void 0 ? void 0 : _b[paramName]; if (parameter) { return this.findAnnotation(parameter, annotationType); } ; } static findAnnotation(info, annotationType) { const annotations = info[mapAnnotationsSymbol]; const len = arguments.length; const cacheKey = (annotationType === null || annotationType === void 0 ? void 0 : annotationType.NativeAnnotation) || annotationType; if (!annotations) { return null; } if (len == 1) { return annotations[0]; } else if (info.get(cacheKey)) { return info.get(cacheKey)[0]; } else { return annotations.find((m) => this.isAnnotationTypeOf(m, annotationType)); } } static findAnnotations(info, annotationType) { const annotations = info[mapAnnotationsSymbol]; const len = arguments.length; if (!annotations) { return null; } if (len == 1) { return annotations; } else { return annotations.filter((m) => this.isAnnotationTypeOf(m, annotationType)); } } static isAnnotationTypeOf(m, type) { const nativeAnnotation = m.nativeAnnotation; const NativeAnnotation = type.NativeAnnotation; return nativeAnnotation instanceof type || (NativeAnnotation && nativeAnnotation instanceof NativeAnnotation); } ; } exports.default = AnnotationIndexer;