This post explains details about using the non-final class information in Sw!ftalyzer. It helps us to identify classes that can be final but are missing the final keyword.
After learning about the final keyword, we’re seeing how we can find non-final classes with Sw!ftalyzer. Finally, we’re going to configure warnings, so that we can find areas of improvement in our app at first glance.
Getting an Overview of Non-Final Classes with Sw!ftalyzer
Classes that have the final keyword added to their declaration can not be subclassed. This has some benefits:
- Preventing unintended side-effects when changing a seemingly unrelated class: No inheriting class can override methods or properties to change the behavior.
- Performance benefits: By restricting the possibility of overrides, the compiler can make certain assumptions about the code. This can result in faster execution.
When all classes without subclasses are final, it’s easy to see if a class is part of a inheritance hierarchy. Looking at its declaration gives us all information without needing to search the project for potential subclasses. However, this requires the team to be consistent with the usage of final.
But how can we find out if a class could be final? We could add the keyword to a class and build the app. If it compiles, the class can be final, otherwise there’ll be errors. Unfortunately, this manual progress quickly becomes time consuming.
Sw!ftalyzer automatically analyses the declarations of the classes in our app and knows, which ones don’t have the final keyword. It also sees all inheritances and thus knows, which classes can not be final because of subclasses. That’s why Sw!ftalyzer can give us a list of classes that can be final but are missing the final keyword. Let’s see how this looks like for a concrete example.
We’ll use a demo project analysis. Download the analysis file and open it in Sw!ftalyzer to explore the analysis: DemoProject
The analysed project contains 5 classes:
final class FinalClass { }
class NonFinalClass { }
class NonFinalSuperClass { }
final class FinalSubClass: NonFinalSuperClass { }
class NonFinalSubClass: NonFinalSuperClass { }
This is how Sw!ftalyzer visualises the dependency graph:
We can get a list of non-final classes when selecting the third tab in the right panel, which is highlighted in the image. This tab shows general project information independent from the currently selected node.
Among other things, we can find a list of classes here, which could be final but are missing the final keyword.
In this example these are the classes NonFinalClass
and NonFinalSubClass
. These two don’t have the final keyword and there are no classes inheriting from them.
NonFinalSuperClass
is also missing the final keyword. But since there are subclasses, making it final would lead to compilation errors.
In case we want to accept that a class is non-final without seeing warnings about it, or if the warning is a false positive, we can ignore the finding.
To do so, we open a context menu via a right click on the dark grey box. This context menu has an item to ignore finding. The next picture shows how this looks like when the finding for the class NonFinalClass
is ignored.
A finding can be un-ignored again by opening the context menu again and clicking on the item to un-ignore it.
Finding Non-Final Classes with Warnings
Warnings are a great way of quickly finding areas of improvement in our apps. A class with a warning has a red bubble in the upper right corner of the node that shows the number of warnings.
We can configure warnings in the configuration tab. It’s the fourth tab in the right panel, which is highlighted in the image. Select it to see options for various warnings, like the warning about non-final classes below.
There’s a checkbox to enable or disable the warning. It’s selected by default meaning that Sw!ftalyzer shows a warning next to each class node that could be final but is missing the final keyword. Unselecting this checkbox removes all warnings about non-final classes in the dependency graph.
With the non-final class warning enabled, we see indicators at the same classes as we’ve seen in the list before: