In this post we’re looking at the unused entities information and how to configure warnings for it. This is one of many ways Sw!ftalyzer helps us finding potential areas of improvement in our app.
Getting an Overview of Unused Entities with Sw!ftalyzer
When removing an old and unused feature or refactoring code, it’s easy to miss that some part of the code stays in the project although it’s no longer in usage. Later on its often time consuming to find and remove unused code. But keeping code entities around longer than needed can slow down development.
Sw!ftalyzer automatically analyses all dependencies and can find entities without any incoming dependencies. Although these entities are not necessarily unused, they are a good starting point for checking and removing unused code.
We’ll use a demo project analysis to see how this looks like. Download the analysis file and open it in Sw!ftalyzer to explore the analysis: DemoProject
This project contains two files, DemoProjectApp.swift and ContentView.swift. The first one includes the declaration of DemoProjectApp
. This struct is the main entry point of the app.
@main
struct DemoProjectApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
This is the code for the second file, there are four different entities:
struct ContentView: View { /* ... */ }
struct ContentView_Previews: PreviewProvider { /* ... */ }
protocol LegacyService { }
class OldViewController: NSViewController { }
The struct DemoProjectApp
has a dependency to ContentView
, same is true for ContentView_Previews
. The protocol LegacyService
and the class OldViewController
are never used. Most probably they are a left-over from a previous refactoring.
This is how Sw!ftalyzer visualises the dependency graph:
We can see the code entities and their dependencies. There are two arrows pointing from DemoProjectApp
and ContentView_Previews
to ContentView
. This shows us, that these two entities use the struct ContentView
. No arrow leads to the protocol LegacyService
and the class OldViewController
.
The dependency graph is a great way of getting an overview of our code entities and the dependencies between them. Another way of finding this information is in the information panel to the right of the graph.
We can get a list of unused entities 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 unused entities here. For the demo project it shows the entities DemoProjectApp
, LegacyService
and OldViewController
.
This list doesn’t contain the entity ContentView_Previews
, although it has no incoming dependency. Previews are generally not referenced by other entities and are stand-alone. Thus Sw!ftalyzer ignores them when listing unused entities.
There may be good reasons to keep dead code around, e.g. to use it as a reference later on. In case we want to accept that an entity is unused without seeing warnings about it, or if the warning is a false positive, we can ignore the finding.
It may also be that an entity has no incoming dependency in the analysed module. But there can still be code in another module not included in the analysis that uses this entity. So always be careful when removing an entity.
In this example, DemoProjectApp
is important, although it has no incoming dependency. Thus we want to ignore it in this list. 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 after ignoring the finding for the entity DemoProjectApp.
A finding can be un-ignored again by opening the context menu again and clicking on the item to un-ignore it.
Configuring Warnings about Unused Entities
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 unused entities below.
There’s a checkbox to enable or disable the warning. When enabled, Sw!ftalyzer shows a warning for each entity node without incoming dependency. It’s selected by default.
Unselecting this checkbox removes all warnings about unused entities in the dependency graph.
With the unused entities warning enabled, we see indicators at the same nodes as we’ve seen in the list before: