digitalmars.D.learn - aspects on methods?
- jj75607 (33/33) Jul 12 2016 I want to use aspect-like annotations to transform
- Lodovico Giaretta (9/42) Jul 12 2016 I don't think UDAs can be used that way in D, but I'm not an
- ketmar (3/3) Jul 12 2016 On Tuesday, 12 July 2016 at 11:26:20 UTC, jj75607 wrote:
- Anonymouse (23/24) Jul 13 2016 [...]
I want to use aspect-like annotations to transform Lockable class Abc { sync void f() { writeln("f"); } shared void g() { writeln("g"); } } to something like: class Abc { shared(ReadWriteMutex) _lock123; this() { _lock123 = cast(shared)(new ReadWriteMutex()); } void f() { synchronized((cast()_lock123).writer) { writeln("f"); } } void g() { synchronized((cast()_lock123).reader) { writeln("g"); } } } How can I do that?
Jul 12 2016
On Tuesday, 12 July 2016 at 11:26:20 UTC, jj75607 wrote:I want to use aspect-like annotations to transform Lockable class Abc { sync void f() { writeln("f"); } shared void g() { writeln("g"); } } to something like: class Abc { shared(ReadWriteMutex) _lock123; this() { _lock123 = cast(shared)(new ReadWriteMutex()); } void f() { synchronized((cast()_lock123).writer) { writeln("f"); } } void g() { synchronized((cast()_lock123).reader) { writeln("g"); } } } How can I do that?I don't think UDAs can be used that way in D, but I'm not an expert. When I want to achieve something similar to this kind of rewriting, I usually use a mix of template mixins[1] and string mixins[2,3]. [1] https://dlang.org/spec/template-mixin.html [2] https://dlang.org/spec/statement.html#MixinStatement [3] https://dlang.org/mixin.html
Jul 12 2016
On Tuesday, 12 July 2016 at 11:26:20 UTC, jj75607 wrote: you can't. there is no AST macros in D, so you can't rewrite parsed source.
Jul 12 2016
On Tuesday, 12 July 2016 at 11:26:20 UTC, jj75607 wrote:I want to use aspect-like annotations to transform[...] Two methods spring to mind but both create new types. You can either write a function that iterates through the members of your class, generating a string mixin that selectively hijacks calls to functions you have annotated with some UDA. Then it would just forward the function call inside synchronized blocks. alias this should hopefully be enough to forward other members. See https://dpaste.dzfl.pl/6a9cc4946caf for a rough example. It's not robust, doesn't work with overloads (needs an additional foreach over __traits(getOverloads, C, memberstring)), but I hope it conveys the idea. The alternative is to write a wrapper that similarly hijacks and wraps calls inside synchronized blocks, but by using opDispatch. The approach is less complex but sadly doesn't work as well; alias this seems to be more or less mutually exclusive to opDispatch, which makes sense. See https://dpaste.dzfl.pl/a5dac71ab4f8. Accessing enums and other types is also iffy since functions can't return types. As long as you make the base class instance public you can always bypass things that way. In both examples it may make sense to have the generated functions return via auto ref, it depends on your use cases.
Jul 13 2016