Migrate Java code to separate QL repo.

This commit is contained in:
Pavel Avgustinov
2018-08-30 10:48:05 +01:00
parent d957c151a6
commit 846c9d5860
2319 changed files with 134386 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
public static void main(String[] args) {
String firstName = /*...*/; String lastName = /*...*/;
// Construct a customer
Customer customer = new Customer();
// Set important properties (but not the address)
customer.setName(firstName, lastName);
// Save the customer
customer.save();
}
public class Customer {
private Address address;
// ...
// This setter and getter are unused, and so may be deleted.
public void addAddress(String line1, String line2, String line3) {
address = new Address(line1, line2, line3);
}
public Address getAddress() { return address; }
}
/*
* This class is only constructed from dead code, and may be deleted.
*/
public class Address {
// ...
public Address(String line1, String line2, String line3) {
// ...
}
}

View File

@@ -0,0 +1,99 @@
<!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.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.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.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.qhelp" />
</qhelp>

View File

@@ -0,0 +1,35 @@
/**
* @name Dead class
* @description Dead classes add unnecessary complexity.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @id java/dead-class
* @tags maintainability
* useless-code
* external/cwe/cwe-561
*/
import semmle.code.java.deadcode.DeadCode
from DeadClass c, Element origin, string reason
where
if exists(DeadRoot root | root = c.getADeadRoot() | not root = c.getACallable()) then (
// Report a list of the dead roots.
origin = c.getADeadRoot() and
not origin = c.getACallable() and
// There are uses of this class from outside the class.
reason = " is only used from dead code originating at $@."
) else (
// There are no dead roots outside this class.
origin = c and
if c.isUnusedOutsideClass() then
// Never accessed outside this class, so it's entirely unused.
reason = " is entirely unused."
else
/*
* There are no dead roots outside the class, but the class has a possible liveness cause
* external to the class, so it must be accessed from at least one dead-code cycle.
*/
reason = " is only used from or in a dead-code cycle."
)
select c, "The class " + c.getName() + reason, origin, origin.getName()

View File

@@ -0,0 +1,24 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<p>
A class, method, or field may be dead even if it has dependencies from other parts of the program,
if those dependencies are from code that is also considered to be dead. We can also consider this
from the opposite side - an element is live, if and only if there is an entry point - such as a
<code>main</code> method - that eventually calls the method, reads the field or constructs the class.
</p>
<p>
When identifying dead code, we make an assumption that the snapshot of the project includes all
possible callers of the code. If the project is a library project, this may not be the case, and
code may be flagged as dead when it is only used by other projects not included in the snapshot.
</p>
<p>
You can customize the results by defining additional "entry points" or by identifying fields that
are accessed using reflection. You may also wish to "whitelist" classes, methods or fields that
should be excluded from the results. Please refer to the Semmle documentation for more information.
</p>
</fragment>
</qhelp>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<p>
If you observe a large number of false positives, you may need to add extra entry points to
identify hidden dependencies caused by the use of a particular framework or technique, or to
identify library project entry points. Please refer to the Semmle documentation for more
information on how to do this.
</p>
</fragment>
</qhelp>

View File

@@ -0,0 +1,9 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<references>
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/Redundant_code">Redundant code</a>.</li>
<li>CERT Java Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/java/MSC56-J.+Detect+and+remove+superfluous+code+and+values">MSC56-J. Detect and remove superfluous code and values</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,17 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<p>
Redundant, or "dead", code imposes a burden on those reading or maintaining the software project.
It can make it harder to understand the structure of the code, as well as increasing the complexity
of adding new features or fixing bugs. It can also affect compilation and build times for the
project, as dead code will still be compiled and built even if it is never used. In some cases it
may also affect runtime performance - for example, fields that are written to but never read from,
where the value written to the field is expensive to compute. Removing dead code should not
change the meaning of the program.
</p>
</fragment>
</qhelp>

View File

