...
[RT] Compile-time-data injection
...
title | Proposal |
---|
...
Summary
Introduction of new Metadata Tags that instruct the compiler to fill-in arguments or properties with data that is available at compile-time.
...
Code is right now introspected using describeType, exception stack-traces (that only work in the debug players) and passing data by hand. Also: Developers need to set up ant tasks to pass in data like the build version or compiler flags or need to do some code twisting for it to work. If some of the data was compiled into the bytecode then performance could be traded for swf size. This is specially interesting for low-level apis like logging or dependency injection. All this could be achieved by including all compiler data into a swf but this would result in unnecessarily bloated swfs. An approach using meta-data would allow selective injection for those parts that are needed.
Mailinglist discussions
Trace & Log
Proposal Compile-time-data-injection
Available data
Type
Information about classes, their methods and those arguments. Basically things that are right now available with describeType
and getQualifiedClassName
.
...
key | description | type | ||||||
---|---|---|---|---|---|---|---|---|
caller.type | Type in which the calling method was located | Type | ||||||
caller.args | The arguments that have been passed to the caller | Array | ||||||
call | <ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="4ed3bfc4-d295-4487-8981-55c6a9cabafe"><ac:plain-text-body><![CDATA[ | caller.clean | Called clean like | Boolean | ]]></ac:plain-text-body></ac:structured-macro> | caller.args | The arguments that have been passed to the caller | Array |
call.lineNo | The line number of the file of the type where the method has been called | int | ||||||
call.preferedReturnType | Type that the code wants to work with afterwards | Type | ||||||
call.arguments args | Types passed in for all arguments | Array | ||||||
call.argumentarg.<argument> | Type for a particular argument | Type |
...
Code Block | ||
---|---|---|
| ||
[Fill(data="type")]
private static const typeInfo:XML;
|
This would be equal to writing:
Code Block | ||
---|---|---|
| ||
private static const typeInfo:XML = describeType(Foo);
|
To preset a property if the compiler doesn't recognize (or ignore) that meta-data it is possible to set data like:
...
This way the code does have a standard content even when its not compiled with this system.
Variables do not have caller information available.
Method argument declarations
Method arguments should also be inject-able. The syntax is slightly different as it doesn't utilize the "data" property but naming the arguments in the meta data:
Code Block | ||
---|---|---|
| ||
[Fill(args="caller.args")]
function foo(args:Array=null) {}
|
This means that the argument will be filled on call:
Code Block | ||
---|---|---|
| ||
[Fill(args="caller.args")]
function foo(args:Array=null) {}
function bar(a:String, b:int) {
foo();
}
|
will be transformed to an equivalent of
Code Block | ||
---|---|---|
| ||
function foo(args:Array=null) {}
function bar(a:String, b:int) {
foo([a,b]);
}
|
This means: always the calling code is rewritten, not the method itself!
Handling data
All the injected data would need to be made accessible using regular ActionScript3 data types. While a XML can be nicely edited and stepped through it also is a quite heavy in its consumption and ultimately unnecessary if you use other code. To make life easier, there should be a possible way of automatic type conversion.
Code Block | ||
---|---|---|
| ||
[Fill(data="type")] const type: XML; // Type as in describe-type ] [Fill(data="type")] const type: Object; // describe-type xml in a object tree [FileFill(data="compile.time")] const time: int; // Time as Integer; [FileFill(data="compile.time")] const time: String; // Time as String; [FileFill(data="compile.time")] const time: Date; // Time as Date; [FileFill(bar="callercall.argumentarg.content")] function foo(content:*, bar:Class=null); // Content type as class [FileFill(bar="callercall.argumentarg.content")] function foo(content:*, bar:String=null); // Content type as String [FileFill(bar="callercall.argumentarg.content")] function foo(content:*, bar:XML=null); // Content type as XML |
...