UNPKG

power-di

Version:

A lightweight Dependency Injection library. Using es6 and other features, remove unnecessary concepts, easy and convenient to use.

234 lines 10.4 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.before = void 0; // tslint:disable var path = require("path"); var fs = require("fs"); var ts = require("typescript"); var util_1 = require("./util"); console.log('[power-di] load transformer: class metadata.'); function transformer(program, config) { var typeChecker = program.getTypeChecker(); return { before: function (ctx) { return function (sourceFile) { return (0, util_1.walker)(sourceFile, ctx, before(ctx, sourceFile, typeChecker, config)); }; }, }; } exports.default = transformer; function before(ctx, sf, typeChecker, config) { var pkg = findPkg(sf.fileName); if (!pkg) { console.log('no pkg', sf.fileName); } return function (node) { var _a, _b, _c, _d, _e, _f; if (!pkg) { return node; } if (!ts.isDecorator(node)) { return node; } // 处理注入 type var injectDecorators = ((_a = config === null || config === void 0 ? void 0 : config.decoratorNames) === null || _a === void 0 ? void 0 : _a.inject) || ((_c = (_b = pkg['power-di']) === null || _b === void 0 ? void 0 : _b.decoratorNames) === null || _c === void 0 ? void 0 : _c.inject) || [ 'inject', 'getContributions', 'getExtensions', 'getPlugins', ]; if (injectDecorators.includes("".concat(getDecoratorName(node)))) { return processInject(ctx, node, sf, typeChecker); } // 处理 class var classDecorators = ((_d = config === null || config === void 0 ? void 0 : config.decoratorNames) === null || _d === void 0 ? void 0 : _d.class) || ((_f = (_e = pkg['power-di']) === null || _e === void 0 ? void 0 : _e.decoratorNames) === null || _f === void 0 ? void 0 : _f.class) || [ 'classInfo', 'injectable', 'contribution', 'extension', 'plugin', ]; if (classDecorators.includes("".concat(getDecoratorName(node)))) { return processClassInfo(ctx, node, pkg, sf, typeChecker); } return node; }; } exports.before = before; function processClassInfo(ctx, node, pkg, sourceFile, typeChecker) { var _a; var clsNode = node.parent; if (!ts.isClassDeclaration(clsNode) || !ts.isCallExpression(node.expression)) { return node; } var decoratorFactory = node.expression; if (decoratorFactory.arguments && decoratorFactory.arguments[0] && !ts.isObjectLiteralExpression(decoratorFactory.arguments[0])) { console.warn('[power-di] class metadata transformer fail!', "@".concat(getDecoratorName(node), " of class [").concat(clsNode.name.escapedText, "] param is not a ObjectLiteral.")); return node; } var oldArg = decoratorFactory.arguments.length && decoratorFactory.arguments[0]; var oldArgObj = oldArg && ts.isObjectLiteralExpression(oldArg) && oldArg; var impls = !hasField(oldArgObj, 'implements') && ((_a = clsNode.heritageClauses) === null || _a === void 0 ? void 0 : _a.find(function (hc) { return hc.token === ts.SyntaxKind.ImplementsKeyword; })); impls && impls.types.forEach(function (typeNode) { var _a, _b, _c; var type = typeChecker.getTypeFromTypeNode(typeNode); var symbol = type.getSymbol(); fixedImport(ctx, (symbol === null || symbol === void 0 ? void 0 : symbol.name) || ((_a = typeNode.getText) === null || _a === void 0 ? void 0 : _a.call(typeNode)) || ((_c = (_b = typeNode.expression).getText) === null || _c === void 0 ? void 0 : _c.call(_b)) || typeNode.expression.escapedText, sourceFile); }); var f = ctx.factory; var info = [ f.createPropertyAssignment('pkg', f.createStringLiteral(pkg.name)), f.createPropertyAssignment('version', f.createStringLiteral(pkg.version)), impls && f.createPropertyAssignment('implements', f.createArrayLiteralExpression(impls.types.map(function (type) { return type.expression; }))), ].filter(function (s) { return s; }); var config = oldArgObj ? f.updateObjectLiteralExpression(oldArgObj, f.createNodeArray(__spreadArray(__spreadArray([], info, true), oldArgObj.properties.filter(function (p) { return p.name && ts.isIdentifier(p.name) && !['pkg', 'version', impls ? 'implements' : undefined] .filter(function (s) { return s; }) .includes("".concat(p.name.escapedText)); }), true))) : f.createObjectLiteralExpression(f.createNodeArray(info), false); return f.updateDecorator(node, f.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [config])); } function processInject(ctx, node, sourceFile, typeChecker) { var _a, _b, _c, _d, _e, _f; var propertyNode = node.parent; if (!ts.isPropertyDeclaration(propertyNode) || !ts.isCallExpression(node.expression)) { return node; } var decoratorFactory = node.expression; if (decoratorFactory.arguments && decoratorFactory.arguments[0] && !ts.isObjectLiteralExpression(decoratorFactory.arguments[0])) { console.warn('[power-di] class metadata transformer fail!', "@".concat(getDecoratorName(node), " of class [").concat((_b = (_a = propertyNode.name).getText) === null || _b === void 0 ? void 0 : _b.call(_a), "] param is not a ObjectLiteral.")); return node; } var oldArg = decoratorFactory.arguments.length && decoratorFactory.arguments[0]; var oldArgObj = oldArg && ts.isObjectLiteralExpression(oldArg) && oldArg; var refType = propertyNode.type ? ts.isTypeReferenceNode(propertyNode.type) ? propertyNode.type : ts.isArrayTypeNode(propertyNode.type) ? ts.isTypeReferenceNode(propertyNode.type.elementType) ? propertyNode.type.elementType : undefined : undefined : undefined; if (!refType) { return node; } var identifier = refType.typeName; if (identifier.escapedText === 'Array') { identifier = (_c = refType.typeArguments[0]) === null || _c === void 0 ? void 0 : _c.typeName; if (!identifier) { console.warn('[power-di] class metadata transformer fail!', getDecoratorName(node), (_e = (_d = propertyNode.name).getText) === null || _e === void 0 ? void 0 : _e.call(_d), (_f = refType.getText) === null || _f === void 0 ? void 0 : _f.call(refType)); return node; } } fixedImport(ctx, identifier.escapedText, sourceFile); var f = ctx.factory; var info = [ f.createPropertyAssignment('type', identifier), propertyNode.questionToken && f.createPropertyAssignment('optional', f.createTrue()), ].filter(function (s) { if (!s) { return false; } if (!oldArgObj) { return true; } return !oldArgObj.properties.some(function (p) { return ts.isIdentifier(p.name) && ts.isIdentifier(s.name) && p.name.escapedText === s.name.escapedText; }); }); var config = oldArgObj ? f.updateObjectLiteralExpression(oldArgObj, f.createNodeArray(__spreadArray(__spreadArray([], info, true), oldArgObj.properties, true))) : f.createObjectLiteralExpression(f.createNodeArray(info), false); return f.updateDecorator(node, f.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [config])); } var pkgCache = []; function findPkg(filePath) { if (filePath === '/') { return; } var parsed = path.parse(filePath); var cache = pkgCache .sort(function (a, b) { return b.path.length - a.path.length; }) .find(function (pc) { return parsed.dir === pc.path; }); if (cache) { return cache.pkg; } var pkgPath = path.join(parsed.dir, 'package.json'); if (!fs.existsSync(pkgPath)) { return findPkg(parsed.dir); } var pkgData = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); pkgCache.push({ path: parsed.dir, pkg: pkgData }); return pkgData; } function getDecoratorName(node) { if (!node) { return ''; } return ts.isIdentifier(node.expression) ? node.expression.escapedText : ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) ? node.expression.expression.escapedText : ''; } function getField(config, fieldName) { var prop = config && ts.isObjectLiteralExpression(config) && config.properties.find(function (p) { return p.name && ts.isIdentifier(p.name) && p.name.escapedText === fieldName; }); return prop && ts.isPropertyAssignment(prop) && prop; } function hasField(config, fieldName) { return !!getField(config, fieldName); } function fixedImport(ctx, escapedText, sourceFile) { if (!escapedText) { console.warn('fixedImport no escapedText!', sourceFile.fileName); return; } // IFoo<IBar> => IFoo escapedText = "".concat(escapedText).split('<')[0]; sourceFile.statements .filter(function (n) { return ts.isImportDeclaration(n); }) .forEach(function (im) { var _a, _b; var nb = (_a = im.importClause) === null || _a === void 0 ? void 0 : _a.namedBindings; var el = (_b = nb === null || nb === void 0 ? void 0 : nb.elements) === null || _b === void 0 ? void 0 : _b.find(function (el) { return el.name.escapedText === escapedText; }); if (el) { im.flags = im.flags | ts.NodeFlags.Synthesized; } }); } //# sourceMappingURL=classMetadata.js.map