/
ModuleMetricCalculate.js
88 lines (82 loc) · 3.49 KB
/
ModuleMetricCalculate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* Provides a typhonjs-escomplex-module / ESComplexModule plugin which gathers and calculates all default metrics.
*
* @see https://www.npmjs.com/package/typhonjs-escomplex-commons
* @see https://www.npmjs.com/package/typhonjs-escomplex-module
*/
export default class ModuleMetricCalculate
{
/**
* Coordinates calculating all metrics. All module and class methods are traversed. If there are no module or class
* methods respectively the aggregate MethodReport is used for calculations.
*
* @param {ModuleReport} moduleReport - The ModuleReport being processed.
*/
static calculate(moduleReport)
{
// Handle module methods.
moduleReport.methods.forEach((methodReport) =>
{
ModuleMetricCalculate.calculateCyclomaticDensity(methodReport);
ModuleMetricCalculate.calculateHalsteadMetrics(methodReport.halstead);
});
// Handle module class reports.
moduleReport.classes.forEach((classReport) =>
{
// Process all class methods.
classReport.methods.forEach((methodReport) =>
{
ModuleMetricCalculate.calculateCyclomaticDensity(methodReport);
ModuleMetricCalculate.calculateHalsteadMetrics(methodReport.halstead);
});
ModuleMetricCalculate.calculateCyclomaticDensity(classReport.aggregateReport);
ModuleMetricCalculate.calculateHalsteadMetrics(classReport.aggregateReport.halstead);
});
ModuleMetricCalculate.calculateCyclomaticDensity(moduleReport.aggregateReport);
ModuleMetricCalculate.calculateHalsteadMetrics(moduleReport.aggregateReport.halstead);
}
/**
* Calculates cyclomatic density - Proposed as a modification to cyclomatic complexity by Geoffrey K. Gill and
* Chris F. Kemerer in 1991, this metric simply re-expresses it as a percentage of the logical lines of code. Lower
* is better.
*
* @param {AggregateMethodReport} report - An AggregateMethodReport to perform calculations on.
*
* @private
*/
static calculateCyclomaticDensity(report)
{
report.cyclomaticDensity = report.sloc.logical === 0 ? 0 : (report.cyclomatic / report.sloc.logical) * 100;
}
/**
* Calculates Halstead metrics. In 1977, Maurice Halstead developed a set of metrics which are calculated based on
* the number of distinct operators, the number of distinct operands, the total number of operators and the total
* number of operands in each function. This site picks out three Halstead measures in particular: difficulty,
* volume and effort.
*
* @param {HalsteadData} halstead - A HalsteadData instance to perform calculations on.
*
* @see https://en.wikipedia.org/wiki/Halstead_complexity_measures
*
* @private
*/
static calculateHalsteadMetrics(halstead)
{
halstead.length = halstead.operators.total + halstead.operands.total;
/* istanbul ignore if */
if (halstead.length === 0)
{
halstead.reset();
}
else
{
halstead.vocabulary = halstead.operators.distinct + halstead.operands.distinct;
halstead.difficulty = (halstead.operators.distinct / 2)
* (halstead.operands.distinct === 0 ? 1 : halstead.operands.total / halstead.operands.distinct);
halstead.volume = halstead.length * (Math.log(halstead.vocabulary) / Math.log(2));
halstead.effort = halstead.difficulty * halstead.volume;
halstead.bugs = halstead.volume / 3000;
halstead.time = halstead.effort / 18;
}
}
}