Inicio
Explorar
Enviar búsqueda
Cargar
Iniciar sesión
Registrarse
Publicidad
Creating ASTTs The painful truth
Denunciar
Mario García
Seguir
Software Developer en Kaleidos Open Source
10 de Apr de 2016
•
0 recomendaciones
2 recomendaciones
×
Sé el primero en que te guste
ver más
•
1,285 vistas
vistas
×
Total de vistas
0
En Slideshare
0
De embebidos
0
Número de embebidos
0
Check these out next
Security Challenges in Node.js
Websecurify
Tdc 2013 - Ecossistema Ruby
Fabio Akita
Grunt.js introduction
Claudio Mignanti
Chromium Embedded Framework + Go at Brooklyn JS
quirkey
G* on GAE/J 挑戦編
Tsuyoshi Yamamoto
Gaelyk
Kazuchika Sekiya
Groovy & Grails: Scripting for Modern Web Applications
rohitnayak
Git Going for the Transylvania JUG
Matthew McCullough
1
de
170
Top clipped slide
Creating ASTTs The painful truth
10 de Apr de 2016
•
0 recomendaciones
2 recomendaciones
×
Sé el primero en que te guste
ver más
•
1,285 vistas
vistas
×
Total de vistas
0
En Slideshare
0
De embebidos
0
Número de embebidos
0
Descargar ahora
Descargar para leer sin conexión
Denunciar
Software
Talk about creating Groovy AST transformations. Pitfalls, wins, things to come...
Mario García
Seguir
Software Developer en Kaleidos Open Source
Publicidad
Publicidad
Publicidad
Recomendados
Grooscript and Grails 3
Jorge Franco Leza
1.1K vistas
•
21 diapositivas
Grooscript greach
Jorge Franco Leza
2.2K vistas
•
45 diapositivas
Grooscript gr8conf 2015
Jorge Franco Leza
2K vistas
•
31 diapositivas
Grooscript greach 2015
Jorge Franco Leza
2.7K vistas
•
27 diapositivas
Grooscript in Action SpringOne2gx 2015
Jorge Franco Leza
2.3K vistas
•
49 diapositivas
Grails 1.4.0.M1 メモLT
Tsuyoshi Yamamoto
1.2K vistas
•
16 diapositivas
Más contenido relacionado
Presentaciones para ti
(20)
Security Challenges in Node.js
Websecurify
•
3.3K vistas
Tdc 2013 - Ecossistema Ruby
Fabio Akita
•
2.1K vistas
Grunt.js introduction
Claudio Mignanti
•
1K vistas
Chromium Embedded Framework + Go at Brooklyn JS
quirkey
•
633 vistas
G* on GAE/J 挑戦編
Tsuyoshi Yamamoto
•
1.8K vistas
Gaelyk
Kazuchika Sekiya
•
1.8K vistas
Groovy & Grails: Scripting for Modern Web Applications
rohitnayak
•
1.9K vistas
Git Going for the Transylvania JUG
Matthew McCullough
•
449 vistas
Learning Svelte
Christoffer Noring
•
524 vistas
Gradle in 45min
Schalk Cronjé
•
1.6K vistas
Rest, sockets em golang
jefferson Otoni Lima
•
179 vistas
groovy & grails - lecture 13
Alexandre Masselot
•
1.1K vistas
Meetup-js-032815
Joe Devlin
•
490 vistas
Griffon @ Svwjug
Andres Almiray
•
853 vistas
Automating Front-End Workflow
Dimitris Tsironis
•
1.8K vistas
React for Beginners
Derek Willian Stavis
•
1.6K vistas
Searched gems which supports only ruby 2.6
Maki Toshio
•
882 vistas
Agile Breakfast with Gradle
Rene Gröschke
•
906 vistas
State management in a GraphQL era
kristijanmkd
•
381 vistas
NetBeans Support for EcmaScript 6
Kostas Saidis
•
1.9K vistas
Similar a Creating ASTTs The painful truth
(20)
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
Tsuyoshi Yamamoto
•
1.8K vistas
Dependency Management in C++ (NDC Security 2021)
Patricia Aas
•
19 vistas
Ant build tool2
Rohit Kumar
•
526 vistas
Crushing React bugs with Jest and Enzyme
All Things Open
•
150 vistas
Groovy for Java Developers
Andres Almiray
•
2.1K vistas
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
•
1.4K vistas
Multi Client Development with Spring - Josh Long
jaxconf
•
2.5K vistas
Maven + Jsf + Richfaces + Jxl + Jdbc - Complete Code Example
Nikhil Bhalwankar
•
781 vistas
Groovy for java developers
Puneet Behl
•
376 vistas
Jersey framework
knight1128
•
3.6K vistas
node.js Module Development
Jay Harris
•
3.9K vistas
Groovy And Grails JUG Trento
John Leach
•
946 vistas
Ast transformations
HamletDRC
•
788 vistas
AST Transformations at JFokus
HamletDRC
•
944 vistas
Metaprogramming with Groovy
Ali Tanwir
•
1.3K vistas
MetaProgramming with Groovy
NexThoughts Technologies
•
148 vistas
The Spring 4 Update - Josh Long
jaxconf
•
807 vistas
比XML更好用的Java Annotation
javatwo2011
•
1K vistas
Os Secoske
oscon2007
•
379 vistas
GTLAB Overview
marpierc
•
665 vistas
Publicidad
Más de Mario García
(16)
Blockchain 101 (spanish)
Mario García
•
171 vistas
Jbake workshop (Greach 2019)
Mario García
•
800 vistas
Groovy 2.5 and 3.0 (Spanish)
Mario García
•
907 vistas
GraphQL & Ratpack
Mario García
•
450 vistas
GraphQL y Groovy
Mario García
•
1.2K vistas
Calidad del codigo (MadridGUG)
Mario García
•
1.3K vistas
GraphQL and Groovy
Mario García
•
2K vistas
Macro macro, burrito burrit
Mario García
•
1.4K vistas
Groovy android
Mario García
•
3.3K vistas
Groovy on Android
Mario García
•
6.1K vistas
Gpars Workshop 2014
Mario García
•
1.1K vistas
Functional Programming with Groovy
Mario García
•
1.1K vistas
Test Motherfucker...Test
Mario García
•
1.6K vistas
Programación concurrente con GPars
Mario García
•
959 vistas
Gradle vs Maven
Mario García
•
10.7K vistas
Greach 2011 : Creando Plugins Con Griffon
Mario García
•
633 vistas
Último
(20)
PPT Web Clustering Engine.pptx
DhammanandLonare
•
0 vistas
在哪里可以办荷兰大学文凭《荷兰南方高等专业大学毕业证成绩单仿制》
nukotk
•
2 vistas
SOFTWARE.pptx
CharenReposposa
•
2 vistas
wallet79
Chhay Lin Lim
•
7 vistas
在哪里可以办意大利大学文凭《佛罗伦萨美术学院毕业证成绩单仿制》
nukotk
•
3 vistas
Online Notice Board.pptx
ManikjitChohan
•
0 vistas
Agile Development with Scrum.pptx
zuma14
•
2 vistas
DREAM 5 benefits of CRM Software for pest management.pptx
Dream Service Software
•
0 vistas
javascript_tutorial.pdf
kaouthar20
•
0 vistas
AI: Your Personal Intern
Joe Brinkman
•
0 vistas
在哪里可以办法国大学文凭《图尔大学毕业证成绩单仿制》
efagvah
•
0 vistas
python ppt.pptx
ssuserd10678
•
2 vistas
在哪里可以办美国大学文凭《加州州立大学长滩分校毕业证成绩单仿制》
nukotk
•
2 vistas
Custom ERP software
babuprasad38
•
0 vistas
SugarCRM.ppt
RajJar12
•
0 vistas
Patches_Presentation.pptx
ssuser46d193
•
0 vistas
ch11lect1.ppt
NupurMishra34
•
2 vistas
在哪里可以办英国大学文凭《白金汉大学毕业证成绩单仿制》
efagvah
•
3 vistas
Software testing.pdf
SwagatGogoi3
•
5 vistas
JPrime_JITServer.pptx
Grace Jansen
•
0 vistas
Publicidad
Creating ASTTs The painful truth
1
2
3 . 1
3 . 1
3 . 1
… … 3 .
1
3 . 2
4 . 1
4 . 1
4 . 1
… 4 . 1
4 . 2
5
5
5
5
6 . 1
6 . 2
6 . 3
6 . 3
6 . 3
… 6 . 4
6 . 5
6 . 6
6 . 7
⇒ 1 == 1 6 . 8
⇒ 1 == 1 6 . 8
⇒ 1 == 1 6 . 8
⇒ 1 == 1 6 . 8
⇒ ⇒ ref.myMethod(3) 6 .
9
⇒ ⇒ ref.myMethod(3) 6 .
9
⇒ ⇒ ref.myMethod(3) 6 .
9
⇒ ⇒ ref.myMethod(3) 6 .
9
6 . 10
if(booleanExpression) { println "hello" // statement } 6 . 11
if(booleanExpression) { println "hello" // statement } 6 . 11
if(booleanExpression) { println "hello" // statement } 6 . 11
public void main(String[] args) { // block starts // this is inside a block statement } // block ends 6 . 12
public void main(String[] args) { // block starts // this is inside a block statement } // block ends 6 . 12
public void main(String[] args) { // block starts // this is inside a block statement } // block ends 6 . 12
public String greetings() { return "Hello Greach" } 6 . 13
6 . 14
6 . 15
6 . 15
6 . 15
6 . 15
6 . 15
… 6 . 15
… … class A { // ClassNode String greetings // FieldNode String hello() { // MethodNode } } 6 . 16
class A { // ClassNode String hello() // MethodNode { // blockStatement { return "Hello" // returnStatement(constantExpression) } // } } 6 . 17
7 . 1
7 . 2
7 . 3
7 . 3
7 . 3
7 . 4
7 . 5
… 7 . 5
… 7 . 5
7 . 6
8 . 1
8 . 2
8 . 3
8 . 4
8 . 5
8 . 6
9
10 . 1
10 . 2
10 . 3
10 . 4
10 . 5
10 . 5
10 . 5
10 . 5
11 . 1
package greach.local class A { @WithLogging void doSomething() { // println "Starting doSomething" println "mystuff" // println "Ending doSomething" } } 11 . 2
11 . 3
… 11 . 3
… 11 . 3
11 . 4
11 . 4
11 . 4
package greach.local import org.codehaus.groovy.transform.GroovyASTTransformationClass import java.lang.annotation.* (1) @Retention(RetentionPolicy.SOURCE) @Target([ElementType.METHOD]) (2) @GroovyASTTransformationClass( ["greach.local.WithLoggingExplainedTransformation"]) @interface WithLoggingExplained { } 11 . 5
11 . 6
import org.codehaus.groovy.ast.expr.* import org.codehaus.groovy.ast.stmt.* import org.codehaus.groovy.ast.* import org.codehaus.groovy.transform.* 11 . 7
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS) class WithLoggingExplainedTransformation implements ASTTransformation { 11 . 8
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS) class WithLoggingExplainedTransformation implements ASTTransformation { 11 . 8
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS) class WithLoggingExplainedTransformation implements ASTTransformation { 11 . 8
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS) class WithLoggingExplainedTransformation implements ASTTransformation { 11 . 8
@Override void visit(ASTNode[] nodes, SourceUnit sourceUnit) { MethodNode method = (MethodNode) nodes[1] (1) def startMessage = createPrintlnAst("Starting $method.name") def endMessage = createPrintlnAst("Ending $method.name") def existingStatements = ((BlockStatement)method.code).statements (2) existingStatements.add(0, startMessage) existingStatements.add(endMessage) } 11 . 9
11 . 10
11 . 10
11 . 10
private static Statement createPrintlnAst(String message) { new ExpressionStatement( new MethodCallExpression( new VariableExpression("this"), new ConstantExpression("println"), new ArgumentListExpression( new ConstantExpression(message) ) ) ) } 11 . 11
11 . 12
11 . 12
11 . 12
12 . 1
12 . 2
12 . 3
import static org.codehaus.groovy.ast.tools.GeneralUtils.* 12 . 4
12 . 5
12 . 5
12 . 5
private static Statement createPrintlnAst(String message) { new ExpressionStatement( new MethodCallExpression( new VariableExpression("this"), new ConstantExpression("println"), new ArgumentListExpression( new ConstantExpression(message) ) ) ) } 12 . 6
private static Statement createPrintlnAst(String message) { return stmt(callThisX("println", args(constX(message)))) } 12 . 7
private static Statement createPrintlnAst(String message) { new ExpressionStatement( new MethodCallExpression( new VariableExpression("this"), new ConstantExpression("println"), new ArgumentListExpression( new ConstantExpression(message) ) ) ) } private static Statement createPrintlnAst(String message) { return stmt(callThisX("println", args(constX(message)))) } 12 . 8
… 12 . 9
12 . 10
BlockStatement getBlockStmt() { ASTNode[] stmts = new AstBuilder().buildFromCode { return number % 2 == 0 } return stmts.first() as BlockStatement } 12 . 11
BlockStatement getMD5Code(final String propertyName) { def blockStatement = new AstBuilder().buildFromString """ java.security.MessageDigest.getInstance('MD5') .digest(${propertyName}.getBytes('UTF-8')) .encodeHex() .toString() """ return blockStatement.first() as BlockStatement } 12 . 12
12 . 13
13 . 1
@GroovyASTTransformation(phase=CompilePhase.INSTRUCTION_SELECTION) class PlayAst extends ExceptionFriendlyAst{ static final PLAY_METHOD_NAME = "play" static final PLAY_METHOD_PARAM_NAME = "params" /* We need to inject a DataFlows instance in a variable called "flow" */ void processNodes(ASTNode[] astNodes,SourceUnit sourceUnit){ /* Checking constraints */ if (!astNodes) return if (!astNodes[0] || !astNodes[1]) return if (!(astNodes[0] instanceof AnnotationNode)) return if (astNodes[0].classNode?.name != Play.class.name) return if (!(astNodes[1] instanceof MethodNode)) return 13 . 2
… … package greach.builder class Order { @ToMD5 String name @ToMD5 String description } Order order = new Order(name: "john", description: "desc") assert order.nameToMD5() == "527bd5b5d689e2c32ae974c6229ff785" assert order.descriptionToMD5() == "1dee80c7d5ab2c1c90aa8d2f7dd47256" 13 . 3
@CompileStatic @LocalTransformation(A.PHASE_LOCAL.INSTRUCTION_SELECTION) class ToMD5Impl extends LocalTransformationImpl<ToMD5,FieldNode> { @Override void doVisit(AnnotationNode annotation, FieldNode fieldNode, SourceUnit sourceUnit) { MethodNode md5Method = getMD5Method(fieldNode.name) fieldNode.declaringClass.addMethod(md5Method) } 13 . 4
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) class MacroExpandAst extends AbstractASTTransformation { void visit(ASTNode[] nodes, SourceUnit sourceUnit) { sourceUnit.AST.classes.each { ClassNode classNode -> new MacroExpandTransformer().visitClass(classNode) } } } 13 . 5
13 . 6
13 . 7
class MacroExpandTransformer extends ClassCodeExpressionTransformer { private SourceUnit sourceUnit MacroExpandTransformer(SourceUnit sourceUnit) { // PASSING SOURCE UNIT this.sourceUnit = sourceUnit } public Expression transform(Expression expression) { // CHECKING AGAIN if (expression instanceof MethodCallExpression && expression.methodAsString == 'let') // CASTINGS MethodCallExpression methodCallExpression = (MethodCallExpression) expression 13 . 8
@GlobalTransformation(A.PHASE_GLOBAL.SEMANTIC) class AddTransformation extends GlobalTransformationImpl { List<Class<Transformer>> getTransformers() { return [AddPropertyTransformer, AddMethodTransformer] } } 13 . 9
class ChangeTripleXToPlusOne extends ExpressionTransformer<MethodCallExpression> { ChangeTripleXToPlusOne(final SourceUnit sourceUnit) { super(sourceUnit, methodCallByNameEq('xxx')) } Expression transformExpression(final MethodCallExpression target) { return A.EXPR.constX(1) } } 13 . 10
class ChangeTripleXToPlusOne extends ExpressionTransformer<MethodCallExpression> { ChangeTripleXToPlusOne(final SourceUnit sourceUnit) { super(sourceUnit, methodCallByNameEq('xxx')) } Expression transformExpression(final MethodCallExpression target) { return A.EXPR.constX(1) } } 13 . 10
class ChangeTripleXToPlusOne extends ExpressionTransformer<MethodCallExpression> { ChangeTripleXToPlusOne(final SourceUnit sourceUnit) { super(sourceUnit, methodCallByNameEq('xxx')) } Expression transformExpression(final MethodCallExpression target) { return A.EXPR.constX(1) } } 13 . 10
14 . 1
14 . 2
… package greach.builder import org.codehaus.groovy.transform.GroovyASTTransformationClass import java.lang.annotation.ElementType import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy import java.lang.annotation.Target @Retention(RetentionPolicy.SOURCE) @Target([ElementType.TYPE]) @GroovyASTTransformationClass(["greach.builder.EvenCheckerImpl"]) @interface EvenCheckerJava { } 14 . 3
package greach.builder import asteroid.local.Local @Local(EvenCheckerImpl) @interface EvenChecker { } 14 . 4
package greach.builder import asteroid.local.Local @Local(EvenCheckerImpl) @interface EvenChecker { } 14 . 4
package greach.builder import asteroid.local.Local @Local(EvenCheckerImpl) @interface EvenChecker { } 14 . 4
14 . 5
… 14 . 6
package greach.meta import groovy.transform.ToString import groovy.transform.AnnotationCollector @ToJson @ToString @AnnotationCollector @interface ToEverything { } 14 . 7
package greach.meta @ToEverything class A { String name } A aInstance = new A() assert aInstance.toJson() assert aInstance.toString() 14 . 8
package greach.meta @ToEverything class A { String name } A aInstance = new A() assert aInstance.toJson() assert aInstance.toString() 14 . 8
package greach.meta @ToEverything class A { String name } A aInstance = new A() assert aInstance.toJson() assert aInstance.toString() 14 . 8
15 . 1
@CompileStatic @LocalTransformation(A.PHASE_LOCAL.INSTRUCTION_SELECTION) class SerializableImpl extends LocalTransformationImpl<Serializable, ClassNode> { @Override void doVisit(AnnotationNode annotation, ClassNode classNode, SourceUnit source) { check: 'package starts with asteroid' classNode.packageName.startsWith('asteroid') check: 'there are at most 2 methods' classNode.methods.size() < 3 then: 'make it implements Serializable and Cloneable' addInterfaces(classNode, java.io.Serializable, Cloneable) } } 15 . 2
15 .
3
15 . 4
@ASTTest({ assert node .properties .every { it.type == ClassHelper.make(Integer) } }) @EvenChecker class A { Integer max Integer min String toString() { return "A" } } 15 . 5
16 . 1
16 . 2
package greach.builder class ToMD5Test extends GroovyTestCase { 16 . 3
package greach.builder class ToMD5Test extends GroovyTestCase { 16 . 3
package greach.builder class ToMD5Test extends GroovyTestCase { 16 . 3
void testAddingToMD5() { assertScript ''' package greach.builder class Order { @ToMD5 String name @ToMD5 String description } Order order = new Order(name: "john", description: "desc") assert order.nameToMD5() == "527bd5b5d689e2c32ae974c6229ff785" assert order.descriptionToMD5() == "1dee80c7d5ab2c1c90aa8d2f7dd47256" ''' } 16 . 4
void testFailsToUseAnInteger() { shouldFail ''' package greach.builder class Order { @ToMD5 Integer month } ''' } 16 . 5
16 . 6
17 . 1
17 . 2
17 . 3
17 . 4
BlockStatement result = macro(true) { println "foo" } 17 . 5
BlockStatement result = macro(true) { println "foo" } // VS def expected = block(stmt(callThisX("println", args(constX("foo"))))) // CHECKED BY AstAssert.assertSyntaxTree([expected], [result]); 17 . 6
BlockStatement result = macro(true) { println "foo" } // VS def expected = block(stmt(callThisX("println", args(constX("foo"))))) // CHECKED BY AstAssert.assertSyntaxTree([expected], [result]); 17 . 6
BlockStatement result = macro(true) { println "foo" } // VS def expected = block(stmt(callThisX("println", args(constX("foo"))))) // CHECKED BY AstAssert.assertSyntaxTree([expected], [result]); 17 . 6
BlockStatement result = macro(true) { println "foo" } // VS def expected = block(stmt(callThisX("println", args(constX("foo"))))) // CHECKED BY AstAssert.assertSyntaxTree([expected], [result]); 17 . 6
… 17 . 7
void testClosureExpression() { def ast1 = macro { {-> a } } def ast2 = macro { {-> a } } def ast3 = macro { {-> b } } def ast4 = macro { { a -> a } } def ast5 = macro { { a -> a } } def ast6 = macro { { a,b -> a } } def ast7 = macro { { int a -> a } } assert ASTMatcher.matches(ast1, ast1) assert ASTMatcher.matches(ast1, ast2) assert ASTMatcher.matches(ast2, ast1) assert !ASTMatcher.matches(ast1, ast3) assert !ASTMatcher.matches(ast1, ast4) assert ASTMatcher.matches(ast4, ast5) assert !ASTMatcher.matches(ast5, ast6) assert !ASTMatcher.matches(ast5, ast7) } 17 . 8
17 . 9
17 . 10
17 . 11
18 . 1
18 . 2
18 . 3
18 . 4
18 . 5
18 . 6
Publicidad