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