UNPKG

node-web-mvc

Version:
339 lines (338 loc) 13.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /** * @module RuntimeAnnotation * @description 运行时注解类 */ const src_1 = __importDefault(require("../../../hmr/src")); const ElementType_1 = __importStar(require("./ElementType")); const Javascript_1 = __importDefault(require("../../../interface/Javascript")); const Tracer_1 = __importDefault(require("./Tracer")); const Merge_1 = require("../Merge"); const AnnotationIndexer_1 = __importDefault(require("./AnnotationIndexer")); const Alias_1 = __importDefault(require("./Alias")); const metadata_1 = require("./metadata"); // 所有运行时注解 const runtimeAnnotations = []; const isMatchType = (m, clazz) => { if (m.ctor === clazz) { return true; } return Javascript_1.default.createTyper(clazz).isExtendOf(m.ctor); }; class RuntimeAnnotation { /** * 标注类的构造函数 */ get ctor() { switch (this.elementType) { case ElementType_1.default.TYPE: return this.target; default: return this.target.constructor; } } /** * 当前标注的方法 */ get method() { const fn = this.elementType === ElementType_1.default.TYPE ? null : this.target[this.methodName]; if (fn) { Object.defineProperty(fn, 'name', { value: this.methodName }); } return fn; } /** * 如果当前注解为:函数注解,则能获取到返回结果类型 */ get returnType() { return (0, metadata_1.getRuntimeType)('design:returntype', this.target, this.name); } /** * 如果当前为函数注解,则能获取到当前函数的参数类型 */ get paramTypes() { const paramTypes = (Reflect.getMetadata('design:paramtypes', this.target, this.name) || []); return paramTypes.map((paramType, i) => { return (0, metadata_1.getRuntimeType)('design:paramtypes', this.target, this.name, i); }); } /** * 如果当前注解为参数注解,则能获取到当前参数的类型 * @param ctor */ get paramType() { return (0, metadata_1.getRuntimeType)('design:paramtypes', this.target, this.name, this.paramIndex); } /** * 当注解,作用在属性上时,的类型 */ get dataType() { if (this.elementType == ElementType_1.default.PARAMETER) { return this.paramType; } return (0, metadata_1.getRuntimeType)('design:type', this.target, this.name); } /** * 获取所有指定类型的注解 * @param type 注解类型 */ static getTypedRuntimeAnnotations(type, match) { const isMatch = match || (() => true); return runtimeAnnotations.filter((m) => AnnotationIndexer_1.default.isAnnotationTypeOf(m, type) && isMatch(m)); } /** * 获取指定类型的注解 * @param type 注解类型 */ static getTypedRuntimeAnnotation(type, match) { const isMatch = match || (() => true); return runtimeAnnotations.find((m) => AnnotationIndexer_1.default.isAnnotationTypeOf(m, type) && isMatch(m)); } /** * 根据现有注解来获取相同作用于下对应的指定类型的注解 * @param anno 当前注解 * @param type 要获取的注解类型 */ static getAnnotationsByAnno(anno, type) { if (!anno) { return []; } return this.getTypedRuntimeAnnotations(type, (m) => { return m.ctor == anno.ctor && m.name == anno.name && m.methodName == anno.methodName && m.paramIndex == anno.paramIndex; }); } static getClassAnnotations(clazz, annotationType) { const indexcer = AnnotationIndexer_1.default.getIndexer(clazz); if (!indexcer) return []; if (arguments.length == 1) { return AnnotationIndexer_1.default.findAnnotations(indexcer.clazz); } return AnnotationIndexer_1.default.findAnnotations(indexcer.clazz, annotationType); } /** * 获取指定类的指定类型的注解信息 * @param {Function} clazz 被修饰的类 * @param {Function} type 注解类型 */ static getClassAnnotation(clazz, annotationType) { return AnnotationIndexer_1.default.getClazzAnnotation(clazz, annotationType); } /** * 判断当前类是否存在指定类型的注解 * @param {Function} clazz 被修饰的类 * @param {Function} type 注解类型 */ static hasClassAnnotation(clazz, type) { return !!this.getClassAnnotation(clazz, type); } /** * 获取指定类型的多个注解信息 * @param {Function} type 注解类型 * @param {Function} clazz 被修饰的类 */ static getAnnotations(annotationType, clazz) { const isScope = arguments.length >= 2 ? (m) => isMatchType(m, clazz) : () => true; const types = annotationType instanceof Array ? annotationType : [annotationType]; return runtimeAnnotations.filter((m) => { return isScope(m) && !!types.find((t) => AnnotationIndexer_1.default.isAnnotationTypeOf(m, t)); }); } /** * 获取指定类型的注解信息 * @param {Function} type 注解类型 * @param {Function} clazz 被修饰的类 */ static getAnnotation(annotationType, clazz) { // eslint-disable-next-line prefer-rest-params return this.getAnnotations.call(this, ...arguments)[0]; } static getMethodAnnotations(clazz, method, annotationType) { const methodIndexer = AnnotationIndexer_1.default.getMethodIndexer(clazz, method); if (!methodIndexer) return []; if (arguments.length == 2) { return AnnotationIndexer_1.default.findAnnotations(methodIndexer.annotations); } return AnnotationIndexer_1.default.findAnnotations(methodIndexer.annotations, annotationType); } /** * 获取指定函数的指定注解 * @param clazz 函数所在类 * @param method 函数名称 */ static getMethodAnnotation(clazz, method, annotationType) { return AnnotationIndexer_1.default.getMethodAnnotation(clazz, method, annotationType); } static getMethodParamAnnotations(clazz, method, paramName, annotationType) { var _a, _b; const parameterIndexer = (_b = (_a = AnnotationIndexer_1.default.getMethodIndexer(clazz, method)) === null || _a === void 0 ? void 0 : _a.parameters) === null || _b === void 0 ? void 0 : _b[paramName]; if (!parameterIndexer) return []; if (arguments.length == 3) { return AnnotationIndexer_1.default.findAnnotations(parameterIndexer); } return AnnotationIndexer_1.default.findAnnotations(parameterIndexer, annotationType); } /** * 获取指定函数指定名称参数注解 * @param clazz 函数所在类 * @param method 函数名称 * @param paramName 参数下标 */ static getMethodParamAnnotation(clazz, method, paramName, annotationType) { return AnnotationIndexer_1.default.getParameterAnnotation(clazz, method, paramName, annotationType); } /** * 获取指定类的属性上的注解信息 * @param clazz 属性所在类 * @param name 属性名称 * @param annotationType 要获取的注解类型,如果不指定则返回该属性上的所有注解 */ static getPropertyAnnotations(clazz, name, annotationType) { var _a, _b; const property = (_b = (_a = AnnotationIndexer_1.default.getIndexer(clazz)) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b[name]; if (!property) return []; if (arguments.length == 2) { return AnnotationIndexer_1.default.findAnnotations(property); } else { return AnnotationIndexer_1.default.findAnnotations(property, annotationType); } } /** * 获取指定类的属性上的注解信息 * @param clazz 属性所在类 * @param name 属性名称 * @param annotationType 要获取的注解类型 */ static getPropertyAnnotation(clazz, name, annotationType) { return AnnotationIndexer_1.default.getPropertyAnnotation(clazz, name, annotationType); } /** * 获取指定类的所有属性名称 * @param clazz * @returns */ static getClazzPropertyKeys(clazz) { const indexcer = AnnotationIndexer_1.default.getIndexer(clazz); if (!indexcer) return []; return Object.keys(indexcer.properties); } /** * 合并配置值到nativeAnnotation上 * @param nativeAnnotation * @param initializer */ static mergeAnnotationValues(annotation, initializer) { const nativeAnnotation = annotation.nativeAnnotation; const aliasAnnotations = RuntimeAnnotation.getAnnotations(Alias_1.default, nativeAnnotation.constructor); const mergeAnnotations = runtimeAnnotations.filter((m) => m.ownerAnnotation == annotation); const mappings = {}; aliasAnnotations.forEach((m) => { mappings[m.name] = m.nativeAnnotation; }); // 自动将配置的值赋值到nativeAnnotation上 Object.keys(initializer).forEach((key) => { var _a; const aliasAnno = mappings[key]; const value = initializer[key]; nativeAnnotation[key] = value; if (aliasAnno) { const target = aliasAnno.annotation ? (_a = mergeAnnotations.find((m) => AnnotationIndexer_1.default.isAnnotationTypeOf(m, aliasAnno.annotation))) === null || _a === void 0 ? void 0 : _a.nativeAnnotation : nativeAnnotation; if (target) { const aliasKey = aliasAnno.value || key; // 如果有别名,则执行别名赋值 target[aliasKey] = value; } } }); } constructor(meta, NativeAnnotation, elementTypes, initializer, ownerAnnotation) { const [target, name, descritpor] = meta; if (ownerAnnotation && ownerAnnotation instanceof RuntimeAnnotation) { this.ownerAnnotation = ownerAnnotation; } this.meta = meta; this.target = target; this.elementType = (0, ElementType_1.checkAnnotation)(elementTypes, meta, NativeAnnotation.name); const indexer = AnnotationIndexer_1.default.createIndexerIfNeed(this.ctor); // 初始化元信息 switch (this.elementType) { case ElementType_1.default.TYPE: break; case ElementType_1.default.METHOD: this.name = name; this.methodName = name; this.descriptor = descritpor; this.parameters = Javascript_1.default.resolveParameters(target[name]); break; case ElementType_1.default.PROPERTY: this.name = name; this.descriptor = descritpor; break; case ElementType_1.default.PARAMETER: this.name = name; this.methodName = name; this.paramIndex = descritpor; this.paramName = Javascript_1.default.resolveParameters(target[name])[this.paramIndex]; break; } // 根据构造创建注解实例 this.nativeAnnotation = new NativeAnnotation(this, initializer, meta); // 合并注解 const mergeAnnotations = (NativeAnnotation[Merge_1.mergeAnnotationSymbol] || []); mergeAnnotations.forEach((decorator) => { decorator(...meta, this); }); if (Object.prototype.toString.call(initializer) === '[object Object]') { RuntimeAnnotation.mergeAnnotationValues(this, initializer); } else if (initializer) { RuntimeAnnotation.mergeAnnotationValues(this, { value: initializer }); } // 添加到索引中 indexer.addAnnotation(this); // 将注解添加到注解列表 runtimeAnnotations.push(this); } } exports.default = RuntimeAnnotation; src_1.default .create(module) .preload((old) => { // 当有文件更新时,需要检测那些注解是依赖该文件,如果是则需要移除,因为热更新后会重新注册。 const file = old.filename; const annotations = runtimeAnnotations.filter((m) => !Tracer_1.default.isDependency(m.ctor, file)); runtimeAnnotations.length = 0; runtimeAnnotations.push(...annotations); });