Skip to content

Commit a720579

Browse files
authored
Merge pull request #1 from lemz1/feature/final-macro
Final Macro Implementation
2 parents 835f696 + 5fe8285 commit a720579

File tree

1 file changed

+53
-29
lines changed

1 file changed

+53
-29
lines changed

polymod/hscript/_internal/PolymodFinalMacro.hx

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ package polymod.hscript._internal;
33
import haxe.macro.Context;
44
import haxe.macro.Expr;
55
import haxe.macro.Type;
6+
import haxe.rtti.Meta;
67

78
class PolymodFinalMacro
89
{
10+
private static var _allFinals:Map<String, Array<String>> = null;
11+
912
public static function getAllFinals():Map<String, Array<String>>
1013
{
11-
return Reflect.callMethod(null, Reflect.field(Type.resolveClass("polymod.hscript._internal.PolymodFinals"), "getAllFinals"), []);
14+
if (_allFinals == null)
15+
_allFinals = PolymodFinalMacro.fetchAllFinals();
16+
return _allFinals;
1217
}
1318

1419
public static macro function locateAllFinals():Void
@@ -18,53 +23,45 @@ class PolymodFinalMacro
1823
if (calledBefore)
1924
return;
2025

21-
var allFinals:Map<String,Array<String>> = [];
26+
var allFinals:Array<Expr> = [];
2227

2328
for (type in types)
2429
{
2530
switch (type)
2631
{
2732
case TClassDecl(t):
2833
var classType:ClassType = t.get();
29-
var className:String = t.toString();
34+
var classPath:String = t.toString();
3035
if (classType.isInterface) continue;
3136

32-
allFinals.set(className, []);
37+
var finals:Array<String> = [];
3338
for (field in classType.statics.get())
3439
{
3540
if (!field.isFinal) continue;
36-
allFinals[className].push(field.name);
41+
finals.push(field.name);
3742
}
3843

44+
var entryData = [
45+
macro $v{classPath},
46+
macro $v{finals}
47+
];
48+
49+
allFinals.push(macro $a{entryData});
3950
default:
4051
continue;
4152
}
4253
}
4354

44-
Context.defineModule('polymod.hscript._internal.PolymodFinalMacro', [
45-
{
46-
pack: ['polymod', 'hscript', '_internal'],
47-
name: 'PolymodFinals',
48-
kind: TypeDefKind.TDClass(null, [], false, false, false),
49-
fields: [
50-
{
51-
name: 'getAllFinals',
52-
access: [Access.APublic, Access.AStatic],
53-
kind: FieldType.FFun(
54-
{
55-
args: [],
56-
ret: (macro :Map<String, Array<String>>),
57-
expr: macro
58-
{
59-
return $v{allFinals};
60-
}
61-
}),
62-
pos: Context.currentPos()
63-
}
64-
],
65-
pos: Context.currentPos()
66-
}
67-
]);
55+
var finalMacroType:Type = Context.getType('polymod.hscript._internal.PolymodFinalMacro');
56+
57+
switch (finalMacroType)
58+
{
59+
case TInst(t, _):
60+
var finalMacroClassType:ClassType = t.get();
61+
finalMacroClassType.meta.add('finals', allFinals, Context.currentPos());
62+
default:
63+
throw 'Could not find PolymodFinalMacro type';
64+
}
6865

6966
calledBefore = true;
7067
});
@@ -73,4 +70,31 @@ class PolymodFinalMacro
7370
#if macro
7471
static var calledBefore:Bool = false;
7572
#end
73+
74+
public static function fetchAllFinals():Map<String, Array<String>>
75+
{
76+
var metaData = Meta.getType(PolymodFinalMacro);
77+
78+
if (metaData.finals != null)
79+
{
80+
var result:Map<String, Array<String>> = [];
81+
82+
for (element in metaData.finals)
83+
{
84+
if (element.length != 2)
85+
throw 'Malformed element in finals: ' + element;
86+
87+
var classPath:String = element[0];
88+
var finals:Array<String> = element[1];
89+
90+
result.set(classPath, finals);
91+
}
92+
93+
return result;
94+
}
95+
else
96+
{
97+
throw 'No finals found in PolymodFinalMacro';
98+
}
99+
}
76100
}

0 commit comments

Comments
 (0)