Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion polymod/hscript/HScriptedClass.hx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface HScriptedClass
* @param constArgs The arguments to pass to the constructor.
* @return The instance of the scripted class.
*/
// public static function init(clsName:String, constArgs:Array<Dynamic>):ThisType;
// public static function scriptInit(clsName:String, ...constArgs:Dynamic):ThisType;

/**
* Call a custom static function on a scripted class, by the given name, with the given arguments.
Expand Down
29 changes: 18 additions & 11 deletions polymod/hscript/_internal/HScriptedClassMacro.hx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class HScriptedClassMacro

/**
* Create the complicated parts of the generated class,
* specifically the `init()` function and the override methods.
* specifically the `scriptInit()` function and the override methods.
*/
public static function buildHScriptClass(cls:haxe.macro.Type.ClassType, fields:Array<Field>):Array<Field>
{
Expand Down Expand Up @@ -123,7 +123,7 @@ class HScriptedClassMacro
for (arg in args)
{name: arg.name, opt: arg.opt, type: Context.toComplexType(arg.t)}
];
var initField:Field = buildScriptedClassInit(cls, superCls, constArgs);
var initField:Field = buildScriptedClassInit(cls, superCls);
fields.push(initField);
constructor = buildScriptedClassConstructor(constArgs);
case TLazy(builder):
Expand All @@ -136,7 +136,7 @@ class HScriptedClassMacro
for (arg in args)
{name: arg.name, opt: arg.opt, type: Context.toComplexType(arg.t)}
];
var initField:Field = buildScriptedClassInit(cls, superCls, constArgs);
var initField:Field = buildScriptedClassInit(cls, superCls);
fields.push(initField);
constructor = buildScriptedClassConstructor(constArgs);
default:
Expand All @@ -151,7 +151,7 @@ class HScriptedClassMacro
constructor = buildEmptyScriptedClassConstructor();
// Create scripted class utility functions.
Context.info(' Creating scripted class utils...', Context.currentPos());
var initField:Field = buildScriptedClassInit(cls, superCls, []);
var initField:Field = buildScriptedClassInit(cls, superCls);
fields.push(initField);
fields.push(constructor);
}
Expand All @@ -166,25 +166,22 @@ class HScriptedClassMacro
return fields;
}

static function buildScriptedClassInit(cls:haxe.macro.Type.ClassType, superCls:haxe.macro.Type.ClassType, superConstArgs:Array<FunctionArg>):Field
static function buildScriptedClassInit(cls:haxe.macro.Type.ClassType, superCls:haxe.macro.Type.ClassType):Field
{
// Context.info(' Building scripted class init() function', Context.currentPos());
var clsTypeName:String = cls.pack.join('.') != '' ? '${cls.pack.join('.')}.${cls.name}' : cls.name;
var superClsTypeName:String = superCls.pack.join('.') != '' ? '${superCls.pack.join('.')}.${superCls.name}' : superCls.name;

var constArgs = [for (arg in superConstArgs) macro $i{arg.name}];
var typePath:haxe.macro.TypePath = {
pack: cls.pack,
name: cls.name,
};
var function_init:Field = {
name: 'init',
name: 'scriptInit',
doc: "Initializes a scripted class instance using the given scripted class name and constructor arguments.",
access: [APublic, AStatic],
meta: null,
pos: cls.pos,
kind: FFun({
args: [{name: 'clsName', type: macro :String},].concat(superConstArgs),
args: [{name: 'clsName', type: macro :String}, {name: 'args', type: macro :...Dynamic}],
params: null,
ret: Context.toComplexType(Context.getType(clsTypeName)),
expr: macro
Expand All @@ -198,7 +195,7 @@ class HScriptedClassMacro
}

try {
var result = clsRef.instantiate([$a{constArgs}]);
var result = clsRef.instantiate((cast args) ?? []);
if (result == null)
{
polymod.Polymod.error(SCRIPT_RUNTIME_EXCEPTION, 'Could not construct instance of scripted class (${clsName} extends ' + $v{clsTypeName} + '):\nUnknown error instantiating class');
Expand Down Expand Up @@ -377,8 +374,18 @@ class HScriptedClassMacro
})
};

var var__isHScriptedClass:Field = {
name: '_isHScriptedClass',
doc: 'Field used to identify a HScriptedClass.',
access: [APrivate, AStatic],
meta: [{ name: ':noCompletion', pos: cls.pos }],
pos: cls.pos,
kind: FVar(macro :Bool, macro true)
};

return [
var__asc,
var__isHScriptedClass,
function_listScriptClasses,
function_scriptCall,
function_scriptGet,
Expand Down
8 changes: 8 additions & 0 deletions polymod/hscript/_internal/PolymodInterpEx.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,14 @@ class PolymodInterpEx extends Interp
if (o == null)
errorEx(ENullObjectReference(f));

// Backwards compatibility for scripts using HScriptedClass.init
// Std.isOfType(o, HScriptedClass) only works with class instances
// so we look for a specific field to double check the type
if ((f == 'init' || f == 'scriptInit') && o._isHScriptedClass == true)
{
return Reflect.makeVarArgs((args:Array<Dynamic>) -> return o.scriptInit(args[0], args.slice(1)));
}

var oCls:String = Util.getTypeName(Type.typeof(o));

// Check if the field is a blacklisted static field.
Expand Down