Skip to content

Instantly share code, notes, and snippets.

@bamboo
Created October 25, 2011 22:04
Show Gist options
  • Save bamboo/1314499 to your computer and use it in GitHub Desktop.
Save bamboo/1314499 to your computer and use it in GitHub Desktop.
macro resolving a type after macro expansion
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.TypeSystem.Services
import Boo.Lang.Compiler.MetaProgramming
import Boo.Lang.Environments
macro delegate:
case [| delegate $field as $fieldType |]:
enclosingType = delegate.GetAncestor of TypeDefinition()
Context.Parameters.Pipeline.AfterStep += do (sender, args):
if args.Step isa Boo.Lang.Compiler.Steps.MacroAndAttributeExpansion:
implementDelegationOf field, fieldType, enclosingType
def implementDelegationOf(field as ReferenceExpression, fieldType as TypeReference, typeDef as TypeDefinition):
for member in membersOf(fieldType):
match member:
case IMethod(Name: methodName, ReturnType: returnType):
newMethod = [|
def $methodName() as $returnType:
$(field.CloneNode()).$methodName()
|]
typeDef.Members.Add(newMethod)
def membersOf(typeRef as TypeReference):
my(NameResolutionService).ResolveTypeReference(typeRef)
return (typeRef.Entity cast INamespace).GetMembers()
[extension] def op_Implicit(type as IType) as TypeReference:
return my(BooCodeBuilder).CreateTypeReference(type)
code = [|
class Foo:
def Bar():
print "Foo.Bar"
def Baz():
print "Foo.Baz"
class Gazonk:
delegate foo as Foo
foo = Foo()
|]
result = compile_(code, System.Reflection.Assembly.GetExecutingAssembly())
print result.CompileUnit.ToCodeString()
assert len(result.Errors) == 0, result.Errors.ToString(true)
gazonk as duck = result.GeneratedAssembly.GetType("Gazonk")()
gazonk.Bar()
gazonk.Baz()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment