Proposal: External @Nullable / @NotNull annotations for third party classes

often lack of @Nullablea nd @NotNull annotations on third party classes
causes false warnings. It would be great if there was a way to supply list
of annotations commonly used methods in some sort of config file(s) and fave
Idea use it in its analysis.

For example String.trim() is not null method if I could annotate it in a
config file I would be able to get rid of several false warning.

Overtime Idea community could build a fairly comprehensive set of such
"external" annotations and share it.

Thanks

Alex


11 comments
Comment actions Permalink

That sounds indeed tasty and has been discussed here several times. The point against it is the unreliability of these annotations. Since you don't have access to third-party code, you cannot be sure that the contract won't change in the next version of the library since it is not a part of standard language. The way we wanted it to be done is through JCP and standardizing those annotations. However it hasn't been any progress made yet.

0
Comment actions Permalink

I think changes of the contract between versions is far less a problem than it might look like. Since the biggest benefit would come from being able to declare things as @Nullable this would not have any ill effect if the contract silently changed to @NotNull. On the other hand, when things silently become @Nullable in a new version, it's likely that you'll have a problem anyway. It's certainly no silver bullet, but could certainly help avoid several NPEs.

BTW: The subject of external annotations has been discussed here already: http://www.jetbrains.net/jira/browse/IDEABKL-3524#action_40611

Sascha

0
Comment actions Permalink

Sascha Weinreuter kirjoitti:

I think changes of the contract between versions is far less a problem than it might look like. Since the biggest benefit would come from being able to declare things as @Nullable this would not have any ill effect if the contract silently changed to @NotNull. On the other hand, when things silently become @Nullable in a new version, it's likely that you'll have a problem anyway. It's certainly no silver bullet, but could certainly help avoid several NPEs.

BTW: The subject of external annotations has been discussed here already: http://www.jetbrains.net/jira/browse/IDEABKL-3524#action_40611

Sascha


I think that overriding methods of third-party code should use
@ProbablyNotNull to indicate, that contract is assumed but not
quaranted. Also new inspection is needed to warn, if @NotNull is used
for those parameters as well modification to existing inspections.

- Olli -

0
Comment actions Permalink

I think it would make most sense to integrate this into a more general Design-by-Contract solution like requested here
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4449383

0
Comment actions Permalink

Hello Stephen,

SK> I think it would make most sense to integrate this into a more
SK> general Design-by-Contract solution like requested here
SK>
SK> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4449383

I think these are orthogonal issues. While it's very well possible that IDEA
will support additional annotations for Design-by-Contract support, we'll
still need a way to specify them for libraries which weren't annotated by
their authors (and there will be lots and lots of such libraries regardless
of whether the annotations JSR will be eventually passed).

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Hello Sascha,

SW> BTW: The subject of external annotations has been discussed here
SW> already:
SW> http://www.jetbrains.net/jira/browse/IDEABKL-3524#action_40611

While it's unlikely that external annotations will make it into Demetra,
here's a syntax proposal that I'd like to discuss with the community.

The external annotations are specified as real annotations on members of
an abstract Java class which is parallel to the class being annotated. The
class doesn't have any implementation.

package annotate.java.lang;

@AnnotateFor("java.lang.String")
public abstract class Annotate_String {
@NotNull abstract String trim() { }
@NotNull abstract String toUpperCase(@NotNull String locale) { }

// static methods need implementations, but they are ignored
@NotNull static String valueOf(@Nullable Object obj) { return null; }
}

Such annotation classes can be packaged into libraries which are used at
coding time but not redistributed. Quickfixes to create and update annotation
stub classes can be provided by the IDE.

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Two remarks:
- I think the added flexibility of @AnnotateFor is a Bad Thing.
Why not simply require the class stubs to have the same name as the original class
and be in package annotate.<original-package>?
- It still does not really solve the problem of different constraints in different library versions.
Only solution would be to copy the annotation library for each version, which is clumsy
if the library contains some hundreds of annotations where only four or five are really
different in between library versions.

BTW: My main interest in this topic comes from the fact that I tried to write a plugin
that does smarter completion on method parameters, e.g. when I invoke smart completion
after "JTable.setAutoResizeMode(" Idea suggests all possible integers, which isn't really
that smart after all.
Of course I would need a way to store the allowed set of values somewhere...
In the end I did not continue the plugin because I could not figure out a way to
replace/augment the code completion values.
I heard somebody mention a completion OpenAPI for Demetra. Is that already
implemented, so that I can do my "smarter completion"?

0
Comment actions Permalink

Hello Stephen,

SK> Two remarks:
SK> - I think the added flexibility of @AnnotateFor is a Bad Thing.
SK> Why not simply require the class stubs to have the same name as
SK> the original class and be in package annotate.<original-package>?

Why do you think it's a Bad Thing?

I think it's a good thing that the name of the annotation class can be different
from the name of the class being annotated, because it ensures that Ctrl-N
won't bring you to the wrong place. Also, hard-coding some package name prefix
feels uglier to me than having an annotation.

SK> - It still does not really solve the problem of different
SK> constraints in different library versions.
SK> Only solution would be to copy the annotation library for each
SK> version, which is clumsy
SK> if the library contains some hundreds of annotations where only
SK> four or five are really
SK> different in between library versions.

I don't think that a really clean solution is possible without a stable way
to identify a library version, which doesn't really exist now. One possible
solution is to have multiple sets of annotation stubs for the same class
- one for the stuff which didn't change and one for the stuff which did.

@AnnotateFor("java.lang.String") class String_JDK13 { ... }
@AnnotateFor("java.lang.String") class String_JDK15 { ... }

SK> BTW: My main interest in this topic comes from the fact that I tried
to write a plugin
SK> that does smarter completion on method parameters, e.g. when I invoke
smart completion
SK> after "JTable.setAutoResizeMode(" Idea suggests all possible integers,
which isn't really
SK> that smart after all.
SK> Of course I would need a way to store the allowed set of values somewhere...
SK> In the end I did not continue the plugin because I could not figure out
a way to
SK> replace/augment the code completion values.
SK> I heard somebody mention a completion OpenAPI for Demetra. Is that already
SK> implemented, so that I can do my "smarter completion"?

The OpenAPI for completion should allow you to do that, but unfortunately
it was cut from the Demetra release. You can try to use the closed API for
that - while we don't officially support it, there are people here who can
help. :)

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Hm, the flexibility does not really add much value.
Without the flexibility we would have enforced a convention how to store the external annotation data and everybody could rely on that. But I see the problem of having each class appear twice in ctrl-N.

Maybe it isn't such a good idea after all to use java source code with annotations for external annotations.
How about reverting to good ole xml for this.
Then provide a custom GUI to edit these XML files.

Concerning my "smart api plugin": I have revived an old thread
http://www.intellij.net/forums/thread.jspa?messageID=5145274
Maybe you could get in touch people there who can help, and ask them to have a look ;)

I was surprised myself how far I already got with the plugin. The "external annotations" (allowed param values) are read from an xml file.
Inspections are already implemented, e.g. if you have a call like
"myTable.setAutoResizeMode(3);" you are getting an inspection warning complete with quick fix "Replace with 'JTable.AUTO_RESIZE_LAST_COLUMN'".

It would be nice if any "external annotation feature" would be extendable to include more information than simple @Nullable/@NotNull.
To give you some idea, here's a snippet of the xml I currently use (I don't say this is the best or even only a very good representation of constraints):

]]>

0
Comment actions Permalink

Hello Stephen,

SK> Maybe it isn't such a good idea after all to use java source code
SK> with annotations for external annotations.
SK>
SK> How about reverting to good ole xml for this.
SK>
SK> Then provide a custom GUI to edit these XML files.

This is certainly possible, but storing the annotations as regular Java code
will let us reuse much more of the existing infrastructure, and not invent
any proprietary formats and custom editors.

SK> It would be nice if any "external annotation feature" would be
SK> extendable to include more information than simple
SK> @Nullable/@NotNull.

We definitely want to support any Java annotations, not only @Nullable/@NotNull.

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Ooooh, shiny.

--Dave Griffith

0

Please sign in to leave a comment.