Skip to content

Commit 835f696

Browse files
committed
block final setting
1 parent 0fbdf27 commit 835f696

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

include.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
<!-- These values are added to the project XML when you include this library. -->
44
<haxelib name="thx.semver" />
55
<!-- <haxelib name="hscript" /> This library is now OPTIONAL. -->
6+
<haxeflag name="--macro" value="polymod.hscript._internal.PolymodFinalMacro.locateAllFinals()" />
67
</project>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package polymod.hscript._internal;
2+
3+
import haxe.macro.Context;
4+
import haxe.macro.Expr;
5+
import haxe.macro.Type;
6+
7+
class PolymodFinalMacro
8+
{
9+
public static function getAllFinals():Map<String, Array<String>>
10+
{
11+
return Reflect.callMethod(null, Reflect.field(Type.resolveClass("polymod.hscript._internal.PolymodFinals"), "getAllFinals"), []);
12+
}
13+
14+
public static macro function locateAllFinals():Void
15+
{
16+
Context.onAfterTyping((types) ->
17+
{
18+
if (calledBefore)
19+
return;
20+
21+
var allFinals:Map<String,Array<String>> = [];
22+
23+
for (type in types)
24+
{
25+
switch (type)
26+
{
27+
case TClassDecl(t):
28+
var classType:ClassType = t.get();
29+
var className:String = t.toString();
30+
if (classType.isInterface) continue;
31+
32+
allFinals.set(className, []);
33+
for (field in classType.statics.get())
34+
{
35+
if (!field.isFinal) continue;
36+
allFinals[className].push(field.name);
37+
}
38+
39+
default:
40+
continue;
41+
}
42+
}
43+
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+
]);
68+
69+
calledBefore = true;
70+
});
71+
}
72+
73+
#if macro
74+
static var calledBefore:Bool = false;
75+
#end
76+
}

polymod/hscript/_internal/PolymodInterpEx.hx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,27 @@ class PolymodInterpEx extends Interp
204204
}
205205
}
206206
}
207+
else
208+
{
209+
@:privateAccess
210+
{
211+
// Check if we are setting a final. If so, throw an error.
212+
if (_proxy != null && _proxy._c != null)
213+
{
214+
for (imp in _proxy._c.imports)
215+
{
216+
if (imp.name != id0) continue;
217+
var finals = PolymodFinalMacro.getAllFinals().get(imp.fullPath);
218+
for (fin in finals)
219+
{
220+
if (fin != id) continue;
221+
errorEx(EInvalidAccess(fin));
222+
return null;
223+
}
224+
}
225+
}
226+
}
227+
}
207228
default:
208229
// Do nothing
209230
}

0 commit comments

Comments
 (0)