Download - Ast transformations
![Page 1: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/1.jpg)
Groovy AST
![Page 2: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/2.jpg)
![Page 3: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/3.jpg)
Agenda
• Local ASTTransforma5ons – Groovy – Grails – Griffon
• Como funcionan?
• Otras formas de modificar AST
![Page 4: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/4.jpg)
LISTADO DE TRANSFORMACIONES DE AST (NO EXHAUSTIVO)
![Page 5: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/5.jpg)
@Singleton
@Singleton
class AccountManager {
void process(Account account) { ... } }
def account = new Account() AccountManager.instance.process(account)
![Page 6: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/6.jpg)
@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)
![Page 7: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/7.jpg)
@Immutable
@Immutable
class Person {
String name
}
def person1 = new Person("ABC") def person2 = new Person(name: "ABC")
assert person1 == person2
person1.name = "Boom!” // error!
![Page 8: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/8.jpg)
@Category @Category(Integer) class Pouncer { String pounce() { (1..this).collect([]) { 'boing!' }.join(' ') } }
use(Pouncer) { 3.pounce() // boing! boing! boing! }
![Page 9: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/9.jpg)
@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!
![Page 10: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/10.jpg)
@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"]
![Page 11: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/11.jpg)
@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…
![Page 12: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/12.jpg)
@InheritConstructors
@groovy.transform.InheritConstructors class MyException extends RuntimeException {}
def x1 = new MyException("Error message")
def x2 = new MyException(x1)
assert x2.cause == x1
![Page 13: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/13.jpg)
@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
![Page 14: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/14.jpg)
@Scalify
trait Output {
@scala.reflect.BeanProperty
var output:String = "" }
@groovyx.transform.Scalify class GroovyOutput implements Output {
String output
}
![Page 15: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/15.jpg)
@En5ty
@grails.persistence.Entity
class Book {
String title
}
def book = new Book().save() assert book.id
assert book.version
![Page 16: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/16.jpg)
@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"
![Page 17: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/17.jpg)
@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"
![Page 18: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/18.jpg)
@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"
![Page 19: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/19.jpg)
@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
![Page 20: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/20.jpg)
@En5ty
@griffon.persistence.Entity(‘gsql’)
class Book {
String title
}
def book = new Book().save() assert book.id
assert book.version
![Page 21: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/21.jpg)
Y otras tantas …
• @PackageScope • @Lazy • @Newify • @Field • @Synchronized • @Vetoable • @ToString, @EqualsAndHashCode, @TupleConstructor
• @AutoClone, @AutoExternalize • …
![Page 22: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/22.jpg)
LA RECETA SECRETA PARA HACER TRANSFORMACIONES DE AST
![Page 23: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/23.jpg)
1 Definir interface @Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD, ElementType.TYPE})
@GroovyASTTransformationClass("org.codehaus.griffon.ast.ListenerASTTransformation")
public @interface Listener {
String value();
}
![Page 24: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/24.jpg)
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! =)
}
}
![Page 25: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/25.jpg)
3 Anotar el codigo
@groovy.beans.Bindable
class Book {
@griffon.beans.Listener(snooper) String title
private snooper = {e ->
// awesome code …
}
}
![Page 26: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/26.jpg)
OTRO TIPO DE TRANSFORMACIONES
![Page 27: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/27.jpg)
GContracts
![Page 28: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/28.jpg)
Spock
![Page 29: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/29.jpg)
CodeNarc
![Page 30: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/30.jpg)
Griffon
![Page 31: Ast transformations](https://reader034.vdocuments.site/reader034/viewer/2022052205/554f3a3db4c90572088b4ec4/html5/thumbnails/31.jpg)
Gracias!
@aalmiray hXp://jroller.com/aalmiray