[macro] add ClassTypeMacro and FieldMacro
This commit is contained in:
21
src/main/haxework/macro/ClassTypeMacro.hx
Normal file
21
src/main/haxework/macro/ClassTypeMacro.hx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package haxework.macro;
|
||||||
|
|
||||||
|
import haxe.macro.Expr;
|
||||||
|
import haxe.macro.Type;
|
||||||
|
|
||||||
|
class ClassTypeMacro {
|
||||||
|
|
||||||
|
public var metaName(default, null):String;
|
||||||
|
|
||||||
|
public function new(metaName:String) {
|
||||||
|
this.metaName = metaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has(classType:ClassType):Bool {
|
||||||
|
return classType.meta.has(metaName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,20 +6,10 @@ import haxe.macro.ExprTools;
|
|||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
|
|
||||||
class DispatcherMacro {
|
class DispatcherMacro extends ClassTypeMacro {
|
||||||
|
|
||||||
private static inline var metaName:String = ':dispatcher';
|
public function new() {
|
||||||
|
super(":dispatcher");
|
||||||
public static function has(classType:ClassType):Bool {
|
|
||||||
return classType.meta.has(metaName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private var classType:ClassType;
|
|
||||||
private var fields:Array<Field>;
|
|
||||||
|
|
||||||
public function new(classType:ClassType, fields:Array<Field>) {
|
|
||||||
this.classType = classType;
|
|
||||||
this.fields = fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static inline function signalName(fieldName:String):String {
|
private static inline function signalName(fieldName:String):String {
|
||||||
@@ -30,7 +20,7 @@ class DispatcherMacro {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
override public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||||
var result:Array<Field> = fields.slice(0);
|
var result:Array<Field> = fields.slice(0);
|
||||||
var typeName = ExprTools.toString(classType.meta.extract(metaName)[0].params[0]);
|
var typeName = ExprTools.toString(classType.meta.extract(metaName)[0].params[0]);
|
||||||
var type:ClassType = switch Context.getType(typeName) {
|
var type:ClassType = switch Context.getType(typeName) {
|
||||||
|
|||||||
21
src/main/haxework/macro/FieldMacro.hx
Normal file
21
src/main/haxework/macro/FieldMacro.hx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package haxework.macro;
|
||||||
|
|
||||||
|
import haxe.macro.Expr;
|
||||||
|
|
||||||
|
using haxework.macro.Util;
|
||||||
|
|
||||||
|
class FieldMacro {
|
||||||
|
public var metaName(default, null):String;
|
||||||
|
|
||||||
|
public function new(metaName:String) {
|
||||||
|
this.metaName = metaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has(field:Field):Bool {
|
||||||
|
return field.getFieldMeta(metaName) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function apply(field:Field):Array<Field> {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,23 +5,14 @@ import haxe.macro.Expr;
|
|||||||
|
|
||||||
using haxework.macro.Util;
|
using haxework.macro.Util;
|
||||||
|
|
||||||
class ProvideMacro {
|
class ProvideMacro extends FieldMacro {
|
||||||
|
|
||||||
private static var metaName = ":provide";
|
public function new() {
|
||||||
|
super(":provide");
|
||||||
public static function has(field:Field):Bool {
|
|
||||||
return field.getFieldMeta(metaName) != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var field:Field;
|
override public function apply(field:Field):Array<Field> {
|
||||||
private var meta:MetadataEntry;
|
var meta:MetadataEntry = field.getFieldMeta(metaName);
|
||||||
|
|
||||||
public function new(field:Field) {
|
|
||||||
this.field = field;
|
|
||||||
this.meta = field.getFieldMeta(metaName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
|
||||||
var result:Array<Field> = [];
|
var result:Array<Field> = [];
|
||||||
var type:ComplexType = switch field.kind {
|
var type:ComplexType = switch field.kind {
|
||||||
case FVar(t): t;
|
case FVar(t): t;
|
||||||
@@ -33,12 +24,7 @@ class ProvideMacro {
|
|||||||
}
|
}
|
||||||
var provideType:String = meta.params.length == 0 ? null : Util.getExprString(meta.params[0].expr);
|
var provideType:String = meta.params.length == 0 ? null : Util.getExprString(meta.params[0].expr);
|
||||||
var isStatic = Lambda.exists(field.access, function(a: Access) return a == AStatic);
|
var isStatic = Lambda.exists(field.access, function(a: Access) return a == AStatic);
|
||||||
result.push({
|
field.kind = FProp('get', 'set', type);
|
||||||
name: field.name,
|
|
||||||
access: isStatic ? [APublic, AStatic] : [APublic],
|
|
||||||
pos: field.pos,
|
|
||||||
kind: FProp('get', 'set', type),
|
|
||||||
});
|
|
||||||
var access = [APrivate, AInline];
|
var access = [APrivate, AInline];
|
||||||
if (isStatic) access.push(AStatic);
|
if (isStatic) access.push(AStatic);
|
||||||
var args = [name];
|
var args = [name];
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
package haxework.macro;
|
package haxework.macro;
|
||||||
|
|
||||||
import haxe.macro.Expr;
|
|
||||||
|
|
||||||
using haxework.macro.Util;
|
using haxework.macro.Util;
|
||||||
|
|
||||||
class ResourceMacro {
|
class ResourceMacro extends FieldMacro {
|
||||||
public static function has(field:Field):Bool {
|
|
||||||
return field.getFieldMeta(":resource") != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private var field:Field;
|
public function new() {
|
||||||
|
super(":resource");
|
||||||
public function new(field:Field) {
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
|
||||||
var result:Array<Field> = [];
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,17 @@
|
|||||||
package haxework.macro;
|
package haxework.macro;
|
||||||
|
|
||||||
import haxe.macro.TypeTools;
|
|
||||||
import haxe.macro.Context;
|
import haxe.macro.Context;
|
||||||
import haxe.macro.ExprTools;
|
|
||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
|
|
||||||
class SingletonMacro {
|
class SingletonMacro extends ClassTypeMacro {
|
||||||
|
|
||||||
private static inline var metaName:String = ":singleton";
|
public function new() {
|
||||||
|
super(":singleton");
|
||||||
public static function has(classType:ClassType):Bool {
|
|
||||||
return classType.meta.has(metaName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private var classType:ClassType;
|
|
||||||
private var fields:Array<Field>;
|
|
||||||
|
|
||||||
public function new(classType:ClassType, fields:Array<Field>) {
|
|
||||||
this.classType = classType;
|
|
||||||
this.fields = fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
override public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||||
var result:Array<Field> = fields.slice(0);
|
var result:Array<Field> = fields.slice(0);
|
||||||
var classTypePath:TypePath = {
|
var classTypePath:TypePath = {
|
||||||
pack: classType.pack,
|
pack: classType.pack,
|
||||||
|
|||||||
@@ -13,21 +13,10 @@ typedef TProperty<T> = {
|
|||||||
var defaultValue: T;
|
var defaultValue: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyleMacro {
|
class StyleMacro extends ClassTypeMacro {
|
||||||
private static inline var metaName:String = ':style';
|
|
||||||
|
|
||||||
public static function has(classType:ClassType):Bool {
|
public function new() {
|
||||||
return classType.getClassMeta(metaName) != null;
|
super(":style");
|
||||||
}
|
|
||||||
|
|
||||||
private var classType:ClassType;
|
|
||||||
private var fields:Array<Field>;
|
|
||||||
private var overrideStyle:Bool;
|
|
||||||
|
|
||||||
public function new(classType:ClassType, fields:Array<Field>) {
|
|
||||||
this.classType = classType;
|
|
||||||
this.fields = fields;
|
|
||||||
this.overrideStyle = classType.getClassMeta(":style").params.length > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function processPropertyField(field:Field):Array<Field> {
|
private static function processPropertyField(field:Field):Array<Field> {
|
||||||
@@ -201,14 +190,15 @@ class StyleMacro {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
override public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||||
|
var overrideStyle = classType.getClassMeta(metaName).params.length > 0;
|
||||||
var result:Array<Field> = fields.slice(0);
|
var result:Array<Field> = fields.slice(0);
|
||||||
var styleds:Array<Field> = [];
|
var styleds:Array<Field> = [];
|
||||||
var properties:Array<Field> = [];
|
var properties:Array<Field> = [];
|
||||||
var newFields:Array<Field> = [];
|
var newFields:Array<Field> = [];
|
||||||
var hasOnStyle:Bool = fields.getField("onStyle") != null;
|
var hasOnStyle:Bool = fields.getField("onStyle") != null;
|
||||||
for (field in fields) if (field.meta != null) {
|
for (field in fields) if (field.meta != null) {
|
||||||
var meta = field.getFieldMeta(":style");
|
var meta = field.getFieldMeta(metaName);
|
||||||
if (meta != null) {
|
if (meta != null) {
|
||||||
if (meta.params.length > 0) {
|
if (meta.params.length > 0) {
|
||||||
newFields = newFields.concat(processPropertyField(field));
|
newFields = newFields.concat(processPropertyField(field));
|
||||||
|
|||||||
@@ -1,45 +1,23 @@
|
|||||||
package haxework.macro;
|
package haxework.macro;
|
||||||
|
|
||||||
import Lambda;
|
|
||||||
import haxe.macro.Context;
|
import haxe.macro.Context;
|
||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
import haxework.macro.PositionJsonParser;
|
import haxework.macro.PositionJsonParser;
|
||||||
|
import Lambda;
|
||||||
|
|
||||||
using haxework.macro.Util;
|
using haxework.macro.Util;
|
||||||
|
|
||||||
class TemplateMacro {
|
class TemplateMacro extends ClassTypeMacro {
|
||||||
|
|
||||||
private static inline var metaName:String = ':template';
|
|
||||||
|
|
||||||
public static function has(classType:ClassType):Bool {
|
|
||||||
return classType.getClassMeta(metaName) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private var classType:ClassType;
|
|
||||||
private var fields:Array<Field>;
|
|
||||||
private var bindings:Map<String, String>;
|
private var bindings:Map<String, String>;
|
||||||
|
|
||||||
private var meta:MetadataEntry;
|
|
||||||
private var templateFile:String;
|
private var templateFile:String;
|
||||||
private var template:Dynamic;
|
private var template:Dynamic;
|
||||||
private var i:Int;
|
private var i:Int;
|
||||||
|
|
||||||
|
public function new() {
|
||||||
public function new(classType:ClassType, fields:Array<Field>) {
|
super(":template");
|
||||||
this.classType = classType;
|
|
||||||
this.meta = classType.getClassMeta(metaName);
|
|
||||||
this.fields = fields;
|
|
||||||
var params = Util.getMetaParams(meta);
|
|
||||||
var filePath = params[0];
|
|
||||||
if (filePath == null) {
|
|
||||||
filePath = classType.pack.join("/") + "/" + classType.name + ".yaml";
|
|
||||||
}
|
}
|
||||||
templateFile = Context.resolvePath(filePath);
|
|
||||||
template = FileUtil.loadFile(templateFile);
|
|
||||||
bindings = findViewsBindings(fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static function getSpecField(object:Dynamic, field:String):Dynamic {
|
private static function getSpecField(object:Dynamic, field:String):Dynamic {
|
||||||
if (Reflect.hasField(object, "@" + field)) {
|
if (Reflect.hasField(object, "@" + field)) {
|
||||||
@@ -215,8 +193,18 @@ class TemplateMacro {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function apply():Array<Field> {
|
override public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
var meta = classType.getClassMeta(metaName);
|
||||||
|
var params = Util.getMetaParams(meta);
|
||||||
|
var filePath = params[0];
|
||||||
|
if (filePath == null) {
|
||||||
|
filePath = classType.pack.join("/") + "/" + classType.name + ".yaml";
|
||||||
|
}
|
||||||
|
// ToDo: template builder
|
||||||
|
templateFile = Context.resolvePath(filePath);
|
||||||
|
template = FileUtil.loadFile(templateFile);
|
||||||
|
bindings = findViewsBindings(fields);
|
||||||
var result:Array<Field> = fields.slice(0);
|
var result:Array<Field> = fields.slice(0);
|
||||||
var exprs:Array<Expr> = [];
|
var exprs:Array<Expr> = [];
|
||||||
var init = Lambda.exists(result, function(f) return f.name == "init");
|
var init = Lambda.exists(result, function(f) return f.name == "init");
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
package haxework.parser;
|
package haxework.parser;
|
||||||
|
|
||||||
import haxework.macro.SingletonMacro.SingletonMacro;
|
|
||||||
import haxework.macro.StyleMacro;
|
|
||||||
import haxe.macro.TypeTools;
|
|
||||||
import haxe.macro.Context;
|
import haxe.macro.Context;
|
||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
|
import haxe.macro.TypeTools;
|
||||||
|
import haxework.macro.ClassTypeMacro;
|
||||||
import haxework.macro.DispatcherMacro;
|
import haxework.macro.DispatcherMacro;
|
||||||
|
import haxework.macro.FieldMacro;
|
||||||
import haxework.macro.ProvideMacro;
|
import haxework.macro.ProvideMacro;
|
||||||
import haxework.macro.ResourceMacro;
|
import haxework.macro.ResourceMacro;
|
||||||
|
import haxework.macro.SingletonMacro;
|
||||||
|
import haxework.macro.StyleMacro;
|
||||||
import haxework.macro.TemplateMacro;
|
import haxework.macro.TemplateMacro;
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
|
|
||||||
|
private static var classTypeMacros:Array<ClassTypeMacro> = [
|
||||||
|
new TemplateMacro(),
|
||||||
|
new DispatcherMacro(),
|
||||||
|
new StyleMacro(),
|
||||||
|
new SingletonMacro(),
|
||||||
|
];
|
||||||
|
|
||||||
|
private static var fieldMacros:Array<FieldMacro> = [
|
||||||
|
new ProvideMacro(),
|
||||||
|
new ResourceMacro(),
|
||||||
|
];
|
||||||
|
|
||||||
private static var processed:Map<String, Bool> = new Map();
|
private static var processed:Map<String, Bool> = new Map();
|
||||||
|
|
||||||
private static function auto():Void {
|
private static function auto():Void {
|
||||||
@@ -30,44 +44,25 @@ class Parser {
|
|||||||
var modify:Bool = false;
|
var modify:Bool = false;
|
||||||
var fields:Array<Field> = Context.getBuildFields();
|
var fields:Array<Field> = Context.getBuildFields();
|
||||||
var result:Array<Field> = [];
|
var result:Array<Field> = [];
|
||||||
var appends:Array<Field> = [];
|
|
||||||
// process fields meta
|
// process fields meta
|
||||||
for (field in fields) {
|
for (field in fields) {
|
||||||
if (ProvideMacro.has(field)) {
|
|
||||||
modify = true;
|
|
||||||
var provide = new ProvideMacro(field);
|
|
||||||
result = result.concat(provide.apply());
|
|
||||||
} else if (ResourceMacro.has(field)) {
|
|
||||||
modify = true;
|
|
||||||
var resource = new ResourceMacro(field);
|
|
||||||
result = result.concat(resource.apply());
|
|
||||||
} else {
|
|
||||||
result.push(field);
|
result.push(field);
|
||||||
|
for (item in fieldMacros) {
|
||||||
|
if (item.has(field)) {
|
||||||
|
modify = true;
|
||||||
|
result = result.concat(item.apply(field));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modify) {
|
if (modify) {
|
||||||
fields = result;
|
fields = result;
|
||||||
}
|
}
|
||||||
// process class meta
|
// process class meta
|
||||||
if (TemplateMacro.has(ct)) {
|
for (item in classTypeMacros) {
|
||||||
|
if (item.has(ct)) {
|
||||||
modify = true;
|
modify = true;
|
||||||
var template = new TemplateMacro(ct, fields);
|
fields = item.apply(ct, fields);
|
||||||
fields = template.apply();
|
|
||||||
}
|
}
|
||||||
if (DispatcherMacro.has(ct)) {
|
|
||||||
modify = true;
|
|
||||||
var dispatcher = new DispatcherMacro(ct, fields);
|
|
||||||
fields = dispatcher.apply();
|
|
||||||
}
|
|
||||||
if (StyleMacro.has(ct)) {
|
|
||||||
modify = true;
|
|
||||||
var style = new StyleMacro(ct, fields);
|
|
||||||
fields = style.apply();
|
|
||||||
}
|
|
||||||
if (SingletonMacro.has(ct)) {
|
|
||||||
modify = true;
|
|
||||||
var singleton = new SingletonMacro(ct, fields);
|
|
||||||
fields = singleton.apply();
|
|
||||||
}
|
}
|
||||||
processed.set(localName, true);
|
processed.set(localName, true);
|
||||||
modify ? fields : null;
|
modify ? fields : null;
|
||||||
|
|||||||
Reference in New Issue
Block a user