[ANN] InspectionGadgets 0.0.1 released


Announcing the first, beta release of InspectionGadgets, available at http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.

The InspectionGadgets plugin extends the IDEA inspection system, providing over 140 new code inspections and interactive warnings. These inspections provide insight into the small-scale structure of your code, find (and in some cases automatically fix) bugs and code weaknesses before compilation, assist in the enforcement of coding standards, and enable more productive code reviews. These code inspections are available both in batch mode, via the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line" warnings during editing. The inspections implemented here have been chosen from popular coding standards, as well as from existing commercially available and open-source code inspection tools. It is hoped and planned that IDEA+InspectionGadgets will grow to become the most full-featured platform available for static analysis of Java and J2EE programs. Simply put, I want to kill a lot of bugs with this thing.

Inspections provided:

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit declaration)
Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

Please let me know of any problems, or ways to improve it.

42 comments
Comment actions Permalink

You're a star. Cheers for all the hard work (and obviously late nights ;) )
N.

Dave Griffith wrote:

Announcing the first, beta release of InspectionGadgets, available at
http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.

>

The InspectionGadgets plugin extends the IDEA inspection system,
providing over 140 new code inspections and interactive warnings.
These inspections provide insight into the small-scale structure of
your code, find (and in some cases automatically fix) bugs and code
weaknesses before compilation, assist in the enforcement of coding
standards, and enable more productive code reviews. These code
inspections are available both in batch mode, via the Tools/Inspect
Code... panel, and in interactive mode, as "yellow-line" warnings
during editing. The inspections implemented here have been chosen
from popular coding standards, as well as from existing commercially
available and open-source code inspection tools. It is hoped and
planned that IDEA+InspectionGadgets will grow to become the most
full-featured platform available for static analysis of Java and J2EE
programs. Simply put, I want to kill a lot of bugs with this thing.

>

Inspections provided:

>

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

>

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

>

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

>

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

>

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

>

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

>

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

>

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

>

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

>

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

>

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

>

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

>

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

>

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

>

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

>

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit
declaration)
Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

>

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

>

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

>

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

>

Please let me know of any problems, or ways to improve it.



0
Comment actions Permalink

Wow! Great work - this is fantastic!

Vil.

Dave Griffith wrote:

Announcing the first, beta release of InspectionGadgets

]]>

Please let me know of any problems, or ways to improve it.


--
Vilya Harvey
vilya.harvey@digitalsteps.com / digital steps /
(W) +44 (0)1483 469 480
(M) +44 (0)7816 678 457 http://www.digitalsteps.com/

Disclaimer

This e-mail and any attachments may be confidential and/or legally
privileged. If you have received this email and you are not a named
addressee, please inform the sender at Digital Steps Ltd by phone on
+44 (0)1483 469 480 or by reply email and then delete the email from
your system. If you are not a named addressee you must not use,
disclose, distribute, copy, print or rely on this email. Although
Digital Steps Ltd routinely screens for viruses, addressees should
check this email and any attachments for viruses. Digital Steps Ltd
makes no representation or warranty as to the absence of viruses in this
email or any attachments.

0
Comment actions Permalink

Dave Griffith wrote:

Please let me know of any problems, or ways to improve it.


Great work! I'm just beginning to use it but it seems this will be an
extremely valuable tool.

Maybe you haven't started looking at generics yet, but I'd still like to
suggest one feature I'd love to see eventually: The "Declaration of
ArrayList should probably be weakened to List" inspection does not work
for generic classes like ArrayList being weakened to List]]>.

0
Comment actions Permalink

Jonas Kvarnström wrote:

The "Declaration of
ArrayList should probably be weakened to List" inspection does not work
for generic classes like ArrayList<String> being weakened to List<String>.


And it could perhaps be applied to method return values as well as
declarations.

0
Comment actions Permalink

Recurring ClassCastException when editing a generic class (actually,
while beginning to make a non-generic class generic).

