From 715a4abd8b0dc9fc445b5d5d51a80326c036b54e Mon Sep 17 00:00:00 2001 From: Kolo <67389779+JustKolosaki@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:09:02 +0100 Subject: [PATCH] add support for `import.hxc` files --- polymod/hscript/_internal/PolymodInterpEx.hx | 119 ++++++++++++++----- 1 file changed, 89 insertions(+), 30 deletions(-) diff --git a/polymod/hscript/_internal/PolymodInterpEx.hx b/polymod/hscript/_internal/PolymodInterpEx.hx index e147fccd..a8be5611 100644 --- a/polymod/hscript/_internal/PolymodInterpEx.hx +++ b/polymod/hscript/_internal/PolymodInterpEx.hx @@ -255,6 +255,10 @@ class PolymodInterpEx extends Interp // Clear the script class descriptors. _scriptClassDescriptors.clear(); + // Also clear the imports from the import.hx files. + _scriptClassImports.clear(); + _scriptClassUsings.clear(); + // Also destroy local variable scope. this.resetVariables(); } @@ -296,6 +300,22 @@ class PolymodInterpEx extends Interp this.resetVariables(); } + private static var _scriptClassImports:Map> = new Map>(); + private static var _scriptClassUsings:Map> = new Map>(); + + private static function registerImportForPackage(pkg:Null>, imp:PolymodClassImport, isUsing:Bool = false) + { + var impFilePkg:String = pkg?.join(".") ?? ""; + var map:Map> = isUsing ? _scriptClassUsings : _scriptClassImports; + + if (!map.exists(impFilePkg)) + { + map.set(impFilePkg, []); + } + + map.get(impFilePkg).push(imp); + } + public static function validateImports():Void { for (cls in _scriptClassDescriptors) @@ -328,6 +348,26 @@ class PolymodInterpEx extends Interp } } + // Import classes from the import.hx files. + var pkg:String = cls.pkg?.join(".") ?? ""; + + for (key => imps in _scriptClassImports) + { + if (!pkg.startsWith(key) && key.length != 0) continue; + + for (imp in imps) + cls.imports.set(imp.name, imp); + } + + for (key => imps in _scriptClassUsings) + { + if (!pkg.startsWith(key) && key.length != 0) continue; + + for (imp in imps) + cls.usings.set(imp.name, imp); + } + + // Add the scripted imports. for (key => imp in cls.importsToValidate) { if (_scriptClassDescriptors.exists(imp.fullPath)) @@ -660,9 +700,8 @@ class PolymodInterpEx extends Interp // Using a clone to prevent locals getting wiped out. var clone = this.clone(); - // This CREATES a new function in memory, that we call later. - var newFun:Dynamic = function(args:Array) - { + // This CREATES a new function in memory, that we call later. + var newFun:Dynamic = function(args:Array) { if (args == null) args = []; validateArgumentCount(params, args, name); @@ -1723,13 +1762,13 @@ class PolymodInterpEx extends Interp } /** - * Initializes function arguments within the interpreter scope. + * Initializes function arguments within the interpreter scope. * - * @param fn The function declaration to extract arguments from. - * @param args The arguments to pass to the function. - * @param name The function's name - * @return The Map containing the variable values before they are shadowed in the local scope. - */ + * @param fn The function declaration to extract arguments from. + * @param args The arguments to pass to the function. + * @param name The function's name + * @return The Map containing the variable values before they are shadowed in the local scope. + */ public function setFunctionValues(fn:Null, args:Array = null, name:String = "Unknown"):Map { var previousValues:Map = []; @@ -1982,23 +2021,29 @@ class PolymodInterpEx extends Interp public function registerModules(module:Array, ?origin:String = "hscript") { + var isImportFile:Bool = (new haxe.io.Path(origin).file == "import"); + var pkg:Array = null; var imports:Map = []; var importsToValidate:Map = []; var usings:Map = []; - for (importPath in PolymodScriptClass.defaultImports.keys()) + // Don't add the default imports to import.hx since they're added to other script classes anyways. + if (!isImportFile) { - var splitPath = importPath.split("."); - var clsName = splitPath[splitPath.length - 1]; + for (importPath in PolymodScriptClass.defaultImports.keys()) + { + var splitPath = importPath.split("."); + var clsName = splitPath[splitPath.length - 1]; - imports.set(clsName, - { - name: clsName, - pkg: splitPath.slice(0, splitPath.length - 1), - fullPath: importPath, - cls: PolymodScriptClass.defaultImports.get(importPath), - }); + imports.set(clsName, + { + name: clsName, + pkg: splitPath.slice(0, splitPath.length - 1), + fullPath: importPath, + cls: PolymodScriptClass.defaultImports.get(importPath), + }); + } } for (decl in module) @@ -2062,6 +2107,12 @@ class PolymodInterpEx extends Interp // If the class is still not found, skip this import entirely. if (resultCls == null && resultEnm == null) { + if (isImportFile) + { + registerImportForPackage(pkg, importedClass); + continue; + } + // Polymod.error(SCRIPT_CLASS_MODULE_NOT_FOUND, 'Could not import class ${importedClass.fullPath}', origin); // this could be a scripted class or enum that hasn't been registered yet importsToValidate.set(importedClass.name, importedClass); @@ -2077,6 +2128,12 @@ class PolymodInterpEx extends Interp } } + if (isImportFile) + { + registerImportForPackage(pkg, importedClass); + continue; + } + Polymod.debug('Imported class ${importedClass.name} from ${importedClass.fullPath}'); imports.set(importedClass.name, importedClass); case DUsing(path): @@ -2127,22 +2184,22 @@ class PolymodInterpEx extends Interp var resultCls:Class = Type.resolveClass(importedClass.fullPath); // If the class is still not found, skip this import entirely. - if (resultCls == null) - { - // Polymod.error(SCRIPT_CLASS_MODULE_NOT_FOUND, 'Could not import class ${importedClass.fullPath}', origin); - // this could be a scripted class that hasn't been registered yet - importsToValidate.set(importedClass.name, importedClass); - continue; - } - else - { - importedClass.cls = resultCls; - } + if (resultCls == null) continue; + + importedClass.cls = resultCls; + } + + if (isImportFile) + { + registerImportForPackage(pkg, importedClass, true); + continue; } Polymod.debug('Using class ${importedClass.name} from ${importedClass.fullPath}'); usings.set(importedClass.name, importedClass); case DClass(c): + if (isImportFile) continue; + var instanceFields = []; var staticFields = []; for (f in c.fields) @@ -2175,6 +2232,8 @@ class PolymodInterpEx extends Interp }; registerScriptClass(classDecl); case DEnum(e): + if (isImportFile) continue; + if (pkg != null) { imports.set(e.name,