@@ -19,7 +19,7 @@ using StringTools;
1919class PolymodScriptClassMacro {
2020 /**
2121 * Returns a `Map<String, Class<Dynamic>>` which maps superclass paths to scripted classes.
22- * So `class ScriptedStage extends Stage implements HScriptable` will be `"Stage" -> ScriptedStage`
22+ * So `class ScriptedStage extends Stage implements HScriptable` will be `"Stage" -> ScriptedStage`
2323 */
2424 public static macro function listHScriptedClasses (): ExprOf <Map <String , Class <Dynamic >>> {
2525 if (! onGenerateCallbackRegistered )
@@ -62,22 +62,22 @@ class PolymodScriptClassMacro {
6262 static var onAfterTypingCallbackRegistered : Bool = false ;
6363
6464 static function onGenerate (allTypes : Array <haxe.macro. Type >) {
65- // Reset these, since onGenerate persists across multiple builds.
65+ // Reset these, since onGenerate persists across multiple builds.
6666 var hscriptedClassType : ClassType = MacroUtil .getClassType (' polymod.hscript.HScriptedClass' );
6767
68- var hscriptedClassEntries : Array <Expr > = [];
68+ var hscriptedClassEntries : Array <Expr > = [];
6969 var abstractImplEntries : Array <Expr > = [];
7070 var abstractStaticEntries : Array <Expr > = [];
7171
7272 for (type in allTypes ) {
7373 switch (type ) {
7474 // Class instances
7575 case TInst (t , _params ):
76- var classType : ClassType = t .get ();
76+ var classType : ClassType = t .get ();
7777 var classPath : String = ' ${classType .pack .join (" ." )}. ${classType .name }' ;
7878
79- if (classType .isInterface ) {
80- // Ignore interfaces.
79+ if (classType .isInterface ) {
80+ // Ignore interfaces.
8181 } else if (MacroUtil .implementsInterface (classType , hscriptedClassType )) {
8282 // Context.info('${classPath} implements HScriptedClass? YEAH', Context.currentPos());
8383 // TODO: Do we need to parameterize?
@@ -95,54 +95,54 @@ class PolymodScriptClassMacro {
9595 } else { }
9696 case TAbstract (t , _params ):
9797 var abstractPath : String = t .toString ();
98- if (abstractPath == ' flixel.util.FlxColor' ) {
99- var abstractType = t .get ();
100- var abstractImpl = abstractType .impl .get ();
101- var abstractImplPath = abstractType .impl .toString ();
102- // Context.info('${abstractImplPath} implements FlxColor', Context.currentPos());
98+ var abstractType = t .get ();
99+ var abstractImpl = abstractType .impl ?. get ();
100+ var abstractImplPath : String = abstractType .impl ?. toString () ?? ' ' ;
103101
104- var entryData = [
105- macro $ v { abstractPath },
106- macro $ v { abstractImplPath }
107- ];
102+ if ( abstractImpl == null ) {
103+ // If the abstract doesn't have an implementation, it's usually an extern or something, so we always want to ignore it.
104+ continue ;
105+ }
108106
109- abstractImplEntries .push (macro $a {entryData });
107+ var entryData = [
108+ macro $v {abstractPath },
109+ macro $v {abstractImplPath }
110+ ];
110111
111- for (field in abstractImpl .statics .get ()) {
112- switch (field .type ) {
113- case TAbstract (_ , _ ):
114- //
115- case TType (_ , _ ):
116- //
117- default :
118- continue ;
119- }
120-
121- var key : String = ' ${abstractImplPath }. ${field .name }' ;
112+ abstractImplEntries .push (macro $a {entryData });
122113
123- if (! staticFieldToClass .exists (key )) {
114+ for (field in abstractImpl .statics .get ()) {
115+ switch (field .type ) {
116+ case TAbstract (_ , _ ):
117+ //
118+ case TType (_ , _ ):
119+ //
120+ default :
124121 continue ;
125- }
126-
127- var staticEntryData = [
128- macro $v {key },
129- macro $v {staticFieldToClass [key ]},
130- ];
122+ }
123+
124+ var key : String = ' ${abstractImplPath }. ${field .name }' ;
131125
132- abstractStaticEntries .push (macro $a {staticEntryData });
126+ if (! staticFieldToClass .exists (key )) {
127+ continue ;
133128 }
134129
135- // Try to apply RTTI?
136- abstractType .meta .add (' :rtti' , [], Context .currentPos ());
137- abstractImpl .meta .add (' :rtti' , [], Context .currentPos ());
130+ var staticEntryData = [
131+ macro $v {key },
132+ macro $v {staticFieldToClass [key ]},
133+ ];
134+
135+ abstractStaticEntries .push (macro $a {staticEntryData });
138136 }
139137 default :
140- continue ;
138+ continue ;
141139 }
142140 }
143141
144- var polymodScriptClassClassType : ClassType = MacroUtil .getClassType (' polymod.hscript._internal.PolymodScriptClassMacro' );
145- polymodScriptClassClassType .meta .remove (' hscriptedClasses' );
142+ Context .info (' PolymodScriptClassMacro: Registering ${hscriptedClassEntries .length } HScriptedClasses, ${abstractImplEntries .length } abstract impls, ${abstractStaticEntries .length } abstract statics' , Context .currentPos ());
143+
144+ var polymodScriptClassClassType : ClassType = MacroUtil .getClassType (' polymod.hscript._internal.PolymodScriptClassMacro' );
145+ polymodScriptClassClassType .meta .remove (' hscriptedClasses' );
146146 polymodScriptClassClassType .meta .add (' hscriptedClasses' , hscriptedClassEntries , Context .currentPos ());
147147 polymodScriptClassClassType .meta .remove (' abstractImpls' );
148148 polymodScriptClassClassType .meta .add (' abstractImpls' , abstractImplEntries , Context .currentPos ());
@@ -161,11 +161,15 @@ class PolymodScriptClassMacro {
161161 var abstractPath = a .toString ();
162162 var abstractType = a .get ();
163163
164- if (abstractPath != ' flixel.util.FlxColor' ) {
164+ // If the abstract is private, the implementation won't be accessible.
165+ var abstractIsPrivate = abstractType .isPrivate ;
166+ if (abstractIsPrivate ) {
165167 continue ;
166168 }
167-
168- if (abstractType .impl == null ) {
169+
170+ // Check if, for other reasons, the implementation is missing.
171+ var abstractHasNoImpl = abstractType .impl == null ;
172+ if (abstractHasNoImpl ) {
169173 continue ;
170174 }
171175
@@ -187,15 +191,15 @@ class PolymodScriptClassMacro {
187191 }
188192
189193 if (getter == null ) {
190- throw ' This should not happen ' ;
194+ throw ' Getter is null? ' ;
191195 }
192196
193197 switch (getter .type ) {
194198 case TFun (args , _ ):
195199 if (args .length != 0 )
196200 continue ;
197201 default :
198- throw ' This should not happen ' ;
202+ throw ' Getter has an unknown type? ' ;
199203 }
200204
201205 canGet = true ;
@@ -211,15 +215,15 @@ class PolymodScriptClassMacro {
211215 }
212216
213217 if (setter == null ) {
214- throw ' This should not happen ' ;
218+ throw ' Setter is null? ' ;
215219 }
216220
217221 switch (setter .type ) {
218222 case TFun (args , _ ):
219223 if (args .length != 1 )
220224 continue ;
221225 default :
222- throw ' This should not happen ' ;
226+ throw ' Setter has an unknown type? ' ;
223227 }
224228
225229 canSet = true ;
@@ -299,25 +303,25 @@ class PolymodScriptClassMacro {
299303 public static function fetchHScriptedClasses (): Map <String , Class <Dynamic >> {
300304 var metaData = Meta .getType (PolymodScriptClassMacro );
301305
302- // trace('Got metaData: ' + metaData);
306+ // trace('Got metaData: ' + metaData);
303307
304308 if (metaData .hscriptedClasses != null ) {
305- trace (' Got hscriptedClasses: ' + metaData .hscriptedClasses );
309+ trace (' Got hscriptedClasses: ' + metaData .hscriptedClasses );
306310
307311 var result : Map <String , Class <Dynamic >> = [];
308312
309313 // Each element is formatted as `[superClassPath, classPath]`.
310314
311315 for (element in metaData .hscriptedClasses ) {
312- if (element .length != 2 ) {
313- throw ' Malformed element in hscriptedClasses: ' + element ;
314- }
316+ if (element .length != 2 ) {
317+ throw ' Malformed element in hscriptedClasses: ' + element ;
318+ }
315319
316- var superClassPath : String = element [0 ];
317- var classPath : String = element [1 ];
320+ var superClassPath : String = element [0 ];
321+ var classPath : String = element [1 ];
318322 var classType : Class <Dynamic > = cast Type .resolveClass (classPath );
319- result .set (superClassPath , classType );
320- }
323+ result .set (superClassPath , classType );
324+ }
321325
322326 return result ;
323327 } else {
0 commit comments