About

This blog is about a Google Summer of Code project that aims to improve EclipseFP, the Haskell plugin for Eclipse. Read more about the blog, the author and the project in a series of three introductional posts.

New post, new theme! With this wider theme, the screenshots will no longer fall off the edge.

Although I did not plan to “build one to throw away”, this largely became reality nonetheless. By now I’ve done so many refactorings on the Scion client code that hardly a single line of the original remains. But I’m finally happy with the result.

The Scion client previously used its own command queue, which ensured that commands were sent to the server one after another. After some investigation, I replaced that by Eclipse’s job scheduling mechanism. With proper scheduling rules, we can keep the scheduler from running two commands simultaneously, so it is as powerful as the home-brew command queue. If one command depends on the result of another, we can make the second job fall asleep and have the first wake the second up when it’s done. And it has several advantages over the old system:

We can now set priorities on commands, so that interactive commands (such as computing the text of a tool tip) take precedence over longer-running commands (such as builds).

Commands will automatically be shown in the progress report windows.

The sender of a command can either run it asynchronously, or wait for the command to complete before continuing.

Of course, it’s simply less code to maintain and have bugs in!

Secondly, I introduced a Scion “manager” class that ensures that there is always one Scion server running per project. If the server crashes, it is restarted automatically and brought back to the same state as its previous incarnation.

Thirdly, all significant errors are now logged to the Error Log window in Eclipse. There should no longer be a need to turn on error tracing to troubleshoot problems in the Scion client/server system.

Finally, if the server fails to start in the first place, this is probably because its executable program could not be found. Most likely this is because the plugin is used for the first time. Therefore, we pop up a helpful dialog:

Little things like this go a long way, making it easier to get up to speed with EclipseFP. In the same vein, I will start working on a “new project from existing source” feature that is well known from Java development in Eclipse. (EclipseFP is already able to import Cabal packages from a .tar.gz, but strangely not from a directory on disk!)

It may seem that progress on this project has been quite slow during the last few weeks. Partly, this is because progress has been quite slow during the last few weeks. Writing a lot of self-contained code is easy, but as soon as I have to interface with the Eclipse API, each line of code can easily take an hour of poking around in documentation. Another reason for the lack of visible progress is that I’ve spent a few days refactoring and reorganizing the preference pages for EclipseFP. However, these changes aren’t ready yet and are currently parked away in a branch. But I decided not to let work “under the hood” keep me from posting updates!

Nominolo (my mentor, and the author of Scion) and I decided that it was no good to have the Scion server speak different protocols for each type of client that it serves. There were already separate Emacs and vim protocols, each with a different set of accessible commands, and adding and maintaining additional protocols would quickly grow unwieldy.

We therefore settled on one, and only one, protocol that is easy to parse from nearly every language: JSON. As simple as possible, but not any simpler. I threw away my hacked Lisp parser and implemented the JSON-based protocol in EclipseFP.

There are several options for JSON parsing from Java. Two feasible ones referenced from the JSON homepage are org.json (or whatever its name is) and json-simple. org.json uses specialized objects to represent the different JSON types, whereas json-simple uses standard Java classes. Although this sounds simple and elegant indeed, I abandoned json-simple because it does not employ generics, and therefore still requires many typecasts. In fact, neither of the two libraries are very nice and type-safe (because of JSON’s dynamic nature, they cannot be!), but org.json provides many utility methods that save typing out explicit casts.

Apart from simplicity and well-definedness, JSON has another advantage over the previous protocol: it is now possible to test the Scion server through telnet.

Because of other obligations (mainly my Master’s thesis) I had a late start with this Summer of Code, but now it has really begun. Below are the first results, but first some background information.

To make Eclipse understand your Haskell source, a lot of parsing and processing code is needed. Fortunately, this code has already been written, in the form of the GHC compiler. Unfortunately, this code is written in Haskell, whereas Eclipse is written in Java. Part of the purpose of Scion is to overcome this problem. On one side, it communicates with the GHC API; on the other side, it communicates with whatever program is interested. This used to mean Emacs only, but now it also includes Eclipse!

There are essentially two ways to make Scion communicate with a non-Haskell program. One is through an intermediary C program. Haskell can call into C using FFI, and Java can call into C using JNI, so this is technically possible. However, it would be very painful and cumbersome.

The alternative is to communicate through some kind of intermediary format that is sent over a stream (say, a pipe or a socket). This is how Scion’s current Emacs frontend is implemented. When needed, Emacs launches a separate process (scion_server) that listens on a local TCP socket. Emacs connects to the socket and sends a command; the server responds in a similar, Lisp-like format. (In fact, the returned value is sent straight into the Lisp interpreter.)

To do a similar thing with Eclipse, I could either make the server speak another language that is easily parsed from Java (XML-RPC comes to mind), or make Eclipse parse the Lisp code. To get quick results, my mentor nominolo and I chose the latter route, so I hacked together some code to parse a small number of specific responses. The full Lisp parser will have to wait a day or two.

Add some code to start the server, connect to its socket, send and receive commands, and we’re all set. The screenshot below shows one of the many things that are now within reach: automatic type inference, in a tooltip, straight from Eclipse!

The current code is still full of TODO comments, lousy error handling and hard-coded configuration, but it works. At the moment it is necessary to save the file before the type information gets updated, but I hope that it will be possible to send changes to the server incrementally.

Over the next few days, I will replace my quick hacks by something better, improve the error handling, and make the whole thing more robust. And I should also really, really do something about the hard-coded absolute path that points to the Scion server in my home directory…