Flutter Static Analysis, Dart Code Metrics

The other part of static analysis of your flutter dart code besides linting is analyzing code metrics. In this article, I show you how to install the dart_code-metrics plugin and effectively use it to analyze dart code.
Background
The problem is while Google does an excellent job at giving you an introduction to widgets; it’s not the techniques you really need to have mastered to develop a professional application and in a mature market. That is my self-assigned job in pushing out medium articles and my flutter design and development book series.
I am finding that by showing the cool visual and animation that I can get you guys and gals to do the boring devOPS and OOP and FP to get you to the point for flutter expert. Some subjects covered are:
DevOPS
Tuning A Cheap MS Windows Laptop for Flutter Development https://readmedium.com/tuning-a-cheap-ms-windows-laptop-for-flutter-app-development-572d09cd4d19
Log Driven Learning Flutter https://readmedium.com/log-driven-learning-flutter-d76b49b75a8c
UML Coolness in Flutter https://itnext.io/uml-coolness-in-flutter-6bb14217b5f2
Lint Like A Boss https://itnext.io/lint-like-a-boss-60b85e82c227
McCabe Cycles in Flutter https://readmedium.com/mccabe-cycles-in-flutter-3aa913e19428
Getting Real Code Coverage https://readmedium.com/getting-real-code-coverage-951231afa2bc
Lcov on Windows https://readmedium.com/lcov-on-windows-7c58dda07080
Test Secrets, Test Suites https://itnext.io/test-secrets-test-suites-99f8390b8d4b
How To, Flutter Internal Packages https://itnext.io/how-to-flutter-internal-packages-cad1285fe8c
An Architecture Layout https://readmedium.com/an-architecture-layout-8f414271b2b4
Logging, The Expert Way https://readmedium.com/logging-the-expert-way-5beb5c967e44
Catch Flutter Application Exceptions https://itnext.io/catch-flutter-application-exceptions-cad036d0fd4e
Flutter Perfect SetUp https://readmedium.com/flutter-perfect-setup-c5462b412f78
Cool Flutter Docs https://readmedium.com/cool-flutter-docs-383b951d7feb
Visual
Animations Users Love(rive) https://readmedium.com/animations-users-love-75a57a8cad5
Full Flutter Background Trick https://readmedium.com/full-flutter-background-trick-d1ea813470d2
Cool Rive Background Animation in Flutter Apps https://readmedium.com/cool-rive-background-animation-in-flutter-apps-2fd5e58bc81b
Flutter Cross-Platform Tricks https://itnext.io/flutter-cross-platform-tricks-2196986c619c
Since, my articles appear in multiple publications the best way to keep updated to those posting is to join one of these social platforms and follow me using my profile links:
LinkedIN https://www.linkedin.com/in/fredgrottstartupfluttermobileappdesigner/
Xing https://www.xing.com/profile/Fred_Grott/cv
Discord https://discordapp.com/users/9388/
Gitter(join this forum to get the article links) https://gitter.im/flutter/flutter
Slack https://app.slack.com/client/TGT6YF2J1/CGS4QDJ56/user_profile/UHK8PNRGU
Twitter https://twitter.com/fredgrott
Medium https://fredgrott.medium.com
Reddit FlutterDev Subedit(just join this forum and you will get the notices via reddit) https://www.reddit.com/r/FlutterDev/
As always, the code to both the articles and the books can be found at:
flutter design and arch rosetta at Github https://github.com/fredgrott/flutter_design_and_arch_rosetta
And, the plugins I contribute to are
Flutter Platform Widgets https://github.com/stryder-dev/flutter_platform_widgets
Flutter Rive(player) Plugin https://github.com/rive-app/rive-flutter
Concepts Covered
These are the code metrics concepts covered in this article.
Cyclomatic Complexity
Lines Of Code(LOC)
Maximum Nesting(MN)
Number of Methods(NM)
Number of Parameters(NP)
Source Lines Of Code(SLOC)
Weight Of Class(WOC)
Dart Code Metrics Plugin
The Dart Code Metrics Plugin page is at:
https://pub.dev/packages/dart_code_metrics
The code metrics it reports on are:
Cyclomatic Complexity:
Methods have a base complexity of 1.every control flow statement (if, catch, throw, do, while, for, break, continue) and conditional expression (? ... : ...) increase complexityelse, finally and default don't countsome operators (&&, ||, ?., ??, ??=) increase complexityAn example:
void visitBlock(Token firstToken, Token lastToken) {const tokenTypes = [TokenType.AMPERSAND_AMPERSAND,TokenType.BAR_BAR,TokenType.QUESTION_PERIOD,TokenType.QUESTION_QUESTION,TokenType.QUESTION_QUESTION_EQ,];var token = firstToken;while (token != lastToken) {if (token.matchesAny(tokenTypes)) {_increaseComplexity(token);}
token = token.next;}
}
That would produce a cc score of 3.
LINES OF CODE:
The lines of code are the total number of lines in a method (or function).
An example:
MetricComputationResult<int> computeImplementation(Declaration node,Iterable<ScopedClassDeclaration> classDeclarations,Iterable<ScopedFunctionDeclaration> functionDeclarations,InternalResolvedUnitResult source,) =>MetricComputationResult(value: 1 +source.lineInfo.getLocation(node.endToken.offset).lineNumber -source.lineInfo.getLocation(node.beginToken.offset).lineNumber,);That produces a loc score of 11.
MAXIMUM NESTING:
Maximum Nesting Level this is the maximum level of nesting blocks/control structures that are present in a method (or function). Code with deep nesting level is often complex and tough to maintain.
Generally the blocks with if, else, else if, do, while, for, switch, catch, etc statements are part of nested loops.
An example:
void visitBlock(Block node) {final nestingNodesChain = <AstNode>[];AstNode astNode = node;do {if (astNode is Block &&(astNode?.parent is! BlockFunctionBody ||astNode?.parent?.parent is FunctionExpression ||astNode?.parent?.parent is ConstructorDeclaration)) {nestingNodesChain.add(astNode);}
astNode = astNode.parent;} while (astNode.parent != _functionNode);if (nestingNodesChain.length > _deepestNestingNodesChain.length) {_deepestNestingNodesChain = nestingNodesChain;}
super.visitBlock(node);}
That produces an MN score of 3.
NUMBER OF METHODS:
The number of methods is the total number of methods in a class (or mixin, or extension). Too many methods indicate a high complexity.
NUMBER OF PARAMETERS:
The number of parameters is the number of parameters received by a method (or function). If a method receives too many parameters, it is difficult to call and also difficult to change if it’s called from many places.
An example:
MetricComputationResult<int> computeImplementation(Declaration node,Iterable<ScopedClassDeclaration> classDeclarations,Iterable<ScopedFunctionDeclaration> functionDeclarations,InternalResolvedUnitResult source,) {int parametersCount;if (node is FunctionDeclaration) {parametersCount = node.functionExpression?.parameters?.parameters?.length;} else if (node is MethodDeclaration) {parametersCount = node?.parameters?.parameters?.length;}
return MetricComputationResult(value: parametersCount ?? 0);}
That produces a NP score of 4.
SOURCE LINES OF CODE:
Source lines of Code is an approximate number of source code lines in a function or method. Blank or comment lines are not counted.
This metric is used to measure the size of a computer program by counting the number of lines in the text of the program’s source code. SLOC is typically used to predict the amount of effort that will be required to develop a program, as well as to estimate programming productivity or maintainability once the software is produced.
An example:
MetricComputationResult<int> computeImplementation(Declaration node,Iterable<ScopedClassDeclaration> classDeclarations,Iterable<ScopedFunctionDeclaration> functionDeclarations,InternalResolvedUnitResult source,) {final visitor = SourceCodeVisitor(source.lineInfo);node.visitChildren(visitor);return MetricComputationResult(value: visitor.linesWithCode.length,context: _context(node, visitor.linesWithCode, source),);}
Source lines of Code for the example function is 6.
WEIGHT OF A CLASS:
Number of functional public methods divided by the total number of public methods.
This metric tries to quantify whether the measured class (or mixin, or extension) interface reveals more data than behavior. Low values indicate that the class reveals much more data than behavior, which is a sign of poor encapsulation.
Our definition of functional method excludes getters and setters.
Installing The Plugin
It’s a plugin that is also a dart binary so in the terminal you install it with this:
flutter pub global activate dart_code_metricsThen in your pubspec:
dev_dependencies:dart_code_metrics: ^3.3.4And you add this to your analysis_options.yaml file:
analyzer:plugins:- dart_code_metricsdart_code_metrics:anti-patterns:- long-method- long-parameter-listmetrics:cyclomatic-complexity: 20lines-of-executable-code: 50maximum-nesting-level: 5number-of-parameters: 4source-lines-of-code: 50metrics-exclude:- test/**rules:- newline-before-return- no-boolean-literal-compare- no-empty-block- prefer-trailing-comma- prefer-conditional-expressions- no-equal-then-elseThen to get an output report it this in your terminal from your project directory:
metrics lib --reporter=html --output-directory=reportsSince it’s a dart binary no need to put the dart or flutter prefix.
And that report looks like this:

Conclusion
This the second half of static analysis with the first part getting your project code linted. This is only a sliver of the devOPS needed to properly implement speed-code-sprints.
Resources
Resources specific to the article:
flutter design and arch rosetta https://github.com/fredgrott/flutter_design_and_arch_rosetta
General Flutter and Dart resources:
Flutter Community Resources https://flutter.dev/community
Flutter SDK https://flutter.dev/docs/get-started/install
Android Studio IDE https://developer.android.com/studio
MS’s Visual Studio Code https://code.visualstudio.com/
Flutter Docs https://flutter.dev/docs
Dart Docs https://dart.dev/guides
Google Firebase Mobile Device TestLab https://firebase.google.com/docs/test-lab
Trademark Notice
Google LLC owns the following trademarks; Dart, Flutter, Android, Roboto, Noto. Apple Inc owns the trademarks iOS, MacOSX, Swift, and Objective-C. Apple Inc owns trademarks to their fonts of SF Pro, Sf Compact, SF mono, and New York. JetBeans Inc owns the trademarks of JetBeans, IntelliJ, and Kotlin. Oracle Inc owns the Java trademark. Microsoft Inc owns the trademarks of MS Windows OS and Powershell. Gradle is a trademark of Gradle Inc. The Git Project owns the trademark to Git. Linux Foundation owns the trademark of Linux. Smartphone OEM’s own trademarks to their mobile phone product names. Samsung owns the trademark to Tizen. To the best of my ability, I follow the brand and usage guidelines with the above-mentioned trademarks.
About Me, Fred Grott
I am on a different adventure of creating a Maker and Creator studio the bootstrap way in teaching Flutter Application Design and Development to you guys and gals.
My keybase profile is at: https://keybase.io/fredgrott



