UNPKG

sicua

Version:

A tool for analyzing project structure and dependencies

281 lines (280 loc) 9.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParameterParser = void 0; const typescript_1 = __importDefault(require("typescript")); /** * Utility class for parsing function parameters comprehensively */ class ParameterParser { /** * Parses function parameters and returns detailed information * @param node The function-like declaration * @returns Array of parameter name strings (for backward compatibility) */ parseParameters(node) { return node.parameters.map((param) => this.parseParameter(param).name); } /** * Parses function parameters with detailed information * @param node The function-like declaration * @returns Array of detailed parameter information */ parseParametersDetailed(node) { return node.parameters.map((param) => this.parseParameter(param)); } /** * Parses a single parameter node * @param param The parameter declaration * @returns Detailed parameter information */ parseParameter(param) { const result = { name: this.extractParameterName(param), type: this.extractParameterType(param), isOptional: this.isOptionalParameter(param), hasDefaultValue: !!param.initializer, defaultValue: this.extractDefaultValue(param), isRestParameter: !!param.dotDotDotToken, isDestructured: this.isDestructuredParameter(param), destructuredProperties: this.extractDestructuredProperties(param), }; return result; } /** * Extracts the parameter name, handling destructuring and rest parameters */ extractParameterName(param) { try { // Handle rest parameters if (param.dotDotDotToken) { const name = this.getNameFromBindingName(param.name); return `...${name}`; } // Handle destructuring patterns if (typescript_1.default.isObjectBindingPattern(param.name)) { return this.formatObjectDestructuring(param.name); } if (typescript_1.default.isArrayBindingPattern(param.name)) { return this.formatArrayDestructuring(param.name); } // Handle simple identifier if (typescript_1.default.isIdentifier(param.name)) { return param.name.text; } return "unknown"; } catch (error) { return "unknown"; } } /** * Extracts parameter type information */ extractParameterType(param) { try { if (param.type) { return param.type.getText().trim(); } return "unknown"; } catch (error) { return "unknown"; } } /** * Checks if a parameter is optional */ isOptionalParameter(param) { return !!param.questionToken || !!param.initializer; } /** * Extracts the default value of a parameter if it exists */ extractDefaultValue(param) { try { if (param.initializer) { return param.initializer.getText().trim(); } return null; } catch (error) { return null; } } /** * Checks if a parameter uses destructuring */ isDestructuredParameter(param) { return (typescript_1.default.isObjectBindingPattern(param.name) || typescript_1.default.isArrayBindingPattern(param.name)); } /** * Extracts properties from destructured parameters */ extractDestructuredProperties(param) { const properties = []; if (typescript_1.default.isObjectBindingPattern(param.name)) { param.name.elements.forEach((element) => { if (typescript_1.default.isBindingElement(element)) { const name = this.getNameFromBindingName(element.name); if (name) { properties.push(name); } } }); } if (typescript_1.default.isArrayBindingPattern(param.name)) { param.name.elements.forEach((element) => { if (element && typescript_1.default.isBindingElement(element)) { const name = this.getNameFromBindingName(element.name); if (name) { properties.push(name); } } }); } return properties; } /** * Formats object destructuring pattern for display */ formatObjectDestructuring(pattern) { try { const elements = pattern.elements .map((element) => { if (typescript_1.default.isBindingElement(element)) { const name = this.getNameFromBindingName(element.name); const propertyName = element.propertyName ? this.getNameFromPropertyName(element.propertyName) : null; if (propertyName && propertyName !== name) { return `${propertyName}: ${name}`; } return name; } return "unknown"; }) .filter(Boolean); return `{ ${elements.join(", ")} }`; } catch (error) { return "{ ... }"; } } /** * Safely extracts name from property name node */ getNameFromPropertyName(name) { try { if (typescript_1.default.isIdentifier(name)) { return name.text; } if (typescript_1.default.isStringLiteral(name) || typescript_1.default.isNumericLiteral(name)) { return name.text; } if (typescript_1.default.isComputedPropertyName(name)) { return `[${name.expression.getText()}]`; } return "unknown"; } catch (error) { return "unknown"; } } /** * Formats array destructuring pattern for display */ formatArrayDestructuring(pattern) { try { const elements = pattern.elements.map((element) => { if (element && typescript_1.default.isBindingElement(element)) { return this.getNameFromBindingName(element.name); } return "_"; // Hole in array destructuring }); return `[ ${elements.join(", ")} ]`; } catch (error) { return "[ ... ]"; } } /** * Safely extracts name from binding name node */ getNameFromBindingName(name) { try { if (typescript_1.default.isIdentifier(name)) { return name.text; } if (typescript_1.default.isObjectBindingPattern(name)) { return this.formatObjectDestructuring(name); } if (typescript_1.default.isArrayBindingPattern(name)) { return this.formatArrayDestructuring(name); } return "unknown"; } catch (error) { return "unknown"; } } /** * Gets parameter count including rest parameters */ getParameterCount(node) { return node.parameters.length; } /** * Gets required parameter count (excluding optional and rest parameters) */ getRequiredParameterCount(node) { return node.parameters.filter((param) => !param.questionToken && !param.initializer && !param.dotDotDotToken).length; } /** * Checks if function has destructured parameters */ hasDestructuredParameters(node) { return node.parameters.some((param) => this.isDestructuredParameter(param)); } /** * Checks if function has rest parameters */ hasRestParameters(node) { return node.parameters.some((param) => !!param.dotDotDotToken); } /** * Checks if function has optional parameters */ hasOptionalParameters(node) { return node.parameters.some((param) => this.isOptionalParameter(param)); } /** * Gets the complexity score for parameters (for analysis purposes) */ getParameterComplexity(node) { let complexity = 0; node.parameters.forEach((param) => { // Base complexity per parameter complexity += 1; // Additional complexity for destructuring if (this.isDestructuredParameter(param)) { complexity += 2; const properties = this.extractDestructuredProperties(param); complexity += properties.length * 0.5; } // Additional complexity for optional parameters if (this.isOptionalParameter(param)) { complexity += 1; } // Additional complexity for rest parameters if (param.dotDotDotToken) { complexity += 1; } }); return Math.round(complexity * 10) / 10; // Round to 1 decimal place } } exports.ParameterParser = ParameterParser;