2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager -
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - IntelliJ IDEA (Aurora) Build #873
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - JDK: 1.4.2
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - VM: Java HotSpot(TM) Client VM
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - Vendor: Sun Microsystems Inc.
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - OS: Windows XP
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager - Last Action: EditorLineEnd
2003-07-25 12:45:08,656 ERROR -
intellij.plugins.PluginManager -
java.lang.ClassCastException
at com.intellij.psi.impl.bm.a(bm.java:140)
at com.intellij.psi.impl.bm.a(bm.java:377)
at com.intellij.psi.impl.source.bb.a(bb.java:14)
at com.intellij.psi.impl.source.bg.f(bg.java:38)
at com.intellij.psi.impl.source.g.a.cr.getReferenceElements(cr.java:23)
at
com.siyeh.ig.classlayout.ClassMayBeInterfaceInspection$ClassMayBeInterfaceVisitor.mayBeInterface(ClassMayBeInterfaceInspection.java:66)
at
com.siyeh.ig.classlayout.ClassMayBeInterfaceInspection$ClassMayBeInterfaceVisitor.visitClass(ClassMayBeInterfaceInspection.java:51)
at
com.intellij.psi.JavaElementVisitor.visitClassParameter(JavaElementVisitor.java:4)
at com.intellij.psi.impl.source.g.a.cq.accept(cq.java:10)
at com.siyeh.ig.ClassInspection.checkClass(ClassInspection.java:17)
at com.intellij.codeInsight.h.a.bw.a(bw.java:27)
at com.intellij.codeInsight.h.a.cn.run(cn.java:10)
at com.intellij.openapi.application.b.d.runReadAction(d.java:152)
at com.intellij.codeInsight.h.a.cy.a(cy.java:28)
at com.intellij.codeInsight.h.a.cy.a(cy.java:29)
at com.intellij.codeInsight.h.a.cm.run(cm.java)
at com.intellij.progress.c.a(c.java:35)
at com.intellij.codeInsight.h.a.cy.run(cy.java:43)

0
Comment actions Permalink

Is it possible that the inspections:
Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

can have an option on them to only highlight the hiding of fields that would
be accessible from the smae context? - e.g. I have a subclass of Component
with a method that has a parameter "width", at the moment it's highlighted,
but I don't care about this one as it's package private to Component.
However if it was hiding a local instance field then I'd care.

I'm going to have to switch that inspection off for now as it's too noisy,
but I'd like it to be there because it would be quite useful.

Cheers,
N.


0
Comment actions Permalink

Very impressive! Gongrats!

--

Best regards,
Maxim Shafirov
JetBrains, Inc / IntelliJ Software
http://www.intellij.com
"Develop with pleasure!"


"Dave Griffith" <dave.griffith@cnn.com> wrote in message
news:31013037.1059098187322.JavaMail.itn@is.intellij.net...
>

Announcing the first, beta release of InspectionGadgets, available at

http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.
>

The InspectionGadgets plugin extends the IDEA inspection system, providing

over 140 new code inspections and interactive warnings. These inspections
provide insight into the small-scale structure of your code, find (and in
some cases automatically fix) bugs and code weaknesses before compilation,
assist in the enforcement of coding standards, and enable more productive
code reviews. These code inspections are available both in batch mode, via
the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line"
warnings during editing. The inspections implemented here have been chosen
from popular coding standards, as well as from existing commercially
available and open-source code inspection tools. It is hoped and planned
that IDEA+InspectionGadgets will grow to become the most full-featured
platform available for static analysis of Java and J2EE programs. Simply
put, I want to kill a lot of bugs with this thing.
>

Inspections provided:

>

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

>

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

>

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

>

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

>

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

>

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

>

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

>

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

>

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

>

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

>

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

>

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

>

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

>

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

>

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

>

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit

declaration)

Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

>

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

>

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

>

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

>

Please let me know of any problems, or ways to improve it.

>


0
Comment actions Permalink


This is a bug. I was already filtering out "private" variables from being hidden by locals and parameters. I'll put on the list to filter out package-visible variables if they are in a different package.

