BusinessCentral.LinterCop icon indicating copy to clipboard operation
BusinessCentral.LinterCop copied to clipboard

Maintainability Index Calculation

Open tscottjendev opened this issue 2 years ago • 4 comments

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.

tscottjendev avatar Sep 06 '22 15:09 tscottjendev

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: image

TBH, I care much more about the Cyclomatic complexity. If you keep that low your Maintainability index will be good as well

StefanMaron avatar Sep 07 '22 04:09 StefanMaron

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.

tscottjendev avatar Sep 07 '22 06:09 tscottjendev

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

tscottjendev avatar Sep 07 '22 11:09 tscottjendev

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 };

StefanMaron avatar Oct 07 '22 07:10 StefanMaron

@tscottjendev , If you have any follow-up questions about this, feel free to reopen this issue.

Arthurvdv avatar Nov 07 '23 12:11 Arthurvdv