UNPKG

ngrx-uml

Version:
260 lines (259 loc) 12.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegisterReducerCallConverter = void 0; const chalk_1 = __importDefault(require("chalk")); const loglevel_1 = __importDefault(require("loglevel")); const os_1 = require("os"); const typescript_1 = __importDefault(require("typescript")); const node_converter_1 = require("../../../core/converters/node.converter"); const utils_1 = require("../../../utils"); const preparet_to_print_1 = require("../../../utils/preparet-to-print"); const registered_reducer_model_1 = require("../models/registered-reducer.model"); var ReducerFunctions; (function (ReducerFunctions) { ReducerFunctions["createReducer"] = "createReducer"; ReducerFunctions["combineReducers"] = "combineReducers"; })(ReducerFunctions || (ReducerFunctions = {})); class RegisterReducerCallConverter extends node_converter_1.NodeConverter { convert(context, storeModuleCall) { let callName; const callSymbol = context.typeChecker.getSymbolAtLocation(storeModuleCall.expression); if (callSymbol) { callName = callSymbol.getName(); } else { callName = storeModuleCall.expression.getText(); loglevel_1.default.debug('no call symbol for callName:', callName); } let name; let reducerSearchItem; switch (callName) { case 'StoreModule.forFeature': case 'forFeature': { name = this.getStringValue(context, storeModuleCall.arguments[0]) || 'noForFeatureKey'; reducerSearchItem = this.getReducer(context, storeModuleCall.arguments[1]); break; } case 'StoreModule.forRoot': name = 'root'; break; default: // log.warn('StoreModule not supported call:', callName); return; } // log.info(`registeredReducer [${name}]:`, reducerSearchItem); const registeredReducer = this.createRegisteredReducer(name, storeModuleCall, reducerSearchItem); return registeredReducer; } createRegisteredReducer(name, srcNode, reducer) { const registeredReducer = new registered_reducer_model_1.RegisteredReducerItem(name || 'noName', srcNode.getSourceFile().fileName, srcNode.getStart(), srcNode.getEnd()); if (reducer) { registeredReducer.reducerItems = reducer.registered; registeredReducer.reducerSymbol = reducer.symbol; } return registeredReducer; } symbolFlagsToString(flags) { let i = 0; let flag; let resultText = ''; while (typescript_1.default.SymbolFlags[flag = 1 << i++]) { if (flags & flag) { resultText += typescript_1.default.SymbolFlags[flag]; } } return resultText; } getReducer(context, exp) { var _a; const foundReducer = this.getReducerRecursive(context, exp); loglevel_1.default.debug('getReducer:', preparet_to_print_1.prepareToPrint(foundReducer)); if (foundReducer) { if ((_a = foundReducer.symbol) === null || _a === void 0 ? void 0 : _a.flags) { loglevel_1.default.debug('reducer symbol flags:', this.symbolFlagsToString(foundReducer.symbol.flags)); } } return foundReducer; } getReducerRecursive(context, exp) { loglevel_1.default.trace('getReducerRecursive:', utils_1.syntaxKindText(exp)); switch (exp.kind) { case typescript_1.default.SyntaxKind.PropertyAccessExpression: { const propertyExp = exp; const symbol = context.typeChecker.getSymbolAtLocation(propertyExp); if (symbol) { return this.getReducerRecursive(context, symbol.valueDeclaration); } else { loglevel_1.default.warn('no symbol for PropertyAccessExpression'); } return; } case typescript_1.default.SyntaxKind.ShorthandPropertyAssignment: { const assigment = exp; if (assigment.objectAssignmentInitializer) { const result = this.getReducerRecursive(context, assigment.objectAssignmentInitializer); if ((result === null || result === void 0 ? void 0 : result.callName) === ReducerFunctions.createReducer) { const symbol = context.typeChecker.getSymbolAtLocation(assigment.name); return symbol && { symbol }; } return result; } return; } case typescript_1.default.SyntaxKind.VariableDeclaration: { const declaration = exp; if (declaration.initializer) { const result = this.getReducerRecursive(context, declaration.initializer); if ((result === null || result === void 0 ? void 0 : result.callName) === ReducerFunctions.createReducer) { const symbol = context.typeChecker.getSymbolAtLocation(declaration.name); return symbol && { symbol }; } return result; } return; } case typescript_1.default.SyntaxKind.CallExpression: { const callExp = exp; if (typescript_1.default.isIdentifier(callExp.expression)) { const callName = callExp.expression.getText(); switch (callName) { case ReducerFunctions.createReducer: return { callName }; case ReducerFunctions.combineReducers: { const reducerItems = this.extractCombineReducers(context, callExp); return reducerItems && { registered: reducerItems }; } default: { const symbol = context.typeChecker.getSymbolAtLocation(callExp.expression); if (symbol) { return this.getReducerRecursive(context, symbol.valueDeclaration); } else { loglevel_1.default.warn('no symbol for callExpression:', callName); return; } } } } return this.getReducerRecursive(context, callExp.expression); } case typescript_1.default.SyntaxKind.ArrowFunction: { const arrowFunction = exp; return this.getReducerRecursive(context, arrowFunction.body); } case typescript_1.default.SyntaxKind.Block: { const block = exp; for (const statement of block.statements) { const reducer = this.getReducerRecursive(context, statement); if (reducer) { return reducer; } } return; } case typescript_1.default.SyntaxKind.ReturnStatement: { const returnStatement = exp; if (returnStatement.expression) { return this.getReducerRecursive(context, returnStatement.expression); } return; } case typescript_1.default.SyntaxKind.FunctionDeclaration: { const declaration = exp; if (declaration.body) { return this.getReducerRecursive(context, declaration.body); } return; } default: loglevel_1.default.info(`getReducerRecursive - Unknown argument kind [${utils_1.syntaxKindText(exp)}] [${chalk_1.default.gray(exp.getSourceFile().fileName)}]`, os_1.EOL, chalk_1.default.gray(exp.getText())); return; } } extractPropertyName(context, node) { switch (node.kind) { case typescript_1.default.SyntaxKind.StringLiteral: return node.text; case typescript_1.default.SyntaxKind.ComputedPropertyName: { const symbol = context.typeChecker.getSymbolAtLocation(node.expression); if (symbol) { return this.getStringValue(context, symbol.valueDeclaration); } loglevel_1.default.warn('extractPropertyName symbol:', preparet_to_print_1.prepareToPrint(symbol), '\r\n', node.expression.getText()); } break; default: loglevel_1.default.warn('extractPropertyName:', utils_1.syntaxKindText(node), preparet_to_print_1.prepareToPrint(node)); break; } return; } extractCombineReducers(context, callExp) { if (callExp.arguments.length > 0) { const [reducers] = callExp.arguments; if (typescript_1.default.isObjectLiteralExpression(reducers)) { const registeredReducerItems = []; for (const property of reducers.properties) { if (typescript_1.default.isPropertyAssignment(property)) { loglevel_1.default.debug('combineReducers:', preparet_to_print_1.printNode(property, 5)); if (property.name) { const name = this.extractPropertyName(context, property.name); loglevel_1.default.trace('extractCombineReducers propertyName:', name); const reducer = this.getReducer(context, property.initializer); if (reducer === null || reducer === void 0 ? void 0 : reducer.symbol) { registeredReducerItems.push(this.createRegisteredReducer(name, reducer.symbol.valueDeclaration, reducer)); } // log.info('extractCombineReducers reducer:', prepareToPrint(reducer)); } } } if (registeredReducerItems.length) { return registeredReducerItems; } // reducers. } } return; } getStringValue(context, exp) { switch (exp.kind) { case typescript_1.default.SyntaxKind.PropertyAccessExpression: { const propertyExp = exp; const symbol = context.typeChecker.getSymbolAtLocation(propertyExp); if (symbol) { return this.getStringValue(context, symbol.valueDeclaration); } else { loglevel_1.default.warn('no symbol for PropertyAccessExpression'); } } return; case typescript_1.default.SyntaxKind.ShorthandPropertyAssignment: { const assigment = exp; if (assigment.objectAssignmentInitializer) { return this.getStringValue(context, assigment.objectAssignmentInitializer); } return; } case typescript_1.default.SyntaxKind.VariableDeclaration: { const declaration = exp; if (declaration.initializer) { return this.getStringValue(context, declaration.initializer); } return; } case typescript_1.default.SyntaxKind.StringLiteral: return exp.text; default: loglevel_1.default.info('arg kind', utils_1.syntaxKindText(exp)); return; } } } exports.RegisterReducerCallConverter = RegisterReducerCallConverter;