Wednesday, March 21, 2012

Contributing a quick fix and a quick assist for Java code

JDT offers a large number of quick fixes and quick assists for Java code. However, you may want to implement your own as well, and it is actually quite easy to do so with the help of org.eclipse.jdt.ui.quickFixProcessors and org.eclipse.jdt.ui.quickAssistProcessors extension points.

Using the extension points
To create a new extension for the extension points you need to first provide the required extensions in the plugin.xml. For example, JDT defines the following processors

 <extension
       point="org.eclipse.jdt.ui.quickFixProcessors">
    <quickFixProcessor
          name="%defaultQuickFixProcessor"
          class="org.eclipse.jdt.internal.ui.text.correction.QuickFixProcessor"
          id="org.eclipse.jdt.ui.text.correction.QuickFixProcessor">
    </quickFixProcessor>
 </extension>
   
 <extension
       point="org.eclipse.jdt.ui.quickAssistProcessors">
    <quickAssistProcessor
          name="%defaultQuickAssistProcessor"
          class="org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor"
          id="org.eclipse.jdt.ui.text.correction.QuickAssistProcessor">
    </quickAssistProcessor>
 </extension>

For a description of the individual attributes, please refer to the extension point documentation.

Contributing a quick fix and a quick assist
To contribute a quick fix, you need to create the class that implements the org.eclipse.jdt.ui.text.java.IQuickFixProcessor interface. This is the same class that you specified in the extension declaration. Each Java problem has a unique id which is defined in org.eclipse.jdt.core.compiler.IProblem interface. For a particular Java problem you may offer one or more correction proposals.

To contribute a quick assist, you need to create the class that implements the org.eclipse.jdt.ui.text.java.IQuickAssistProcessor interface. Again, this is the same class that you specified in the extension declaration.

Supplying the right IJavaCompletionProposal
JDT provides the following default implementations for correction proposals that can be used to contribute quick fixes and quick assists.
  • org.eclipse.jdt.ui.text.java.correction.ChangeCorrectionProposal
  • org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal
  • org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal
Typically you will use an org.eclipse.jdt.core.dom.rewrite.ASTRewrite, in that case you should create an ASTRewriteCorrectionProposal. However, if as a result of a quick assist you want to start an action e.g. open a wizard, you should create a ChangeCorrectionProposal and override its apply(IDocument) method.

Note: These default implementations became API only in 3.8/4.2 (Juno) M6.

Manipulating Java code via ASTRewrite
Using ASTRewrite is simple enough, you can read more about AST and ASTRewrite in this Eclipse Corner Article and in this EclipseCon tutorial (slides 44-46). However, sometimes you may not know which AST nodes need to be modified and to what. ASTView plugin helps you visualize the AST of a Java source file, and is really helpful in identifying what modifications need to be done in the AST.

Friday, March 16, 2012

JDT 3.8/4.2 M6 - New and Noteworthy

M6 was a long milestone - there was one extra week of development - and hence we could do a little bit more.  There are quite a few new features and a few API additions as well.

JDT always provided extension points to contribute Quick Fixes/Assists. However, it was hard for contributors to supply the right IJavaCompletionProposal required by IQuickFixProcessor and IQuickAssistProcessor interfaces. This has been improved as JDT now provides the following default implementations for correction proposals

  • org.eclipse.jdt.ui.text.java.correction.ChangeCorrectionProposal
  • org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal
  • org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal

This makes it easier to implement quick fixes/assists that operate on .java files and use an ASTRewrite. Of course you could always use the internal implementations, but then your code would be littered with forbidden access warnings and the implementations could change any time :)

The bracket matching support in Java Editor has been improved, and among other things it now supports highlighting of enclosing brackets.
This can be configured on the Java > Editor preference page.


While the feature is visible in Java editor, the infrastructure is in Platform/Text. Hence, if anyone wishes to add the same functionality to other editors they can make use of the following types
  • org.eclipse.jface.text.source.DefaultCharacterPairMatcher
  • org.eclipse.jface.text.source.MatchingCharacterPainter

Marcel Bruch, of Code Recommenders fame, added the concept of sorting to the content assist framework by adding several new APIs on the content assistant and the processor - see org.eclipse.jface.text.contentassist.ICompletionProposalSorter. Thanks Marcel, and hope to see more contributions from you in future! :-)

There are a few more interesting items, like Selectively ignore errors/warnings from source folders and
Null analysis treats org.eclipse.core.runtime.Assert like Java assert. You can read the complete list here.

As always, feedback is greatly appreciated especially in the form of bug reports!