macro macro, burrito burrit

97
MACRO MACRO, BURRITO MACRO MACRO, BURRITO MACRO MACRO, BURRITO MACRO MACRO, BURRITO MACRO MACRO, BURRITO MACRO MACRO, BURRITO BURRITO BURRITO BURRITO BURRITO BURRITO BURRITO @marioggar 1

Upload: mario-garcia

Post on 14-Apr-2017

588 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Macro macro, burrito burrit

MACROMACRO,BURRITOMACROMACRO,BURRITOMACROMACRO,BURRITOMACROMACRO,BURRITOMACROMACRO,BURRITOMACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITO

MACROMACRO,BURRITOMACROMACRO,BURRITO

BURRITOBURRITOBURRITOBURRITOBURRITOBURRITO

BURRITO

BURRITO

BURRITO

BURRITO

BURRITO

BURRITO

BURRITO

BURRITO

BURRITOBURRITO@marioggar

1

Page 2: Macro macro, burrito burrit

SOBREMIMarioGarcia

TrabajoenKaleidos

ProgramoconGroovy,JDK_8

https://twitter.com/marioggar

http://kaleidos.net/

2

Page 3: Macro macro, burrito burrit

DEQUEVOYAHABLAR?Metaprogramacion

Macros

Asteroid

3

Page 4: Macro macro, burrito burrit

THEORY101TeoriabasicaparaentenderelapiAST.

4

Page 5: Macro macro, burrito burrit

QUE

5 . 1

Page 6: Macro macro, burrito burrit

ABSTRACTSYNTAXTREEElcompiladornecesitaunarepresentaciondetucodigo:

5 . 2

Page 7: Macro macro, burrito burrit

EXPRESSIONSUnaexpresionesunacombinaciondeunoomasvalores,constantesvariables,operadores,yfuncionesqueel

lenguagedeprogramacioninterpretayejecutaparaproducirotrovalor.

5 . 3

Page 8: Macro macro, burrito burrit

BINARY⇒BOOLEANBinaryExpression

constantexpression1

token==

constantexpression1

1==1

5 . 4

Page 9: Macro macro, burrito burrit

VARIABLE⇒CONSTANT⇒CALL

variableexpressionref

constantmyMethod

paramexpression3

ref.myMethod(3)

5 . 5

Page 10: Macro macro, burrito burrit

SENTENCIASEnprogramacion,unasentenciaeslapartemaspequenadeunlenguagedeprogramacionimperativoqueexpresauna

accionquesedebellevaracabo.Unasentenciapuedetenerexpresiones.

5 . 6

Page 11: Macro macro, burrito burrit

IFSTATEMENT

expressiontoevaluate

statementtobeexecutedifthebooleanexpressionevaluatestotrue

