Cyotek Development Bloghttps://devblog.cyotek.com/tag/code-analysis/atom.xml2015-06-27T09:32:49ZA brief look at code analysis with NDependurn:uuid:794c1179-a855-47aa-a2c3-b17f98abf0bf2015-06-27T09:32:49Z2015-06-27T09:32:49Z<p>If you're a developer, you're probably familiar with various
tenets of your craft, such as &quot;<em>naming things is hard</em>&quot; and
&quot;<em>every non trivial program has at least one bug</em>&quot;. The latter
example is one of the reasons why there are ever increasing
amounts of tools designed to reduce the number of bugs in an
application, from testing, to performance profiling, to code
analysis.</p>
<p>In this article, I'm going to briefly take a look <a href="http://www.ndepend.com/" rel="external nofollow noopener">NDepend</a>,
a code analysis tool for Visual Studio. This is the point where
I'd like to quote the summary of the product from the NDepend
website, but there's no simple description - which sums up
NDepend pretty well actually. This is a complicated product
offering a lot of features.</p>
<p>So when I say &quot;a brief look&quot;, that's exactly what I mean. When
I've had a chance to explore the functionality fully I hope I'll
have enough knowledge and material to expand upon this initial
post.</p>
<blockquote>
<p>Disclaimer: I received a professional license for NDepend on
the condition I would write about my experiences.</p>
</blockquote>
<h2 id="what-is-ndepend-and-what-can-it-do-for-me">What is NDepend and what can it do for me?</h2>
<p>Simply put, NDepend will analyse your code and spit out a report
full of metrics, and violations against a large database of
rules. These might be the mundane (a method has too many lines)
to the more serious (your method is so complicated you will
never remember how it works in 6 months time).</p>
<p>This really doesn't even begin to cover it though, as it can do
so much more, from dependency graphs to trend analysis. One of
the interesting things about NDepend is it saves the results of
each analysis you do, allowing you to see if metrics such as
test coverage are improving (good) or critical violations
increased (not so good!).</p>
<h2 id="a-sample-project">A sample project</h2>
<p>For this article, I'm going to be using the <a href="https://github.com/cyotek/Dithering" rel="external nofollow noopener">Dithering</a>
project I created in previous blog posts to test some of the
functionality of NDepend. I choose this because the project was
fresh in my mind as I've been heavily working on it the last few
weeks, and because it was small enough that I assumed NDepend
wouldn't find much amiss. Here's another tenet - <em>assumptions
are the mother of all &lt;censored&gt;</em>.</p>
<p>You can use NDepend one of two ways, either via a stand alone
application, or via a Visual Studio extension. For this article,
I'm going to be using Visual Studio, but you should be able to
do everything in the stand alone tool as well. There's also a
CLI tool which I assume is for build integration but I haven't
looked at it yet.</p>
<h2 id="that-first-analysis">That first analysis</h2>
<p>If this is the first time using NDepend, you need to attach an
NDepend project to your solution.</p>
<ul>
<li>Open the <strong>NDepend</strong> menu and select the <strong>Attach New NDepend
Project to Current VS Solution</strong> menu item</li>
<li>The dialog that is displayed will list all the projects in
your solution, if there any you don't want to include in the
analysis, just right click them and choose the appropriate
option</li>
<li>Click the <strong>Analyze</strong> button to generate the project</li>
<li>Once the project has been created, a welcome dialog will be
displayed. Click the <strong>View NDepend Dashboard</strong> button to
continue</li>
</ul>
<p>This will open the dashboard, looking something similar to the
below.</p>
<blockquote>
<p>A HTML report will also be generated and opened in your
default browser, providing a helpful synopsis of the analysis.</p>
</blockquote>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-dashboard.png" class="gallery" title="The initial dashboard for the Dithering project" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-dashboard.png" alt="The initial dashboard for the Dithering project" decoding="async" loading="lazy" /></a><figcaption>The initial dashboard for the Dithering project</figcaption></figure>
<p>At this point, all the charts you can see are going to be
non-existent as you have to rerun the analysis at future times
in order to get additional data points for plotting.</p>
<p>The main information I'm interested in right now is contained in
the <strong>Code Rules</strong> block. And it doesn't make me happy to read
it:</p>
<ul>
<li>4 Critical Rules Violated for a total of 9 Critical Violations</li>
<li>37 Rules Violated for a total of 215 Violations</li>
</ul>
<p>Wow, that's a lot of violations for such a small project! Lets
take a look at these in detail.</p>
<h2 id="viewing-rules">Viewing Rules</h2>
<p>Clicking the blue hyper-links in the Dashboard will
automatically open a new view to drill down into the details of
the analysis. On clicking the <strong>Critical Rules Violated</strong> link,
I'm presented with the following</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-criticalrules.png" class="gallery" title="Viewing rule violations" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-criticalrules.png" alt="Viewing rule violations" decoding="async" loading="lazy" /></a><figcaption>Viewing rule violations</figcaption></figure>
<p>Clicking one of the rules in the list displays the code of the
rule and the execution results.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-viewrule.png" class="gallery" title="Viewing the results of a violated rule" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-viewrule.png" alt="Viewing the results of a violated rule" decoding="async" loading="lazy" /></a><figcaption>Viewing the results of a violated rule</figcaption></figure>
<p>Here we can see the the violation is triggered if any method has
more than eight parameters. In the dithering example project,
there is a class I that I used to generate the diagrams used on
the blog posts, and the <code>DrawString</code> method of this helper class
has 10 parameters, thus falling foul of the rule. Great start!</p>
<p>The next rule on the list is a bit more complicated, but
essentially it's trying to detect dead code. In a non-library
project, this should be fairly straight forward and true to form
it has detected that the <code>ArticleDiagrams</code> class and its methods
are dead code.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-viewcomplexrule.png" class="gallery" title="A more complicated rule with a lot of conditions" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-viewcomplexrule.png" alt="A more complicated rule with a lot of conditions" decoding="async" loading="lazy" /></a><figcaption>A more complicated rule with a lot of conditions</figcaption></figure>
<p>This is actually a very useful rule if your coding standards
insist that all dead code is removed. How useful depends on your
code coverage, if you also have a 100% rule then you should
already found and removed such code.</p>
<p>So far so good. Lets look at the final critical rule failure.</p>
<h2 id="when-rules-go-wrong">When rules go wrong</h2>
<p>The last critical rule violation is <strong>Don't call your method
Dispose</strong>. I imagine this makes a lot of sense, if your class
doesn't implement <code>IDisposable</code>, then having a method named
<code>Dispose</code> is going to be confusing at best.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-falsepositive.png" class="gallery" title="I'm either mad, or this is a false positive" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-falsepositive.png" alt="I'm either mad, or this is a false positive" decoding="async" loading="lazy" /></a><figcaption>I'm either mad, or this is a false positive</figcaption></figure>
<p>Interesting. So it somehow thinks that the <code>MainForm</code> and
<code>AboutDialog</code> classes - both of which inherit from <code>Form</code> -
shouldn't have methods named <code>Dispose</code>. Well, somewhere in its
inheritance chain <code>Form</code> does implement <code>IDisposable</code> so this
violation is completely wrong.</p>
<p>As a test, I added <code>IDisposable</code> to the signature of
<code>AboutDialog</code> and re-ran the NDepend analysis. It promptly
decided that the <code>Dispose</code> method in that class was now fine. Of
course, now Resharper is complaining <em>Base interface
'IDisposable' is redundant because
Cyotek.DitheringTest.AboutDialog inherits 'Form'</em>. Sorry
NDepend, you're definitely wrong in this instance.</p>
<blockquote>
<p>At this point, I excluded the <code>ArticleDiagrams</code> class from the
solution and reran the analysis, removing some the violations
that were valid, but not really appropriate as it was dead
code.</p>
</blockquote>
<h2 id="more-violations">More violations</h2>
<p>So far, I've looked at 4 failed rules. 3 I'm happy to accept,
and if this were production code I'd be getting rid of the dead
code and resolving all three. The fourth violation is flat out
wrong and I'm ignoring it for now.</p>
<p>However, there were lots of other (non-critical) violations, so
I'll have a look at those now. The <strong>Queries and Rules
Explorer</strong> window opened earlier has a drop down list which I
can use to filter the results, so now I choose <strong>31 Rules
Violated</strong> to look at the other warnings.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-morerules.png" class="gallery" title="A bunch of important, but not critical, rule violations" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-morerules.png" alt="A bunch of important, but not critical, rule violations" decoding="async" loading="lazy" /></a><figcaption>A bunch of important, but not critical, rule violations</figcaption></figure>
<p>There's plenty of other violations listed. I'll outline a tiny
handful of them below.</p>
<h3 id="override-equals-and-operator-equals-on-value-types-structures-should-be-immutable">Override equals and operator equals on value types / Structures should be immutable</h3>
<p>This pair of failures is caused by the custom <code>ArgbColor</code> struct
and is the simplest structure to handle a 32bit colour.
Actually, this struct is being called out for a few rules all of
which I agree with. If this were production code, I'd be
following a lot of the recommendations it makes (in fact, in the
&quot;real&quot; version of this class in my production libraries I do
follow most of them - a key exception being my structs are still
mutable).</p>
<h3 id="static-fields-should-be-prefixed-with-a-s_instance-fields-should-be-prefixed-with-a-m">Static fields should be prefixed with a 's_' / Instance fields should be prefixed with a 'm_'</h3>
<p>These rules vie between I disagree with them, and NDepend
shouldn't be picking them up. In the first place, I disagree
with the rule - I simply use an underscore prefix and leave it
at that.</p>
<p>However, NDepend is also picking up all of the control names in
my forms. I seriously doubt any developer is going to use <code>m_</code>
in front of their control names and so I don't think NDepend
should be looking at these - I consider them &quot;designer&quot; code of
sorts and should be excluded. There's a few more rules being
triggered by controls, and I think it's looking messier than it
should.</p>
<p>I can edit the rule to use my own conversion of the plain
underscore, but I can't do much about NDepend picking up WinForm
control names.</p>
<h3 id="non-static-classes-should-be-instantiated-or-turned-to-static">Non-static classes should be instantiated or turned to static</h3>
<p>This is an interesting one. It's basically being triggered by
the <code>LineDesigner</code> class, a designer for the <code>Line</code> control to
allow only horizontal resizing. Control designers can't be
static and so this rule doesn't apply. It is referenced by the
<code>Designer</code> attribute of the <code>Line</code> class so we probably just
need to edit the rule to support it.</p>
<h2 id="and-more">And more</h2>
<p>There's quite a few rule violations so I won't cover them all.
It's an interesting mix of rules I would find useful, and rules
subject to interpretation (an example is if I have an <code>internal</code>
class I still mark its members as <code>public</code>, NDepend think this
is incorrect).</p>
<p>But, NDepend doesn't force you to accept its view. You can
simply turn off any rule that you don't want influencing the
analysis and it will be fully disabled, including the dashboard
updating itself in real-time.</p>
<p>Assuming you have analysed the project multiple times, you can
turn on recent violations only, thus hiding any previous
violations. You may find this very useful if you are working
from a legacy code base!</p>
<h2 id="editing-rules">Editing Rules</h2>
<p>With that said, there are other options if a rule doesn't quite
fit the bill. NDepend uses LINQ with a set of custom extensions
(Code Query over LINQ (CQLinq)) as the base of its rules. So you
can put your programmer hat on and modify these rules to suit
your needs.</p>
<p>As a concrete example, I'm going to look at the <strong>Instances size
shouldn't be too big</strong> rule. This has flagged the <code>Line</code> control
as being too big, something I found curious as the control is a
simple affair that just draws a 3D line. When I look at the
details for the violation it mentions 6 fields. But the control
only has 3. Or does it?</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-editrule.png" class="gallery" title="Why does this rule think a class with 3 fields really has 6?" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-editrule.png" alt="Why does this rule think a class with 3 fields really has 6?" decoding="async" loading="lazy" /></a><figcaption>Why does this rule think a class with 3 fields really has 6?</figcaption></figure>
<p>The query results don't include the names of the fields, so I'm
going to adjust the code of the rule to include them. This is a
really nice aspect of NDepend - as I type in the code pane, it
continually tries to compile and run the rule, including syntax
highlighting of errors, and intellisense.</p>
<p>I added the <code>, names = ...</code> condition to the code as follows,
which allowed me to influence the output to include an extra
column</p>
<figure class="lang-csharp highlight"><figcaption><span>csharp</span></figcaption><pre class="code">
warnif count <span class="symbol">&gt;</span> <span class="number">0</span> <span class="keyword">from</span> t <span class="keyword">in</span> JustMyCode<span class="symbol">.</span>Types <span class="keyword">where</span> 
 t<span class="symbol">.</span>SizeOfInst <span class="symbol">&gt;</span> <span class="number">64</span> 
 <span class="keyword">orderby</span> t<span class="symbol">.</span>SizeOfInst <span class="keyword">descending</span>
