UNPKG

escomplex-plugin-metrics-module

Version:

Provides the core module metric / report generation plugin for typhonjs-escomplex module processing.

347 lines (281 loc) 14.4 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _isInteger = require('babel-runtime/core-js/number/is-integer'); var _isInteger2 = _interopRequireDefault(_isInteger); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _HalsteadArray = require('typhonjs-escomplex-commons/dist/module/traits/HalsteadArray'); var _HalsteadArray2 = _interopRequireDefault(_HalsteadArray); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Provides the main processing of syntax data for all default metrics gathered. */ var ModuleMetricProcess = function () { function ModuleMetricProcess() { (0, _classCallCheck3.default)(this, ModuleMetricProcess); } (0, _createClass3.default)(ModuleMetricProcess, null, [{ key: 'addDependencies', /** * Potentially adds given dependencies for tracking. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {object|Array<object>} dependencies - Dependencies to add. */ value: function addDependencies(moduleReport, dependencies) { if ((typeof dependencies === 'undefined' ? 'undefined' : (0, _typeof3.default)(dependencies)) === 'object' || Array.isArray(dependencies)) { moduleReport.dependencies = moduleReport.dependencies.concat(dependencies); } } /** * Creates a moduleReport scope when a class or method is entered. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {object} newScope - An object hash defining the new scope including: * @param {object} node - Current AST node. * @param {object} parent - Parent AST node. * ``` * (string) type - Type of report scope being created. * ``` */ }, { key: 'preScopeCreated', value: function preScopeCreated(moduleReport, scopeControl) { var newScope = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var node = arguments[3]; var parent = arguments[4]; if ((typeof newScope === 'undefined' ? 'undefined' : (0, _typeof3.default)(newScope)) !== 'object') { throw new TypeError('preScopeCreated error: \'newScope\' is not an \'object\'.'); } if (typeof newScope.type !== 'string') { throw new TypeError('preScopeCreated error: \'newScope.type\' is not a \'string\'.'); } switch (newScope.type) { case 'class': case 'method': // Increments logical SLOC for previous report scopes. if ((0, _isInteger2.default)(newScope.lloc)) { // Increments current module report associated aggregate report parameter count. moduleReport.aggregateReport.sloc.logical += newScope.lloc; var classReport = scopeControl.getCurrentClassReport(); var methodReport = scopeControl.getCurrentMethodReport(); if (classReport) { classReport.aggregateReport.sloc.logical += newScope.lloc; } if (methodReport) { methodReport.sloc.logical += newScope.lloc; } } if (newScope.operands instanceof _HalsteadArray2.default) { var identifiers = newScope.operands.valueOf(node, parent); identifiers.forEach(function (identifier) { ModuleMetricProcess.halsteadItemEncountered(moduleReport, scopeControl, 'operands', identifier); }); } if (newScope.operators instanceof _HalsteadArray2.default) { var _identifiers = newScope.operators.valueOf(node, parent); _identifiers.forEach(function (identifier) { ModuleMetricProcess.halsteadItemEncountered(moduleReport, scopeControl, 'operators', identifier); }); } break; } } /** * Creates a moduleReport scope when a class or method is entered. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {object} newScope - An object hash defining the new scope including: * ``` * (string) type - Type of report scope being created. * (string) name - Name of the class or method. * (number) lineStart - Start line of method. * (number) lineEnd - End line of method. * (Array<string>) paramNames - (For method scopes) An array of parameters names for method. * ``` */ }, { key: 'postScopeCreated', value: function postScopeCreated(moduleReport, scopeControl) { var newScope = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if ((typeof newScope === 'undefined' ? 'undefined' : (0, _typeof3.default)(newScope)) !== 'object') { throw new TypeError('postScopeCreated error: \'newScope\' is not an \'object\'.'); } if (typeof newScope.type !== 'string') { throw new TypeError('postScopeCreated error: \'newScope.type\' is not a \'string\'.'); } switch (newScope.type) { case 'class': break; case 'method': { if (!(0, _isInteger2.default)(newScope.cyclomatic)) { throw new TypeError('postScopeCreated error: \'newScope.cyclomatic\' is not an \'integer\'.'); } if (!Array.isArray(newScope.paramNames)) { throw new TypeError('postScopeCreated error: \'newScope.paramNames\' is not an \'array\'.'); } var classReport = scopeControl.getCurrentClassReport(); var methodReport = scopeControl.getCurrentMethodReport(); // Increments current module report associated aggregate report cyclomatic count. moduleReport.aggregateReport.cyclomatic += newScope.cyclomatic; // Increments current module report associated aggregate report parameter count. moduleReport.aggregateReport.paramCount += newScope.paramNames.length; if (classReport) { // Increments current class report associated aggregate report cyclomatic count. classReport.aggregateReport.cyclomatic += newScope.cyclomatic; // Increments current class report associated aggregate report parameter count. classReport.aggregateReport.paramCount += newScope.paramNames.length; } if ((0, _isInteger2.default)(newScope.postLloc)) { moduleReport.aggregateReport.sloc.logical += newScope.postLloc; if (classReport) { classReport.aggregateReport.sloc.logical += newScope.postLloc; } if (methodReport) { methodReport.sloc.logical += newScope.postLloc; } } break; } } } /** * Increments the Halstead `metric` for the given `identifier` for the ModuleReport and any current class or method * report being tracked. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {string} metric - A Halstead metric name. * @param {string} identifier - A Halstead identifier name. */ }, { key: 'halsteadItemEncountered', value: function halsteadItemEncountered(moduleReport, scopeControl, metric, identifier) { var currentClassReport = scopeControl.getCurrentClassReport(); var currentMethodReport = scopeControl.getCurrentMethodReport(); ModuleMetricProcess.incrementHalsteadItems(moduleReport, metric, identifier); if (currentClassReport) { ModuleMetricProcess.incrementHalsteadItems(currentClassReport, metric, identifier); } if (currentMethodReport) { ModuleMetricProcess.incrementHalsteadItems(currentMethodReport, metric, identifier); } } /** * Increments the cyclomatic metric for the ModuleReport and any current class or method report being tracked. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {number} amount - Amount to increment. */ }, { key: 'incrementCyclomatic', value: function incrementCyclomatic(moduleReport, scopeControl, amount) { var currentClassReport = scopeControl.getCurrentClassReport(); var currentMethodReport = scopeControl.getCurrentMethodReport(); moduleReport.aggregate.cyclomatic += amount; if (currentClassReport) { currentClassReport.aggregate.cyclomatic += amount; } if (currentMethodReport) { currentMethodReport.cyclomatic += amount; } } /** * Increments the logical SLOC (source lines of code) metric for the ModuleReport and any current class or method * report being tracked. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {number} amount - Amount to increment. */ }, { key: 'incrementLogicalSloc', value: function incrementLogicalSloc(moduleReport, scopeControl, amount) { var currentClassReport = scopeControl.getCurrentClassReport(); var currentMethodReport = scopeControl.getCurrentMethodReport(); moduleReport.aggregate.sloc.logical += amount; if (currentClassReport) { currentClassReport.aggregate.sloc.logical += amount; } if (currentMethodReport) { // if (amount > 0) // { // console.log('!! MMP - incrementLogicalSloc (method) - node type: ' + nodeType + '; amount: ' + amount); // } currentMethodReport.sloc.logical += amount; } } /** * Increments the associated aggregate report Halstead items including distinct and total counts. * * @param {ModuleReport|ClassReport|MethodReport} report - The report being processed. * @param {string} metric - A Halstead metric name. * @param {string} identifier - A Halstead identifier name. */ }, { key: 'incrementHalsteadItems', value: function incrementHalsteadItems(report, metric, identifier) { // Increments the associated aggregate report HalsteadData for distinct identifiers. if (report.aggregateReport.halstead[metric].identifiers.indexOf(identifier) === -1) { report.aggregateReport.halstead[metric].identifiers.push(identifier); report.aggregateReport.halstead[metric]['distinct'] += 1; } // Increment total halstead items report.aggregateReport.halstead[metric]['total'] += 1; } /** * Processes all TraitHalstead identifier data. * * @param {ModuleReport} moduleReport - The ModuleReport being processed. * @param {ModuleScopeControl} scopeControl - The associated module report scope control. * @param {object} syntax - The associated syntax being processed for current node. * @param {object} node - The node being entered. * @param {object} parent - The parent node of the node being entered. */ }, { key: 'processSyntax', value: function processSyntax(moduleReport, scopeControl, syntax, node, parent) { var _loop = function _loop(key) { var trait = syntax[key]; switch (trait.metric) { case 'cyclomatic': ModuleMetricProcess.incrementCyclomatic(moduleReport, scopeControl, trait.valueOf(node, parent)); break; case 'dependencies': ModuleMetricProcess.addDependencies(moduleReport, trait.valueOf(node, parent)); break; case 'lloc': // if (trait.valueOf(node, parent) > 0) // { // console.log('!! MMP - increment sloc - node type: ' + node.type + '; value: ' + trait.valueOf(node, parent)); // } ModuleMetricProcess.incrementLogicalSloc(moduleReport, scopeControl, trait.valueOf(node, parent)); break; } // Process operands / operators HalsteadArray entries. if (trait instanceof _HalsteadArray2.default) { var identifiers = trait.valueOf(node, parent); identifiers.forEach(function (identifier) { ModuleMetricProcess.halsteadItemEncountered(moduleReport, scopeControl, trait.metric, identifier); }); } }; for (var key in syntax) { _loop(key); } } }]); return ModuleMetricProcess; }(); exports.default = ModuleMetricProcess; module.exports = exports['default'];