@@ -0,0 +1,23 @@
public enum Result {
SUCCESS,
FAILURE,
ERROR
}
public Result runOperation(String value) {
if (value == 1) {
return SUCCESS;
} else {
return FAILURE;
}
}
public static void main(String[] args) {
Result operationResult = runOperation(args[0]);
if (operationResult == Result.ERROR) {
exit(1);
} else {
exit(0);
}
}

View File

@@ -0,0 +1,55 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Enum constants that are never used at runtime are redundant and should be removed.
</p>
<include src="DeadCodeSummary.qhelp"/>
<p>
An enum constant is considered dead if at runtime it is never used, or only used in comparisons. Any
enum constant which is not dead is considered to be "live".
</p>
<p>
An enum constant that is only used in a comparison is considered dead because the comparison will
always produce the same result. This is because no variable holds the value of the enum constant,
so the comparison of any variable against the constant will always return the same result.
</p>
<include src="DeadCodeDetails.qhelp"/>
</overview>
<recommendation>
<p>
Before making any changes, confirm that the enum constant is not required by verifying that the
enum constant is never used. 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 enum constant 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 enum constant is not required, remove the enum constant. You will also
need to remove any references to this enum constant, which may, in turn, require removing other dead
code.
</p>
<include src="DeadCodeExtraEntryPoints.qhelp"/>
</recommendation>
<example>
<p>
In the following example, we have an enum class called <code>Result</code>, intended to report the
result of some operation:
</p>
<sample src="DeadEnumConstant.java" />
<p>
The method <code>runOperation</code> performs some operation, and returns a <code>Result</code>
depending on whether the operation succeeded. However, it only returns either <code>SUCCESS</code>
or <code>FAILURE</code>, and never <code>ERROR</code>. The <code>main</code> method calls
<code>runOperation</code>, and checks whether the returned result is the <code>ERROR</code>.
However, this check will always return the same result - <code>false</code>. This is because the
<code>operationResult</code> can never hold <code>ERROR</code>, because <code>ERROR</code> is never
stored or returned anywhere in the program. Therefore, <code>ERROR</code> is dead and can be removed,
along with the comparison check, and the <code>exit(1);</code>.
</p>
</example>
<include src="DeadCodeReferences.qhelp" />
</qhelp>

View File

@@ -0,0 +1,18 @@
/**
* @name Dead enum constant
* @description Dead enum constants add unnecessary complexity.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @id java/dead-enum-constant
* @tags maintainability
* useless-code
* external/cwe/cwe-561
*/
import java
import semmle.code.java.deadcode.DeadCode
from UnusedEnumConstant e
where not e.whitelisted()
select e, e.getName() + " is unused -- its value is never obtained."

View File

@@ -0,0 +1,7 @@
public class FieldOnlyRead {
private int deadField;
private int getDeadField() {
return deadField;
}
}

View File

@@ -0,0 +1,68 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Fields that are never read at runtime are unnecessary and should be removed.
</p>
<include src="DeadCodeSummary.qhelp"/>
<p>
Fields are considered dead if at runtime they are never read directly or indirectly, for example
through a framework or a use of reflection. Any field which is not dead is considered to be "live".
</p>
<p>
Fields are considered to be dead if they are only written to, and never read.
</p>
<include src="DeadCodeDetails.qhelp"/>
</overview>
<recommendation>
<p>
Before making any changes, confirm that the field is not required by verifying that the field is
only read from dead 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 field 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 field is not required, remove the field. You will also need to remove any
references to this field, which may, in turn, require removing other unused classes, methods
and fields.
</p>
<include src="DeadCodeExtraEntryPoints.qhelp"/>
</recommendation>
<section title="Example 1">
<p>
In the following example, we have a class containing a single field called <code>deadField</code>:
</p>
<sample src="DeadField.java" />
<p>
The field is only read from the method <code>getDeadField</code>. However, <code>getDeadField</code>
is never called, so the field is never read at runtime. The field is therefore marked as dead.
</p>
</section>
<section title="Example 2">
<p>
In this example, we have another class containing a single field called <code>writtenToField</code>:
</p>
<sample src="DeadFieldWrittenTo.java" />
<p>
The field is written to in the method <code>runThing</code>, which is live because it is called by
the <code>main</code> method. However, the field is never read at runtime, only written to. The
field is therefore marked as dead.
</p>
</section>
<section title="Example 3">
<p>
In this example, we have a class representing something that can be serialized to and from XML:
</p>
<sample src="DeadFieldSerialized.java" />
<p>
The field <code>field</code> is written and read by the serialization framework in order to store
the contents of the object in an XML file, or to construct an instance of the object from an XML
file. The field is therefore considered to be read at runtime, which makes the field live.
</p>
</section>
<include src="DeadCodeReferences.qhelp" />
</qhelp>