Also, there's no filtering on hiding by subclass or inner class, intentionally. If you have a private instance variable which has the same name as the private instance variable of your parent, it'll be flagged. I had thought this was the desired behaviour, but am willing to take arguments on it.

Thanks!

0
Comment actions Permalink

Maxim Shafirov wrote:

Very impressive! Gongrats!


yes,great!

IDEA team,
has this bug been forgotten ?

http://www.intellij.net/tracker/idea/viewSCR?publicId=4405

(inspection marks readObjcet/writeObject as unused)

Edo

0
Comment actions Permalink

Bug report :


Foo.this is not redundant.


--

Best regards,
Maxim Shafirov
JetBrains, Inc / IntelliJ Software
http://www.intellij.com
"Develop with pleasure!"


"Dave Griffith" <dave.griffith@cnn.com> wrote in message
news:31013037.1059098187322.JavaMail.itn@is.intellij.net...
>

Announcing the first, beta release of InspectionGadgets, available at

http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.
>

The InspectionGadgets plugin extends the IDEA inspection system, providing

over 140 new code inspections and interactive warnings. These inspections
provide insight into the small-scale structure of your code, find (and in
some cases automatically fix) bugs and code weaknesses before compilation,
assist in the enforcement of coding standards, and enable more productive
code reviews. These code inspections are available both in batch mode, via
the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line"
warnings during editing. The inspections implemented here have been chosen
from popular coding standards, as well as from existing commercially
available and open-source code inspection tools. It is hoped and planned
that IDEA+InspectionGadgets will grow to become the most full-featured
platform available for static analysis of Java and J2EE programs. Simply
put, I want to kill a lot of bugs with this thing.
>

Inspections provided:

>

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

>

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

>

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

>

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

>

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

>

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

>

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

>

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

>

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

>

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

>

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

>

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

>

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

>

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

>

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

>

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit

declaration)

Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

>

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

>

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

>

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

>

Please let me know of any problems, or ways to improve it.

>


0
Comment actions Permalink

I knew there had to be some uses of "this" that I was unaware of. Should be quick to fix. Thanks.

0
Comment actions Permalink

You're quite right that I hadn't checked out any of the inspections with generics. I'll look into this one, though, since it affects collections, which is probably the first place generics will see wide use. You're also right about method returns (which'll be easy to add). Thanks.

0
Comment actions Permalink

Hmm, it won't complain about serialVersionUID being unused, though, so there's clearly some special case logic going on.

0
Comment actions Permalink

This is amazing.

One small thing (probably out of your control) - Have you looked at the
Errors IDE setting? It is huge now...

This is a layout problem that probably needs to be addressed more by
JetBrains than you.

I will probably start turning these on slowly, this kind of functionality is
great.

Amnon

"Dave Griffith" <dave.griffith@cnn.com> wrote in message
news:31013037.1059098187322.JavaMail.itn@is.intellij.net...
>

Announcing the first, beta release of InspectionGadgets, available at

http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.
>

The InspectionGadgets plugin extends the IDEA inspection system, providing

over 140 new code inspections and interactive warnings. These inspections
provide insight into the small-scale structure of your code, find (and in
some cases automatically fix) bugs and code weaknesses before compilation,
assist in the enforcement of coding standards, and enable more productive
code reviews. These code inspections are available both in batch mode, via
the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line"
warnings during editing. The inspections implemented here have been chosen
from popular coding standards, as well as from existing commercially
available and open-source code inspection tools. It is hoped and planned
that IDEA+InspectionGadgets will grow to become the most full-featured
platform available for static analysis of Java and J2EE programs. Simply
put, I want to kill a lot of bugs with this thing.
>

Inspections provided:

>

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

>

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

>

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

>

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

>

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

>

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

>

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

>

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

>

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

>

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

>

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

>

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

>

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

>

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

>

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

>

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit

declaration)

Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

>

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

>

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

>

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

>

Please let me know of any problems, or ways to improve it.

>


