mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
100 lines
4.6 KiB
XML
100 lines
4.6 KiB
XML
<!DOCTYPE qhelp PUBLIC
|
|
"-//Semmle//qhelp//EN"
|
|
"qhelp.dtd">
|
|
<qhelp>
|
|
|
|
<overview>
|
|
<p>
|
|
Classes that are never used at runtime are redundant and should be removed.
|
|
</p>
|
|
<include src="DeadCodeSummary.inc.qhelp"/>
|
|
<p>
|
|
Classes are considered dead if at runtime:
|
|
</p>
|
|
<ul>
|
|
<li>No methods declared in the class, or a sub-type, are called.</li>
|
|
<li>No fields declared in the class, or a sub-type, are read.</li>
|
|
<li>The class is never constructed.</li>
|
|
</ul>
|
|
<p>Any class which is not dead is considered to be "live". Nested classes are considered and listed
|
|
separately, as a live nested class within a dead outer class can be moved to a separate file,
|
|
allowing the outer class to be deleted.
|
|
</p>
|
|
<p>
|
|
A special exception is made for "namespace classes". A namespace class is used only to group static
|
|
fields, methods and nested classes - it is never instantiated, has no public constructor and has no
|
|
instance methods. If a class is considered to be a namespace class, then it is live if at least one
|
|
of the static members of that class is live - including static nested classes.
|
|
</p>
|
|
<include src="DeadCodeDetails.inc.qhelp"/>
|
|
</overview>
|
|
<recommendation>
|
|
<p>
|
|
Before making any changes, confirm that the class is not required by verifying that the only
|
|
dependencies on the class are from other dead classes and methods. This confirmation is necessary
|
|
because there may be project-specific frameworks or techniques which can introduce hidden
|
|
dependencies. If this project is for a library, then consider whether the class is part of the
|
|
external API, and may be used in external projects that are not included in the snapshot.
|
|
</p>
|
|
<p>
|
|
After confirming that the class is not required, remove the class. You will also need to remove any
|
|
references to this class, which may, in turn, require removing other unused classes, methods
|
|
and fields (see Example 1).
|
|
</p>
|
|
<p>
|
|
Nested classes within this type should be moved, either to a new top-level type, or to another
|
|
type, unless they are also marked as dead, in which case they can also be removed. Alternatively,
|
|
if there are some live nested classes within the dead class, the class can be retained by
|
|
converting all live nested classes to static members, and removing all instance methods and fields,
|
|
and all dead static members (see Example 2).
|
|
</p>
|
|
<include src="DeadCodeExtraEntryPoints.inc.qhelp"/>
|
|
</recommendation>
|
|
<section title="Example 1">
|
|
<p>
|
|
In the following example, we have a number of classes, and an "entry point" in the form of a main
|
|
method.
|
|
</p>
|
|
<sample src="DeadClass.java" />
|
|
<p>
|
|
The class <code>Customer</code> is constructed in the main method, and is therefore live. The
|
|
class <code>Address</code> is constructed in <code>setAddress</code>, so we might think that it
|
|
would also be live. However, <code>setAddress</code> is never called by the main method, so,
|
|
assuming that this is the entire program, an <code>Address</code> is never constructed at runtime.
|
|
Therefore, the <code>Address</code> class is dead and can be removed without changing the meaning
|
|
of this program. To delete the <code>Address</code> class we will also need to delete the
|
|
<code>setAddress</code> and <code>getAddress</code> methods, and the <code>address</code> field,
|
|
otherwise the program will not compile.
|
|
</p>
|
|
</section>
|
|
<section title="Example 2">
|
|
<p>
|
|
In the next example, we have a <code>CustomerActions</code> class containing <code>Action</code>s
|
|
that affect customers. For example, this could be a Java Swing application, and the
|
|
<code>Action</code>s could be actions that are available in the user interface.
|
|
</p>
|
|
<sample src="NamespaceClass.java" />
|
|
<p>
|
|
The <code>CustomerActions</code> class has a constructor and an instance method, which are never
|
|
called. Instead, actions are instantiated directly. Although this makes the nested
|
|
<code>Action</code> classes live, live nested classes do not make the outer class live. Therefore,
|
|
the <code>CustomerActions</code> class is marked as dead.
|
|
</p>
|
|
<p>
|
|
There are two ways to resolve the dead <code>CustomerActions</code> class:
|
|
</p>
|
|
<ul>
|
|
<li>Move each nested static action that is used by the program to a new file, or nest it within
|
|
a different class, then delete the dead <code>CustomerActions</code> class.</li>
|
|
<li>Convert the <code>CustomerActions</code> class to a <em>namespace class</em>. First convert the
|
|
constructor to a <em>suppressed constructor</em> by making it private, preventing the class from
|
|
being instantiated, then remove the instance method <code>createAddCustomerAction</code>.</li>
|
|
</ul>
|
|
<p>
|
|
Taking the second approach, this is the final result.
|
|
</p>
|
|
<sample src="NamespaceClass2.java" />
|
|
</section>
|
|
<include src="DeadCodeReferences.inc.qhelp" />
|
|
</qhelp>
|