Better DSL Support for Groovy-Eclipse

Preview:

DESCRIPTION

Here are the slides from my presentation at GR8Conf Europe 2011. I showed Groovy-Eclipse's new DSLD feature that improved DSL support in the editor.

Citation preview

© 2011 SpringSource, A division of VMware. All rights reserved

What’s new in Groovy & Grails Support? DSL Support in Groovy-Eclipse Andrew Eisenberg, SpringSource Tools Team

© 2011 SpringSource, A division of VMware. All rights reserved

What’s new in Groovy & Grails Support?

Part 1

3 3

New Groovy-Eclipse Support in 2.5.0

  DSL Descriptors (discussed later)  Groovy 1.8   Parameter guessing content assist   Script outline view   Distinguish read vs. write access in search   Conditional breakpoints in Groovy files (STS only)

4 4

New Grails tooling support in STS 2.7.0.M1

  Service field content assist  Groovy search results in GSPs

© 2011 SpringSource, A division of VMware. All rights reserved

Gradle support in STS

Part 1.5

6 6

First cut at Gradle support now available in STS

  Demoed this morning in the Gradle talk   Yay!

© 2011 SpringSource, A division of VMware. All rights reserved

DSL Support in Groovy-Eclipse

Part 2

8 8

The Problem

9 9

A DSL for distance calculations

3.m + 2.yd + 2.mi - 1.km

In the Groovy editor:

Uh oh!

Can we do better???

10 10

The Solution: DSL Descriptors (DSLDs)

11 CONFIDENTIAL

DSL Descriptors

  Teach the IDE about DSLs through scripting

12 12

DSL Descriptors

  In English: •  “Any subtype of Number should have the following properties: m, yd, mi, km”

  In DSLD: •  “Any subtype of Number”:

currentType( subType( Number ) )!

•  “…the following properties…”: [ “m”, “yd”, “cm”, “mi”, “km” ].each {!

property name:it, type:"Distance”!

}!

3.m + 2.yd + 2.mi - 1.km

13 13

Let’s see that

  Ex 1: Distances

14 14

Anatomy of a DSLD file

15 15

DSLD and the Inferencing Engine

  Hooks into Groovy-Eclipse’s type inferencing engine •  Visit each expression AST node

• Determine type using previous expression • Move to next expression

  DSLD operates on Groovy AST Expression nodes •  Exposes Groovy AST nodes and uses Groovy API

  In the background, while typing (reconciling) org.codehaus.groovy.ast.expr.Expression!

16 16

Pointcuts and Contribution blocks

  Pointcuts: • Where to do it.

• What is the current expression? • Declaring type?

•  Enclosing class?

  Contribution blocks: • What to do

•  “Add” method

•  “Add” property •  (not at runtime, in the editor only)

class Other {! def x!}!class Foo {! def method() {! new Other().x! }!}!

17 17

What goes in a Contribution Block?

  property : “adds” a property •  arguments

•  name: “blarb” •  type: “java.lang.String” •  declaringType :”com.foo.Frumble” •  isStatic: false •  doc: “Some html” •  provider: “My DSL”

 method : “adds” a method •  all arguments above, and

•  params: [firstName:“java.lang.String”, lastName:“java.lang.String”] •  useNamedArgs: true

  name is required, others optional

(…).accept {! property name: “myName”! method name: “getMyName”!}!

18 18

Pointcuts

 currentType() : Matches on the current declaring type  enclosingClass() : Matches on the enclosing class  currentType(“com.bar.Foo”)  methods(“run”)  annotatedBy(“org.junit.runner.RunWith”)

 enclosingClass( annotatedBy(“org.junit.runner.RunWith”) ) & currentType(methods(“run”) )

19 19

Where does this pointcut match? What does it add?

(enclosingClass(annotatedBy(“org.junit.runner.RunWith”)) & currentType(methods(“run”))).accept { property name:”blarb” }!

@RunWith(Sumthin) !class Foo {! def someTest() {! print “Hello”! def x = new MyRunner()! x.blarb! }!}!

class MyRunner { def run() {…} }!

enclosed by @RunWith

has run method

blarb

Looking for an expression that:

20 20

Wait…isn’t this Aspect-Oriented Programming?

  Pointcut •  Intentionally borrowed from AOP

  AspectJ: pointcuts and advice •  operates on Java instructions at runtime

  DSLD: pointcuts and contribution blocks •  operates on AST org.codehaus.groovy.ast.expr.*!

  Join Point Model •  Join points (e.g., instructions, expressions)

• Mechanism for quantifying join points (e.g., pointcuts)

• Means of affect at a join point (e.g., advice, contribution blocks)

class Foo {! def x = {! def i = 0!

i++! }!}!

21 21

Other things to help with DSLDs

22 22

New DSLD Wizard

  File New Groovy DSL Descriptor

23 23

DSLD Preferences Page

24 24

Groovy Event Console

  Keep this open while implementing DSLDs: •  Shows exceptions

•  Pointcuts • Matches

  Find the Console here:

25 25

Groovy AST Viewer

  Exploration of AST of current Groovy file

26 26

Examples

27 27

Basic Script Ex 2: Using the DSLD wizard

28 28

Meta DSL Ex 3: DSLD script for editing DSLDs

29 29

AST Transforms Ex 3: Standard AST Transforms

30 30

SwingBuilder Ex 4: Long script, but simple to understand

31 31

Grails Constraints DSL Ex 5: encapsulate Grails domain knowledge in a script

32 32

Criteria Queries Ex 6: simple script, large effect

33 33

Griffon Ex 7: from last night

34 34

What’s next?

35 35

DSLD is not complete

 Guided by user feedback   Collaboration with library developers

• Grails, Gaelyk, Griffon, etc.

  Release standard DSLDs (AST Transforms, Builders, etc.) • With Groovy-Eclipse? • With Groovy core?

 More pointcuts • What do users need that isn’t implemented? •  regex(), instanceof(), superType(), enclosingEnum(), etc.

 What about IntelliJ’s GDSL?

36 36

Thanks!

 More information: • Google: groovy eclipse dsld

  Full documentation on Codehaus.org: •  http://docs.codehaus.org/display/GROOVY/DSL+Descriptors+for+Groovy-Eclipse

  Install from update site: •  http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.6/

 Mailing list: •  eclipse-plugin-users@codehaus.org

 Or chat with me whenever

Recommended