0
Comment actions Permalink

There is no question that the IDE Settings/Errors panel is just not set up for this sort of thing. At a minimum, it needs to have some hierarchical structure, like the Inspections panel, because an 150 element unsorted flat list just isn't going to work. Ideally, I'd love to see multiple, named configurations that you can choose between (like Code Style or Keymaps). That way you could specify different naming conventions for different projects, turn internationalization checking on or off quickly, etc.

I really should put in Tracker items for all of this...

0
Comment actions Permalink

Dave,

Thank you for this great plugin! It's very very useful.

Request. Ability to specify which inspections will be registered (or will not be registered). I'm not interested in some inspections. It will be easier to work (inspection panel, errors settings panel) with the limited set of inspections.

Bugs/Issues/Requests.

1. Not redundant parentheses:


2. Legit empty catch block (test case, try block ends with fail):


3. An option to exclude empty catch blocks with comments inside them.

4. Suggesting 'protected' constructor for non-public abstract class:


5. Legit catch generic class if a library method throws Exception (e.g. Velocity).


Timur

0
Comment actions Permalink

UI suggestion: As far as I've seen you always mark warnings
ProbelmHighlightType.LIKE_UNUSED_SYMBOL. Most of use used to this highlight
type denotes somewhat unused and having long method name highlighted the
same as unused is confusing. I'd suggest you using
ProblemHighlightType.GENERIC_ERROR_OR_WARNING which is more appropriate.

--

Best regards,
Maxim Shafirov
JetBrains, Inc / IntelliJ Software
http://www.intellij.com
"Develop with pleasure!"


"Dave Griffith" <dave.griffith@cnn.com> wrote in message
news:31013037.1059098187322.JavaMail.itn@is.intellij.net...
>

Announcing the first, beta release of InspectionGadgets, available at

http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.
>

The InspectionGadgets plugin extends the IDEA inspection system, providing

over 140 new code inspections and interactive warnings. These inspections
provide insight into the small-scale structure of your code, find (and in
some cases automatically fix) bugs and code weaknesses before compilation,
assist in the enforcement of coding standards, and enable more productive
code reviews. These code inspections are available both in batch mode, via
the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line"
warnings during editing. The inspections implemented here have been chosen
from popular coding standards, as well as from existing commercially
available and open-source code inspection tools. It is hoped and planned
that IDEA+InspectionGadgets will grow to become the most full-featured
platform available for static analysis of Java and J2EE programs. Simply
put, I want to kill a lot of bugs with this thing.
>

Inspections provided:

>

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

>

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

>

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

>

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

>

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

>

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

>

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

>

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

>

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

>

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

>

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

>

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

>

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

>

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

>

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

>

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit

declaration)

Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

>

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

>

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

>

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

>

Please let me know of any problems, or ways to improve it.

>


0
Comment actions Permalink

>1. Not redundant parentheses:

Yup, definitely a bug, and it looks like a bear to fix.

>2. Legit empty catch block (test case, try block ends with fail):

Unfortunately, I don't see any way to auto-detect this. I've implemented your suggestion (3) about optionally letting catch blocks with comments not be reported. That'll have to do, I'm afraid.

>4. Suggesting 'protected' constructor for non-public abstract class:

Maybe I'm dense, but I don't see the issue here.

>5. Legit catch generic class if a library method throws Exception (e.g. Velocity).

Uggh, I didn't realize any library vendor was cheesy enough to do this. I've got a fix for it, though.

0
Comment actions Permalink


I'll admit that I didn't give the ProblemHighlightType a whole lot of thought. You're right that it should be GENERIC_ERROR_OR_WARNING, for consistency. OTOH, the default rendering of GENERIC_ERROR_OR_WARNING is frankly horrible (which is why I didn't use it). I've remapped mine to bright yellow background, so that it fits in with the gutter bars, and looks like someone has run a highlighter over your code. I like it a lot, and some thought should be given to making that the default.

0
Comment actions Permalink

>4. Suggesting 'protected' constructor for non-public
abstract class:

