Search

Dark theme | Light theme
Showing posts with label IntelliJ IDEA 12. Show all posts
Showing posts with label IntelliJ IDEA 12. Show all posts

May 28, 2013

Groovy Goodness: @DelegatesTo For Type Checking DSL

Groovy 2.1 introduced the @DelegatesTo annotation. With this annotation we can document a method and tell which class is responsible for executing the code we pass into the method. If we use @TypeChecked or @CompileStatic then the static type checker of the compiler will use this information to check at compile-time if the code is correct. And finally this annotation allows an IDE to give extra support like code completion.

Suppose we have the following class Reservation with the method submit(). The method accepts a closure with methods that need to be applied with the instance of the Reservation class. This is a very common pattern for writing simple DSLs in Groovy.

class Reservation {
    private Date date
    private String event
    private String attendee
    
    void date(final Date date) { this.date = date }
    void event(final String event) { this.event = event }
    void attendee(final String attendee) { this.attendee = attendee }
    
    /** Submit a reservation. 
      * @param config Configuration for reservation, invoking method class on Reservation.
      */
    static void submit(final Closure config) {
        final Reservation reservation = new Reservation()
        reservation.with config
    }

}

class Event {
    /** Use Reservation configuration DSL to submit a reservation. */
    void submitReservation() {
        Reservation.submit {
            date Date.parse('yyyyMMdd', '20130522')
            event 'Gr8Conf'
            attendee 'mrhaki'
            reserved true
        }
    }
}

final event = new Event()
event.submitReservation()

When we look at the code we might already see there is an error. In the Event.submitReservation() method we have the line reserved true, which will try to invoke the reserve() method of the Reservation class. But that method is not defined. When we run the application we get the expected error:

Exception thrown
May 28, 2013 6:58:36 AM org.codehaus.groovy.runtime.StackTraceUtils sanitize
WARNING: Sanitizing stacktrace:
groovy.lang.MissingMethodException: No signature of method: Reservation.reserved() is applicable for argument types: (java.lang.Boolean) values: [true]

To get an error for this line at compile-time we must add some annotation so the Groovy compiler can do static type checking on our code. We change the code and get the following sample:

import groovy.transform.*

class Reservation {
    private Date date
    private String event
    private String attendee
    
    void date(final Date date) { this.date = date }
    void event(final String event) { this.event = event }
    void attendee(final String attendee) { this.attendee = attendee }
    
    /** Submit a reservation. 
      * @param config Configuration for reservation, invoking method class on Reservation.
      */
    static void submit(@DelegatesTo(Reservation) final Closure config) {
        final Reservation reservation = new Reservation()
        reservation.with config
    }

}

@TypeChecked
// @CompileStatic - will also do static type checking
class Event {
    /** Use Reservation configuration DSL to submit a reservation. */
    void submitReservation() {
        Reservation.submit {
            date Date.parse('yyyyMMdd', '20130522')
            event 'Gr8Conf'
            attendee 'mrhaki'
            reserved true
        }
    }
}

final event = new Event()
event.submitReservation()

When the code is compiled we immediately get a compilation error:

1 compilation error:

[Static type checking] - Cannot find matching method Event#reserved(boolean). Please check if the declared type is right and if the method exists.
 at line: 26, column: 13

Wow, this useful! We find errors in our DSL before the code is run.

When we create this code in an IDE like IntelliJ IDEA we also get code completion in the Reservation.submit() method invocation in the Event class. The following screenshot shows code completion and a red font for reserved to indicate the compilation error.


Code written in Groovy 2.1.3

April 14, 2013

IntelliJ IDEA Knows How to Format Spock where: Blocks

IntelliJ IDEA keeps amazing me. Last week I learned the code formatter of IntelliJ IDEA 12 supports Spock specific where: block formatting. Spock has great a great feature called data tables. We can define a fixed set of data values in a table-like format where cells are separated with pipe (|) symbols. These tables are easiest to read if formatted in fixed size columns. The IntelliJ IDEA formatter will do this for us automatically.

Look at the following source code with a data table just typed with pipe symbols as separators, but not clearly formatted in fixed size columns:


If we run the code reformat command with Cmd+Alt+L (Windows/Linux: Ctrl+Alt+L) or use the menu option Code | Reformat Code... we get a dialog and select Run button to format the code:


The result is that our data table in the where: block is now correctly formatted:


Example with IntelliJ IDEA 12.1

March 24, 2013

Quick Access to VCS Operations in IntelliJ IDEA

JetBrains's IntelliJ IDEA has a lot shortcut keys to increase your development productivity. I always prefer to leave my hands on the keyboard when typing code and I want to execute an action in the IDE. If I first have to use my trackpad or mouse it slows down and stops the "flow". To access version control system (VCS) operations in IDEA we only have to type Ctrl + V (Alt + ` for Linux/Windows). IntelliJ IDEA opens a dialog window with several actions appropriate for the version control system we are using (for example Subversion or Git).


Now we only have to use the cursor keys, type the number before the action. Like in most dialog windows in IntelliJ IDEA we can start typing part of the action name and the list will only show the actions that contain the text we are typing:


Written with IntelliJ IDEA 12 on Mac OS X.

March 13, 2013

Pasting Content from Previous Copy or Paste Actions in IntelliJ IDEA

If we copy or cut a text selection in IntelliJ IDEA we can paste it directly from the clipboard with Cmd + V (Ctrl + V for Windows or Linux), just like in any other application. But we can also paste content from previous copy or cut actions. IntelliJ IDEA keeps track of our last 15 text selections that were placed on the clipboard. With the shortcut key Cmd + Shift + V (Ctrl + Shift + V for Windows or Linux) we can select an item from the clipboard buffer. IntelliJ IDEA opens a dialog window with all items in the buffer:


We can select the content we want to paste using the cursor keys, type in the number or start typing the first letters of the content. We select the OK button to paste the content in our editor:


IntelliJ IDEA 12 is used for this post.