View File

@@ -0,0 +1,31 @@
/**
* @name Dead field
* @description Fields that are never read are likely unnecessary.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @id java/dead-field
* @tags maintainability
* useless-code
* external/cwe/cwe-561
*/
import java
import semmle.code.java.deadcode.DeadCode
from DeadField f, Element origin, string reason
where
not f.isInDeadScope() and
if exists(FieldRead read | read = f.getAnAccess()) then (
if exists(DeadRoot root | root = getADeadRoot(f.getAnAccess().(FieldRead).getEnclosingCallable())) then (
origin = getADeadRoot(f.getAnAccess().(FieldRead).getEnclosingCallable()) and
reason = " is only read from dead code originating at $@."
) else (
origin = f and
reason = " is only read from a dead-code cycle."
)
) else (
origin = f and
reason = " is entirely unread."
)
select f, "The field " + f.getName() + reason, origin, origin.getName()

View File

@@ -0,0 +1,9 @@
@XmlRootElement
public class SerializableClass {
@XmlAttribute
private String field;
public void setField(String field) {
this.field = field;
}
}

View File

@@ -0,0 +1,12 @@
public class FieldOnlyRead {
private int writtenToField;
public void runThing() {
writtenToField = 2;
callOtherThing();
}
public static main(String[] args) {
runThing();
}
}

View File

@@ -0,0 +1,23 @@
public static void main(String[] args) {
// Only call the live method
liveMethod();
}
/** This method is live because it is called by main(..) */
public static void liveMethod() {
otherLiveMethod()
}
/** This method is live because it is called by a live method */
public static void otherLiveMethod() {
}
/** This method is dead because it is never called */
public static void deadMethod() {
otherDeadMethod();
}
/** This method is dead because it is only called by dead methods */
public static void otherDeadMethod() {
}

View File

@@ -0,0 +1,81 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Methods that are never called at runtime are redundant and should be removed.
</p>
<include src="DeadCodeSummary.qhelp"/>
<p>
Methods are considered dead if at runtime they are never called, either directly, by a method call,
or indirectly, through a framework or use of reflection. Any method which is not dead is considered
to be "live".
</p>
<p>
The results can include methods, constructors and initializers. Initializers come in two forms,
instance initializers and static initializers. For each class there will be at most one dead
initializer of each type, representing all the initialization of that type in the class.
</p>
<include src="DeadCodeDetails.qhelp"/>
</overview>
<recommendation>
<p>
Before making any changes, confirm that the method is not required by verifying that the only
dependencies on the method are from other dead 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 method 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 method is not required, remove the method. You will also need to remove
any references to this method, which may, in turn, require removing other unused classes, methods
and fields (see Example 1).
</p>
<p>
If the result is a static initializer, then all <code>static { ... }</code> blocks and
initializers on static fields are dead within that class. In addition, the lack of static
initialization implies that all static methods and fields are also dead and can be removed. These
methods and fields will also be reported separately. In contrast, static nested classes may still
be live, because constructing or accessing the nested static class does not trigger static
initialization of the outer class.
</p>
<p>
If the result is an instance initializer, then all instance initializer <code>{ ... }</code> blocks
and initializers on instance fields are dead. In addition, the lack of instance initialization
implies that the class is never constructed, which means that all instance methods and fields are
also dead and can be removed. These methods and fields will also be reported separately.
</p>
<include src="DeadCodeExtraEntryPoints.qhelp"/>
</recommendation>
<section title="Example 1">
<p>
In the following example, we have a number of methods, and an "entry point" in the form of a main
method.
</p>
<sample src="DeadMethod.java" />
<p>
The method <code>liveMethod</code> is called from the main method, and is therefore considered live.
<code>liveMethod</code> calls <code>otherLiveMethod</code>, which also makes that live.
</p>
<p>
In contrast, <code>deadMethod</code> is never called, and does not represent an entry point, so is
marked as dead. Likewise, <code>otherDeadMethod</code> is only called from the
<code>deadMethod</code>, so is also marked as dead.
</p>
</section>
<section title="Example 2">
<p>
In this example, we have a test class containing a number of methods.
</p>
<sample src="DeadMethodTest.java" />
<p>
In this case, no methods are called directly. However, the annotations on the methods indicate that
this is a test class - specifically, JUnit - and that the methods will be called by the test
framework when running the tests. <code>testCustomer</code> and <code>setUp</code> are therefore
considered to be "live".
</p>
</section>
<include src="DeadCodeReferences.qhelp" />
</qhelp>