Maybe I'm dense, but I don't see the issue here.


For this class:


I have the constructor is highlighted, there's a fix ("Constructor 'A' is not declared 'protected' in 'abstract' class") if "constructor not 'protected' in 'abstract' class" inspection (more precisely, error highlighting option) is enabled.


Timur

0
Comment actions Permalink


Um, yes. That's what it's supposed to do. It doesn't matter whether the class is package scope or public. If the class is abstract, this code will tell you that it's constructor can be marked protected, since it is only callable from within the constructor of a subclass. Just a small bit of extra documentation, implemented more or less because it was easy and on the tick-list of some commercial product (probably Instantiations CodePro).

Is the confusion that you view "protected" as less restrictive that "package visible", and thus I shouldn't be weakening protection. If so, we may have to agree to disagree.

0
Comment actions Permalink

Ok, then it's a request: an option not to run this inspection for non-public classes.


Timur

0
Comment actions Permalink


Cool. It's on the list.

0
Comment actions Permalink

Dave,

This is very very impressive!

A couple of issues:

1. String concatenation in loop:

String str = "";
for(int i = 0; i < 10; i++) {
str = str + 1;
if( i == 5 )
throw new RuntimeException("i = " + i);
}

The first '+' must be detected, the secord one shouldn't.

2. Small UI issue. You are using JFormattedTextField class which does
not inherit the font from the panel it is added to. I guess it is a
swing issue. Could you set its font property explicitly from the panel?

3. This might be IDEA issue:

ERROR - mand.impl.CommandProcessorImpl -
ERROR - mand.impl.CommandProcessorImpl - IntelliJ IDEA
(Aurora) B
uild #873
ERROR - mand.impl.CommandProcessorImpl - JDK: 1.4.2
ERROR - mand.impl.CommandProcessorImpl - VM: Java
HotSpot(TM) Clien
t VM
ERROR - mand.impl.CommandProcessorImpl - Vendor: Sun
Microsystems I
nc.
ERROR - mand.impl.CommandProcessorImpl - OS: Windows XP
ERROR - mand.impl.CommandProcessorImpl - Last Action:
ShowIntention
Actions
ERROR - mand.impl.CommandProcessorImpl - Current Command:
Remove un
necessary 'this.'
ERROR - mand.impl.CommandProcessorImpl -
java.lang.NullPointerException
at com.intellij.psi.impl.source.f.h.c(h.java:6)
at com.intellij.psi.impl.source.g.r.a(r.java:0)
at com.intellij.psi.impl.source.g.s.replace(s.java:83)
at
com.siyeh.ig.BaseInspection.replaceExpression(BaseInspection.java:37)

at
com.siyeh.ig.verbose.UnnecessaryThisInspection.access$200(Unnecessary
ThisInspection.java:13)
at
com.siyeh.ig.verbose.UnnecessaryThisInspection$UnnecessaryReturnFix.a
pplyFix(UnnecessaryThisInspection.java:64)
at com.intellij.codeInspection.s.bk.invoke(bk.java:10)
at com.intellij.codeInsight.intention.b.bm.run(bm.java:6)
at com.intellij.openapi.application.b.d.runWriteAction(d.java:248)
at com.intellij.codeInsight.intention.b.bl.run(bl.java)
at com.intellij.openapi.command.b.b.executeCommand(b.java:44)
at com.intellij.codeInsight.intention.b.bu.run(bu.java)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.s.a(s.java:15)
at com.intellij.ide.s.dispatchEvent(s.java:53)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

