Import aliases for Custom Classes

Import aliases support for Custom Classes. This allows you to import classes and other custom classes with an alias inside of a Custom Class.

This includes some improvements on "parseModuleDecl()"
This commit is contained in:
Jaime Humberto Macias Bustamante
2025-02-01 21:00:41 -07:00
parent b25ecb08bc
commit 241d97aed0
5 changed files with 55 additions and 20 deletions
+1 -1
View File
@@ -159,7 +159,7 @@ enum Error {
enum ModuleDecl {
DPackage( path : Array<String> );
DImport( path : Array<String>, ?everything : Bool );
DImport( path : Array<String>, ?everything : Bool, ?asname:String );
DClass( c : ClassDecl );
DTypedef( c : TypeDecl );
}
+12 -9
View File
@@ -81,10 +81,11 @@ class Interp {
return _customClasses.exists(name);
}
private static function registerCustomClass(c:CustomClassDecl) {
private static function registerCustomClass(c:CustomClassDecl, ?as:String) {
#if CUSTOM_CLASSES
var name = c.classDecl.name;
if (c.pkg != null) {
if (as != null) name = as;
else if (c.pkg != null) {
name = c.pkg.join(".") + "." + name;
}
_customClasses.set(name, c);
@@ -129,7 +130,7 @@ class Interp {
return scriptObject = v;
}
public var errorHandler:Error->Void;
public var importFailedCallback:Array<String>->Bool;
public var importFailedCallback:Array<String> -> ?Null<String> -> Bool;
public var customClasses:Map<String, Dynamic>;
public var variables:Map<String, Dynamic>;
@@ -829,7 +830,7 @@ class Interp {
}
if (cl == null && en == null) {
if (importFailedCallback == null || !importFailedCallback(oldSplitName))
if (importFailedCallback == null || !importFailedCallback(oldSplitName, n))
error(EInvalidClass(oldClassName));
} else {
if (en != null) {
@@ -1593,24 +1594,26 @@ class Interp {
}
}
public function registerModule(module:Array<ModuleDecl>) {
public function registerModule(module:Array<ModuleDecl>, ?as:String) {
var pkg:Array<String> = null;
var imports:Map<String, CustomClassImport> = [];
for (decl in module) {
switch (decl) {
case DPackage(path):
pkg = path;
case DImport(path, _):
case DImport(path, _, asname):
if (importBlocklist.contains(path.join(".")))
continue;
var last = path[path.length - 1];
var hasAlias = asname != null;
var importedClass:CustomClassImport = {
name: last,
pkg: [for (e in path) e.trim()],
fullPath: path.join(".")
fullPath: path.join("."),
as: asname
}
imports.set(importedClass.name, importedClass);
imports.set(hasAlias ? asname : importedClass.name, importedClass);
case DClass(c):
var extend = c.extend;
if (extend != null) {
@@ -1640,7 +1643,7 @@ class Interp {
pkg: pkg
}
customClassDecl.cacheFields();
registerCustomClass(customClassDecl);
registerCustomClass(customClassDecl, as);
case DTypedef(_):
//TODO: maybe make this work :3
}
+37 -7
View File
@@ -1509,10 +1509,22 @@ class Parser {
return DPackage(path);
case "import":
var path = [getIdent()];
var star = false;
var asname:String = null;
var star = false; // For now, unused
while( true ) {
var t = token();
if( t != TDot ) {
if (t.match(TId("as"))) {
t = token();
switch (t) {
case TId(id):
asname = id;
default:
unexpected(t);
}
break;
}
push(t);
break;
}
@@ -1520,34 +1532,52 @@ class Parser {
switch( t ) {
case TId(id):
path.push(id);
/* idk if put this work
case TOp("*"):
star = true;
*/
default:
unexpected(t);
}
}
ensure(TSemicolon);
return DImport(path, star);
return DImport(path, star, asname);
case "class":
var name = getIdent();
var params = parseParams();
var extend = null;
var implement = [];
var extend:Null<CType> = null;
var implement:Array<CType> = [];
while( true ) {
var t = token();
switch( t ) {
case TId("extends"):
extend = parseType();
var e = parseType();
switch(e) {
case CTPath(path, params):
if(extend != null) {
error(ECustom('Cannot extend a class twice.'), 0, 0);
}
extend = e;
default:
error(ECustom('${Std.string(e)} is not a valid path.'), 0, 0);
}
case TId("implements"):
implement.push(parseType());
var i = parseType();
switch(i) {
case CTPath(path, params):
implement.push(i);
default:
error(ECustom('${Std.string(i)} is not a valid interface path.'), 0, 0);
}
//implement.push(parseType());
default:
push(t);
break;
}
}
var fields = [];
var fields:Array<FieldDecl> = [];
ensure(TBrOpen);
while( !maybe(TBrClose) )
fields.push(parseField());
+4 -3
View File
@@ -152,22 +152,23 @@ class CustomClass implements IHScriptCustomAccessBehaviour{
var i:Int = 0;
for(_import in __class.imports) {
var importedClass = _import.fullPath;
var importAlias = _import.as;
if(Interp.customClassExist(importedClass) && this.interp.importFailedCallback != null) {
this.interp.importFailedCallback(importedClass.split("."));
this.interp.importFailedCallback(importedClass.split("."), importAlias);
continue;
}
#if hscriptPos
var e:Expr = {
e: ExprDef.EImport(importedClass),
e: ExprDef.EImport(importedClass, importAlias),
pmin: 0,
pmax: 0,
origin: this.className,
line: i
};
#else
var e = Expr.EImport(importedClass);
var e = Expr.EImport(importedClass, importAlias);
#end
this.interp.expr(e);
i++;
+1
View File
@@ -157,4 +157,5 @@ typedef CustomClassImport = {
var ?name:String;
var ?pkg:Array<String>;
var ?fullPath:String; // pkg.pkg.pkg.name
var ?as:Null<String>; // import pkg.Name as OtherName
}