Ast transformations

2,076 views
1,968 views

Published on

Groovy AST - 18va reunion Spring Hispano

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,076
On SlideShare
0
From Embeds
0
Number of Embeds
87
Actions
Shares
0
Downloads
17
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Ast transformations

  1. 1. Groovy  AST  
  2. 2. Agenda   •  Local  ASTTransforma5ons   –  Groovy   –  Grails   –  Griffon   •  Como  funcionan?   •  Otras  formas  de  modificar  AST  
  3. 3. LISTADO  DE  TRANSFORMACIONES   DE  AST  (NO  EXHAUSTIVO)  
  4. 4. @Singleton   @Singleton class AccountManager { void process(Account account) { ... } } def account = new Account() AccountManager.instance.process(account)
  5. 5. @Delegate   class Event { @Delegate Date when String title, url } df = new SimpleDateFormat("MM/dd/yyyy") so2gx = new Event(title: "SpringOne2GX", url: "http://springone2gx.com", when: df.parse("10/19/2010")) oredev = new Event(title: "Oredev", url: "http://oredev.org", when: df.parse("11/02/2010")) assert oredev.after(so2gx.when)
  6. 6. @Immutable   @Immutable class Person { String name } def person1 = new Person("ABC") def person2 = new Person(name: "ABC") assert person1 == person2 person1.name = "Boom!” // error!
  7. 7. @Category   @Category(Integer) class Pouncer { String pounce() { (1..this).collect([]) { 'boing!' }.join(' ') } } use(Pouncer) { 3.pounce() // boing! boing! boing! }
  8. 8. @Mixin   class Pouncer { String pounce() { (1..this.times).collect([]) { 'boing!' }.join(' ') } } @Mixin(Pouncer) class Person{ int times } person1 = new Person(times: 2) person1.pounce() // boing! boing!
  9. 9. @Grab   @Grab('net.sf.json-lib:json-lib:2.3:jdk15') def builder = new net.sf.json.groovy.JsonGroovyBuilder() def books = builder.books { book(title: "Groovy in Action", name: "Dierk Koenig") } assert books.name == ["Dierk Koenig"]
  10. 10. @Log   @groovy.util.logging.Log class Person { String name void talk() { log.info("$name is talking…") } } def person = new Person(name: "Duke") person.talk() // Oct 7, 2010 10:36:09 PM sun.reflect.NativeMethodAccessorImpl invoke0 // INFO: Duke is talking…  
  11. 11. @InheritConstructors   @groovy.transform.InheritConstructors class MyException extends RuntimeException {} def x1 = new MyException("Error message") def x2 = new MyException(x1) assert x2.cause == x1
  12. 12. @Canonical   @groovy.transform.Canonical class Person { String name } def person1 = new Person("Duke") def person2 = new Person(name: "Duke") assert person1 == person2 person2.name = "Tux" assert person1 != person2
  13. 13. @Scalify   trait Output { @scala.reflect.BeanProperty var output:String = "" } @groovyx.transform.Scalify class GroovyOutput implements Output { String output }
  14. 14. @En5ty   @grails.persistence.Entity class Book { String title } def book = new Book().save() assert book.id assert book.version
  15. 15. @Bindable   @groovy.beans.Bindable class Book { String title } def book = new Book() book.addPropertyChangeListener({e -> println "$e.propertyName $e.oldValue -> $e.newValue" } as java.beans.PropertyChangeListener) book.title = "Foo” // prints "title Foo" book.title = "Bar” // prints "title Foo Bar"
  16. 16. @Listener   @groovy.beans.Bindable class Book { @griffon.beans.Listener(snooper) String title private snooper = {e -> println "$e.propertyName $e.oldValue -> $e.newValue" } } def book = new Book() book.title = "Foo" // prints "title Foo" book.title = "Bar" // prints "title Foo Bar"
  17. 17. @EventPublisher   @Singleton @griffon.util.EventPublisher class AccountManager { void process(Account account) { publishEvent("AccountProcessed", [account)] } } def am = AccountManager.instance am.addEventListener("AccountProcessed") { account -> println "Processed account $account" } def acc = new Account() AccountManager.instance.process(acc) // prints "Processed account Account:1"
  18. 18. @Scaffold   class Book { String title } @griffon.presentation.Scaffold class BookBeanModel {} def model = new BookBeanModel() def book = new Book(title: "Foo") model.value = book assert book.title == model.title.value model.value = null assert !model.title.value assert model.title
  19. 19. @En5ty   @griffon.persistence.Entity(‘gsql’) class Book { String title } def book = new Book().save() assert book.id assert book.version
  20. 20. Y  otras  tantas  …   •  @PackageScope   •  @Lazy   •  @Newify   •  @Field   •  @Synchronized   •  @Vetoable   •  @ToString,  @EqualsAndHashCode,   @TupleConstructor   •  @AutoClone,  @AutoExternalize   •  …  
  21. 21. LA  RECETA  SECRETA  PARA  HACER   TRANSFORMACIONES  DE  AST  
  22. 22. 1  Definir  interface   @Retention(RetentionPolicy.SOURCE) @Target({ElementType.FIELD, ElementType.TYPE}) @GroovyASTTransformationClass ("org.codehaus.griffon.ast.ListenerASTTransformation ") public @interface Listener { String value(); }
  23. 23. 2  Implementar  la  transformacion   import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.transform.ASTTransformation; import org.codehaus.groovy.transform.GroovyASTTransformation; @GroovyASTTransformation(phase=CompilationPhase.CANONICALIZATION) public class ListenerASTTransformation implements ASTTransformation { public void visit(ASTNode[] nodes, SourceUnit source) { // MAGIC GOES HERE, REALLY! =) } }
  24. 24. 3  Anotar  el  codigo   @groovy.beans.Bindable class Book { @griffon.beans.Listener(snooper) String title private snooper = {e -> // awesome code … } }
  25. 25. OTRO  TIPO  DE   TRANSFORMACIONES  
  26. 26. GContracts  
  27. 27. Spock  
  28. 28. CodeNarc  
  29. 29. Griffon  
  30. 30. Gracias!   @aalmiray   hXp://jroller.com/aalmiray  

×