4.
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl -
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - IntelliJ IDEA (Aurora) Build #873
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - JDK: 1.4.2
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - VM: Java HotSpot(TM) Client VM
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - Vendor: Sun Microsystems Inc.
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - OS: Windows XP
2003-07-27 18:33:26,329 ERROR -
mand.impl.CommandProcessorImpl - Last Action: CloseAllEditors
2003-07-27 18:33:26,339 ERROR -
mand.impl.CommandProcessorImpl - Current Command: Apply fix
2003-07-27 18:33:26,339 ERROR -
mand.impl.CommandProcessorImpl -
java.lang.NullPointerException
at com.intellij.psi.impl.source.f.h.c(h.java:6)
at com.intellij.psi.impl.source.g.r.a(r.java:0)
at com.intellij.psi.impl.source.g.s.replace(s.java:83)
at com.siyeh.ig.BaseInspection.replaceExpression(BaseInspection.java:37)
at
com.siyeh.ig.performance.LengthOneStringsInConcatenationInspection.access$200(LengthOneStringsInConcatenationInspection.java:13)
at
com.siyeh.ig.performance.LengthOneStringsInConcatenationInspection$ReplaceStringsWithCharsFix.applyFix(LengthOneStringsInConcatenationInspection.java:75)
at com.intellij.codeInspection.s.bv.b(bv.java:37)
at com.intellij.codeInspection.s.bj.run(bj.java)
at com.intellij.openapi.application.b.d.runWriteAction(d.java:248)
at com.intellij.codeInspection.s.bi.run(bi.java:3)
at com.intellij.openapi.command.b.b.executeCommand(b.java:44)
at com.intellij.codeInspection.s.bu.a(bu.java:22)
at com.intellij.codeInspection.r.f.hyperlinkUpdate(f.java:18)
at javax.swing.JEditorPane.fireHyperlinkUpdate(Unknown Source)
at
javax.swing.text.html.HTMLEditorKit$LinkController.activateLink(Unknown
Source)
at
javax.swing.text.html.HTMLEditorKit$LinkController.mouseClicked(Unknown
Source)
at java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.s.a(s.java:15)
at com.intellij.ide.s.dispatchEvent(s.java:74)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

5. In the code like this

String str = i < 10 ? "0" + i : Integer.toString(i);

"Single character string concatenation" inspection produces non
compilable code after applying Quick fix operation.

The same with: String str = 1 + " ";

6. I think the following is IDEA issue, but I'm not sure. Sometimes I
get an exception when I click a link in the problem synopsis window.

java.lang.ClassCastException
at com.intellij.codeInspection.r.f.hyperlinkUpdate(f.java:6)
at javax.swing.JEditorPane.fireHyperlinkUpdate(Unknown Source)
at
javax.swing.text.html.HTMLEditorKit$LinkController.activateLink(Unkno
wn Source)
at
javax.swing.text.html.HTMLEditorKit$LinkController.mouseClicked(Unkno
wn Source)
at java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown
Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.s.a(s.java:15)
at com.intellij.ide.s.dispatchEvent(s.java:74)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)



/kesh

Dave Griffith wrote:

Announcing the first, beta release of InspectionGadgets, available at http://www.intellij.org/twiki/bin/view/Main/InspectionGadgets.

The InspectionGadgets plugin extends the IDEA inspection system, providing over 140 new code inspections and interactive warnings. These inspections provide insight into the small-scale structure of your code, find (and in some cases automatically fix) bugs and code weaknesses before compilation, assist in the enforcement of coding standards, and enable more productive code reviews. These code inspections are available both in batch mode, via the Tools/Inspect Code... panel, and in interactive mode, as "yellow-line" warnings during editing. The inspections implemented here have been chosen from popular coding standards, as well as from existing commercially available and open-source code inspection tools. It is hoped and planned that IDEA+InspectionGadgets will grow to become the most full-featured platform available for static analysis of Java and J2EE programs. Simply put, I want to kill a lot of bugs with this thing.

Inspections provided:

Naming conventions
Class naming convention (min. length, max. length, regex)
Interface naming convention (min. length, max. length, regex)
Instance variable naming convention (min. length, max. length, regex)
Static variable naming convention (min. length, max. length, regex)
Constant naming convention (min. length, max. length, regex)
Instance method naming convention (min. length, max. length, regex)
Static method naming convention (min. length, max. length, regex)
Local Variable naming convention (min. length, max. length, regex)
Parameter naming convention (min. length, max. length, regex)
Exception class name doesn't end with Exception
Non-exception class name ends with 'Exception'
Class name prefixed with package name
Method name same as class name
Method name same as parent class name

