avatarFred Grott

Summary

The provided content discusses the importance of static analysis in Flutter development, focusing on the use of the dart_code_metrics plugin to analyze Dart code metrics for improving code quality and maintainability.

Abstract

The article emphasizes the significance of static analysis beyond linting in Flutter development, particularly the analysis of code metrics to enhance the quality of Dart code. It introduces the dart_code_metrics plugin as a tool for developers to effectively evaluate their codebase, detailing various metrics such as Cyclomatic Complexity, Lines of Code (LOC), Maximum Nesting (MN), Number of Methods (NM), Number of Parameters (NP), and Source Lines of Code (SLOC). The author, Fred Grott, argues that understanding and applying these metrics is crucial for developing professional-level applications in a mature market. The article also provides practical guidance on installing the plugin, integrating it into the development workflow, and interpreting the resulting metrics. Additionally, Grott shares a collection of his articles and resources that cover a range of topics from DevOps to visual animations in Flutter, and he encourages readers to follow him on various social platforms for updates on his work.

Opinions

  • The author believes that Google's introduction to widgets is not sufficient for professional Flutter development, and that mastering DevOps and programming paradigms is essential.
  • Grott suggests that by engaging readers with interesting visual and animation topics, he can motivate them to also focus on the less exciting but necessary aspects of development like code metrics analysis.
  • The article conveys that code with high complexity, such as deep nesting levels or a large number of methods and parameters, can be difficult to maintain and should be refactored for better clarity and performance.
  • The author's opinion is that the dart_code_metrics plugin is a valuable tool for developers to gain insights into their code's complexity and maintainability, thereby facilitating a more efficient development process.
  • Grott emphasizes the importance of encapsulation by discussing the Weight of Class (WOC) metric, which indicates the balance between data and behavior in a class's interface.
  • He also expresses the need for proper static analysis as part of a broader set of devOPS practices, which he refers to as "speed-code-sprints," to ensure high-quality software development.
  • The author provides a comprehensive list of resources, including his own contributions to the Flutter community, to support developers in their learning and application of best practices in Flutter and Dart development.

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 complexity
else, finally and default don't count
some operators (&&, ||, ?., ??, ??=) increase complexity

An 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_metrics

Then in your pubspec:

dev_dependencies:
dart_code_metrics: ^3.3.4

And you add this to your analysis_options.yaml file:

analyzer:
plugins:
- dart_code_metrics
dart_code_metrics:
anti-patterns:
- long-method
- long-parameter-list
metrics:
cyclomatic-complexity: 20
lines-of-executable-code: 50
maximum-nesting-level: 5
number-of-parameters: 4
source-lines-of-code: 50
metrics-exclude:
- test/**
rules:
- newline-before-return
- no-boolean-literal-compare
- no-empty-block
- prefer-trailing-comma
- prefer-conditional-expressions
- no-equal-then-else

Then to get an output report it this in your terminal from your project directory:

metrics lib --reporter=html --output-directory=reports

Since 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

Flutter
DevOps
Dart
Software Development
Software Engineering
Recommended from ReadMedium