I was looking at transforming the AST to take the links into account.
Last year with Clara we did that with a AST visitor that copies the AST while
transforming it
(e.g. adding the code for the before link).
But this is not that easy as it sounds when taking the whole picture into
account
(cached #ast per method, using AST for mapping byte code offset->text and using
it in all the tools).
for example, this should work:
testUninstallLinkAndRun
| sendNode link |
sendNode := (ReflectivityExamples>>#exampleMethod) ast body statements
first value.
link := MetaLink new metaObject: nil; selector: #value. “do nothing"
sendNode link: link.
self assert: sendNode hasMetalink.
self assert: (ReflectivityExamples>>#exampleMethod) class =
ReflectiveMethod.
self assert: (ReflectivityExamples new exampleMethod = 5).
sendNode := (ReflectivityExamples>>#exampleMethod) ast body statements
first value.
self assert: sendNode hasMetalink.
self assert: (ReflectivityExamples>>#exampleMethod) class =
CompiledMethod.
link uninstall.
this means asking the compiled method for an AST *after* putting a link onto an
AST node
of the method should return an AST where that node actually has that link… even
after recompiling
the method.
So I think what we should do is to not change the AST and not even transform
it, instead
we keep the original and annotate it.
We generate AST nodes (small sub ASTs) for the links and annotate the AST with
those,
then visit them in the visitors later as if they would be part of the AST.
e.g. for before, the semantic checker visits the exception added for the links,
then
ASTTranslator visited them for code generation.
This way everything should work.
What we need
-> finally simplify ASTTranslator so we can actually subclass it and configure
a compiler
instance to use the subclass.
-> implement that plugin infrastructure
-> implement ASTTranslator subclass that takes #before into account
-> check how much complexity is needed for #around… or #after on methodNode
with
primitive methods. Does it work for these cases?
The change is too big for Pharo4 and will happen in Pharo5.
Marcus
> After experimenting with the AST transformer, I think I will for now (for
> Pharo4)
> just do it very simple: add the resulting hook as an annotation (beforeHook)
> to
> the AST node, do name analysis on those and then visit them in the
> ASTTranslator
> to generate code.
>
> This is very easy for “before” links, and the milestone we need for Pharo4 is
> just before to support Breakpoints and change-notification on variable access.
>
> Having just one AST is important for text/bc to AST mapping… when transforming
> one needs to take care to not destroy all this meta information… so we will
> postpone
> that to Pharo5.
>