Skip to content

Macro under the hood & Proxy Traits

Tom Byrne edited this page Jul 18, 2012 · 3 revisions

Sometimes it's necessary to create a trait which doesn't extend AbstractTrait but that still has access to other traits. This is possible using the @bind build macro, as mentioned on the metadata page.

It's worth looking into how the macro achieves this though, as occasionally it is necessary to implement this manually (especially if you're using composure in a target language where macros are unavailable). When this type of implementation is found:

	class PositionDisplay extends AbstractTrait{

		@inject
		public var position:Position;

		public function new(msg:String){
			super();
		}
	}

The build macro amends it to this:

	class PositionDisplay extends AbstractTrait{

		public var position:Position;

		public function new(msg:String){
			super();

			addInjector(new PropInjector(Position, this, "suspect"));
		}
	}

So when your trait does not extend AbstractTrait (and the method addInjector is unavailable), the macro must behave differently.

When the macro comes this (equivilant) class:

	@:build(composure.macro.InjectorMacro.inject())
	class PositionDisplay{

		@inject
		public var position:Position;

		public function new(msg:String){
			super();
		}
	}

The build macro amends it to this:

	class PositionDisplay extends AbstractTrait{

		public var position:Position;

		private var _proxiedTrait:AbstractTrait;

		public function new(msg:String){
			super();

			_proxiedTrait = new AbstractTrait(this);
			_proxiedTrait.addInjector(new PropInjector(Position, this, "suspect"));
		}

		public function getProxiedTrait():ITrait{
			return _proxiedTrait;
		}
	}