What's New in IntelliJ Elixir v10.3.0

Tags

Magnifying ball held up to cityscape

IntelliJ Elixir, the Elixir plugin for JetBrains IDEs (IntelliJ IDEA, RubyMine, WebStorm, etc), version 10.3.0 has been released. Let’s see what’s new.

Type Specification in Dbgi

IntelliJ Elixir allows viewing the various chunks of .beam files. Previous versions already allowed viewing parts of the Dbgi chunk:

  • Attributes
  • Compile Options
  • Definitions

IntelliJ Elixir 10.3.0 adds Type Specifications.

Tree

As the name implies you can see the module’s @types in the Type Specifications tree.

Types

You can see how those @types are used in functions and macros by looking at the @specs.

Specs.png

You can see how those @types are used in callbacks and whether those callbacks are optional.

Callbacks Optional Callbacks

Having the Type Specifications in the chunk viewer is the start of supporting types more generally. I hope to be able to show the types for Parameter Info and Parameter Hints.

Performance Improvement

I’ve always tried to ensure that IntelliJ Elixir will work with the widest range of Elixir versions as possible. I’ve personally experienced the frustration of being stuck on old library or programming language versions at jobs before DockYard. I wanted to ensure that none of the IntelliJ Elixir users would be locked out of using it because they can’t upgrade Elixir.

To have better error handling and assistance while typing, IntelliJ Elixir implements its own lexer and parser. For the lexer and grammar to support multiple incompatible Elixir versions, the lexer rule and parser grammar are a superset of all supported Elixir versions. They choose how to behave by computing the Elixir version from the SDK’s version associated with the current file. This computed Elixir version is stored using what JetBrains’ OpenAPI calls a FilePropertyPusher, LevelPropertyPusher, which is modelled on the one used for PyCharm’s Python version detection.

LevelPropertyPusher was added in the 7.0.0 release of IntelliJ Elixir, which was released on 2017-12-15. Before 10.3.0 it was last updated in the 7.5.0 release of IntelliJ Elixir, which was released on 2018-06-03. Sometime in this period a bug was introduced.

Last week, Will Davies opened a performance issue. Gerard de Brieder, a longtime user and supporter, chimed in to say that he was also experiencing similar problems. Helpfully, Gerard included an archive of the thread dumps from IntelliJ. Building on top of IntelliJ OpenAPI allows IntelliJ Elixir to get a lot of really nice features for free an one of those features are these thread dumps. The thread dumps are generated anytime the UI is slow or locks up.

At the time I was busy finalizing my slides for my presentation at Lonestar ElixirConf, so I did some quick triaging to determine that nothing was wrong with Gerard’s SDK setup. There wasn’t so I was a little stumped without looking at the code more.

Clearing my head after the conference, I was able to look at LevelPropertyPusher in detail and determine that although it was writing to the cache, most of the helpers I wrote to read the level weren’t actually reading this cached value and instead recomputing it. Fixing LevelPropertyPusher, I was able to get a debug build out to Gerard. He confirmed the fix over a day of normal usage testing and now the fix is available to everyone.

Shallow Bugs

Looking at LevelPropertyPusher with the thread dumps, it became obvious the cache wasn’t actually being read, but it took collaboration of users and the tools to find this bug that is potentially 18 months old. It has been claimed that all bugs are shallow in open-source, but the full description is that it only applies with enough co-developers and beta-testers.

For IntelliJ Elixir I have no phone-home analytics. I depend on users being able to describe problems enough that I can reproduce them locally. For most of the prior reports of performance problems, including some in person at conference, all I could do was shrug because I couldn’t be given access to user’s private repositories to reproduce problems that only occurred with their large projects. The thread dumps were so useful to diagnosing this bug that I’ve added bug report GitHub Issue Template. that includes instructions for how to include the thread dumps. If you notice a performance issues with IntelliJ Elixir and can’t share a public reproduction repo with me on GitHub, please use the thread dumps to help me trace the problem.

Upgrade now

Some users reported to me that 6.X felt much snapper than 7.X, but 7.X added so many features, I couldn’t (until now) track down the problem. If you experienced slowdowns when going from 6.X to any of the later versions, I encourage you to update to 10.3.0 and see if you were affected by LevelPropertyPusher bug. If you still see a slow down, check your thread dumps and report them as issues. Shallow bugs are only shallow if we work together.

Installation

You can install IntelliJ Elixir v10.3.0 from inside any of the support JetBrains IDEs. I recommend using IntelliJ IDEA (Community or Ultimate) edition if you’re using umbrella projects.

DockYard is a digital product agency offering exceptional user experience, design, full stack engineering, web app development, custom software, Ember, Elixir, and Phoenix services, consulting, and training. With a nationwide staff, we’ve got consultants in key markets across the United States, including Seattle, Los Angeles, Denver, Chicago, Austin, New York, and Boston.