Created
February 19, 2014 05:11
-
-
Save jasononeil/9086395 to your computer and use it in GitHub Desktop.
Method used in a macro to figure out the return type of a member method. Uses tink_macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Figure out return type of function. | |
Will first to check if it is explicitly defined. | |
If not, it attempts to set the function up as a local function expression (EFunction), and then use `Context.typeof( fnExpr )` to evaluate the type. | |
Will generate a compiler error if member was not a method or method type could not be determined. | |
**/ | |
static function figureOutReturnTypeOfMemberMethod( member:Member ) { | |
switch member.getFunction() { | |
case Success( fn ): | |
if ( fn.ret!=null ) { | |
return fn.ret; | |
} | |
else { | |
try { | |
var fnExpr:Expr = { expr: EFunction(null,fn), pos: member.pos }; | |
var args:Array<Expr> = [ for (i in 0...fn.args.length) macro null ]; | |
var callExpr = macro $fnExpr( $a{args} ); | |
var t = Context.typeof( callExpr ); | |
return t.toComplexType(); | |
} | |
catch (e:Dynamic) { | |
Context.error( 'Failed to get type of method ${member.name}: '+e, member.pos ); | |
} | |
} | |
case Failure( err ): | |
Context.error('figureOutReturnTypeOfMemberMethod expected a method, but got some other kind of field: '+err.message, err.pos ); | |
} | |
return null; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please note in the end this didn't work. Basically Context.parse() would go through each expression in the function body, and for simple stuff, it was fine. Once you started including links to outside variables and classes, things got difficult.
I tried to use tink's
expr.typeof( [ variables in context ] )
trick, and was able to fake the current fields and the super class, but any references to a 3rd party class had no guarantee of being compiled yet, and so their fields were not accessible, resulting intypeof
failing with errors likeFuture has no field sync
, when Future most certainly did have a field called sync.In the end I've had to settle for a solution where I use
Context.onGenerate
to provide a callback after all the typing is done, but at this point, it's too late to change any expressions, so I have to settle for writing metadata, and then at runtime, read that metadata and act accordingly.It's a little disappointing, but at least it will work.