Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

[RT] Compile-time-data injection

...

titleProposal

...

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 foo.bar() or not (like foo["bar"]() or foo.bar.call(null))

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
langactionscript
[Fill(data="type")]
private static const typeInfo:XML;

This would be equal to writing:

Code Block
langactionscript
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
langactionscript

[Fill(args="caller.args")]
function foo(args:Array=null) {}

This means that the argument will be filled on call:

Code Block
langactionscript

[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
langactionscript

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
langactionscript
[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

...