[Reflectivity] ... and Roassal

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Reflectivity] ... and Roassal

Marcus Denker-4
Hi,

Yesterday Alex and me played with using Roassal in combination with reflectivity.

Very quickly (within half an hour, even shorter) we had a view per class that shows coverage for ASTs as trees
like this: 


 


this is

| t |
t := false.
t ifTrue: [ self bar ] ifFalse: [ 'hello' ].
^ 5 


and you directly see that I have not yet added support for annotating optimized blocks… will come soon.
(These views are nice for debugging reflectivity…)


The code:

1) node-by-node coverage:

getCoverageOf: aPharoClass whileExecuting: aBlock
"
self new getCoverageOf: CoverageDemoTest whileExecuting: [  CoverageDemoTest new simpleAst ]
"

| link |
link := MetaLink new
metaObject: #node;
selector: #tagExecuted.
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass
and the code for visalization:

renderCoverage
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape label
text: [ :astNode | 
| aName |
aName := astNode class name copyFrom: 3 to: astNode class name size.
(aName endsWith: 'Node') 
ifTrue: [ aName copyFrom: 1 to: aName size - 'Node' size ]
ifFalse: [ aName ]
] ;
color: Color red;
if: #hasBeenExecuted color: Color green.
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


A second example shows often executed nodes larger (shows another bug… the one largest should have the same size as the other large ones):


Code:



renderNodeExecutions
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape rectangle
size: [ :astNode | astNode propertyAt: #nbExecutions ifAbsent: [ 0 ] ].
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


getNodeExecution: aPharoClass whileExecuting: aBlock
"
self new getNodeExecution: CoverageDemoTest whileExecuting: [ 
30 timesRepeat: [  CoverageDemoTest new simpleAst  ] ]
"

| link |
link := MetaLink new
metaObject: [ :node | 
| v |
v := node propertyAt: #nbExecutions ifAbsentPut: [ 0 ].
node propertyAt: #nbExecutions put: v + 1 ];
selector: #value:;
arguments: #(#node).
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass


These are just very quick and raw experiments… but they got us excited about the possibilities when this is all
debugged and ready…

Marcus



Reply | Threaded
Open this post in threaded view
|

Re: [Reflectivity] ... and Roassal

Tudor Girba-2
Exactly!

This is what happens when all these tools are readily available in the IDE during development.

It's often hard to understand the power of these seemingly small things, until you experience their impact on your own problem.

Cheers,
Doru



On Fri, Jul 24, 2015 at 8:57 AM, Marcus Denker <[hidden email]> wrote:
Hi,

Yesterday Alex and me played with using Roassal in combination with reflectivity.

Very quickly (within half an hour, even shorter) we had a view per class that shows coverage for ASTs as trees
like this: 


 


this is

| t |
t := false.
t ifTrue: [ self bar ] ifFalse: [ 'hello' ].
^ 5 


and you directly see that I have not yet added support for annotating optimized blocks… will come soon.
(These views are nice for debugging reflectivity…)


The code:

1) node-by-node coverage:

getCoverageOf: aPharoClass whileExecuting: aBlock
"
self new getCoverageOf: CoverageDemoTest whileExecuting: [  CoverageDemoTest new simpleAst ]
"

| link |
link := MetaLink new
metaObject: #node;
selector: #tagExecuted.
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass
and the code for visalization:

renderCoverage
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape label
text: [ :astNode | 
| aName |
aName := astNode class name copyFrom: 3 to: astNode class name size.
(aName endsWith: 'Node') 
ifTrue: [ aName copyFrom: 1 to: aName size - 'Node' size ]
ifFalse: [ aName ]
] ;
color: Color red;
if: #hasBeenExecuted color: Color green.
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


A second example shows often executed nodes larger (shows another bug… the one largest should have the same size as the other large ones):


Code:



renderNodeExecutions
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape rectangle
size: [ :astNode | astNode propertyAt: #nbExecutions ifAbsent: [ 0 ] ].
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


getNodeExecution: aPharoClass whileExecuting: aBlock
"
self new getNodeExecution: CoverageDemoTest whileExecuting: [ 
30 timesRepeat: [  CoverageDemoTest new simpleAst  ] ]
"

| link |
link := MetaLink new
metaObject: [ :node | 
| v |
v := node propertyAt: #nbExecutions ifAbsentPut: [ 0 ].
node propertyAt: #nbExecutions put: v + 1 ];
selector: #value:;
arguments: #(#node).
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass


These are just very quick and raw experiments… but they got us excited about the possibilities when this is all
debugged and ready…

Marcus






--

"Every thing has its own flow"
Reply | Threaded
Open this post in threaded view
|

Re: [Reflectivity] ... and Roassal

Thierry Goubier
In reply to this post by Marcus Denker-4
Hi Marcus,

what is interesting is when you show the control flow graph overlaid over the AST, inter procedural analysis (i.e. follow the call graph) and thread or process-based decomposition if the code is run in parallel. This is some of the things I've done for a demo, and, yes, it doesn't take much time. Roassal is very cool for doing that :)

Thierry

2015-07-24 8:57 GMT+02:00 Marcus Denker <[hidden email]>:
Hi,

Yesterday Alex and me played with using Roassal in combination with reflectivity.

Very quickly (within half an hour, even shorter) we had a view per class that shows coverage for ASTs as trees
like this: 


 


this is

| t |
t := false.
t ifTrue: [ self bar ] ifFalse: [ 'hello' ].
^ 5 


and you directly see that I have not yet added support for annotating optimized blocks… will come soon.
(These views are nice for debugging reflectivity…)


The code:

1) node-by-node coverage:

getCoverageOf: aPharoClass whileExecuting: aBlock
"
self new getCoverageOf: CoverageDemoTest whileExecuting: [  CoverageDemoTest new simpleAst ]
"

| link |
link := MetaLink new
metaObject: #node;
selector: #tagExecuted.
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass
and the code for visalization:

renderCoverage
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape label
text: [ :astNode | 
| aName |
aName := astNode class name copyFrom: 3 to: astNode class name size.
(aName endsWith: 'Node') 
ifTrue: [ aName copyFrom: 1 to: aName size - 'Node' size ]
ifFalse: [ aName ]
] ;
color: Color red;
if: #hasBeenExecuted color: Color green.
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


A second example shows often executed nodes larger (shows another bug… the one largest should have the same size as the other large ones):


Code:



renderNodeExecutions
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape rectangle
size: [ :astNode | astNode propertyAt: #nbExecutions ifAbsent: [ 0 ] ].
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


getNodeExecution: aPharoClass whileExecuting: aBlock
"
self new getNodeExecution: CoverageDemoTest whileExecuting: [ 
30 timesRepeat: [  CoverageDemoTest new simpleAst  ] ]
"

| link |
link := MetaLink new
metaObject: [ :node | 
| v |
v := node propertyAt: #nbExecutions ifAbsentPut: [ 0 ].
node propertyAt: #nbExecutions put: v + 1 ];
selector: #value:;
arguments: #(#node).
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass


These are just very quick and raw experiments… but they got us excited about the possibilities when this is all
debugged and ready…

Marcus




Reply | Threaded
Open this post in threaded view
|

Re: [Reflectivity] ... and Roassal

stepharo
In reply to this post by Marcus Denker-4
This is super cool :)

Stef

Le 24/7/15 08:57, Marcus Denker a écrit :
Hi,

Yesterday Alex and me played with using Roassal in combination with reflectivity.

Very quickly (within half an hour, even shorter) we had a view per class that shows coverage for ASTs as trees
like this: 


 


this is

| t |
t := false.
t ifTrue: [ self bar ] ifFalse: [ 'hello' ].
^ 5 


and you directly see that I have not yet added support for annotating optimized blocks… will come soon.
(These views are nice for debugging reflectivity…)


The code:

1) node-by-node coverage:

getCoverageOf: aPharoClass whileExecuting: aBlock
"
self new getCoverageOf: CoverageDemoTest whileExecuting: [  CoverageDemoTest new simpleAst ]
"

| link |
link := MetaLink new
metaObject: #node;
selector: #tagExecuted.
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass
and the code for visalization:

renderCoverage
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape label
text: [ :astNode | 
| aName |
aName := astNode class name copyFrom: 3 to: astNode class name size.
(aName endsWith: 'Node') 
ifTrue: [ aName copyFrom: 1 to: aName size - 'Node' size ]
ifFalse: [ aName ]
] ;
color: Color red;
if: #hasBeenExecuted color: Color green.
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


A second example shows often executed nodes larger (shows another bug… the one largest should have the same size as the other large ones):


Code:



renderNodeExecutions
| b |
b := RTMondrian new.

b shape rectangle withTextAbove: #selector.
b nodes: self methods forEach: [ :aMethod |
b shape rectangle
size: [ :astNode | astNode propertyAt: #nbExecutions ifAbsent: [ 0 ] ].
b nodes: aMethod ast  allChildren.
b edges connectFrom: #parent.
b layout tree.
].

b layout flow.
b build.
^ b view


getNodeExecution: aPharoClass whileExecuting: aBlock
"
self new getNodeExecution: CoverageDemoTest whileExecuting: [ 
30 timesRepeat: [  CoverageDemoTest new simpleAst  ] ]
"

| link |
link := MetaLink new
metaObject: [ :node | 
| v |
v := node propertyAt: #nbExecutions ifAbsentPut: [ 0 ].
node propertyAt: #nbExecutions put: v + 1 ];
selector: #value:;
arguments: #(#node).
aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
aBlock value.
^ aPharoClass


These are just very quick and raw experiments… but they got us excited about the possibilities when this is all
debugged and ready…

Marcus




Reply | Threaded
Open this post in threaded view
|

Re: [Reflectivity] ... and Roassal

Sven Van Caekenberghe-2
In reply to this post by Tudor Girba-2
Very nice.

Yes, interactive visualisation tools raise the level of abstraction beyond the status quo.

> On 24 Jul 2015, at 09:53, Tudor Girba <[hidden email]> wrote:
>
> Exactly!
>
> This is what happens when all these tools are readily available in the IDE during development.
>
> It's often hard to understand the power of these seemingly small things, until you experience their impact on your own problem.
>
> Cheers,
> Doru
>
>
>
> On Fri, Jul 24, 2015 at 8:57 AM, Marcus Denker <[hidden email]> wrote:
> Hi,
>
> Yesterday Alex and me played with using Roassal in combination with reflectivity.
>
> Very quickly (within half an hour, even shorter) we had a view per class that shows coverage for ASTs as trees
> like this:
>
>
>  <coverage.png>
>
>
> this is
>
> | t |
> t := false.
> t ifTrue: [ self bar ] ifFalse: [ 'hello' ].
> ^ 5
>
>
> and you directly see that I have not yet added support for annotating optimized blocks… will come soon.
> (These views are nice for debugging reflectivity…)
>
>
> The code:
>
> 1) node-by-node coverage:
>
> getCoverageOf: aPharoClass whileExecuting: aBlock
> "
> self new getCoverageOf: CoverageDemoTest whileExecuting: [  CoverageDemoTest new simpleAst ]
> "
>
> | link |
> link := MetaLink new
> metaObject: #node;
> selector: #tagExecuted.
> aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
> aBlock value.
> ^ aPharoClass
>
>
> and the code for visalization:
>
> renderCoverage
> | b |
> b := RTMondrian new.
>
> b shape rectangle withTextAbove: #selector.
> b nodes: self methods forEach: [ :aMethod |
> b shape label
> text: [ :astNode |
> | aName |
> aName := astNode class name copyFrom: 3 to: astNode class name size.
> (aName endsWith: 'Node')
> ifTrue: [ aName copyFrom: 1 to: aName size - 'Node' size ]
> ifFalse: [ aName ]
> ] ;
> color: Color red;
> if: #hasBeenExecuted color: Color green.
> b nodes: aMethod ast  allChildren.
> b edges connectFrom: #parent.
> b layout tree.
> ].
>
> b layout flow.
> b build.
> ^ b view
>
>
> A second example shows often executed nodes larger (shows another bug… the one largest should have the same size as the other large ones):
>
> <executions.png>
>
> Code:
>
>
>
> renderNodeExecutions
> | b |
> b := RTMondrian new.
>
> b shape rectangle withTextAbove: #selector.
> b nodes: self methods forEach: [ :aMethod |
> b shape rectangle
> size: [ :astNode | astNode propertyAt: #nbExecutions ifAbsent: [ 0 ] ].
> b nodes: aMethod ast  allChildren.
> b edges connectFrom: #parent.
> b layout tree.
> ].
>
> b layout flow.
> b build.
> ^ b view
>
>
> getNodeExecution: aPharoClass whileExecuting: aBlock
> "
> self new getNodeExecution: CoverageDemoTest whileExecuting: [
> 30 timesRepeat: [  CoverageDemoTest new simpleAst  ] ]
> "
>
> | link |
> link := MetaLink new
> metaObject: [ :node |
> | v |
> v := node propertyAt: #nbExecutions ifAbsentPut: [ 0 ].
> node propertyAt: #nbExecutions put: v + 1 ];
> selector: #value:;
> arguments: #(#node).
> aPharoClass methods do: [ :cm | cm ast nodesDo: [ :node | node link: link ] ].
> aBlock value.
> ^ aPharoClass
>
>
> These are just very quick and raw experiments… but they got us excited about the possibilities when this is all
> debugged and ready…
>
> Marcus
>
>
>
>
>
>
> --
> www.tudorgirba.com
>
> "Every thing has its own flow"