Cache annotations mini-framework
Hi all!
I'm developing a mini-framework to implement annotations in Cache. I want to support two kind of annotations: metadata and method decorators. I've got stuck trying to implement the second one.
Metadata
With metadata annotations I can add metadata to any kind of target. A target can be a method/classmethod, parameter, property and class.
For example:
Class cache.TestClass Extends lib.Annotations { /// @Author(UserName = "me") ClassMethod Test() { Write "Test!",! } }
Then, after compiling the class "cache.TestClass" I can obtain the Author metadata by calling the method "GetMethodAnnotation" of the class "cache.TestClass".
Method decorators
With this kind of annotations it's possible to modify the run-time of a method by just adding an annotation. For example I would like to be able to do:
Class cache.TestClassDecorator Extends lib.Annotations { /// @NiceTest ClassMethod Test() { Write "Test!",! } }
And then, after compiling this class. The output of the method "Test" would be:
Init NiceTest! Test! End NiceTest!
So the code that should be executed if we call the method "Test" is:
ClassMethod Test() { Write "Init NiceTest!",! Do ..MyOriginalMethodTest() Write "End NiceTest!",! }
My ideal approach to solve this problem would be to add a new step in the compiler (preprocessor?), so I can first generate the modified code, and then compile it. I have no idea how to do this.
Another approach that I've investigated, and it's working (partially), is to generate a new method in the same class ("DecoratedTest"), and then redirect the original method to the new one (by modifying an internal Cache global... very dangerous, I know). So from the decorator I'm able to call to the original method by calling the routine. The problem with this solution is that I need to compile two times the same class. The first compilation is when I generate the modified method, and in the second compilation I redirect the original method to the modified one. In the first compilation, the redirection fails because the method doesn't exists yet.
The generated method looks like this:
ClassMethod DecoratedTest()
{
Write "Init NiceTest!",!
Do ztest^cache.TestClassDecorator.1()
Write "End NiceTest!",!
}
Do you have any idea to implement this?
Thank you!
P.D.: For those who doesn't know what is an annotation, here is some lecture: