Java Forum / Tools / February 2004
Tool to find unused functions/classes
Christoph Rabel - 12 Feb 2004 01:58 GMT Hi!
I have got a rather large project recently and found several functions that are never called.
Now I would be interested in having a list of all classes/functions that are never invoked (I really dont care about reflections, I only use them with one class).
Is there a tool, that can give me such information?
thx,
Christoph
Yan Georget - 12 Feb 2004 08:05 GMT Hello,
> I have got a rather large project recently and found several > functions that are never called. [quoted text clipped - 4 lines] > > Is there a tool, that can give me such information? You can use a code coverage tool, eg Koalog Code Coverage (http://www.koalog.com/php/kover.php).
Yan Georget
Ira Baxter - 15 Feb 2004 20:52 GMT > > I have got a rather large project recently and found several > > functions that are never called. [quoted text clipped - 7 lines] > You can use a code coverage tool, eg Koalog Code Coverage > (http://www.koalog.com/php/kover.php). We offer coverage tools too, but I don't think they're the answer to your question. *If* your code actually executes a function during some run, then it will tell you that. *If* your test cases don't exercise that code, it will tell you that. It *won't* tell that your code will never be called.
We have a tool that determines, for every declaration, if that declaration is ever used (no references to its name --> not used). This tool can optionally automatically remove such declarations from the code, leaving behind squeaky clean source code.
See http://www.semanticdesigns.com/Products/index.html.
 Signature Ira D. Baxter, Ph.D., CTO 512-250-1018 Semantic Designs, Inc. www.semdesigns.com
Yan Georget - 15 Feb 2004 21:56 GMT > We have a tool that determines, for every declaration, > if that declaration is ever used (no references to its > name --> not used). // test() is a method returning a constant boolean value but you can predict // if is true or false ... // methods method1 and method2 declarations ... // some code if (test()) { method1(); } else { method2(); }
I am curious to know what your tool will predict...
Regards, Yan Georget, PhD
Chris McMahan - 16 Feb 2004 04:31 GMT Hardly seems like a reasonable requirement. That's something your tests have to determine. When you say "...but you can predict if it is true or false", you're packing a lot of assumptions onto the coverage tool. It would be nice for it to execute the code and set all of these conditions, but doesn't that go beyond the realm of coverage analysis and into the realm of regression tests?
- Chris
> > We have a tool that determines, for every declaration, > > if that declaration is ever used (no references to its [quoted text clipped - 16 lines] > Regards, > Yan Georget, PhD
 Signature (. .) =ooO=(_)=Ooo======================== Chris McMahan | cmcmahan-at-one.net ====================================
Ira Baxter - 21 Feb 2004 22:55 GMT > > We have a tool that determines, for every declaration, > > if that declaration is ever used (no references to its [quoted text clipped - 13 lines] > > I am curious to know what your tool will predict... If the problem is decide if method1() can ever be called, then in general you can't do it (Turing halting problem).
Read what I said again, carefully; it looks for declared entities with no references. (In your example, there's a reference to method1(); our tool would say (conservatively) that it is used.)
While this is a "technically easy" problem, it is still hard to locate a practical solution that works across a system of thousands of files. And I beleive this is what the OP was looking for.
-- IDB
Yan Georget - 22 Feb 2004 17:29 GMT > If the problem is decide if method1() can ever be called, > then in general you can't do it (Turing halting problem). Of course!
> Read what I said again, carefully; it looks for declared > entities with no references. > (In your example, there's a reference to method1(); our tool would > say (conservatively) that it is used.) That is what I expected. And this is why, code coverage goes further by letting you know if method1 (in this example) is called or not.
Yan Georget
Ira Baxter - 23 Feb 2004 13:47 GMT > > If the problem is decide if method1() can ever be called, > > then in general you can't do it (Turing halting problem). [quoted text clipped - 8 lines] > That is what I expected. And this is why, code coverage goes further by > letting you know if method1 (in this example) is called or not. No, it doesn't. Code Coverage tells you only that for the set of executions you have tried, that some block of code has not been executed. It cannot tell you that for all program inputs, the block of code can never be executed. That's my definition of "unused", and I think it matches what the OP was looking for.
If you delete a function from your sources based on test coverage "not executed" results, you may be setting yourself up for failure in the field. Most error handlers will fall into this category. You wouldn't remove error handling code, would you?
That said, I believe test coverage is valuable; it gives you a *hint* that the function might be "unused". But it doesn't answer the question definitively.
 Signature Ira D. Baxter, Ph.D., CTO 512-250-1018 Semantic Designs, Inc. www.semdesigns.com
Michael Amling - 16 Feb 2004 14:38 GMT >>>I have got a rather large project recently and found several >>>functions that are never called. [quoted text clipped - 20 lines] > remove such declarations from the code, leaving > behind squeaky clean source code. Does your program remove unfetched, uncalled and/or unused from the following source?
private static int unfetched=2, unused=7; private static uncalled() { ... } public static main(String[] args) { if (2+2==5) { // This boolean expression is a compile-time constant. unfetched=3; uncalled(); System.out.println(unused); } unfetched=8; }
> See http://www.semanticdesigns.com/Products/index.html. --Mike Amling
Ira Baxter - 21 Feb 2004 23:03 GMT > > We have a tool that determines, for every declaration, > > if that declaration is ever used (no references to its [quoted text clipped - 6 lines] > > private static int unfetched=2, unused=7; public static int unmentioned=3;
> private static uncalled() { > ... [quoted text clipped - 9 lines] > > > > See http://www.semanticdesigns.com/Products/index.html. It won't remove any of yours they all have a reference in the source. It will remove (the declaration that I added), unmentioned, if there are no references to it from this file or any of files in the system of designated files. This doesn't seem like much of a win, and you might argue it is trivial, but it is a requirement for FAA DO-178B certified software. What's hard here is doing full Java name and type resolution across the complete set of files (compilers do this on file at a time), and being able to reliably identify/remove the text attached to the unreferenced declaration (it may be an entire package that isn't referenced).
-- IDB
Michael Amling - 22 Feb 2004 23:56 GMT >>>We have a tool that determines, for every declaration, >>>if that declaration is ever used (no references to its [quoted text clipped - 36 lines] > to the unreferenced declaration (it may be an entire > package that isn't referenced). I'd be interested if you could remove the declarations that are referred to only from code that is compile-time unreachable, such as the three statements conditional on 2+2 equaling 5. This would allow conditional instrumentation that would vanish from production code, e.g. private static final boolean testing=false; private static void onlyfortesting() { ... } ... if (testing) { onlyfortesting(); }
Java compilers already omit the bytecodes for the unreachable statements, but do not omit the methods called only from unreachable code.
--Mike Amling
Ira Baxter - 23 Feb 2004 14:04 GMT > >>>We have a tool that determines, for every declaration, > >>>if that declaration is ever used (no references to its [quoted text clipped - 17 lines] > referred to only from code that is compile-time unreachable, such as the > three statements conditional on 2+2 equaling 5. So the basic problem is, can you determine if the predicate of a conditional is always true (false): if (p(x) { /* delete this if p is always false */ )
> This would allow conditional instrumentation that would vanish from > production code, e.g. [quoted text clipped - 9 lines] > Java compilers already omit the bytecodes for the unreachable > statements, but do not omit the methods called only from unreachable code. The tool we were talking about (removing unused declarations) doesn't do this.
However, the problem of simplifying conditionals, and deleting disabled code, can be handled (within Turing limitations and your sweat equity). DMS provides general program transformation machinery, which includes as a subset the ability to simplify expressions. Certain classes of expressions simplify "easily" (e.g., 2+2==5 can be easily simplified to false) and it is trivial to write rules that delete dead code, e.g., rule delete_useless_ifthen(p: expression, b: block): statement -> statement = " if (\p) \b " -> ";" if simplify_to_false(p). would do the trick for your first example. You still need the useless declaration removal logic, which would be triggered when the references to unfetched/uncalled/unused vanish to delete their corresponding declarations.
To handle the conditional instrumentation, you need to add constant propagation: private ... testing=false; .... if (testing) { ... } ==> private ... testing = false if (false) { ... } and then the above mechanisms can finish the job.
DMS can support constant propagation, but you need control flow analysis (we have it for Java, but not quite yet for other languages).
However, we can take advantage of the fact the *you know* what the testing flags are in your application, to write "idiomatic" transforms to do this job.
As a simple example, we can implement your removal of conditional instrumentation by merely adding the rule: rule testing_is_false():expression->expression = "testing" -> "false". under the assumption that "testing" identifier is unique across the program. This rule has the effect of propagating the "interesting" constant everywhere. Combined with delete_useless_ifthen rule above, and the delete useless declaration logic, you can get exactly what you are looking for, with darn little effort. (Two rules, both of which I've given to you!).
We've used this technique to eliminate dead configurations (as defined by preprocessor conditionals) from large C and C++ systems.
 Signature Ira D. Baxter, Ph.D., CTO 512-250-1018 Semantic Designs, Inc. www.semdesigns.com
Michael Amling - 24 Feb 2004 16:59 GMT >>>>>We have a tool that determines, for every declaration, >>>>>if that declaration is ever used (no references to its [quoted text clipped - 22 lines] > of a conditional is always true (false): > if (p(x) { /* delete this if p is always false */ ) Java has well defined criteria for determining if expressions are compile-time constants. Since the value returned by a method call is never regarded as a compile-time constant, I don't know what you're trying to depict when you use "p(x)" as your example of something that is "always false".
>> This would allow conditional instrumentation that would vanish from >>production code, e.g. [quoted text clipped - 61 lines] > We've used this technique to eliminate dead configurations (as defined by > preprocessor conditionals) from large C and C++ systems. Automatically recognizing compile-time constants, just as the Java compilers do, would be a good feature to add to DMS.
--Mike Amling
Shane Petroff - 12 Feb 2004 18:45 GMT > Is there a tool, that can give me such information? Among it's many other excellent features, IntelliJ IDEA includes code inspections. They highlight unused declarations and numerous other problems. Of course this assumes you are referring to Java.
Shane
Christoph Rabel - 12 Feb 2004 20:32 GMT >> Is there a tool, that can give me such information? > > Among it's many other excellent features, IntelliJ IDEA includes code > inspections. They highlight unused declarations and numerous other > problems. Thanks, I will try it!
> Of course this assumes you are referring to Java. Yes. I thought this was implicated by posting the question to this forum, so I didn't mention it in the post.
thx,
Christoph
Yan Georget - 13 Feb 2004 07:59 GMT >> Among it's many other excellent features, IntelliJ IDEA includes code >> inspections. They highlight unused declarations and numerous other >> problems. Koalog Code Coverage does not only highlight unused declarations but all the dead code ... Moreover it does not require the source: from a jar file it can tell you that class C1 and/or method M in class C2 are not used.
Regards, Yan Georget
Christoph Rabel - 13 Feb 2004 10:49 GMT > Koalog Code Coverage does not only highlight unused declarations but all the > dead code ... > Moreover it does not require the source: from a jar file it can tell you > that class C1 and/or method M in class C2 are not used. Thanks, I will try this tool too!
Christoph
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|