AspectJ is a language that is very close to Java, but it isn't Java. One might expect that since AspectJ is an extension of Java, Eclipse tooling for AspectJ would just be an extension of the Java Development Tools. But it's not that easy. This post describes the problems that we have faced when integrating AspectJ tooling into Eclipse, and motivates a solution that I will elaborate on in future posts.
JDT has not been engineered to be extensible, and rightly so. It is a set of tools that are finely tuned towards making the Java development experience as smooth and convenient as possible. Focusing on extensibility would be to the detriment of the JDT users who program in Java only.
However, this makes life difficult for us tool developers. Users expect high quality tooling for Java-like languages (i.e., languages that run on the JVM) because that is the bar set by JDT. Furthermore, they want tooling that integrates seamlessly with Java tooling. But, JDT won't do that! So, how can we provide good programmer experience in AJDT?
We want to make editing AspectJ look and feel as much like editing Java where it makes sense, and at the same time provide additional functionality so that the user is aware of AspectJ-specific issues. Up until AJDT 1.6.2, there have been limited options to integrate with JDT.
One example of successful integration is the AspectJEditor, which behaves mostly like JDT's CompilationUnitEditor, providing eager error detection, syntax highlighting, content assist, some refactoring support, etc.
The AspectJEditor should be a subclass of the CompilationUnitEditor, But the CompilationUnitEditor is not public API and AJDT really shouldn't be touching it. Or, at least, the responsibility is on us to maintain compatibility in future versions. In addition to using private APIs, the AspectJEditor uses some reflection to access private fields of its super class and copies some code, where reflection isn't practical. Through this combination of techniques, we have been able to largely implement JDT's behavior in AJDT. But, there is some functionality that we want AJDT to provide, but is not possible using private APIs, reflection, or code copying.
Let's take a look at the Open Type Dialog.
We would really like to see our aspect types in the standard Java Open Type Dialog. But this is unfortunately not possible. There is no API (public or private) that we can use to do this. Even the use of reflection or code copying will not help. What we really need is to gain access to JDT's Java indexer and somehow convince it to index aspect files.
This is a big problem, and one that we have run into many times during our development of AJDT. JDT is not engineered to be compatible with Java-like languages. But, tools for languages such as Groovy, Scala, and JRuby are gaining in popularity and require the same kind of JDT integration that is just not available. There is a long standing JDT bug to address this, but it does not seem like it will be fixed any time soon.
However, there is a solution! Since AJDT 1.6.2, we have been able to provide deep integration with JDT by using AspectJ on JDT itself. We are using Equinox Aspects to weave into the platform and expose functionality in a structured way through the use of Eclipse extension points. In future posts, I will describe how we have designed our JDT weaving service to expose otherwise inaccessible functionality in JDT and how this weaving service is generic enough to be used by tool developers for other languages.
You can also hear more about this at my EclipseCon talk: Aspects Everywhere: Using Equinox Aspects to Provide Language Developers with Deep Eclipse Integration.