Code Completion - Phase One
The initial code completion support for GroovyEclipse is complete. As you may have inferred from the banners, this work was made possible by Jay Zimmerman of No Fluff Just Stuff.com - a big thank you to Jay for this short cut to code completion.
I am quite pleased with the result as the available completions exceed what was proposed. It was a case of do more now to do less later. Many classes can be reused in future GroovyEclipse features.
If you can't wait you try things out, the update site for the stable development version is at: http://dist.codehaus.org/groovy/distributions/updateDev/
The following code completions are available:
- complete a local variable
- complete a field
- complete a property
- complete a class name
- complete property expressions, i.e. after the '.'
- complete the default Groovy methods.
- complete category methods inside of 'use' blocks
- 'override method' code assist
- Completions for dynamic methods and properties via an extension point for adding type information - think completion for the very dynamic Grails.
And the best part - type inference! Duck typed variables, fields and return types of methods have their types inferred for simple expressions. Method parameter types are not inferred at this time. Types are inferred on the fly as needed. It would be nice to cache certain results, but this will only happen once GroovyEclipse has a model of the various classes, methods and fields.
The initial scope of the project was to have simple completions e.g. myObject.some_ where the underscore indicates the completion request. With a proper type evaluator more complex completions and inferences would be possible for free. So with a little more work, completions like myObject.doit()[0]._ are possible.
Does it work? As more and more completions were implemented, I started using Groovy to implement any new classes. How many Eclipse based IDEs can say they are implemented in their own language? Well, Java - any more? Proof that Groovy and Java play nicely together.
From now on Java will be used mostly when adding to existing Java code or when performance requires it. Groovy is just too good not to use, especially in the future - maintaining 'pseudo code' is far more fun.
How does this code affect the future?
- There is now a place to start adding inline help.
- Code navigation - many classes used in completion are reusable here. I also get to gleefully destroy the current code which I created during early morning hacking while too tired. I am looking forward to that.
- Hovers with inferred types.
- So much more ...
There are some things to be aware of:
- GroovyEclipse underwent some major changes. Some were to do with packaging - GroovyEclipse is no longer a monolith but a set of plug-ins. Others in core implementation - the building of Groovy source files was rewritten. This squashed many bugs, however there may be some new ones to squash.
- When things don't seem to work, pause a little before asking for a completion. The compiler is not yet incremental, so sometimes it has to catch up to your typing.
- Error recovery handles the case of a dangling '.'. Fix other errors so that a correct AST can be created and then continue coding.
- If you still see problems, please direct them to the eclipse-plugin-dev list on Codehaus.
Well, that's it - an announcement on the groovy user list is imminent. Install, dig in, read some GroovyEclipse docs in Eclipse help.
Info about the completions are available in previous posts:
http://www.rippleinteractive.com/blog/2007/03/07.html
http://www.rippleinteractive.com/blog/2007/03/20.html
http://www.rippleinteractive.com/blog/2007/04/04.html
Any feedback is very welcome at this stage to help polish things.
Dynamic GroovyEclipse
Extending the IDE for dynamic methods and properties
Before I begin it is important to say:
This is just a demo!
GroovyEclipse can be made aware of dynamic methods and properties by extending the extension point org.codehaus.groovy.eclipse.types. Documentation for the extension point is available in the soon to be released GroovyEclipse 1.0.1.
By implementing this extension point, the types of these dynamic features are integrated into GroovyEclipse. This is important for various reasons:
- Large projects will likely inject dynamic types into certain objects. A developer will want code completion for these objects.
- Frameworks will likely do the same, Grails being a prime example where dynamic types are injected in many ways. A developer will want completion for say domain object 'find' methods.
- Completion is just a side effect of having access to the actual types of methods and properties, whether explicitly defined or dynamic. Types are at the top of the pyramid. Just below is type inference. These two layers are the enablers for completion, code browsing, refactoring, and who knows what other kinds of features.
For a quick demo I implemented basic completion for findBy* and findAll* methods for Grails domain objects. Here are two domain classes:

Now in a controller class we get completion for findBy* and one domain class property:

Yes it is only a demo - findByHasMany is incorrect.
Since it is all about the types and not completion specific, the type inference engine resolves the domain object type needed to create a completion list:

Completion is a little enthusiastic showing both the field and the property - another thing to do ...
This next example shows a trick - the findAll* methods return a java.util.List but if we fake it and claim an array is returned, then completions work on the array elements:


Being a trick is breaks the default Groovy method completions for java.util.List. In the future when parameterized type signatures are supported, no tricks will be needed.
The code for the above can be found in the GrailsEclipse repository. And remember - it's only a demo! Perhaps someone wants to flesh it out?
The next step in my code completion quest is completion inside of builders. I have just started thinking about it, but in essence a builder describes a tree of nodes. So given a way to describe this tree for the various Groovy builders, we suddenly have completions inside custom builders. Personally, I would love to have SwingBuilder and AntBuilder completions. And then there are the various builders within Grails - what fun!
Crazy Sensible Smalltalk
Recently I've had the good fortune to be exposed to Blain Buxton, a long time Smalltalker. Initial exposure to Smalltalkers can be rather confusing. At first you think you understand them, after all they are speaking of an object oriented language. Then utter confusion, they are not talking about a language so much as a whole world. Stange talk of 'messages' and 'images' and crazy talk of changing objects on the fly without restarting anything. In fact, not even having the concept of an application to restart. Not saving files. Files? They don't even exist!
A whole parallel computing universe that I, having been on a C/C++/Java path, would not have been exposed to. After some digging and reading, and after a nice demonstration using Squeak, I am starting to understand things and want to be in this lively Smalltalk world. I also see how terminology has been misused. The very word 'method' is too often spoken of as something 'like a function but in an object'. Odd that the meaning could become so twisted: method, aka, process, plan, system, strategy ... algorithm! The misused phrase 'calling a method' when it really is 'executing a method'. Small and perhaps trivial things to some, but for me, my perception has changed. How nice after years of programming to have a few small ideas force a huge paradigm shift.
A while back when I used Python, the dynamic nature was very nice. And now that I am enjoying Groovy, I am enjoying crafting code more than ever. But the feeling that something is missing has always been with me. I created various hacks to auto reload code as I created it. I even started on a hack to have a magic metaclass reload objects on the fly. But hacks are hacks. Not matter what the hack is, the environment is still dead. And when debugging Groovy, it is rare when I can get away with changing a bit of code without having to restart my application. Countless hours and days lost due to restarting applications and having to get back in the flow of things.
What to do? For one learn more - Design Principles Behind Smalltalk is a very easy but thought provoking read. What else is to be done? Well, Java is now open source ... anyone for hacking 250k lines of C++ ?