Skip to content

Instantly share code, notes, and snippets.

@jdonaldson
Forked from andyli/AbstractClass.hx
Last active June 23, 2017 17:28
Show Gist options
  • Save jdonaldson/5027770 to your computer and use it in GitHub Desktop.
Save jdonaldson/5027770 to your computer and use it in GitHub Desktop.
import haxe.macro.Expr;
import haxe.macro.Context;
using Lambda;
@:autoBuild(AbstractClassBuilder.build())
interface AbstractClass {}
class AbstractClassBuilder {
static var abstractFields:Hash<Array<String>> = new Hash();
static public function build():Array<Field> {
var fields = Context.getBuildFields();
var cls = Context.getLocalClass();
if (!abstractFields.exists(cls.toString())){
abstractFields.set(cls.toString(), []);
}
var absFields = abstractFields.get(cls.toString());
//Get all the abstract methods of super class. It should also force building super class first.
var supCls = cls.get().superClass;
if (supCls != null && abstractFields.exists(supCls.t.toString())) {
for (f in abstractFields.get(supCls.t.toString())) {
absFields.push(f);
}
}
var publicCtorPos = null; //place holder for finding a public constructor
for (f in fields) {
if (f.access.has(AStatic)) continue; //we only care non-static methods
switch (f.kind) {
case FFun(fun):
if (fun.expr == null) { //method without an implementation
absFields.push(f.name);
//give a method body so it compiles
fun.expr = macro return throw "abstract method, must override";
} else { //method with an implementation
absFields.remove(f.name);
}
if (f.name == "new" && f.access.has(APublic)) {
publicCtorPos = f.pos;
}
default:
}
}
if (absFields.length > 0 && publicCtorPos != null) {
Context.error("Abstract class cannot have public constructor. Missing implementation of: " + absFields.join(", "), publicCtorPos);
}
return fields;
}
}
class Color implements AbstractClass {
public function toRGBX():RGBX;
public function clone():Color;
}
class RGBX {
public function new(){}
}
// class HSB extends Color {
// public function new(){} //src/Main.hx:12: characters 8-24 : Abstract class cannot have public constructor. Missing implementation of: toRGBX, clone
// }
class HSL extends Color {
public function new(){}
override public function toRGBX():RGBX return new RGBX()
override public function clone():HSL return new HSL()
}
class Main {
static public function main() {
var h = new HSL();
var r = h.toRGBX();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment