Early Access Program

IntelliJ IDEA 2018.2 EAP3: advanced @Contract annotations and more

We’ve just finished assembling a new EAP build of IntelliJ IDEA 2018.2. You’re very welcome to download it right now!

Java

IntelliJ IDEA supports the @org.jetbrains.annotations.Contract annotation, which allows you to specify a method reaction when a particular parameter is passed. This can help with nullability analysis and some other inspections.

We’ve introduced the @Contract annotation a while ago, and we’ve been improving it ever since. We added automatic inference, and today we are ready to take it even further.

Suppose you have a utility method:

Screen Shot 2018-05-29 at 19.06.21

Then the following method does not issue a warning on string dereference:

Screen Shot 2018-05-29 at 19.31.09

The contract says that if str is null, isNotEmptyString returns false. Therefore, str.charAt(0) is not executed.

In the upcoming IntelliJ IDEA 2018.2, we’re improving the Contract language to support more return values. New values include this, new and param1/2/3/....

The contract _ -> this means that the non-static method always returns the this object (like StringBuilder.append does).

A contract like _ -> param1 means that the method always returns its first parameter (unless it throws an exception).

If a contract returns a new value, it means that the method always returns a newly allocated object. New values allow you to describe the method behavior more precisely. Imagine a coalesce method:

Screen Shot 2018-05-29 at 19.47.21

Its contract can be described as null, _ -> param2; !null, _ -> param1. This reads as “if the first parameter is null, then parameter#2 is returned; if the first parameter is not null, then parameter#1 is returned”.

It’s not always necessary to specify the contract. Sometimes (for example, in the “coalesce” example above) it can be inferred automatically for static, private, or final methods.

The contract information is available for various inspections and actions which can use it to produce better warnings or remove false-positives. For example, in the upcoming IntelliJ IDEA 2018.2, you may get a warning in the code like stringBuilder = stringBuilder.append(something); because now the IDE knows that the append method will return its qualifier, so there’s no reason to reassign the stringBuilder variable.

Similarly, the inspection Result of method call ignored will not show a warning if a pure method is known to always return its argument. Likely it’s a validation method which either throws or returns an argument for convenience, so using a return value is unnecessary.

As a result, several new kinds of bugs can now be detected. For example, if you use the coalesce method described above, the IDE is now aware that the inner condition is always false in the following code:

2018-05-29 14_25_36

Actions like Analyze dataflow from here are also aware of new contracts now. For example, consider the following class:

Screen Shot 2018-05-29 at 19.49.00
When starting dataflow analysis from the constructor parameter, you can now eventually reach the getter, as analysis knows that Objects.requireNonNull returns its argument unless it fails (its contract is "null -> fail; _ -> param1"):

image6

Speaking of our annotations, IntelliJ IDEA now provides annotations.jar as a Maven repository library. Previously, for a project that didn’t use Maven or Gradle, IntelliJ IDEA would suggest adding annotations.jar (or junit.jar) from its own installation directory.

Now, when there are some unresolved references to annotations like @NotNull or @Contract, IntelliJ IDEA will provide a quick-fix to add annotations.jar from the Maven repository. After you download this JAR for the first time, it will be stored in the local .m2/repository.

Several libraries can now be added to a project as Maven repository libraries: JUnit 3 and JUnit4, Testng, JCIP, and our own annotations library.

Jump outside closing bracket/quote with Tab

In the upcoming IntelliJ IDEA 2018.2, you will be able to navigate outside the closing brackets, or closing quotes, by pressing Tab. To customize this behavior of Tab, go to Preferences | Editor | General | Smart keys and select Jump outside closing brackets/quote with Tab. This will work in Java, Kotlin, Groovy, SQL, and Python files.

2018-05-29 17_13_42

JVM debugger

Last week we introduced breakpoint intentions, which are available via Alt+Enter. This latest build further enhances this functionality: please welcome new breakpoint intentions that allow filtering by a caller method.

Sometimes it is important to stop at a breakpoint only when a certain condition applies to the call stack. Now, if you filter a breakpoint hit by the caller method, it will stop at a breakpoint only if it’s called from the specified method. (Or, vice versa, it will not stop at a breakpoint if it’s called from that method.)

Screen Shot 2018-05-28 at 12.26.53

You can also set a caller method filter by using the Caller filters field in the Breakpoint dialog.

image5

In other news, we’ve improved our support for SVG files so that now the IDE provides completion in them. Under the hood, it reuses the SVG part of RelaxNG schema from HTML5 support. Quick Documentation Lookup is also available for SVG files now.

Screen Shot 2018-05-28 at 18.12.21

Version Control System

We’ve also improved our Git integration with a small yet very useful feature: the IDE now autocompletes tags in the Checkout dialog.

Screen Shot 2018-05-29 at 16.09.39

We’d love to hear your feedback on these cool new features! Please share your thoughts with us in the discussion forum or on Twitter. If you stumble on a bug, please report it to our issue tracker. Thanks!

Happy Developing!

image description