Switching back to the DayCounter script we'll see that `daysFromNow' is highlighted now as a class property, and, moreover, it's available for completion. This works pretty like Dynamic Properties feature, but GroovyDSL scripting gives much larger freedom in defining context. For example, by script we just have written, `daysFromNow' property will be available only on top of DayCounter scripts, not in others, whereas being defined with dynamic properties it would be available in all Groovy files in project. Of course, there are various scopes to define contexts of different granularity.
More examples of GroovyDSL scripts
GroovyDSL internal language relies on the IntelliJ IDEA open API, namely the set of Program Structure Interfaces (PSI). All GroovyDSL functions and properties are nothing but wrappers around existing PSI interfaces. To get an adequate code assistance with code completion it's strongly recommended to attach openapi.jar from $IDEA_DIR/lib folder as a library to an actual project. GroovyDSL scripts will be working fine even without it being attached, but in this cases case some references in GroovyDSL scripts will be marked as possibly unresolved or untyped. In light of said above, all standard PSI methods are available in GroovyDSL as well as synthetic ones, described below.
It's important to remark, that classType is a predefined property of a closure, passes passed as a parameter to the contributor() method and it's available only inside of it, whereas fields is an invocation of the getFields() method of a PsiClass class. Here we are also using Groovy's higher-order functions to iterate by method `each' through the collection of fetched fields.
Contributors are entities which consume contexts as initialization parameters and answer to the question ``What?''. Contributors provide new properties and methods according to given contexts. We provide a set of utility methods to augment existing types with new behavior, which may be used in a contributor application as regular Groovy methods. New contributor may be defined by an invocation of a method contributor(), taking two parameters:
1. A list of contexts to be used to contribute a new behavior
2. OneZero-argument closure, taking a contexts and adding new behavior to the reference expression ``in the focus'' of a context
The core of GroovyDSL functionality is concentrated in a body of closures, passed to the contributor() method as a second parameter. All invocations of functions and properties inside of it are calls to wrappers around internal IntelliJ IDEA's PSI. There are two kinds of such wrappers. The first kind is unqualified ones, such as findClass(). The second kind is methods, added to the original PSI classes via the mix-in categories mechanism. For example, methods property is added externally by a GroovyDSL environment to the PsiClass class.
GroovyDSL was used to describe compile-time AST transformations, introduced in Groovy 1.6. All scrip files listed below are bundled into last distributions of IntelliJ IDEA 9.
Delegate transformation: delegateTransform.gdsl
Category and Mixin transformations: categoryTransform.gdsl
Newify transformation: newifyTransform.gdsl
Singleton transformation: singletonTransform.gdsl
Bindable and Vetoable transformation: bindableTransform.gdsl, vetoableTransform.gdsl