View File

@@ -0,0 +1,33 @@
/**
* @name Dead method
* @description Dead methods add unnecessary complexity.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @id java/dead-function
* @tags maintainability
* useless-code
* external/cwe/cwe-561
*/
import java
import semmle.code.java.deadcode.DeadCode
from DeadMethod c, Callable origin, string reason
where
not c.isInDeadScope() and
if exists(DeadRoot deadRoot | deadRoot = getADeadRoot(c) | deadRoot.getSourceDeclaration() != c) then (
// We've found a dead root that is not this callable (or an instantiation thereof).
origin = getADeadRoot(c).getSourceDeclaration() and
reason = " is only used from dead code originating at $@."
) else (
origin = c and
if exists(Callable cause | cause = possibleLivenessCause(c) and not cause instanceof DeadRoot |
cause.getSourceDeclaration() = c implies possibleLivenessCause(cause).getSourceDeclaration() != c)
then
// There are no dead roots that are not this callable (or an instantiation thereof), and at least one
// liveness cause (ignoring trivial cycles between a parameterized callable and its source declaration).
reason = " is only used from, or in, a dead-code cycle."
else
reason = " is entirely unused."
)
select c, "The method " + c.getName() + reason, origin, origin.getName()

View File

@@ -0,0 +1,12 @@
public class TestClass {
@Before
public void setUp() {
// ...
}
@Test
public void testCustomer() {
// ...
}
}

View File

@@ -0,0 +1,17 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<include src="DeadCodeSummary.qhelp"/>
<include src="DeadCodeDetails.qhelp"/>
</overview>
<recommendation>
<p>
Any code that is marked as dead should be reviewed and, if it is genuinely not used, deleted. You
can see which classes, methods and fields contribute to this metric using the rules for Dead Code
analysis.
</p>
</recommendation>
<include src="DeadCodeReferences.qhelp" />
</qhelp>

View File

