SlideShare a Scribd company logo
Advanced Re
fl
ection:
MetaLinks
Marcus Denker, Inria
http://marcusdenker.de
Lecture at VUB Brussels, March 31, 2022
What we know…
• Smalltalk is re
fl
ective

• Classes, Methods, Stack-Frames… are Objects

• Re
fl
ective API on all Objects
Re
fl
ection in Smalltalk
• Re
fl
ection is based on the Metaclass model, thus it is
inherently structural

• Behavioral Re
fl
ection limited to:

• Method lookup on failure (#doesNotUndersand:)

• Rei
fi
ed stack (thisContext)
Can we do better?
• A more
fi
ne-grained re
fl
ective mechanism seems to be
missing

• Let’s look again at a Method in the Inspector
Inspector on a Method
The AST
• AST = Abstract Syntax Tree

• Tree Representation of the Method

• Produced by the Parser (part of the Compiler)

• Used by all tools (refactoring, syntax-highlighting,…)
Smalltalk compiler parse: 'test ^(1+2)'
AST
• RBMethodNode Root

• RBVariableNode Variable (read and write)

• RBAssignmentNode Assignment

• RBMessageNode A Message (most of them)

• RBReturnNode Return
Inspect a simple AST
• A very simple Example
Smalltalk compiler parse: 'test ^(1+2)'
AST: Navigation
• To make it easy to
fi
nd and enumerate nodes, there are
some helper methods

• CompiledMethod has: #sendNodes,
#variableNodes, #assignmentNodes
• Every AST node has #nodesDo: and #allChildren
AST: Visitor
• RBProgramNodeVisitor: Visitor Pattern for the AST

• Make subclass, override visit… methods

• Let’s see it in action: Count Message sends
Demo: Visitor
Repeat:The AST
• AST = Abstract Syntax Tree

• Tree Representation of the Method

• Produced by the Parser (part of the Compiler)

• Used by all tools (refactoring, syntax-highlighting,…)
Smalltalk compiler parse: 'test ^(1+2)'
The Compiler
• Smalltalk compiler -> Compiler Facade 

• Classes de
fi
ne the compiler to use

• You can override method #compiler

• Behind: Compiler Chain
The Compiler
Source AST
Annotated
AST
IR
Annotated
AST
Bytecode
RBParser OCSemanticAnalyzer
OCASTTranslator/
IRBuilder
IRBytecodeGenerator
AST Integration
• Originally just internal to the compiler

• Pharo: 

• send #ast to a method to get the AST

• Cached for persistency.
(Point>>#x) ast == (Point>>#x) ast
—> true
AST Integration
• We can navigate from execution to AST

• Example:
[ 1 + 2 ] sourceNode ==
thisContext method sourceNode blockNodes first
Compiler: Extensible
• All parts can be subclassed

• Compiler instance can be setup to use the subclass for
any part (parser, name analysis, translator…)

• enable for a class only by implementing #compiler on the
class side
Compiler Plugins
• The AST can be easily transformed

• We added a Plugin architecture to the Compiler

• enable for a class only by implementing:
compiler

	 ^super compiler addPlugin: MyPlugin
The Compiler
Source AST
Annotated
AST
IR
Annotated
AST
Bytecode
RBParser OCSemanticAnalyzer
OCASTTranslator/
IRBuilder
IRBytecodeGenerator
Plugin
Source AST
Annotated
AST
IR
Annotated
AST
Bytecode
RBParser OCSemanticAnalyzer
OCASTTranslator/
IRBuilder
IRBytecodeGenerator
OCCompilerASTPlugin
Annotated
AST
Plugin: Example
• We get all ifTrue: sends

• replace them with true
DemoPlugin>>transform
transform
| sends |
sends := ast sendNodes.
sends := sends select: [ :each | each selector = #ifTrue: ].
sends do: [:each | each replaceWith:
(RBLiteralNode value: true)].
^ast
Back to the topic…
• A more
fi
ne-grained re
fl
ective mechanism seems to be
missing

• Can’t we do something with the AST?
Wouldn’t it be nice..
• With the AST, wouldn’t it be nice if we could use this
structure for Behavioural Re
fl
ection?

• If we could somehow attach a “arrow to the code” that
points to a meta-object
test
^( 1 + 2 )
meta-object
for this Send
We have all pieces…
• We have the AST for each method

• It is quite simple

• We have a compiler in the system

• So this should be possible…
The MetaLink
• MetaLink points to metaObject

• De
fi
nes a selector to call

• And a control attribute: #before, #after, #instead

• Installed on a AST node:
link := MetaLink new
metaObject: Halt;
selector: #once;
control: #before.
(Number>>#sin) ast link: link
The MetaLink
• Can be installed on any AST Node

• Methods will be re-compiled on the
fl
y just before next
execution

• Link installation is very fast

• Changing a method removes all links from this method

• Managing link re-installation has to be done by the user
MetaLink: MetaObject
• MetaObject can be any object

• Even a Block: [Transcript show ‘hello’]
• Install on any Node with #link:

• de-install a link with #uninstall
MetaLink: Selector
• MetaLink de
fi
nes a message send to the MetaObject

• #selector de
fi
nes which one

• Default is #value

• Yes, a selector with arguments is supported 

• We can pass information to the meta-object
MetaLink: Argument
• The arguments de
fi
ne which arguments to pass

• We support a number of rei
fi
cations
Rei
fi
cations
• Rei
fi
cations de
fi
ne data to be passed as arguments

• Reify —> Make something into an object that is not one
normally

• Example: “All arguments of this message”
Rei
fi
cations: examples
• All nodes: #object #context #class #node
#link
• Sends: #arguments #receiver #selector
• Method: #arguments #selector 

• Variable: #value

They are de
fi
ned as subclasses of class RFRei
fi
cation
Rei
fi
cations as MetaObject
• We support some special metaObjects:

• #node The AST Node we are installed on

• #object self at runtime

• #class The class the links is installed in
MetaLink: Condition
• We can specify a condition for the MetaLink

• Link is active if the condition evaluates to true
• We can pass rei
fi
cations as arguments
link := MetaLink new
metaObject: Halt;
selector: #once;
condition: [:object | object == 5] arguments: #(object).
(Number>>#sin) ast link: link.
MetaLink: control
• We can specify when to call the meta-object

• We support #before, #after and #instead
• The instead is very simple: last one wins
Example: Log
• We want to just print something to the Transcript
link := MetaLink new
metaObject: [Transcript show: 'Reached Here'].
(Number>>#sin) ast link: link
Recursion Problem
• Before we see more examples: There is a problem

• Imagine we put a MetaLink on some method deep in the
System (e.g new, +, do: ).

• Our Meta-Object might use exactly that method, too
Endless Loop!!
Recursion Problem
• Solution: Meta-Level

• We encode the a level in the execution of the system

• Every Link Activation increases the level

• A meta-link is just active for one level. (e.g. 0)
link := MetaLink new
metaObject: [ Object new ];
level: 0.
(Behavior>>#new) ast link: link.
Example: Log
• Better use #level: 0

• Nevertheless: be careful! If you add this to method called
often it can be very slow.
link := MetaLink new
metaObject: [Transcript show: 'Reached Here’];
level: 0.
Example: Counter
• In the Browser you can add a “counter” to the AST

• See class ExecutionCounter
install
link := MetaLink new
metaObject: self;
selector: #increase.
node link: link.
Example: Breakpoint
• “Add Breakpoint” in AST (Suggestions) Menu

• See class Breakpoint

• Break Once 

• Conditional Break breakLink
^ MetaLink new
metaObject: Break;
selector: #break;
options: options
Example: WatchPoint
• Watchpoint: Record Value at a point in the AST

• Example: Watch event in WorldMorph>>#mouseDown:
Click on background
-> value recorded
Example: WatchPoint
• Implementation: class Watchpoint, method install

• example of a #after link with a condition
link := MetaLink new
metaObject: self;
selector: #addValue:;
arguments: #(value);
control: #after;
condition: [ recording ].
Example: Code Coverage
• Small Demo.

• Start with CoverageDemo new open
Example: Code Coverage
• Example of a MetaLink with a #node MetaObject

• Meta-Object is the node that the link is installed on
link := MetaLink new
metaObject: #node;
selector: #tagExecuted.
Interesting Properties
• Cross Cutting

• One Link can be installed multiple times

• Over multiple methods and even Classes

• And across operations (e.g., Send and Assignment) as
long as all rei
fi
cations requested are compatible

• Fully Dynamic: Links can be added and removed at runtime

• Even by the meta-object of another meta-link!
Example: Accept for Test
• Imagine we want to edit a method that is called often by
the System.

• How do we test it?

• It would be nice if we could “Accept for Test”
Example: Accept for Test
• Menu in the browser: AST menu shows for all nodes.
SycSourceCodeCommand subclass: #SycAcceptForTest
instanceVariableNames: 'source'
classVariableNames: ''
package: 'SystemCommands-SourceCodeCommands'
defaultMenuItemName
^'Accept for Test'
readParametersFromContext: aSourceCodeContext
super readParametersFromContext: aSourceCodeContext.
source := aSourceCodeContext tool pendingText
• We implement our code in the #execute method
Example: Accept for Test
• How we know that we are in a test?
CurrentExecutionEnvironment value isTest
• We can compile the current text bu
ff
er
newMethod := method methodClass compiler
source: source;
options: #(+ optionParseErrors);
compile.
Example: Accept for Test
• Add this code to the beginning of the method:
[:aContext :args |
CurrentExecutionEnvironment value isTest ifTrue: [
aContext return: (newMethod
valueWithReceiver: aContext
receiver
arguments: args) ]]
• Let’s do that with a MetaLink!
Example: Accept for Test
execute
| newMethod metaLink |
newMethod := method methodClass compiler
source: source;
options: #(+ optionParseErrors);
compile.
"the link executes the method we just created and returns"
metaLink := MetaLink new
metaObject: [ :aContext :args |
CurrentExecutionEnvironment value isTest
ifTrue: [ aContext return: (newMethod
valueWithReceiver: aContext receiver
arguments: args) ] ];
selector: #value:value:;
arguments: #(context arguments).
self method ast link: metaLink
What did we see?
• ASTs and AST Visitors

• Compiler and Compiler Plugins

• MetaLinks 

• Recursion Problem

• Examples: Counter, Breakpoint, Coverage

• Accept for Test
Limitations
• #instead needs more work (e.g to support conditions)

• Keep in mind: next metaLink taken into account for next
method activation 

• Take care with long running loops!
Help Wanted
• We are always interested in improvements!

• Pharo 10 will be released soon! 

• Pull Requests Welcome!
Questions?

More Related Content

PDF
Lecture: "Advanced Reflection: MetaLinks"
PDF
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
PDF
Lecture: Advanced Reflection. MetaLinks
PDF
Lecture: MetaLinks
PDF
Behavioral Reflection in Pharo
PDF
Reflection in Pharo5
PDF
#Pharo Days 2016 Reflectivity
PDF
Reflection in Pharo: Beyond Smalltak
Lecture: "Advanced Reflection: MetaLinks"
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
Lecture: Advanced Reflection. MetaLinks
Lecture: MetaLinks
Behavioral Reflection in Pharo
Reflection in Pharo5
#Pharo Days 2016 Reflectivity
Reflection in Pharo: Beyond Smalltak

Similar to Lecture. Advanced Reflection: MetaLinks (20)

PDF
Reflection in Pharo: Beyond Smalltak
PPT
Behavioral Reflection
PDF
First Class Variables as AST Annotations
PDF
First Class Variables as AST Annotations
PPTX
Introduction to JcjfjfjfkuutyuyrsdterdfbvAVA.pptx
KEY
DjangoCon 2010 Scaling Disqus
PPTX
Pptchdtdtfygugyxthgihhihigugufydtdfzrzrzrtdyfyfy
PDF
Variables in Pharo
PDF
540slidesofnodejsbackendhopeitworkforu.pdf
PDF
Runtime Bytecode Transformation for Smalltalk
PDF
Runtime Bytecode Transformation for Smalltalk
PPTX
Data weave (MuleSoft)
PPTX
The hardest part of microservices: your data
PPTX
Standard Template Library
PPT
JAVA Servlets
PPTX
gdscWorkShopJavascriptintroductions.pptx
PPTX
TypeScript: Basic Features and Compilation Guide
PPTX
DDD, CQRS and testing with ASP.Net MVC
PDF
Spring Day | Spring and Scala | Eberhard Wolff
Reflection in Pharo: Beyond Smalltak
Behavioral Reflection
First Class Variables as AST Annotations
First Class Variables as AST Annotations
Introduction to JcjfjfjfkuutyuyrsdterdfbvAVA.pptx
DjangoCon 2010 Scaling Disqus
Pptchdtdtfygugyxthgihhihigugufydtdfzrzrzrtdyfyfy
Variables in Pharo
540slidesofnodejsbackendhopeitworkforu.pdf
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for Smalltalk
Data weave (MuleSoft)
The hardest part of microservices: your data
Standard Template Library
JAVA Servlets
gdscWorkShopJavascriptintroductions.pptx
TypeScript: Basic Features and Compilation Guide
DDD, CQRS and testing with ASP.Net MVC
Spring Day | Spring and Scala | Eberhard Wolff
Ad

More from Marcus Denker (20)

PDF
Soil And Pharo
PDF
ConstantBlocks in Pharo11
PDF
Demo: Improved DoIt
PDF
Supporting Pharo / Getting Pharo Support
PDF
thisContext in the Debugger
PDF
Improving code completion for Pharo
PDF
Slot Composition
PDF
PHARO IOT
PDF
Open-Source: An Infinite Game
PDF
PharoTechTalk: Contributing to Pharo
PDF
Feedback Loops in Practice
PDF
Pharo6 - ESUG17
PDF
PDF
Perfection & Feedback Loops or: why worse is better
PDF
Dynamically Composing Collection Operations through Collection Promises
PDF
Variables in Pharo5
PDF
How to Contribute to Pharo
PDF
Pharo Status (from PharoDays 2015)
PDF
Pharo Status Fosdem 2015
PDF
Pharo Status ESUG 2014
Soil And Pharo
ConstantBlocks in Pharo11
Demo: Improved DoIt
Supporting Pharo / Getting Pharo Support
thisContext in the Debugger
Improving code completion for Pharo
Slot Composition
PHARO IOT
Open-Source: An Infinite Game
PharoTechTalk: Contributing to Pharo
Feedback Loops in Practice
Pharo6 - ESUG17
Perfection & Feedback Loops or: why worse is better
Dynamically Composing Collection Operations through Collection Promises
Variables in Pharo5
How to Contribute to Pharo
Pharo Status (from PharoDays 2015)
Pharo Status Fosdem 2015
Pharo Status ESUG 2014
Ad

Recently uploaded (20)

PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
KodekX | Application Modernization Development
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Encapsulation theory and applications.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Electronic commerce courselecture one. Pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Diabetes mellitus diagnosis method based random forest with bat algorithm
Network Security Unit 5.pdf for BCA BBA.
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Empathic Computing: Creating Shared Understanding
KodekX | Application Modernization Development
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Encapsulation theory and applications.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
NewMind AI Monthly Chronicles - July 2025
Electronic commerce courselecture one. Pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
The AUB Centre for AI in Media Proposal.docx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
“AI and Expert System Decision Support & Business Intelligence Systems”
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
CIFDAQ's Market Insight: SEC Turns Pro Crypto

Lecture. Advanced Reflection: MetaLinks

  • 1. Advanced Re fl ection: MetaLinks Marcus Denker, Inria http://marcusdenker.de Lecture at VUB Brussels, March 31, 2022
  • 2. What we know… • Smalltalk is re fl ective • Classes, Methods, Stack-Frames… are Objects • Re fl ective API on all Objects
  • 3. Re fl ection in Smalltalk • Re fl ection is based on the Metaclass model, thus it is inherently structural • Behavioral Re fl ection limited to: • Method lookup on failure (#doesNotUndersand:) • Rei fi ed stack (thisContext)
  • 4. Can we do better? • A more fi ne-grained re fl ective mechanism seems to be missing • Let’s look again at a Method in the Inspector
  • 5. Inspector on a Method
  • 6. The AST • AST = Abstract Syntax Tree • Tree Representation of the Method • Produced by the Parser (part of the Compiler) • Used by all tools (refactoring, syntax-highlighting,…) Smalltalk compiler parse: 'test ^(1+2)'
  • 7. AST • RBMethodNode Root • RBVariableNode Variable (read and write) • RBAssignmentNode Assignment • RBMessageNode A Message (most of them) • RBReturnNode Return
  • 8. Inspect a simple AST • A very simple Example Smalltalk compiler parse: 'test ^(1+2)'
  • 9. AST: Navigation • To make it easy to fi nd and enumerate nodes, there are some helper methods • CompiledMethod has: #sendNodes, #variableNodes, #assignmentNodes • Every AST node has #nodesDo: and #allChildren
  • 10. AST: Visitor • RBProgramNodeVisitor: Visitor Pattern for the AST • Make subclass, override visit… methods • Let’s see it in action: Count Message sends
  • 12. Repeat:The AST • AST = Abstract Syntax Tree • Tree Representation of the Method • Produced by the Parser (part of the Compiler) • Used by all tools (refactoring, syntax-highlighting,…) Smalltalk compiler parse: 'test ^(1+2)'
  • 13. The Compiler • Smalltalk compiler -> Compiler Facade • Classes de fi ne the compiler to use • You can override method #compiler • Behind: Compiler Chain
  • 14. The Compiler Source AST Annotated AST IR Annotated AST Bytecode RBParser OCSemanticAnalyzer OCASTTranslator/ IRBuilder IRBytecodeGenerator
  • 15. AST Integration • Originally just internal to the compiler • Pharo: • send #ast to a method to get the AST • Cached for persistency. (Point>>#x) ast == (Point>>#x) ast —> true
  • 16. AST Integration • We can navigate from execution to AST • Example: [ 1 + 2 ] sourceNode == thisContext method sourceNode blockNodes first
  • 17. Compiler: Extensible • All parts can be subclassed • Compiler instance can be setup to use the subclass for any part (parser, name analysis, translator…) • enable for a class only by implementing #compiler on the class side
  • 18. Compiler Plugins • The AST can be easily transformed • We added a Plugin architecture to the Compiler • enable for a class only by implementing: compiler ^super compiler addPlugin: MyPlugin
  • 19. The Compiler Source AST Annotated AST IR Annotated AST Bytecode RBParser OCSemanticAnalyzer OCASTTranslator/ IRBuilder IRBytecodeGenerator
  • 21. Plugin: Example • We get all ifTrue: sends • replace them with true DemoPlugin>>transform transform | sends | sends := ast sendNodes. sends := sends select: [ :each | each selector = #ifTrue: ]. sends do: [:each | each replaceWith: (RBLiteralNode value: true)]. ^ast
  • 22. Back to the topic… • A more fi ne-grained re fl ective mechanism seems to be missing • Can’t we do something with the AST?
  • 23. Wouldn’t it be nice.. • With the AST, wouldn’t it be nice if we could use this structure for Behavioural Re fl ection? • If we could somehow attach a “arrow to the code” that points to a meta-object test ^( 1 + 2 ) meta-object for this Send
  • 24. We have all pieces… • We have the AST for each method • It is quite simple • We have a compiler in the system • So this should be possible…
  • 25. The MetaLink • MetaLink points to metaObject • De fi nes a selector to call • And a control attribute: #before, #after, #instead • Installed on a AST node: link := MetaLink new metaObject: Halt; selector: #once; control: #before. (Number>>#sin) ast link: link
  • 26. The MetaLink • Can be installed on any AST Node • Methods will be re-compiled on the fl y just before next execution • Link installation is very fast • Changing a method removes all links from this method • Managing link re-installation has to be done by the user
  • 27. MetaLink: MetaObject • MetaObject can be any object • Even a Block: [Transcript show ‘hello’] • Install on any Node with #link: • de-install a link with #uninstall
  • 28. MetaLink: Selector • MetaLink de fi nes a message send to the MetaObject • #selector de fi nes which one • Default is #value • Yes, a selector with arguments is supported • We can pass information to the meta-object
  • 29. MetaLink: Argument • The arguments de fi ne which arguments to pass • We support a number of rei fi cations
  • 30. Rei fi cations • Rei fi cations de fi ne data to be passed as arguments • Reify —> Make something into an object that is not one normally • Example: “All arguments of this message”
  • 31. Rei fi cations: examples • All nodes: #object #context #class #node #link • Sends: #arguments #receiver #selector • Method: #arguments #selector • Variable: #value
 They are de fi ned as subclasses of class RFRei fi cation
  • 32. Rei fi cations as MetaObject • We support some special metaObjects: • #node The AST Node we are installed on • #object self at runtime • #class The class the links is installed in
  • 33. MetaLink: Condition • We can specify a condition for the MetaLink • Link is active if the condition evaluates to true • We can pass rei fi cations as arguments link := MetaLink new metaObject: Halt; selector: #once; condition: [:object | object == 5] arguments: #(object). (Number>>#sin) ast link: link.
  • 34. MetaLink: control • We can specify when to call the meta-object • We support #before, #after and #instead • The instead is very simple: last one wins
  • 35. Example: Log • We want to just print something to the Transcript link := MetaLink new metaObject: [Transcript show: 'Reached Here']. (Number>>#sin) ast link: link
  • 36. Recursion Problem • Before we see more examples: There is a problem • Imagine we put a MetaLink on some method deep in the System (e.g new, +, do: ). • Our Meta-Object might use exactly that method, too Endless Loop!!
  • 37. Recursion Problem • Solution: Meta-Level • We encode the a level in the execution of the system • Every Link Activation increases the level • A meta-link is just active for one level. (e.g. 0) link := MetaLink new metaObject: [ Object new ]; level: 0. (Behavior>>#new) ast link: link.
  • 38. Example: Log • Better use #level: 0 • Nevertheless: be careful! If you add this to method called often it can be very slow. link := MetaLink new metaObject: [Transcript show: 'Reached Here’]; level: 0.
  • 39. Example: Counter • In the Browser you can add a “counter” to the AST • See class ExecutionCounter install link := MetaLink new metaObject: self; selector: #increase. node link: link.
  • 40. Example: Breakpoint • “Add Breakpoint” in AST (Suggestions) Menu • See class Breakpoint • Break Once • Conditional Break breakLink ^ MetaLink new metaObject: Break; selector: #break; options: options
  • 41. Example: WatchPoint • Watchpoint: Record Value at a point in the AST • Example: Watch event in WorldMorph>>#mouseDown: Click on background -> value recorded
  • 42. Example: WatchPoint • Implementation: class Watchpoint, method install • example of a #after link with a condition link := MetaLink new metaObject: self; selector: #addValue:; arguments: #(value); control: #after; condition: [ recording ].
  • 43. Example: Code Coverage • Small Demo. • Start with CoverageDemo new open
  • 44. Example: Code Coverage • Example of a MetaLink with a #node MetaObject • Meta-Object is the node that the link is installed on link := MetaLink new metaObject: #node; selector: #tagExecuted.
  • 45. Interesting Properties • Cross Cutting • One Link can be installed multiple times • Over multiple methods and even Classes • And across operations (e.g., Send and Assignment) as long as all rei fi cations requested are compatible • Fully Dynamic: Links can be added and removed at runtime • Even by the meta-object of another meta-link!
  • 46. Example: Accept for Test • Imagine we want to edit a method that is called often by the System. • How do we test it? • It would be nice if we could “Accept for Test”
  • 47. Example: Accept for Test • Menu in the browser: AST menu shows for all nodes. SycSourceCodeCommand subclass: #SycAcceptForTest instanceVariableNames: 'source' classVariableNames: '' package: 'SystemCommands-SourceCodeCommands' defaultMenuItemName ^'Accept for Test' readParametersFromContext: aSourceCodeContext super readParametersFromContext: aSourceCodeContext. source := aSourceCodeContext tool pendingText • We implement our code in the #execute method
  • 48. Example: Accept for Test • How we know that we are in a test? CurrentExecutionEnvironment value isTest • We can compile the current text bu ff er newMethod := method methodClass compiler source: source; options: #(+ optionParseErrors); compile.
  • 49. Example: Accept for Test • Add this code to the beginning of the method: [:aContext :args | CurrentExecutionEnvironment value isTest ifTrue: [ aContext return: (newMethod valueWithReceiver: aContext receiver arguments: args) ]] • Let’s do that with a MetaLink!
  • 50. Example: Accept for Test execute | newMethod metaLink | newMethod := method methodClass compiler source: source; options: #(+ optionParseErrors); compile. "the link executes the method we just created and returns" metaLink := MetaLink new metaObject: [ :aContext :args | CurrentExecutionEnvironment value isTest ifTrue: [ aContext return: (newMethod valueWithReceiver: aContext receiver arguments: args) ] ]; selector: #value:value:; arguments: #(context arguments). self method ast link: metaLink
  • 51. What did we see? • ASTs and AST Visitors • Compiler and Compiler Plugins • MetaLinks • Recursion Problem • Examples: Counter, Breakpoint, Coverage • Accept for Test
  • 52. Limitations • #instead needs more work (e.g to support conditions) • Keep in mind: next metaLink taken into account for next method activation • Take care with long running loops!
  • 53. Help Wanted • We are always interested in improvements! • Pharo 10 will be released soon! • Pull Requests Welcome!