IntelliJ suppress unused warning for API methods - java

I recently switched to IntelliJ IDEA from Eclipse and I really like the inspectors and find them marking potential errors with warnings for me really useful. I ran into a problem with them that I am unable to solve:
I have some Java projects that are used as APIs in other project, therefore it contains unused methods, which are marked as such:
Unused warning
How can i suppress this for the API methods? Is there an alternative to #SuppressWarnings("unused"), since this also suppresses warnings about unused warnings inside the method and doesn't make it clear to the reader that this method is designed for API use instead of just not being used in the current project?

#Sebastian's suggestion to have your class implement an interface is probably the best way to solve this issue from a good design standpoint. But when that is impractical, there is an alternative...
The "Unused declaration" inspection allows you to configure "entry points" (i.e. a public external API) to ignore. As part of that you can configure "annotations". Anything annotated with the configured annotation is seen as an entry point.
Just configure the inspection to use an annotation that you annotate your public API methods with, either one from a library -- such as #API Guardian (used by some open source projects such as JUnit 5) -- or one you create. Using a library will of course make things easier and consistent across projects. In the below example I used a #PublicApi annotation I created. Notice the method is not highlighted as unused. But the foo String still is highlighted as unused, which is what you want:
As an alternative to opening the Settings dialog, and to limit the impact on your programming flow, you can also use a Quick Fix Intention to add the desired annotation to the "Unused Declaration" settings. After annotating with the desired annotation, place your cursor on the highlighted unused method (or class) name, and invoke the "intention actions and quick-fixes" popup via Alt+Enter or ⌘↩ (or by clicking on the light bulb icon ) and select "Suppress for methods annotated by '{annotation}':

Write an interface for your class. Methods that implement an interface method are not marked as unused. instead the unused methods from the interface are marked as unused but here you can safely use #SuppressWarnings("unused") because you do not have a method body. You could even write #SuppressWarnings("unused") above the whole interface.

In short, no and this isn't really anything to do with IntelliJ, Javac the Java compiler will produce these if you ask it to.
If your method needs this annotation, then that will be for the entire method. However if you just wish a field to be annotated, then that is possible:
#SuppressWarnings("unused")
int iii = 0;
In summary, the method annotation will cover the whole method, placing it per field or instruction will cover that single line.

intellij can do this for you.Just hit Alt+Enter on the occurance that gives you the warning. Some suggestions will pop-up one of them being remove field. there will be an arrow field at the end of the suggestion. Using your arrow keys navigate to the option and use the right arrow to bring up another menu. One of the options will be suppress this for method and suppress this for statement etc.
Suppress for statement will cause this :
//noinspection unused
int iii = 0;
However I have to urge you to heed to the warnings being provided by Intellij and not blindly suppress them.

Related

Create a Java annotation for warnings - #NonOptimal

Is there something special to the #Deprecated annotation that I cannot reproduce?
I need to create an annotation similar to #Deprecated to produce warnings in Eclipse and also at build time. When I mark a method as #Deprecated I get nice warnings. For example, if I have an old method (that I may still keep for compatibility reasons):
#Deprecated
public List<Account> getClientAccounts(final int clientId) {
// Implement search...
}
Then, if I try to use it in Eclipse I can see it strikethrough, and a yellow icon in the left bar:
Also when building I can see the:
[WARNING] app1/src/test/java/com/app1/MyApp.java: app1/src/test/java/com/app1/MyApp.java uses or overrides a deprecated API.
Now, depending on external factors I cannot control (e.g. absence of database indexes) some methods are not optimal, and I would like to clearly mark them as such... with my brand new #NonOptimal annotation. I need to add visibility to the problem. So far I have:
#Retention(RUNTIME)
#Target(METHOD)
// What else here?
public #interface NonOptimal {
}
How can I create this annotation?
I wish I could extend Deprecated, but no can do.
After reading about this quite a bit I ended up with an ugly workaround. It works, though I don't like it.
I decided to mark the bad methods with both the #Deprecated and #NonOptimal annotations. It's conceptually wrong (the methods are not actually deprecated) but it works well out of the box. No need to develop an overkill Eclipse plugin:
The #Deprecated annnotation bugs developers all around the place (in Eclipse and when building), and that's a good thing.
The #NonOptimal annotation provides details on why this is a bad method to use.
Ugly but works. As of now Eclipse does not provide any better option.
Note: to make things worse, the NonOptimal annotation does not work well in Maven when using toolchains: warnings go silent, disappear, nada... Therefore, AnnotationProcessors are kind of useless in the end.
#TheImpaler This is actually not a true answer for your problem, but some time ago I came across the Google Annotations Library (a.k.a. gag) while using Zalando's Problem API.
This library provides a great number of custom annotations that, in some cases, can be used to instrument your actual code by using a ASM and a custom java agent.
Maybe it can give you some ideas regarding your actual issue.
The project is no longer maintained but there is a fork in Github.

