Monday, June 25, 2007

Foolproof content assist for for-each

I recently figured out a strategy for guaranteeing that the Eclipse Java editor will infer the correct local variable while filling in one of the 'for' templates (for-each, for-each array, et cetera.) If it feels complicated, it's possibly because the refactoring keystrokes just aren't ingrained in your brain and your fingers.

After using the for- templates for a while you can get a feel for when Eclipse is likely to properly infer which variable over which you want to iterate. If it doesn't you can give it a great hint:

e.g.

List list = ... Map map = ... foreach{cursor}

{cursor} represents the cursor. Pressing ctrl-space, what will it infer?

The trick is to make it terribly obvious which variable you want foreach to choose for its completion. For instance, supplying a no-op statement that references an iterable object like this:
List list = ... Map<K,V> map = ... list; foreach{cursor}

will complete as
for (String string : list) { }

You can do really nice things with this like:
List list = ... Map<K,V> map = ... map.values(); foreach{cursor}

Now this doesn't *quite* infer correctly, so use Extract Local Variable (Ctrl-Shift-L) to make map.values a local variable:
List list = ...
Map map = ...

Collection values = map.values();
foreach{cursor}

which gets you
Collection values = map.values();
for (Integer integer : values) {
}

After that, use the Inline refactoring tool to inline the temporary variables.
for (Integer integer : map.values()) { }

Whee! Extract Local Variable and Inline are your friends.

No comments: