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
JavaScript
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'];
;