From d4d98d1813c6be07ffb2cd36b1332fefe419904b Mon Sep 17 00:00:00 2001 From: nykwono Date: Wed, 28 Oct 2026 01:11:00 -0400 Subject: [PATCH] Allow several dot paths for access control --- polymod/hscript/_internal/Interp.hx | 119 +++++++++++++++++----------- 1 file changed, 74 insertions(+), 45 deletions(-) diff --git a/polymod/hscript/_internal/Interp.hx b/polymod/hscript/_internal/Interp.hx index 63dd193a..3872855c 100644 --- a/polymod/hscript/_internal/Interp.hx +++ b/polymod/hscript/_internal/Interp.hx @@ -1512,7 +1512,7 @@ class Interp } } - + // Fallback to local variable var l = locals.get(id); v = fop(expr(e1), expr(e2)); @@ -1621,7 +1621,7 @@ class Interp var l = locals.get(id); var v:Dynamic = (l == null) ? resolve(id) : l.r; - + if (l != null && l.isfinal && l.r != null) return error(EInvalidFinalSet(id)); if (prefix) @@ -2327,7 +2327,7 @@ class Interp isfinal: isFinal, isstatic: false }); - + return null; case EParent(e0): return expr(e0); @@ -4598,75 +4598,104 @@ class Interp public function parseAccessMetadata(clsDecl:ClassDecl, meta:{name:String, params:Array}):AccessControl { - var expr = meta.params[0]; - var classPackageExpr:String = new Printer().exprToString(expr); - var path:Array = classPackageExpr.split('.'); - if (path.length == 1) + var accessControl:AccessControl = {}; + + function appendInterface(path:String):Void + { + if (accessControl.interfacePackage != null) + accessControl.interfacePackage.push(path); + else + accessControl.interfacePackage = [path]; + } + + function appendPackage(path:String):Void + { + if (accessControl.pkg != null) + accessControl.pkg.push(path) + else + accessControl.pkg = [path]; + } + + function appendClass(path:String, ?fields:Null> = null):Void { - // We're dealing with an imported class. - // Classes with no package are auto-imported so this should be fine to check. - var clsPack:String = clsDecl.imports.get(classPackageExpr)?.fullPath ?? classPackageExpr; - if (PolymodStaticInterfaceReference.tryBuild(clsPack) != null) + if (accessControl.access != null) { - // We're dealing with an interface package. - return {interfacePackage: [clsPack]}; + accessControl.access.set(path, fields); } else { - // Attempt to resolve the class, and if it fails, this access control is for a package. - var cls:Null = resolveDottedPath(classPackageExpr); - if (cls != null) - { - return {access: [clsPack => null]}; - } - else - { - return {pkg: [clsPack]}; - } + accessControl.access = new Map>>(); + accessControl.access.set(path, fields); } } - else - { - // We're dealing with a multi-dotted package that could potentially also be a field. - // Class metadata don't have very strict syntax in regular Haxe. - // Try to see if we can resolve the class first. - var cls:Null = resolveDottedPath(classPackageExpr); - if (cls != null) + for (expr in meta.params) + { + var classPackageExpr:String = new Printer().exprToString(expr); + var path:Array = classPackageExpr.split('.'); + if (path.length == 1) { - if (cls is PolymodStaticInterfaceReference) + // We're dealing with an imported class. + // Classes with no package are auto-imported so this should be fine to check. + var clsPack:String = clsDecl.imports.get(classPackageExpr)?.fullPath ?? classPackageExpr; + if (PolymodStaticInterfaceReference.tryBuild(clsPack) != null) { // We're dealing with an interface package. - return {interfacePackage: [classPackageExpr]}; + appendInterface(clsPack); } else { - // Regular class path. - return {access: [classPackageExpr => null]}; + // Attempt to resolve the class, and if it fails, this access control is for a package. + var cls:Null = resolveDottedPath(classPackageExpr); + if (cls != null) + { + appendClass(clsPack); + } + else + { + appendPackage(clsPack); + } } } else { - var clsField:String = path[path.length - 1]; - var clsPack:String = path.slice(0, -1).join('.'); + // We're dealing with a multi-dotted package that could potentially also be a field. + // Class metadata don't have very strict syntax in regular Haxe. - // Check for imports just in case the resolved class isn't dotted anymore. - clsPack = clsDecl.imports.get(clsPack)?.fullPath ?? clsPack; - - cls = resolveDottedPath(clsPack); + // Try to see if we can resolve the class first. + var cls:Null = resolveDottedPath(classPackageExpr); if (cls != null) { - // Regular class path. - return {access: [clsPack => [clsField]]}; + if (cls is PolymodStaticInterfaceReference) + { + appendInterface(classPackageExpr); + } + else + { + appendClass(classPackageExpr); + } } else { - // We're most likely dealing with a regular package. - return {pkg: [classPackageExpr]}; + var clsField:String = path[path.length - 1]; + var clsPack:String = path.slice(0, -1).join('.'); + + // Check for imports just in case the resolved class isn't dotted anymore. + clsPack = clsDecl.imports.get(clsPack)?.fullPath ?? clsPack; + + cls = resolveDottedPath(clsPack); + if (cls != null) + { + appendClass(clsPack, [clsField]); + } + else + { + appendPackage(classPackageExpr); + } } } } - return null; + return accessControl; } public static function validateInterfaceImports():Void