BusinessCentral.LinterCop
BusinessCentral.LinterCop copied to clipboard
Maintainability Index Calculation
Hi, just wondering if you could assist in understanding how this get calculated. I have taken the formula from https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022 and put it in a spreadsheet (attached). Maintainability Index.xlsx
I can't come up with the value for this function. I am trying to understand how to make this more maintainable. Yes 90 is high it this is only 90 what could possibly be 100?
Cyclomatic complexity: 1, Maintainability index: 90
local procedure MinimumExemptID(): Integer
begin
exit(99995);
end;
With a "green" range of 20 - 100 that is a pretty broad range. I would like to understand how to make my code strike 70+ in this metric. If that is reasonable.
the code thats being analyzed is just whats between the begin end of the procedure itsself
If I adjust you sheet accordingly it also shows 90:
TBH, I care much more about the Cyclomatic complexity. If you keep that low your Maintainability index will be good as well
Thank you. I figured it had to be something about what operators/operands were being computed.
I agree that Cyclomatic complexity is the main factor but I need to understand what goes into the Maintainability index. An 80 point span for Good and a 20 point span for less good just seems out of kilter but the LOG2 functions may account for sum of that.
I guess I am having trouble counting Operators and Operands. How do you count Record.Field
vs. Record.Procedure
?
Record.Field := value;
is 2 operands (Record.Field, value) and 2 operators (:=, ;)?
Record.Validate(Field1, value);
is 2 operands (Field1, value) and 4 operators (Validate, (), Record.Insert(true);
is 1 operand (true) and 3 operators (Insert, (), ;)?
Record.Init();
is 0 operands and 3 operators (Init, (), ;)?
I can't get the value for this function.
local procedure CreateReleaseCheckEntry(ReleaseNotesHeader: Record "JI Release Notes Header"; Description: Text; CurrentObject: Record Object)
var
ReleaseCheck: Record "JI Release Check";
begin
ReleaseCheck.Init();
ReleaseCheck."Customer No." := ReleaseNotesHeader."Customer No.";
ReleaseCheck."Version No." := ReleaseNotesHeader."Version List No.";
ReleaseCheck.Insert(true);
ReleaseCheck.Description := CopyStr(Description, 1, MaxStrLen(ReleaseCheck.Description));
ReleaseCheck."Bypass Allowed" := IsBypassAllowed(CurrentObject);
ReleaseCheck."Object Type" := CurrentObject.Type;
ReleaseCheck."Object ID" := CurrentObject.ID;
ReleaseCheck.Modify(true);
end;
I have updated my spreadsheet Maintainability Index.xlsx
I did not name all the Operators individually, see this line
var OperatorKinds = Enum.GetValues(typeof(SyntaxKind)).Cast<SyntaxKind>().Where(value => (value.ToString().Contains("Keyword") || value.ToString().Contains("Token")) && !OperandKinds.Contains(value)).ToList();
The Operands are those:
var OperandKinds = new object[] { SyntaxKind.IdentifierToken, SyntaxKind.Int32LiteralToken, SyntaxKind.StringLiteralToken, SyntaxKind.BooleanLiteralValue, SyntaxKind.TrueKeyword, SyntaxKind.FalseKeyword };
@tscottjendev , If you have any follow-up questions about this, feel free to reopen this issue.