Probable bugs
Assignment used as condition
Statement with empty body
Covariant compareTo()
Covariant equals()
Floating point equality comparison
'compareto()' instead of 'compareTo()'
'hashcode()' instead of 'hashCode()'
Fallthrough in 'switch' statement
'switch' statement without 'default' branch
'default' not last case in 'switch'
Object comparison using ==, instead of '.equals()'(*)
String comparison using ==, instead of '.equals()'(*)
Result of InputStream.read() ignored
Loop statement that doesn't loop
Text label in 'switch' statement
Assignment to null
Octal and decimal integers in same array

Potentially confusing code constructs
Assignment to method parameter
Assignment to for-loop parameter
Nested assignment
'break' statement
'break' statement with label
'continue' statement
'continue' statement with label
Conditional expression (?:)
Nested conditional expression
Long literal ending with 'l' instead of 'L'(*)
Value of ++ or -- used
Switch statement with too many branches
Nested 'switch' statement
Chained method calls
Nested method calls

Abstraction issues
'instanceof' a concrete class
Collection declared by class, not interface
"Magic number" (i.e. numeric value used without declaration)

Class structure
Class may be interface
constructor not 'protected' in 'abstract' class(*)
Class without constructor
'final' method in 'final' class(*)
'public' constructor in non-'public' class(*)

Encapsulation issues
Public field
Package-visible field
Protected field
Return of Collection or array field
Assignment to Collection or array field from parameter

Visibility issues
Field names hides field in superclass
Inner class field hides outer class field
Parameter hides member variable
Local variable hides member variable

Finalization issues
finalize() not declared 'protected'(*)
finalize() doesn't call super.finalize()
finalize() called explicitly

Error handling
'catch' generic class
Empty 'catch' block
Empty 'finally' block
'throw' inside 'finally' block
'return' inside 'finally' block
'throw' generic class
Checked exception class
Unchecked exception class

Verbose or redundant code constructs
Redundant boolean comparison(*)
Assignment replacable with operator assignment(*)
Unnecessary 'if' statement(*)
Unnecessary parentheses(*)
Unnecessary 'this' qualifier(*)
Unnecessary interface modifier(*)
Unnecessary 'return' statement(*)
Unnecessary semicolon(*)

Code style issues
Statement bodies without {}(*)
Constant on left side of comparison(*)
Constant on right side of comparison(*)
expression.equals("literal") rather than "literal".equals(expression)
Missorted modifers(*)
C-style array declaration

Serialization issues
Serializable class without 'readObject()' and 'writeObject()'
Serializable class without serialVersionUID
'readObject()' or 'writeObject()' not declared 'private'(*)
'serialVersionUID' field not declared 'static final'(*)
'readResolve()' or 'writeReplace()' not declared 'protected'(*)

Threading issues
Double-checked locking
Call to notify() instead of notifyAll()
'wait()' not in loop
Call to Thread.run()
'synchronized' method
Synchronization on a non-final field
Nested 'synchronized' statement
Empty 'synchronized' statement

Method Metrics
Method with more than three negations
Method with multiple return points.
Method with too many parameters
Overly complex method
Overly nested method
Overly long method

Portability issues
Call to Runtime.exec()
Call to System.exit()
Call to System.getenv()
Hardcoded line separator
Hardcoded file separator
Native method

Internationalization issues
Hardcoded string literal
Character comparison
"Magic character" (i.e. character literal used without explicit declaration)
Call to Numeric .toString()
Call to Date.toString()
Call to Time.toString()
Call to String.compareTo()
Call to String.equalsIgnoreCase()
Call to String.equals()
String concatenation
Use of StringTokenizer

