SlideShare ist ein Scribd-Unternehmen logo
1 von 75
[object Object]
http://hamletdarcy.blogspot.com ,[object Object]
[object Object],[object Object],[object Object]
[object Object],[object Object]
[object Object],[object Object]
public class Person { private String firstName;  private String lastName;  void setFirstName(String fName) { this.firstName = fName;  } public String getFirstName() { return firstName;  } public void setLastName(String lName) { this.lastName = lName;  } public String getLastName() { return firstName;  } } import lombok.Getter; import lombok.Setter; public class Person { @Getter  @Setter  private String firstName;  @Getter  @Setter  private String lastname;  } ,[object Object]
@Getter / @Setter @ToString @EqualsAndHashCode @NoArgsConstructor @RequiredArgsConstructor  @AllArgsConstructor @Data @Cleanup @Synchronized @SneakyThrows @Log @Delegate val ,[object Object]
Generates Java Boilerplate Compile Time Only –  For Eclipse and javac –  IDEA & NetBeans too Removable with delombok –  Javadoc –  GWT Read the fine print –  Know what is generated –  Slows compilation times? ,[object Object]
[object Object],[object Object]
[object Object],[object Object]
[object Object],[object Object]
[object Object],Annotation Processor Javac Handler Eclipse Handler ,[object Object]
 
 
 
 
// javac private   void  generatePropertyChangeSupportField(JavacNode node) { if  (fieldAlreadyExists( PROPERTY_SUPPORT_FIELD_NAME , node))  return ; JCExpression exp = chainDots(node.getTreeMaker(), node,  "this" ); JCVariableDecl fieldDecl = newField() .ofType(PropertyChangeSupport. class ) .withName( PROPERTY_SUPPORT_FIELD_NAME ) .withModifiers( PRIVATE  |  FINAL ) .withArgs(exp) .buildWith(node); injectField(node, fieldDecl); } // ECJ private   void  generatePropertyChangeSupportField(EclipseNode node) { if  (fieldAlreadyExists( PROPERTY_SUPPORT_FIELD_NAME , node))  return ; Expression exp = referenceForThis(node.get()); FieldDeclaration fieldDecl = newField() .ofType(PropertyChangeSupport. class ) .withName( PROPERTY_SUPPORT_FIELD_NAME ) .withModifiers( PRIVATE  |  FINAL ) .withArgs(exp) .buildWith(node); injectField(node, fieldDecl); } Alex Ruiz – Custom AST  Transformations with Project Lombok http://www.ibm.com/developerworks/java/library/j-lombok/
[object Object],[object Object]
class Event { String title } class Event { String title public void getTitle() { title } public String setTitle(String t) { this.title = t  } } ,[object Object]
class Event { @Delegate Date when } class Event implements Comparable, Clonable { Date when boolean after(Date when) { this.when.after(when) } boolean before(Date when)  { this.when.before(when) } Object clone() { this.when.clone() }  Int compareTo(Date anotherDate)  { this.when.compareTo(otherDate)  } Int getDate()  { this.when.date } Int getDay()  { this.when.day } Int getHours()  { this.when.hours } Int getMinutes()  { this.when.minutes } Int getMonth()  { this.when.month } Int getSeconds()  { this.when.seconds } long getTime()  { this.when.time } Int getTimezoneOffset() {  this.when.timezoneOffset }  Int getYear()  { this.when.year } void setDate(int date) { this.when.date = date }  void setHours(int hours)  { this.when.hours = hours } void setMinutes(int minutes)  { this.when.minutes = minutes } void setMonth(int month)  { this.when.month = month } void setSeconds(int seconds) { this.when.seconds = seconds }  void setTime(long time) { this.when.time = time }  void setYear(int year)  { this.when.year = year } String toGMTString()  { this.when.toGMTString() } String toLocaleString() {  this.when.toLocaleString() }  } ,[object Object]
class Event { @Lazy ArrayList speakers } class Event { ArrayList speakers  def getSpeakers() { if (speakers != null) { return speakers } else { synchronized(this) { if (speakers == null) { speakers = [] }  return speakers } } } } ,[object Object]
@Immutable  class Event { String title } ,[object Object],–  Properties must be @Immutable or effectively immutable –  Properties are private –  Mutatators throw ReadOnlyPropertyException –  Map constructor created –  Tuple constructor created –  Equals(), hashCode() & toString() created –  Dates, Clonables, & arrays are defensively copied on way in & out (but not deeply cloned) –  Collections & Maps are wrapped in Immutable variants –  Non-immutable fields force an error –  Special handling for Date, Color, etc –  Many generated methods configurable ,[object Object]
[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Declarative Concurrency ,[object Object],Easier Cloning and Externalizing ,[object Object],Safer Scripting ,[object Object],[object Object],[object Object],[object Object]
[object Object],Local AST Transformations ,[object Object]
 
 
 
 
class  Event {   @Delegate Date when } @GroovyASTTransformationClass( "org.pkg.DelegateTransform" ) public  @ interface  Delegate {   ... } @GroovyASTTransformation(phase =  CANONICALIZATION ) public class   DelegateTransform   implements  ASTTransformation {   public void  visit(ASTNode[] nodes, SourceUnit source) {   ...   } } ,[object Object]
[object Object],[object Object]
[object Object],import   org.codehaus.groovy.ast.* import   org.codehaus.groovy.ast.stmt.* import   org.codehaus.groovy.ast.expr.* def   ast =  new  ReturnStatement( new  ConstructorCallExpression( ClassHelper. make (Date),   ArgumentListExpression. EMPTY_ARGUMENTS   ) ) assert  ast  instanceof  ReturnStatement ,[object Object]
[object Object],def  ast =  new  AstBuilder().buildFromSpec { returnStatement { constructorCall(Date) { argumentList {} } } } assert  ast[0]  instanceof  ReturnStatement ,[object Object]
[object Object],def  ast =  new  AstBuilder().buildFromString( 'new Date()' ) assert  assert ast[0]  instanceof  BlockStatement assert  ast[0].statements[0]  instanceof  ReturnStatement ,[object Object]
[object Object],def  ast =  new  AstBuilder().buildFromCode { new  Date() } assert  ast[0].statements[0]  instanceof  ReturnStatement ,[object Object]
[object Object],class  MainExample { @Main public   void  greet() { println  "Hello from greet()!" } } $ groovy MainExample.groovy  Hello from greet()! ,[object Object]
MethodNode makeMainMethod(MethodNode source) { def  className = source.declaringClass.name def  methodName = source.name def  ast =  new  AstBuilder().buildFromString( INSTRUCTION_SELECTION ,  false ,  """ package $source.declaringClass.packageName class $source.declaringClass.nameWithoutPackage { public static void main(String[] args) { new $className().$methodName() } } """ ) ast[ 1 ].methods.find { it.name ==  'main'  } } ,[object Object]
[object Object],[object Object]
How it Works Compiles Java to AST Analyzes AST Nodes Rewrites with Strings
(x != null && x instanceof SomeClass) @Override public void  visitBinaryExpression(PsiBinaryExpression exp) { if  (exp.token ==  '==' ) { if  (exp.left instanceof BinaryExpression ... ) { if  (exp.right instanceof BinaryExpression ... ) {   registerError(exp,  '...' ) } } } }
(x != null && x instanceof SomeClass) @Override public void visitBinaryExpression(PsiBinaryExpression expression) { super.visitBinaryExpression(expression); if (!expression.getOperationTokenType().equals(JavaTokenType.ANDAND)) { return; } PsiExpression lOperand = expression.getLOperand(); PsiExpression rOperand = expression.getROperand(); if (!isBinaryExpressionAndInstanceOfCheck(lOperand, rOperand) && !isBinaryExpressionAndInstanceOfCheck(rOperand, lOperand)) { return; } PsiBinaryExpression binaryExpression = getInnerBinaryExpression(expression); if (!binaryExpression.getOperationTokenType().equals(JavaTokenType.NE)) { return; } boolean leftIsNullCheck = isNullCheck(binaryExpression.getLOperand(), binaryExpression.getROperand()); boolean rightIsNullCheck = isNullCheck(binaryExpression.getROperand(), binaryExpression.getLOperand()); if (!leftIsNullCheck && !rightIsNullCheck) return; PsiReferenceExpression theReference = getReferenceFromNotNullCheck(binaryExpression); PsiExpression instanceOfOperand = getInstanceOfOperand(expression); if (!(instanceOfOperand instanceof PsiReferenceExpression)) { return; } String referenceNameA = (theReference).getReferenceName(); String referenceNameB = ((PsiReferenceExpression)instanceOfOperand).getReferenceName(); if (referenceNameA == null || referenceNameB == null) { return; } if (!referenceNameA.equals(referenceNameB)) { return; } registerError(expression); }
Rewrite: (x instanceof SomeClass) PsiElement andand = descriptor.getPsiElement(); if  (andand  instanceof  PsiBinaryExpression) { PsiExpression lhs = ((PsiBinaryExpression)andand).getLOperand(); PsiExpression rhs = ((PsiBinaryExpression)andand).getROperand(); if  (lhs  instanceof  PsiInstanceOfExpression) { replaceExpression((PsiBinaryExpression)andand, lhs.getText()); }  else if  (rhs  instanceof  PsiInstanceOfExpression) { replaceExpression((PsiBinaryExpression)andand, rhs.getText()); } }
Rewrite: (x instanceof SomeClass) when  (descriptor.psiElement) { is  PsiBinaryExpression @ ( val  lhs  is  PsiInstanceOfExpression, *) => replaceExpression(descriptor.psiElement, lhs.text)  is  PsiBinaryExpression @ (*,  val  rhs  is  PsiInstanceOfExpression) => replaceExpression(descriptor.psiElement, rhs.text)  } Kotlin's “Decomposer patterns”
How it Works Compiles Java to AST Analyzes AST Nodes Rewrites with Strings
[object Object],[object Object]
–  Dead Code –  Defects like Gstring as Map Key, Duplicate Map Key –  Return path analysis (null returns) –  Type inference (and improving) –  Concurrency Problems (busy wait, etc) –  Poor Testing Practices –  Un-Groovy code …  and 240+ more rules
How it works CodeNarc Rule:  Ban new java.util.Random() calls @Override void  visitConstructorCallExpression(   ConstructorCallExpression call) { if  (AstUtil.classNodeImplementsType(call. type , Random)) {   addViolation(call,  'Using Random is insecure...' )   }   super .visitConstructorCallExpression(call) }
How it works
How it works
How it works
[object Object],[object Object],[object Object],[object Object]
[object Object],From Terrence Parr's  “Language Implementation Patterns” ,[object Object],[object Object]
Embedded Languages def  s =  new  ArithmeticShell() assert 2 == s.evaluate( ' 1+1 ' ) assert 1.0 == s.evaluate( 'cos(2*PI)' ) public interface   GroovyCodeVisitor {   void  visitBlockStatement(BlockStatement statement);   void  visitForLoop(ForStatement forLoop);   void  visitWhileLoop(WhileStatement loop);   void  visitDoWhileLoop(DoWhileStatement loop);   ... }
[object Object],//FinallyStatement//ReturnStatement //SynchronizedStatement/Block[1][count(*) = 0] //AllocationExpression/ClassOrInterfaceType   [contains(@Image,'ThreadGroup')] | //PrimarySuffix   [contains(@Image, 'getThreadGroup')] ,[object Object],[object Object]
How it Works Compiles Groovy to AST Analyzes AST Nodes –  Not well typed –  Not many tokens –  unreliable with other AST Transforms
[object Object],[object Object],[object Object],[object Object]
[object Object],def   "Does simple math work?" () {   expect:   def  s =  new  ArithmeticShell()   s.evaluate(input) == output   where:   input  | output   '1 + 1'   | 2   'cos(2*PI)'   | 1.0 } ,[object Object],[object Object]
[object Object],Transform.jar | - transforms   | - global   | - CompiledAtASTTransformation.class   | - CompiledAtASTTransformation$_visit_closure1.class   | - ... | META-INF   | - services   | - org.codehaus.groovy.transform.ASTTransformation   | - org.codehaus.groovy.source.Extensions ,[object Object],[object Object]
[object Object],[object Object]
Ruby FizzBuzz 1.upto(100) do |n| print "Fizz" if a = ((n % 3) == 0) print "Buzz" if b = ((n % 5) == 0)  print n unless (a || b) print "" end
Mirah FizzBuzz 1.upto(100) do |n| print "Fizz" if a = ((n % 3) == 0) print "Buzz" if b = ((n % 5) == 0)  print n unless (a || b) print "" end
Mirah: Pure JVM Class Output public class Fizz-buzz { public static void main(String[] argv) { ... do { n = __xform_tmp_4; ... if (n % 15 == 0) System.out.println(&quot;FizzBuzz&quot;); else if (n % 5 == 0) System.out.println(&quot;Buzz&quot;); else if (n % 3 == 0) System.out.println(&quot;Fizz&quot;); else System.out.println(n); ... } while (__xform_tmp_4 <= __xform_tmp_5); } }
Mirah: .java File Output if (((n % 15) == 0)) { PrintStream temp$10 = System.out; temp$10.println(&quot;FizzBuzz&quot;); } else { if (((n % 5) == 0)) { PrintStream temp$11 = System.out; temp$11.println(&quot;Buzz&quot;); } else { if (((n % 3) == 0)) { PrintStream temp$12 = System.out; temp$12.println(&quot;Fizz&quot;); } else { PrintStream temp$13 = System.out; temp$13.println(n); } } }
What it Means –  Fast –  Lightweight –  Uses JDK –  Runs on Android? –  Runs on GWT?
How it Works
How it Works
 
Mirah Macros macro def eachChar(value, &block) quote {  `value`.toCharArray.each do | my_char | `block.body` end  } end eachChar('laat de leeeuw niet ...') do | my_char | puts my_char end
Mirah Macros class Person  make_attr :firstName, :string  end  p = Person.new p.firstName = 'hamlet' puts p.firstName
Mirah Macros macro def make_attr(name, type)  attribute_name = name.string_value() quote { def `name`  @`name`  end  def `&quot;#{attribute_name}_set&quot;`(value:`type`)  @`name` = value end  } end
[object Object],[object Object]
Difficult to find call-sites
Still Difficult to generate AST Macros are more general ,[object Object]
Easily quote ASTs into source

Weitere ähnliche Inhalte

Was ist angesagt?

(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
Phil Calçado
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
intelliyole
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
Solution4Future
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
Bartosz Kosarzycki
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
Jan Kronquist
 

Was ist angesagt? (20)

Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Kotlin as a Better Java
Kotlin as a Better JavaKotlin as a Better Java
Kotlin as a Better Java
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Introduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoIntroduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demo
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
 
​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 

Ähnlich wie Ast transformations

Soundreader.classpathSoundreader.project Soundre.docx
Soundreader.classpathSoundreader.project  Soundre.docxSoundreader.classpathSoundreader.project  Soundre.docx
Soundreader.classpathSoundreader.project Soundre.docx
whitneyleman54422
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
Codecamp Romania
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
Seri Moth
 

Ähnlich wie Ast transformations (20)

What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
Soundreader.classpathSoundreader.project Soundre.docx
Soundreader.classpathSoundreader.project  Soundre.docxSoundreader.classpathSoundreader.project  Soundre.docx
Soundreader.classpathSoundreader.project Soundre.docx
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?
 
Groovy
GroovyGroovy
Groovy
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)
 
Expression trees in c#
Expression trees in c#Expression trees in c#
Expression trees in c#
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
 
Scala - en bedre Java?
Scala - en bedre Java?Scala - en bedre Java?
Scala - en bedre Java?
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 

Mehr von HamletDRC (6)

Static Analysis and AST Transformations
Static Analysis and AST TransformationsStatic Analysis and AST Transformations
Static Analysis and AST Transformations
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
10 Years of Groovy
10 Years of Groovy10 Years of Groovy
10 Years of Groovy
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Kürzlich hochgeladen (20)

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

Ast transformations

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.  
  • 14.  
  • 15.  
  • 16.  
  • 17. // javac private void generatePropertyChangeSupportField(JavacNode node) { if (fieldAlreadyExists( PROPERTY_SUPPORT_FIELD_NAME , node)) return ; JCExpression exp = chainDots(node.getTreeMaker(), node, &quot;this&quot; ); JCVariableDecl fieldDecl = newField() .ofType(PropertyChangeSupport. class ) .withName( PROPERTY_SUPPORT_FIELD_NAME ) .withModifiers( PRIVATE | FINAL ) .withArgs(exp) .buildWith(node); injectField(node, fieldDecl); } // ECJ private void generatePropertyChangeSupportField(EclipseNode node) { if (fieldAlreadyExists( PROPERTY_SUPPORT_FIELD_NAME , node)) return ; Expression exp = referenceForThis(node.get()); FieldDeclaration fieldDecl = newField() .ofType(PropertyChangeSupport. class ) .withName( PROPERTY_SUPPORT_FIELD_NAME ) .withModifiers( PRIVATE | FINAL ) .withArgs(exp) .buildWith(node); injectField(node, fieldDecl); } Alex Ruiz – Custom AST Transformations with Project Lombok http://www.ibm.com/developerworks/java/library/j-lombok/
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.  
  • 28.  
  • 29.  
  • 30.  
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40. How it Works Compiles Java to AST Analyzes AST Nodes Rewrites with Strings
  • 41. (x != null && x instanceof SomeClass) @Override public void visitBinaryExpression(PsiBinaryExpression exp) { if (exp.token == '==' ) { if (exp.left instanceof BinaryExpression ... ) { if (exp.right instanceof BinaryExpression ... ) { registerError(exp, '...' ) } } } }
  • 42. (x != null && x instanceof SomeClass) @Override public void visitBinaryExpression(PsiBinaryExpression expression) { super.visitBinaryExpression(expression); if (!expression.getOperationTokenType().equals(JavaTokenType.ANDAND)) { return; } PsiExpression lOperand = expression.getLOperand(); PsiExpression rOperand = expression.getROperand(); if (!isBinaryExpressionAndInstanceOfCheck(lOperand, rOperand) && !isBinaryExpressionAndInstanceOfCheck(rOperand, lOperand)) { return; } PsiBinaryExpression binaryExpression = getInnerBinaryExpression(expression); if (!binaryExpression.getOperationTokenType().equals(JavaTokenType.NE)) { return; } boolean leftIsNullCheck = isNullCheck(binaryExpression.getLOperand(), binaryExpression.getROperand()); boolean rightIsNullCheck = isNullCheck(binaryExpression.getROperand(), binaryExpression.getLOperand()); if (!leftIsNullCheck && !rightIsNullCheck) return; PsiReferenceExpression theReference = getReferenceFromNotNullCheck(binaryExpression); PsiExpression instanceOfOperand = getInstanceOfOperand(expression); if (!(instanceOfOperand instanceof PsiReferenceExpression)) { return; } String referenceNameA = (theReference).getReferenceName(); String referenceNameB = ((PsiReferenceExpression)instanceOfOperand).getReferenceName(); if (referenceNameA == null || referenceNameB == null) { return; } if (!referenceNameA.equals(referenceNameB)) { return; } registerError(expression); }
  • 43. Rewrite: (x instanceof SomeClass) PsiElement andand = descriptor.getPsiElement(); if (andand instanceof PsiBinaryExpression) { PsiExpression lhs = ((PsiBinaryExpression)andand).getLOperand(); PsiExpression rhs = ((PsiBinaryExpression)andand).getROperand(); if (lhs instanceof PsiInstanceOfExpression) { replaceExpression((PsiBinaryExpression)andand, lhs.getText()); } else if (rhs instanceof PsiInstanceOfExpression) { replaceExpression((PsiBinaryExpression)andand, rhs.getText()); } }
  • 44. Rewrite: (x instanceof SomeClass) when (descriptor.psiElement) { is PsiBinaryExpression @ ( val lhs is PsiInstanceOfExpression, *) => replaceExpression(descriptor.psiElement, lhs.text) is PsiBinaryExpression @ (*, val rhs is PsiInstanceOfExpression) => replaceExpression(descriptor.psiElement, rhs.text) } Kotlin's “Decomposer patterns”
  • 45. How it Works Compiles Java to AST Analyzes AST Nodes Rewrites with Strings
  • 46.
  • 47. – Dead Code – Defects like Gstring as Map Key, Duplicate Map Key – Return path analysis (null returns) – Type inference (and improving) – Concurrency Problems (busy wait, etc) – Poor Testing Practices – Un-Groovy code … and 240+ more rules
  • 48. How it works CodeNarc Rule: Ban new java.util.Random() calls @Override void visitConstructorCallExpression( ConstructorCallExpression call) { if (AstUtil.classNodeImplementsType(call. type , Random)) { addViolation(call, 'Using Random is insecure...' ) } super .visitConstructorCallExpression(call) }
  • 52.
  • 53.
  • 54. Embedded Languages def s = new ArithmeticShell() assert 2 == s.evaluate( ' 1+1 ' ) assert 1.0 == s.evaluate( 'cos(2*PI)' ) public interface GroovyCodeVisitor { void visitBlockStatement(BlockStatement statement); void visitForLoop(ForStatement forLoop); void visitWhileLoop(WhileStatement loop); void visitDoWhileLoop(DoWhileStatement loop); ... }
  • 55.
  • 56. How it Works Compiles Groovy to AST Analyzes AST Nodes – Not well typed – Not many tokens – unreliable with other AST Transforms
  • 57.
  • 58.
  • 59.
  • 60.
  • 61. Ruby FizzBuzz 1.upto(100) do |n| print &quot;Fizz&quot; if a = ((n % 3) == 0) print &quot;Buzz&quot; if b = ((n % 5) == 0) print n unless (a || b) print &quot;&quot; end
  • 62. Mirah FizzBuzz 1.upto(100) do |n| print &quot;Fizz&quot; if a = ((n % 3) == 0) print &quot;Buzz&quot; if b = ((n % 5) == 0) print n unless (a || b) print &quot;&quot; end
  • 63. Mirah: Pure JVM Class Output public class Fizz-buzz { public static void main(String[] argv) { ... do { n = __xform_tmp_4; ... if (n % 15 == 0) System.out.println(&quot;FizzBuzz&quot;); else if (n % 5 == 0) System.out.println(&quot;Buzz&quot;); else if (n % 3 == 0) System.out.println(&quot;Fizz&quot;); else System.out.println(n); ... } while (__xform_tmp_4 <= __xform_tmp_5); } }
  • 64. Mirah: .java File Output if (((n % 15) == 0)) { PrintStream temp$10 = System.out; temp$10.println(&quot;FizzBuzz&quot;); } else { if (((n % 5) == 0)) { PrintStream temp$11 = System.out; temp$11.println(&quot;Buzz&quot;); } else { if (((n % 3) == 0)) { PrintStream temp$12 = System.out; temp$12.println(&quot;Fizz&quot;); } else { PrintStream temp$13 = System.out; temp$13.println(n); } } }
  • 65. What it Means – Fast – Lightweight – Uses JDK – Runs on Android? – Runs on GWT?
  • 68.  
  • 69. Mirah Macros macro def eachChar(value, &block) quote { `value`.toCharArray.each do | my_char | `block.body` end } end eachChar('laat de leeeuw niet ...') do | my_char | puts my_char end
  • 70. Mirah Macros class Person make_attr :firstName, :string end p = Person.new p.firstName = 'hamlet' puts p.firstName
  • 71. Mirah Macros macro def make_attr(name, type) attribute_name = name.string_value() quote { def `name` @`name` end def `&quot;#{attribute_name}_set&quot;`(value:`type`) @`name` = value end } end
  • 72.
  • 73. Difficult to find call-sites
  • 74.
  • 75. Easily quote ASTs into source
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83. – Groovy Wiki and Mailing List is amazingly helpful
  • 84. – Use your creativity and patience
  • 85. – http://hamletdarcy.blogspot.com & @HamletDRC Groovy, Grails, Griffon, and Agile Consulting [email_address] or [email_address]