if(booleanExpression){println"hello"//statement}

5 . 7

Page 12: Macro macro, burrito burrit

BLOCKSTATEMENT

Ablockstatementiseasilyrecognizedbycurlybraces

Itisbuiltfromotherstatementscontainingexpressions

publicvoidmain(String[]args){//blockstarts//thisisinsideablockstatement}//blockends

5 . 8

Page 13: Macro macro, burrito burrit

BLOCKSTATEMENT(CONT.)

ThisblockstatementcontainsareturnstatementreceivingaconstantexpressionHelloGreach.

publicStringgreetings(){return"HelloGreach"}

5 . 9

Page 14: Macro macro, burrito burrit

NODES

—LordoftheRings

Aringtorulethemall

5 . 10

Page 15: Macro macro, burrito burrit

NODES(CONT.)Comoestaestructuradonuestroprograma.Agrupana

sentenciayexpressions.

classes

methods

fields

properties

5 . 11

Page 16: Macro macro, burrito burrit

ACLASSNODE

ClassNodemaycontain:methods,fields…MethodNodemaycontainstatements,andexpressions

classA{//ClassNodeStringgreetings//FieldNode

Stringhello(){//MethodNode

}}

5 . 12

Page 17: Macro macro, burrito burrit

PORLOTANTOclassA{//ClassNode

Stringhello()//MethodNode{//blockStatement{

return"Hello"//returnStatement(constantExpression)

}//}}

5 . 13

Page 18: Macro macro, burrito burrit

CUANDO

6 . 1

Page 19: Macro macro, burrito burrit

ENQUEMOMENTOSPUEDOENGANCHARMEALCOMPILADORPARACAMBIARELAST?

Dependsontypeoftransformation(LocalvsGlobal)

DependsontheCompilationPhaseyouneedtotarget

6 . 2

Page 20: Macro macro, burrito burrit

COMPILATIONPHASESInitialization,Parsing,Conversion,Semantic,Canonicalization,Instruction,Class,Output,Finalization

GroovyReference

6 . 3

Page 21: Macro macro, burrito burrit

RESUMIENDOSemanticAnalysis

Canonicalization

Instruction

Beforethatyouhavenotypes/scopes/imports…AfterthatyoubetterknowByteCode-Kunfu

6 . 4

Page 22: Macro macro, burrito burrit

METAPROGRAMACION

7 . 1

Page 23: Macro macro, burrito burrit

7 . 2

Page 24: Macro macro, burrito burrit

QUEES?"Metaprogrammingblablablabla…Itmeansthataprogramcouldbedesignedtoread,generate,analyseortransformotherprograms,andevenmodifyitselfwhilerunning.bla

blablabla…blablablablablablaminimizethenumberoflinesofcodetoexpressasolution…yblablabla. 

— https://en.wikipedia.org/wiki/Metaprogramming

7 . 3

Page 25: Macro macro, burrito burrit

RESUMIENDO… Leer,generar,analizar,transformartucodigo

Tratadeexpresarlomismoconmenoscodigo

7 . 4

Page 26: Macro macro, burrito burrit

7 . 5

Page 27: Macro macro, burrito burrit

DOSSABORES:EntiempodeEJECUCION

EntiempodeCOMPILACION

7 . 6

Page 28: Macro macro, burrito burrit

TIEMPODEEJECUCION:PROSSencillo

Facildetestear

7 . 7

Page 29: Macro macro, burrito burrit

TIEMPODEEJECUCION:CONSDificildeaplicaraisladamente

Problemadepoluciondelcodigo

Tedascuentadelosproblemasentiempodeejecucion

7 . 8

Page 30: Macro macro, burrito burrit

EJEMPLOS:QUICKDEMO

7 . 9

Page 31: Macro macro, burrito burrit

TIEMPODEEJECUCION:TABLAName Category Difficulty

invokeMethod Runtime Easy

method/propertyMissing Runtime Easy

MetaClass Runtime Easy/Tricky

7 . 10

Page 32: Macro macro, burrito burrit

TIEMPODECOMPILACION:PROSPuedescontrolarmejorcomoseaplicanloscambios

Puedescrearnuevasformasdeexpresartucodigo

Muchosproblemassedetectanporelcompilador

7 . 11

Page 33: Macro macro, burrito burrit

TIEMPODECOMPILACION:CONSHastaahoracurvadeapredizajeparecidaa…Haskell?

DesconocimientodelcompiladordeGroovy

7 . 12

Page 34: Macro macro, burrito burrit

TIEMPODECOMPILACION:TABLAName Category Difficulty

Traits Compiletime Super-Easy

Extensions Compiletime Easy

Local Compiletime Hard

Global Compiletime Hardcore

7 . 13

Page 35: Macro macro, burrito burrit

PORQUESONNECESARIASLASMACROS?

8

Page 36: Macro macro, burrito burrit

ENPARTEPOR…

9

Page 37: Macro macro, burrito burrit

LAVIEJATRANSFORMACIONAST

10 . 1

Page 38: Macro macro, burrito burrit

10 . 2

Page 39: Macro macro, burrito burrit

COSASQUENOCAMBIANTransformacionesLOCALES

TransformacionesGLOBALES

10 . 3

Page 40: Macro macro, burrito burrit

ASTLOCALES

11 . 1

Page 41: Macro macro, burrito burrit

UN"SIMPLE"EJEMPLO:

11 . 2

Page 42: Macro macro, burrito burrit

ANOTACIONpackagecompile.old.local.md5

importorg.codehaus.groovy.transform.GroovyASTTransformationClass

importjava.lang.annotation.ElementTypeimportjava.lang.annotation.Retentionimportjava.lang.annotation.RetentionPolicyimportjava.lang.annotation.Target

@Retention(RetentionPolicy.SOURCE)@Target([ElementType.TYPE])@GroovyASTTransformationClass(["compile.old.local.md5.MD5Transform"])@interfaceMD5{}

11 . 3

Page 43: Macro macro, burrito burrit

TRANSFORMATIONimportorg.codehaus.groovy.ast.*importorg.codehaus.groovy.control.*importorg.codehaus.groovy.transform.*

@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)classMD5TransformextendsAbstractASTTransformation{@Overridevoidvisit(ASTNode[]nodes,SourceUnitsourceUnit){//...}}

11 . 4

Page 44: Macro macro, burrito burrit

APLICACIONpackagecompile.old.local.md5

@MD5classDocument{

FilefileStringname

voidprintMD5(){println"===>${nameAsMD5()}"println"===>${fileAsMD5()}"}}

11 . 5

Page 45: Macro macro, burrito burrit

VEAMOSLATRANSFORMACION…

11 . 6

Page 46: Macro macro, burrito burrit

11 . 7

Page 47: Macro macro, burrito burrit

TRANSFORMACION(I)imports

importstaticorg.codehaus.groovy.ast.tools.GeneralUtils.*importstaticorg.codehaus.groovy.ast.ClassHelper.*

importorg.codehaus.groovy.ast.*importorg.codehaus.groovy.ast.expr.*importorg.codehaus.groovy.ast.stmt.*

importorg.codehaus.groovy.control.*importorg.codehaus.groovy.transform.*

11 . 8

Page 48: Macro macro, burrito burrit

TRANSFORMACION(II)clasetransformacion

@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)classMD5TransformextendsAbstractASTTransformation{

11 . 9

Page 49: Macro macro, burrito burrit

TRANSFORMACION(III)visitmethod

@Overridevoidvisit(ASTNode[]nodes,SourceUnitsourceUnit){ClassNodecurrentClass=(ClassNode)nodes[1]

currentClass.fields.each{FieldNodefield->currentClass.addMethod(createMD5Method(field))}}

11 . 10

Page 50: Macro macro, burrito burrit

TRANSFORMACION(IV)MethodNodecreateMD5Method(FieldNodenode){returnnewMethodNode("${node.name}asMD5",ACC_PUBLIC,ClassHelper.STRING_TYPE,[]asParameter[],[]asClassNode[],createBlock(node))}

11 . 11

Page 51: Macro macro, burrito burrit

TRANSFORMACION(V)BlockStatementcreateBlock(FieldNodenode){returnblock(stmt(callX(callX(callX(callX(make(java.security.MessageDigest),'getInstance',args(constX('MD5'))),constX('digest'),args(callX(varX(node.name),constX('getBytes'),args(constX('UTF-8'))))),constX('encodeHex'),args()),constX('toString'),args()

11 . 12

Page 52: Macro macro, burrito burrit

11 . 13

Page 53: Macro macro, burrito burrit

QUEESTAMALENELEJEMPLO?

11 . 14

Page 54: Macro macro, burrito burrit

AGGREGARUNSIMPLEMETODO… RequiereconocerbastanteelAPIdeAST

RequieresabercomoseconstruyeelAST

Requiereunmontondecodigo:(

11 . 15

Page 55: Macro macro, burrito burrit

SEPODRIAHABERHECHO"MEJOR"?

11 . 16

Page 56: Macro macro, burrito burrit

ASTBUILDER.BUILDFROMCODEAstBuilder.buildFromCodeeselabuelodelasmacros

Elcodigoquegeneraesbuggy

Vamosquenolouses!

Sitienesqueusaralguno,usa…

11 . 17

Page 57: Macro macro, burrito burrit

ASTBUILDER.BUILDFROMSTRINGAstBuilder.buildFromString

Notendraschequeoestaticodecodigopero…Elcodigoseracompatibleafuturo

11 . 18

Page 58: Macro macro, burrito burrit

ASTBUILDER.BUILDFROMSTRINGBlockStatementcreateBlock(FieldNodenode){returnAstBuilder.buildFromString("""returnjava.security.MessageDigest.getInstance('MD5').digest(${node.name}.getBytes()).encodeHex().toString()""").first()asBlockStatement}

11 . 19

Page 59: Macro macro, burrito burrit

QUIEROESTOMISMO… PEROBIEN!

11 . 20

Page 60: Macro macro, burrito burrit

MACROS

12 . 1

Page 61: Macro macro, burrito burrit

12 . 2

Page 62: Macro macro, burrito burrit

NOVETA!!NOVETA!!EN2.5.0Graciasa@bsideupy@melix

http://docs.groovy-lang.org/docs/groovy-2.5.0-SNAPSHOT/

12 . 3

Page 63: Macro macro, burrito burrit

QUEESUNAMACRO?

—Wikipedia

Enprogramación,instrucciónescritaenunlenguajefuentequeequivaleavariasinstruccionesdelenguajemáquina.

12 . 4

Page 64: Macro macro, burrito burrit

QUEESUNAMACRO?(CONT)EnGroovy,unamacroesunafuncionquerepresentaunsetdeinstrucciones.Entiempodecompilacionsesustituye

partedelcodigodetuaplicacion(marcadores)porelsetdeinstruccionesqueencapsulabanestasmacros.

12 . 5

Page 65: Macro macro, burrito burrit

EJEMPLOILUSTRATIVOTenemosmacroX="hombremuyalto"

Ysustituimoselmarcadorxen"Johnesunx"porelcontenidodelamacro

Ytendriamos"Johnesunhombremuyalto"

12 . 6

Page 66: Macro macro, burrito burrit

QUENOSDANLASMACROSNosdanseguridaddetipos

Nospermitendevolverexpressionesostatements

Nospermitenespecificarelmomentodelcompiladorenelqueseprocesaraelcodigo

Nospermitensubstituirvariables

12 . 7

Page 67: Macro macro, burrito burrit

COMOENCAPULAMOSELCODIGO?

12 . 8

Page 68: Macro macro, burrito burrit

MACROMETHOD(I)Enrealidadesunameta-transformacion

ElcodigoqueencapsulalotransformaallamadasdelAPIAST

PuedecreartantoStatementscomoExpresiones

12 . 9

Page 69: Macro macro, burrito burrit

MACROMETHOD(II)MethodCallExpressionexpression=macro{println"hey"}

MethodCallExpressionexpression=callThisX('println',param(constX('hey')))

ConstantExpressionexpression=macro{42}

ConstantExpressionexpression=newConstantExpression(42)

ReturnStatementstatement=macro(true){return1+1}

ReturnStatementstatement=newReturnStatement(newBinaryExpression(newConstantExpression(42...

12 . 10

Page 70: Macro macro, burrito burrit

MACROMETHOD(III)

truesiquieresquedevuelvaunStatement

falsesiquieresquedevuelvaunExpression

macro(boolean){/*...CODE...*/}

12 . 11

Page 71: Macro macro, burrito burrit

EJEMPLO

@AddaggregaelmetodogetMessage()

getMessage()devolverasiempre42

@AddclassA{

}

assertnewA().getMessage()==42

12 . 12

Page 72: Macro macro, burrito burrit

SINMACROSClassNodeclassNode=(ClassNode)nodes[1]

ReturnStatementcode=newReturnStatement(newConstantExpression(42))

MethodNodemethodNode=newMethodNode("getMessage",ACC_PUBLIC,ClassHelper.make(String),[]asParameter[],[]asClassNode[],code)

classNode.addMethod(methodNode)

12 . 13

Page 73: Macro macro, burrito burrit

CONMACROSClassNodeclassNode=(ClassNode)nodes[1]

ReturnStatementcode=macro{return"42"}

MethodNodemethodNode=newMethodNode("getMessage",ACC_PUBLIC,ClassHelper.make(String),[]asParameter[],[]asClassNode[],code)

classNode.addMethod(methodNode)

12 . 14

Page 74: Macro macro, burrito burrit

MACROMETHOD(CONT.)

Fasedecompilacionenelquequierasqueseproceseelcodigo

PuedestambienindicarsidevuelveunStatementounExpression

macro(CompilePhase,boolean){/*...CODE...*/}

12 . 15

Page 75: Macro macro, burrito burrit

MD5REVISITEDBlockStatementcreateBlock(FieldNodenode){returnblock(stmt(callX(callX(callX(callX(make(java.security.MessageDigest),'getInstance',args(constX('MD5'))),constX('digest'),args(callX(varX(node.name),constX('getBytes'),args(constX('UTF-8'))))),constX('encodeHex'),args()),constX('toString'),args()

12 . 16

Page 76: Macro macro, burrito burrit

CONMACROSBlockStatementcreateBlock(FieldNodenode){VariableExpressionfieldVar=GeneralUtils.varX(fieldNode.name)

returnmacro(CompilePhase.SEMANTIC_ANALYSIS,true){returnjava.security.MessageDigest.getInstance('MD5').digest($v{fieldVar}.getBytes()).encodeHex().toString()}}

12 . 17

Page 77: Macro macro, burrito burrit

AHORA… Escodigonormal,nounstringollamadasalAPIdeAST

Sepuedecompilarestaticamente

Puedessustituirvariables

12 . 18

Page 78: Macro macro, burrito burrit

YCREARELMETODOENTERO?MacroClass

Necesita@CompileDynamic

http://docs.groovy-lang.org/docs/groovy-2.5.0-SNAPSHOT/html/documentation/#_macroclass

12 . 19

Page 79: Macro macro, burrito burrit

AUNASI… LasASTssiguenteniendomuchaceremonia

12 . 20

Page 80: Macro macro, burrito burrit

ASTEROID

13 . 1

Page 81: Macro macro, burrito burrit

13 . 2

Page 82: Macro macro, burrito burrit

QUEESASTEROIDEsunabibliotecaqueBuscareducirelcodigodetusASTs

http://grooviter.github.io/asteroid/

13 . 3

Page 83: Macro macro, burrito burrit

ORGANIZACIONAbstraccionessobretransformacionesLocalesyGlobales

FluentAPIparacrearexpresiones,metodosy/o

13 . 4

Page 84: Macro macro, burrito burrit

EJEMPLOMD5

13 . 5

Page 85: Macro macro, burrito burrit

ANOTACIONpackagecompile.old.local.md5

importorg.codehaus.groovy.transform.GroovyASTTransformationClass

importjava.lang.annotation.ElementTypeimportjava.lang.annotation.Retentionimportjava.lang.annotation.RetentionPolicyimportjava.lang.annotation.Target

@Retention(RetentionPolicy.SOURCE)@Target([ElementType.TYPE])@GroovyASTTransformationClass(["compile.old.local.md5.MD5Transform"])@interfaceMD5{}

packagecompile.gro.local.md5

importasteroid.Local

@Local(MD5Transform)@interfaceMD5{}

13 . 6

Page 86: Macro macro, burrito burrit

DECLARACIONASTantes

ahora

@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)classMD5TransformextendsAbstractASTTransformation{

@Phase(Phase.LOCAL.SEMANTIC_ANALYSIS)classMD5TransformextendsAbstractLocalTransformation<MD5,ClassNode>{

13 . 7

Page 87: Macro macro, burrito burrit

DECLARACIONAST(CONT.)Noteequivocasdefasedecompilacion

Declarasquetipodeanotacionvaaprocesar(MD5)

Declarassobrequetiposevaaaplicar(ClassNode)

13 . 8

Page 88: Macro macro, burrito burrit

METODODOVISITantes

ahora

@Overridevoidvisit(ASTNode[]nodes,SourceUnitsourceUnit){ClassNodecurrentClass=(ClassNode)nodes[1]

currentClass.fields.each{FieldNodefield->currentClass.addMethod(createMD5Method(field))}}

@OverridevoiddoVisit(AnnotationNodeannotation,ClassNodenode){node.fields.each{FieldNodefield->node.addMethod(createMD5Method(field))}}

13 . 9

Page 89: Macro macro, burrito burrit

METODODOVISIT(CONT.)Yanohacenfaltaelhorriblecastingdetipos

13 . 10

Page 90: Macro macro, burrito burrit

CREANDOMETODO

LosbuildersteguiansinoconoceselAPI

MethodNodecreateMD5Method(FieldNodenode){returnA.NODES.method("${node.name}ToMD5").modifiers(A.ACC.ACC_PUBLIC).returnType(String).code(createBlock(node)).build()}

13 . 11

Page 91: Macro macro, burrito burrit

CREARMETODOMD5BlockStatementcreateBlock(FieldNodenode){VariableExpressionfieldVar=GeneralUtils.varX(node.name)

returnmacro(CompilePhase.SEMANTIC_ANALYSIS,true){returnjava.security.MessageDigest.getInstance('MD5').digest($v{fieldVar}.getBytes()).encodeHex().toString()}}

13 . 12

Page 92: Macro macro, burrito burrit

CREARMETODOMD5(CONT.)Todoescodigocompilado

Nopierdesdinamismograciasalosplaceholders

Aunasi,necesitassabersinecesitasunaExpr.ounStmt.

13 . 13

Page 93: Macro macro, burrito burrit

QUENOHEVISTOYQUEMEREZCALAPENA?MacroClass

ASTMatcher

http://docs.groovy-lang.org/docs/groovy-2.5.0-SNAPSHOT/html/documentation/#_macroclass

http://docs.groovy-lang.org/docs/groovy-2.5.0-SNAPSHOT/html/documentation/#_astmatcher

14 . 1

Page 94: Macro macro, burrito burrit

DETODASMANERASLasASTsconosinmacrosnosonelmejorsitiopordondeempezar

enserio

Traits,extensionmodules,ASTseselcaminomasrecomendado

RevisarladocumentaciondeGroovy

14 . 2

Page 95: Macro macro, burrito burrit

:)

14 . 3

Page 96: Macro macro, burrito burrit

Q&A

14 . 4

Page 97: Macro macro, burrito burrit

RAFFLE

14 . 5