Performance issues
Field may be 'static'(*)
StringBuffer without initial capacity
Collection without initial capacity
String concatenation in loop
Multiply or divide by power of two(*)
Single character string concatenation(*)
Boolean constructor call(*)
Redundant String.toString()(*)
Redundant String constructor call(*)
StringBuffer.toString() in concatenation(*)
Tail recursion
Calls to System.gc() or Runtime.gc()

Code maturity issues
Use of System.out or System.err
Call to printStackTrace()

JUnit issues
Missing message on JUnit assertion
JUnit TestCase with non-trivial constructors
'setup()' instead of 'setUp()'
'teardown()' instead of 'tearDown()'
'suite()' method not declared 'static'

Please let me know of any problems, or ways to improve it.


0
Comment actions Permalink

>1. String concatenation in loop:
>The first '+' must be detected, the secord one shouldn't.

Yeah, I thought about this, but didn't see a particularly good way to auto-detect. Is is just that you're using the concatenation in an assignment? Harumph.

>2. Small UI issue.

I'm ashamed to admit it, but this is the first bit of Swing I've written for public consumptions (it's mostly been engine components and code generation the last few years). It sounds like you've got some insight as to what I should do. It'd save me some time if you'd share.

>5."Single character string concatenation" inspection produces non compilable code after applying Quick fix operation.

Yeah, I thought about this about 5 minutes after I shipped. The fix is easy.

Other misc. stack traces: Thanks, I'll look 'em over. 0.0.2 should ship by a week from Monday or so, with these fixed.

0
Comment actions Permalink

Dave Griffith wrote:

>> 1. String concatenation in loop: The first '+' must be detected,
>> the secord one shouldn't.


Yeah, I thought about this, but didn't see a particularly good way to
auto-detect. Is is just that you're using the concatenation in an
assignment? Harumph.


I'd say it's the fact that you're "modifying" a string declared outside
the loop. Or maybe the fact that you're "modifying" a string at all:
The same String variable occurs on the left-hand side and the right-hand
side of the expression. I'd probably want to detect such statements
regardless of whether they occurred in a loop or not.

0
Comment actions Permalink

Could you also make it work on collections in com.sun.java.util.collections,
we need it to be able to deploy an application that must work in IE withoug
plugins.

Thanx

"Dave Griffith" <dave.griffith@cnn.com> wrote in message
news:17790002.1059138449535.JavaMail.itn@is.intellij.net...

You're quite right that I hadn't checked out any of the inspections with

generics. I'll look into this one, though, since it affects collections,
which is probably the first place generics will see wide use. You're also
right about method returns (which'll be easy to add). Thanks.


0
Comment actions Permalink

Hey Dave how about adding a check for unconditional println statement. So it would flag the following

System.err.println("something");
System.out.println("something else");

but not flag

if(degug)
System.err.println("something");

if(someMethodThatReturnsFalsOnError())
System.err.println("blah");

try{
foo();
}
catch(Exception ex){
handleError(ex);
System.err.println("OOPS");
}

0
Comment actions Permalink

Hmm. This is certainly worth thinking about, and certainly doable, but I need convincing. The reason I included the System.out/System.err and throwStackTrace() inspections is the desire to either get rid of temporary debugging statements before ship, or replace them with more permanant and well thoughout out logging calls (usually log4J, in my case). This seems a "best practice", and doesn't really fit with your request. I would have to say that even if you do want to conditionally dump debug output to console, you're better off either going with a third-party logging framework (possibly including the one that comes with JDK1.4) or building your own trivial wrapper class on System.out and routing the calls through there. That way if you need to change your logging destination or filtering, you've got one choke-point to do it from. My inspection would help with such a change, particularly if I add the fancy auto-fix I've been thinking about. Making it conditional would sort of defeat the purpose.

0
Comment actions Permalink

Ahh, I totally missed the System.out/System.err inspection. I actually had to go look twice once I knew it was there.

Even with 3rd party logging tools do you think it would be good to look for logging that happens inside of a loop (since that can kill performance)....i'm not convinced, just kind of thinking online :)

0

Please sign in to leave a comment.