@@ -0,0 +1,50 @@
/**
* @name Lines of dead code in files
* @description The number of lines of dead code in a file.
* @kind treemap
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @id java/lines-of-dead-code
* @tags maintainability
* external/cwe/cwe-561
*/
import java
import semmle.code.java.deadcode.DeadCode
from File f, int n
where
n =
// Lines of code contributed by dead classes.
sum(DeadClass deadClass | deadClass.getFile() = f |
deadClass.getNumberOfLinesOfCode() -
/*
* Remove inner and local classes, as they are reported as separate dead classes. Do not
* remove anonymous classes, because they aren't reported separately.
*/
sum(NestedClass innerClass | innerClass.getEnclosingType() = deadClass and not innerClass.isAnonymous() |
innerClass.getNumberOfLinesOfCode()
)
) +
// Lines of code contributed by dead methods, not in dead classes.
sum(DeadMethod deadMethod | deadMethod.getFile() = f and not deadMethod.isInDeadScope() |
deadMethod.getNumberOfLinesOfCode() -
/*
* Remove local classes defined in the dead method - they are reported separately as a dead
* class. We keep anonymous class counts, because anonymous classes are not reported
* separately.
*/
sum(LocalClass localClass | localClass.getLocalClassDeclStmt().getEnclosingCallable() = deadMethod |
localClass.getNumberOfLinesOfCode()
)
) +
// Lines of code contributed by dead fields, not in dead classes.
sum(DeadField deadField | deadField.getFile() = f and not deadField.isInDeadScope() |
deadField.getNumberOfLinesOfCode()
) +
// Lines of code contributed by unused enum constants.
sum(UnusedEnumConstant deadEnumConstant | deadEnumConstant.getFile() = f |
deadEnumConstant.getNumberOfLinesOfCode()
)
select f, n
order by n desc

View File

@@ -0,0 +1,25 @@
/*
* This class is dead because it is never constructed, and the instance methods are not
* called.
*/
public class CustomerActions {
public CustomerActions() {
}
// This method is never called,
public Action createAddCustomerAction () {
return new AddCustomerAction();
}
// These two are used directly
public static class AddCustomerAction extends Action { /* ... */ }
public static class RemoveCustomerAction extends Action { /* ... */ }
}
public static void main(String[] args) {
// Construct the actions directly
Action action = new CustomerActions.AddCustomerAction();
action.run();
Action action = new CustomerActions.RemoveCustomerAction();
action.run();
}

View File

@@ -0,0 +1,19 @@
// This class is now live - it is used as a namespace class
public class CustomerActions {
/*
* This constructor is suppressing construction of this class, so is not considered
* dead.
*/
private CustomerActions() { }
// These two are used directly
public static class AddCustomerAction extends Action { /* ... */ }
public static class RemoveCustomerAction extends Action { /* ... */ }
}
public static void main(String[] args) {
// Construct the actions directly
Action action = new CustomerActions.AddCustomerAction();
action.run();
Action action = new CustomerActions.RemoveCustomerAction();
action.run();
}

View File

@@ -0,0 +1,3 @@
public void isAbsolutePath(String path, String name) {
return path.startsWith("/") || path.startsWith("\\");
}

View File

@@ -0,0 +1,39 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Parameters that are never read in the body of the method, and are not required due to overriding,
are useless and can be removed. Useless parameters unnecessarily complicate the interface for that
method, and cause a maintenance and development burden.
</p>
<p>
Methods with useless parameters indicate that either the method can be simplified by removing the
parameter, or that the method is not using a value it should be using. Parameters of methods that
override other methods will not be marked as useless, because they are required. Similarly,
parameters of methods that are overridden by other methods are not marked as useless if they are
used by one of the overriding methods.
</p>
</overview>
<recommendation>
<p>
The method should be inspected to determine whether the parameter should be used within the body.
If the method is overridden, also consider whether any override methods should be using the
parameter. If the parameter is not required, it should be removed.
</p>
</recommendation>
<example>
<p>
In the following example, we have a method for determining whether a <code>String</code> path
is an absolute path:
</p>
<sample src="UselessParameter.java" />
<p>
The method uses the parameter <code>path</code> to determine the return value. However, the
parameter <code>name</code> is not used within the body of the method. The parameter will be marked
as useless, and can be removed from the program.
</p>
</example>
<include src="DeadCodeReferences.qhelp" />
</qhelp>

View File

@@ -0,0 +1,16 @@
/**
* @name Useless parameter
* @description Parameters that are not used add unnecessary complexity to an interface.
* @kind problem
* @problem.severity recommendation
* @precision high
* @id java/unused-parameter
* @tags maintainability
* useless-code
* external/cwe/cwe-561
*/
import semmle.code.java.deadcode.DeadCode
from RootdefCallable c
where not c.whitelisted()
select c.unusedParameter() as p, "The parameter " + p + " is unused."