<span class="keyword">select</span> <span class="keyword">new</span> <span class="symbol">{</span> t<span class="symbol">,</span> t<span class="symbol">.</span>SizeOfInst<span class="symbol">,</span> t<span class="symbol">.</span>InstanceFields<span class="symbol">,</span> names <span class="symbol">=</span> <span class="keyword">string</span><span class="symbol">.</span>Join<span class="symbol">(</span><span class="string">&quot;, &quot;</span><span class="symbol">,</span> t<span class="symbol">.</span>InstanceFields<span class="symbol">.</span>Select<span class="symbol">(</span>f <span class="symbol">=&gt;</span> f<span class="symbol">.</span>Name<span class="symbol">)</span><span class="symbol">)</span> <span class="symbol">}</span>
</pre>
</figure>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-editrule-result.png" class="gallery" title="Apparently because an event is a field!" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-editrule-result.png" alt="Apparently because an event is a field!" decoding="async" loading="lazy" /></a><figcaption>Apparently because an event is a field!</figcaption></figure>
<p>The results of the modified rule show that there are 3 variables
which are backing fields for properties, and then 3 events. Is
an event a field? I don't think so, an event is an event. But
NDepend thinks it is a field. Regardless though, by editing the
rule I was easily able to add additional output from the rule,
and although not demonstrated here I've also used some of the
built in filtering options to exclude results from being
returned.</p>
<p>The ability to write your own rules could potentially be very
useful with many possibilities.</p>
<h2 id="interpretation-is-king">Interpretation is king</h2>
<p>In a way, I'm glad that NDepend doesn't have the ability to
automatically fix violations the way some other tools do. I ran
NDepend on my <a href="https://github.com/cyotek/Cyotek.Collections.Generic.CircularBuffer" rel="external nofollow noopener">CircularBuffer library</a>, and one of the
suggestions was to change the visibility of the class from
<code>public</code> to <code>internal</code>. Making the single class of a library
project inaccessible to consumers isn't the best of ideas!</p>
<p>I think what I'm leading to here, is use common sense with the
violations, do not just blindly accept anything it says as
gospel.</p>
<h2 id="viewing-dependencies">Viewing Dependencies</h2>
<p>Any application is going to have dependencies, and depending on
how tight your coupling is, this could be an evil nightmare. You
can display a visual hierarchy of the dependencies of your
project via a handy <strong>Dependency Diagram</strong> - below is the one
for the dithering project. Quite small as there are few
references, The thicker the arrow, the more dependencies from
the destination assembly you're using.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-dependency-diagram.png" class="gallery" title="Easy dependency viewing" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-dependency-diagram.png" alt="Easy dependency viewing" decoding="async" loading="lazy" /></a><figcaption>Easy dependency viewing</figcaption></figure>
<p>In the case where the diagram is so big as to become
meaningless, you can also view a <strong>Dependency Matrix</strong> - this
lets you plot assemblies against each other and see the usages.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-matrix.png" class="gallery" title="Viewing code dependencies via a matrix" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-matrix.png" alt="Viewing code dependencies via a matrix" decoding="async" loading="lazy" /></a><figcaption>Viewing code dependencies via a matrix</figcaption></figure>
<p>Clicking one of the nodes in the matrix will then open a
simplified Dependency Graph, making it a little easier to browse
than a huge spaghetti diagram.</p>
<h2 id="code-metrics">Code Metrics</h2>
<p>Many years ago, I used a small tool that displayed the size of
the different directories on my computer in a <a href="https://en.wikipedia.org/wiki/Treemapping" rel="external nofollow noopener">treemap</a> to
see which folders took up the most space. I haven't used that
tool for years (I don't need a colour graph to know my Steam
directory is huge!) but I do find that sort of display to be
oddly compelling.</p>
<p>NDepend makes use of a tree map to display code metrics - the
size of the squares defaults to the code size (useful for seeing
huge methods, although again, as the screenshot below indicates,
I really wish NDepend would exclude designer code). You can also
control the colour of the square via another metric - the
default being complexity, so the greener the square the easier
the code should be to maintain.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-codemetrics.png" class="gallery" title="An easy way to gauge the health of your code" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-codemetrics.png" alt="An easy way to gauge the health of your code" decoding="async" loading="lazy" /></a><figcaption>An easy way to gauge the health of your code</figcaption></figure>
<p>I couldn't see how to access this from Visual Studio, but the
HTML report also includes an <strong>Abstractness versus Instability</strong>
diagram which &quot;helps to detect which assemblies are potentially
painful to maintain (i.e concrete and stable) and which
assemblies are potentially useless (i.e abstract and instable)&quot;.
Meaning you should probably take note if anything appears in the
red zone!</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-abstractness-vs-instability.png" class="gallery" title="NDepend doesn't think WebCopy's code is unstable. Well, at least that's one thing that isn't" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-abstractness-vs-instability.png" alt="NDepend doesn't think WebCopy's code is unstable. Well, at least that's one thing that isn't" decoding="async" loading="lazy" /></a><figcaption>NDepend doesn't think WebCopy's code is unstable. Well, at least that's one thing that isn't</figcaption></figure><h2 id="updating-the-analysis">Updating the analysis</h2>
<p>You can trigger a manual refresh of the analysis at any time,
but also by default NDepend will perform one after each build,
meaning you can always be up to date on the metrics of your
project.</p>
<h2 id="show-me-a-big-project">Show me a big project</h2>
<p>So far I have looked at only a small demonstration project.
However, as the ultimate test of my review, I decided to scan
<a href="https://cyotek.com/cyotek-webcopy">WebCopy</a>. I was very curious to see how NDepend would handle
that solution. NDepend scanned the code base quite nicely
(despite an old version of one of my libraries getting detected
and playing havoc)</p>
<p>As an indication of the size of the project, it reports that
WebCopy has 60 thousand lines of code (translating to half a
million IL instructions), 24 thousand lines of comments, and
nearly 1800 types spread over 44 assemblies. A fair amount!</p>
<p>I had a quick look through the violations list, and noticed a
few oddities - there are <em>lots</em> of <code>Forms</code> in these projects,
yet the <strong>Don't call your method Dispose</strong> violation that so
annoyed me earlier was only recorded 4 times. One of these was
actually valid (a manager class who's children were disposable),
while the others weren't. Still, there's a curious disparity in
the way NDepend is running these rules it seems.</p>
<p>I did find some violations indicating genuine problems (or
potential problems) in the code through so at some point (sigh -
there's a lot of them) I will have to take a closer look and go
through them all in detail.</p>
<p>Just before I sign off, I shall show you the dependency diagram
(maybe I need to try and make my code simpler!) and the
complexity diagram.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-dependency-diagram-big.png" class="gallery" title="You are looking at a window into Code Hell. Fear it" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-dependency-diagram-big.png" alt="You are looking at a window into Code Hell. Fear it" decoding="async" loading="lazy" /></a><figcaption>You are looking at a window into Code Hell. Fear it</figcaption></figure><figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/ndepend-a1-codemetrics-big.png" class="gallery" title="A bit too much red here for my liking" ><img src="https://images.cyotek.com/image/thumbnail/devblog/ndepend-a1-codemetrics-big.png" alt="A bit too much red here for my liking" decoding="async" loading="lazy" /></a><figcaption>A bit too much red here for my liking</figcaption></figure><h2 id="thats-all-folks">That's all, folks</h2>
<p>For a &quot;brief&quot; overview, this has been quite a long article -
NDepend is such a big product, one article cannot possibly cover
it all. Just take a look at their <a href="http://www.ndepend.com/features/" rel="external nofollow noopener">feature list</a>!</p>
<p>Ideally I will try to cover more of NDepend in future articles,
as I'm still exploring the feature set, so stay tuned.</p>
<h2 id="update-history">Update History</h2>
<ul>
<li>2015-06-27 - First published</li>
<li>2020-11-21 - Updated formatting</li>
</ul>

<p><small>
All content <a href="https://devblog.cyotek.com/copyright-and-trademarks">Copyright (c) by Cyotek Ltd</a> or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.<br />Original URL of this content is https://devblog.cyotek.com/post/a-brief-look-at-code-analysis-with-ndepend .
</small></p>Richard Mosshttps://www.cyotek.com/richard.moss@cyotek.com