haxe-aspect

Enables aspect-oriented programming in Haxe


Keywords
aspect, cross, macro
License
MIT
Install
haxelib install haxe-aspect 1.0.1

Documentation

Haxe Aspect - Aspect-based programming library for HaXe

This library allows writing aspect-based code in the Haxe programming language.

Motivation

Aspect based programming allows separating code based on features rather than code flow or data flow. When coding a feature, instead of adding code to a large number of core modules, a single module may define multiple code blocks which are automatically called from the various core modules.

This can be likened to applying the observer pattern at compile time.

Terminology

Join point - A location in the code where additional code can be added.

Advice - A block of code intended to be inserted at some join point.

Installation

The library is available from haxelib, and can be installed using

haxelib install haxe-aspect

The library can then be used while compiling code

haxe -lib haxe-aspect Main.hx

Usage

Any class may define a join point by calling Aspect.joinpoint from a static method:

import org.slugfiller.aspect.Aspect;

class MyClass
{
  static function myJoinPoint(param1 : Int, param2 : Int)
  {
    // Defining a join point
    Aspect.joinpoint(param1, param2, " is printed");
  }

  function myNormalMethod()
  {
    // Calling the join point from a normal function
    myJoinPoint(1, 2);
  }
}

The method containing the join point MUST be static.

To add code to be called from the join point from another module, a public class implementing the Advice interface must be created, as so:

import org.slugfiller.aspect.Advice;

class MyAdvice implements Advice<MyClass>
{
  public static function myJoinPoint(param1 : Int, param2 : Int, param3 : String)
  {
    trace((param1+param2*7)+param3);
  }
}

A class implementing Advice must:

  • Be public
  • Contain only public static functions, and no other fields or methods
  • Each static method must have the same name as a static method containing a join point in the class for which advice is given
  • The method's parameters must match the values passed to the call to Aspect.joinpoint

In the above example, the join point from MyClass would be transformed into:

  static function myJoinPoint(param1 : Int, param2 : Int)
  {
    // Defining a join point
    MyAdvice.myJoinPoint(param1, param2, " is printed"); // Join point is resolved based on given advice
  }

Note that it's possible to provide more than one advice for a given join point. No guarantees are made regarding the order in which advice functions are called.