- FAQ 319: What is eScript?
- FAQ 320: Language integration phase 1: How do I compile and build programs?
- FAQ 321: How do I load source files edited outside Eclipse?
- FAQ 322: How do I run an external builder on my source files?
- FAQ 323: How do I implement a compiler that runs inside Eclipse?
- FAQ 324: How do I react to changes in source files?
- FAQ 325: How do I implement an Eclipse builder?
- FAQ 326: Where are project build specifications stored?
- FAQ 327: How do I add a builder to a given project?
- FAQ 328: How do I implement an incremental project builder?
- FAQ 329: How do I handle setup problems for a given builder?
- FAQ 330: How do I make my compiler incremental?
- FAQ 331: Language integration phase 2: How do I implement a DOM?
- FAQ 332: How do I implement a DOM for my language?
- FAQ 333: How can I ensure that my model is scalable?
- FAQ 334: Language integration phase 3: How do I edit programs?
- FAQ 335: How do I write an editor for my own language?
- FAQ 336: How do I add Content Assist to my language editor?
- FAQ 337: How do I add hover support to my text editor?
- FAQ 338: How do I create problem markers for my compiler?
- FAQ 339: How do I implement Quick Fixes for my own language?
- FAQ 340: How do I support refactoring for my own language?
- FAQ 341: How do I create an Outline view for my own language editor?
- FAQ 342: Language integration phase 4: What are the finishing touches?
- FAQ 343: What wizards do I define for my own language?
- FAQ 344: When does my language need its own nature?
- FAQ 345: When does my language need its own perspective?
- FAQ 346: How do I add documentation and help for my own language?
- FAQ 347: How do I support source-level debugging for my own language?
FAQ 340: How do I support refactoring for my own language?
Refactoring is the process of restructuring code for the purpose of readability, performance improvements, reuse, or simply for the regular evolutionary quest for elegance. The kind of refactoring your language will support is heavily dependent on the nature of your language. Almost all languages provide support for expressing abstraction. Therefore, it makes most sense to focus on the processes of encapsulating certain expressions into a more abstract form, such as extracting a method, and the reverse, such as in-lining a method.
To implement refactorings, you need the UI mechanisms for implementing them. Implement a new menu with your refactoring options; use the JDT for inspiration. See the org.eclipse.jdt.ui plug-in’s manifest file and open the Refactor menu. Note how all possible refactorings are exhaustively listed here. Each refactoring can be fired by the user, and Java code will have to determine whether the refactoring is appropriate for the given selection and context. Figure 19.6 shows the refactoring menu for the Java perspective.
Figure 19.6 Refactor menu for the Java perspective
In addition to having a menu in the global menu bar, you will want to add a pop-up menu to your editor to activate a given refactoring from the current selection. Here you can be more creative and restrict the choices given to the user to relate directly to a given selection. Figure 19.7 shows the context menu for the JDT showing the refactoring options for a few selected statements.
Figure 19.7 Refactoring options for the Java editor’s context menu
Now that we have decided what UI support to provide, how do we actually implement the refactorings? As we said earlier, refactorings can be expressed as a restructuring of code. Let us think. What do we have that describes the structure of our program? Right, the DOM. In the case of JDT, all refactoring is directly expressed as operations on the Java model. The fact that an editor is open and will redraw the changes as a result is just a side-effect. Many refactorings go beyond the current text file. Imagine renaming a given method name. You will have to visit all the places where the original method is called and rename each instance accordingly. Without a model, this is very difficult to implement.
In Eclipse 3.0, the generic portions of the JDT refactoring infrastructure were pushed down into a generic IDE layer called the Eclipse Language Toolkit (LTK). The LTK projects provide a model for refactoring operations, a mechanism to allow third parties to participate in your refactorings, and some basic UI components for refactoring wizards. This infrastructure is a logical starting point for writing refactoring support for your own language.
The price of success is adoption. When you release your language plug-ins, you have to assume the worst: that people may like them. You may end up with many programmers who use them. However, these programmers are very much like you and will probably want to enhance your tools.
One of the first things people will want to do is obtain access to your DOM to do code generation, extraction, and analysis. The second thing they will want to do is provide their own refactorings and easily tie them to your existing refactorings. Prepare for this to happen and define your own extension point schema before starting to implement any refactorings. If you define all your refactorings using your own extension point schema, you will iron out the bugs, and people will be grateful once they start using your language IDE.
Note
FAQ 341 How do I create an Outline view for my own language editor?
FAQ 361 What is LTK?