Checkstyle and PMD as advice only

How would i set up using pmd and checkstyle results as advice only and disable them on the build server? And would it be bad practice to do so?
Both pmd and checkstyle offer valuable advice, and i want to keep on using them.
But (here comes the but) i find that my code collects a lot of lint trying to work around some of the warnings. To name a few examples:
Test-classes contain many mockito and junit static imports, invariably i have to add #SuppressWarnings("PMD.TooManyStaticImports").
A class under test needs its fields filled with mock objects, these are not used anywhere in the test but they need to be declared and annotated with #Mock for the class under test to work correctly. Add #SuppressWarnings("PMD.UnusedPrivateField").
In test classes i will have methods for creating objects from a long list of parameters, eg: createPerson(String firstname, String lastname, int shoesize, String favouritecolor, ...). These objects are normally created from a database or XML. Add #SuppressWarnings("PMD.ParameterNumberCheck").
Sometimes my documentation will be: "This method makes sure that X in the following 3 cases: \n ...". Apparently this is not allowed as the first sentence should end with a period.
Parent class X has some field y that all its children need and use, but checkstyle won't allow it unless the field is accessed through a method (getY()). This is just unnatural, IMO.
One option would be to turn the checks causing the most nuisance off permanently, however a check may be a nuisance or very useful depending on the context.
I recognize that explicitly suppressing warnings in the code is also a way to document that only in the specific context, the check is irrelavant and annoying. It is the amount of suppresions that annoys me, almost every testclass needs suppressions, and some of the other classes need workarounds.
So would it be a solutions to generate the warings, but not allow checkstyle and pmd violations to fail te build?
Test-classes contain ...
A class under test ...
In test classes ...
It seems to me, you should suppress these checks under your test code as you don't agree with them.
This is a common occurrence, like in Checkstyle we don't document our test code but our main code documents everything. To get around this for PMD, we split our configuration between test and main. To get around this for Checkstyle utility, we suppress violations for the test directory. You can also look at the options for the Checks, and see if there is anyway to configure it to ignore your cases.
Sometimes my documentation will be: "This method makes sure that X in the following 3 cases: \n ...".
I can't say for certain since I don't know the contents of your methods, but the first sentence should be a simple explanation of what the method does and it's goal. Then you can follow it by your specific cases you mentioned. Checkstyle just requires the first sentence to end with a period, not every sentence.
Parent class X has some field y that all its children need and use, but checkstyle won't allow it unless the field is accessed through a method (getY()). This is just unnatural, IMO.
Since you completely dislike this, then just disable the check for protected fields. If you look at the documentation for VisibilityModifier, you can change protectedAllowed to true and have it ignore these specific cases.
i find that my code collects a lot of lint trying to work around some of the warnings.
To me, it just seems you are not customizing these tools to your preferences and just trying to use a default configuration.

How to fix IntelliJ IDEA method parameter auto-completion?

I am using IntelliJ IDEA 15, and I noticed that (by default) Eclipse offers a much more convenient auto-completion, when it comes to writing method calls, which require multiple parameters.
Eclipse automatically fills in default parameters and allows you to quickly navigate through them by pressing Tab:
However, IntelliJ IDEA does not handle it as conveniently and makes you write them manually:
Is there a way to make IntelliJ IDEA, handle method call auto-completion in a similar way to Eclipse's, and pre-write all the parameters for you, having you just press Tab (or another key) to navigate through them? If it is not possible in original IntelliJ, is there an add-on/plugin/external tool that will improve the intelligent code completion in such cases?
Note: I am not being lazy, it just gets quite annoying, having to manually complete each parameter and put a comma after each one, when code completion should do it for you.
IntelliJ doesn't do it and AFAIK there isn't a plugin for it.
There is no solution for you (unless you built a plugin yourself, but then you'd just have another job to maintain that plugin)
The alternative is to break the habit/need for it and use IntelliJ's Code Completion shortcuts:
Ctrl+P to view possible parameters for function.
Ctrl+Shift+Space to list the possible variables that could be entered as a parameter in the respective parameter position (based on type).
This also enters a comma if another parameter is required for the function.
Hardcoding numbers/strings as parameters to a custom function wouldn't be advisable as that negates the point of the parameters. It's better practice and more common to pass in a pre-defined variable; At which point Ctrl+Shift+Space is the easiest way for Code Completion.
This would also prevent you from closing quotations and adding commas.
Also note: IntelliSense is Microsoft's Intelligent Code Completion implementation which neither IntelliJ nor Eclipse uses.
As frant.hartm states in their answer:
Unfortunately the view of Intellij developers is that this feature would be too error prone. See this issue on youtrack.
They even state that people are welcome to make a plugin that does this.
The closest thing to this AFAIK is "method parameter completion", which allows you to auto complete parameters of current method as parameters of the inner method call at once (works for methods and constructors when calling super()).
Unfortunately the view of Intellij developers is that this feature would be too error prone. See this issue on youtrack.
IDEA doesn't fill the arguments automatically. You can use Ctrl+Shift+Space for auto-completion (completion is based on type, not name) or Ctrl+Alt+Space for suggestion. Or Ctrl+P to see what arguments are accepted.
Try
Ctrl + Space
for
Basic Code Completion
And like previously was written
Ctrl + Shift + Space
for
Type Code Completion
or try the second variant TWICE. More about Auto-Completing Code is in here

Intellij IDEA doesn't grey out some unused methods

In intellij IDEA, if a method is unused, the method is shown in a gray color. But in some cases, IDEA doesn't grey out the method, but when I check the references of those methods using alt + F7, IDEA says that the method is unused.
Is this a IDEA bug or is there any reason why IDEA wouldn't grey out these specific methods? If it is a bug, is there some workaround to make IDEA identify that method is unused?
Most likely it's not a bug, it's a limitation for performance reasons. Methods likely to take a long time when searching for usages are skipped.
A workaround is to run Unused Declaration inspection explicitly in all your project via Analyze | Inspect Code or Analyze | Run Inspection by Name. That'll take some time. You can also set up TeamCity server to do it for you automatically every night.
I used to have it working like charm, but one time, I by mistake clicked on alt+Enter on an unused method, and chose to suppress the inspection on unused code. Ever since then, I stopped getting the grayed out methods and code, so since there is a way to get it undone, there sure must be a way to get it back working.
After 5 minutes of searching, I found a solution:
Settings --> Editor --> Inspections --> Java --> Declaration Redundancy --> Unused Declaration
Make sure you check "Unused Declaration"
And I just checked by creating a new useless method, working like a charm.
My answer is quite late, but perhaps it will help others to identify their problem:
IntelliJ didn't mark methods as unused for me, because they were overloaded methods, for example:
1: methodName(String argument)
2: methodName(ArrayList<String> argument)
The first method was no longer used, but the second method was. IntelliJ (I assume) simply checks the method names, and sees that the method name is used, even though one of them is no longer used.
I have checked the other answers on this page for finding unused methods, but have not found a solution to filter out unused, overloaded methods.
It might be a bug if you're using a method with a very common name.
If you tried #Peter Gromov method above, and your method is still yellow, it might be the case that this is a bug.
I had a very common named method, named "stop".
Looking for usages (using ALT + F7) didn't show anything.
Analyzing the whole project, clearly showed that this method did not have any use.
Despite that, the method was still yellow.
I was surprised to find out, that if I try to refactor the method name, I get a pop-up warning that this will change in other places as well.
Turns out, that the refactoring warned about changing the method name in TODO comments. Somehow Lint recognized the TODO comments as using this method.
My advice is to just not name your methods as something that may be written in a TODO comment.
See this image, where I am using a method named "stop" :

Can I make a Java Annotation which "extends" #SuppressWarnings?

I know that it's not possible to extends Java annotations.
I've created an annotation for a private field which means that the field is likely to appear unused in the class in which it is declared. For this reason, I'm getting a lot of "unused field" warnings on my annotated fields.
Is there any way to give my annotation the behaviour of #SuppressWarnings("unused") so I don't have to doubly-annotate every field which has #MyAnnotation?
The quick answer is "no". Java compiler doesn't know anything about your annotation, so it won't process it the way you want.
But the honest answer is "yes". In this article you can find detailed description of how to write compiler plugin. Chances are you can write plugin, which, in case of finding your annotation, will handle it and won't pass field to unused checker.

Categories

Resources