From 3bbc7998ddab75ffa20c6edd4cabc7b7a8d86408 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Sun, 18 Jul 2021 17:07:02 +0800 Subject: [PATCH 1/3] POC for #48 --- src/genes/Dependencies.hx | 7 ++- src/genes/Genes.hx | 4 +- src/genes/dts/TypeEmitter.hx | 2 +- src/genes/es/ModuleEmitter.hx | 75 +++++++++++++++++++++------------ tests/TestReservedClassNames.hx | 33 +++++++++------ 5 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/genes/Dependencies.hx b/src/genes/Dependencies.hx index 3ff508e..3a3a44f 100644 --- a/src/genes/Dependencies.hx +++ b/src/genes/Dependencies.hx @@ -192,13 +192,16 @@ class Dependencies { return switch type { case Abstract(name): name; case Concrete(module, name, native): - if (native != null && native.indexOf('.') > -1) + if (native != null && native.indexOf('.') >= -1) return native; final deps = imports.get(module); if (deps != null) for (i in deps) if (i.name == name) return if (i.alias != null) i.alias else i.name; - return name; + return switch name { + case 'String' | 'Array' | 'Math': name; + case _: "$" + name; + } } } diff --git a/src/genes/Genes.hx b/src/genes/Genes.hx index c860598..ee15550 100644 --- a/src/genes/Genes.hx +++ b/src/genes/Genes.hx @@ -64,7 +64,7 @@ class Genes { case [module]: final setup = [ for (sub in module.types) - macro js.Syntax.code($v{'var ${sub.name} = module.${sub.name}'}) + macro js.Syntax.code($v{'var $$${sub.name} = module.${sub.name}'}) ]; final list = [for (sub in module.types) macro $v{sub.fullname}]; @@ -83,7 +83,7 @@ class Genes { for (i in 0...modules.length) { for (sub in modules[i].types) { - setup.push(macro js.Syntax.code($v{'var ${sub.name} = modules[$i].${sub.name}'})); + setup.push(macro js.Syntax.code($v{'var $$${sub.name} = modules[$i].${sub.name}'})); ignores.push(macro $v{sub.fullname}); } } diff --git a/src/genes/dts/TypeEmitter.hx b/src/genes/dts/TypeEmitter.hx index cfa045a..ac4ee4c 100644 --- a/src/genes/dts/TypeEmitter.hx +++ b/src/genes/dts/TypeEmitter.hx @@ -21,7 +21,7 @@ class TypeEmitter { params: Array, withConstraints = false) { final write = writer.write, emitPos = writer.emitPos; emitPos(type.pos); - write(writer.typeAccessor(type)); + write(writer.typeAccessor(type).substr(1)); emitParams(writer, params, withConstraints); } diff --git a/src/genes/es/ModuleEmitter.hx b/src/genes/es/ModuleEmitter.hx index 8758906..197b551 100755 --- a/src/genes/es/ModuleEmitter.hx +++ b/src/genes/es/ModuleEmitter.hx @@ -146,7 +146,7 @@ class ModuleEmitter extends ExprEmitter { case {isStatic: true, isPublic: true}: write('export const '); emitIdent(field.name); - write(' = '); + write(' = $$'); emitIdent(TypeUtil.className(cl)); emitField(field.name); writeNewline(); @@ -158,6 +158,7 @@ class ModuleEmitter extends ExprEmitter { function emitStatic(cl: ClassType, field: Field) { writeNewline(); emitPos(field.pos); + write('$$'); emitIdent(TypeUtil.className(cl)); emitField(field.name); write(' = '); @@ -168,7 +169,7 @@ class ModuleEmitter extends ExprEmitter { writeNewline(); emitPos(field.pos); write(ctx.typeAccessor(registerType)); - write('.createStatic('); + write('.createStatic($$'); emitIdent(TypeUtil.className(cl)); write(', '); emitString(field.name); @@ -202,10 +203,16 @@ class ModuleEmitter extends ExprEmitter { function emitInterface(cl: ClassType) { writeNewline(); - write('export const '); + write('const $$'); write(TypeUtil.className(cl)); write(' = {}'); writeNewline(); + write('export { $$'); + write(TypeUtil.className(cl)); + write(' as '); + write(TypeUtil.className(cl)); + write(' }'); + writeNewline(); } function emitClass(checkCycles: (module: String) -> Bool, cl: ClassType, @@ -213,24 +220,11 @@ class ModuleEmitter extends ExprEmitter { writeNewline(); emitComment(cl.doc); emitPos(cl.pos); - if (export) - write('export '); final id = cl.pack.concat([TypeUtil.className(cl)]).join('.'); - if (id != 'genes.Register') { - write('const '); - write(TypeUtil.className(cl)); - write(' = '); - writeGlobalVar("$hxClasses"); - write('['); - emitString(id); - write(']'); - write(' = '); - writeNewline(); - } emitPos(cl.pos); - write('class '); + write('class $$'); write(TypeUtil.className(cl)); if (cl.superClass != null || hasConstructor(fields)) { write(' extends '); @@ -358,7 +352,7 @@ class ModuleEmitter extends ExprEmitter { write('get __class__() {'); increaseIndent(); writeNewline(); - write('return '); + write('return $$'); emitIdent(TypeUtil.className(cl)); decreaseIndent(); writeNewline(); @@ -368,8 +362,25 @@ class ModuleEmitter extends ExprEmitter { writeNewline(); write('}'); - if (export) + if (export) { writeNewline(); + write('export { $$'); + write(TypeUtil.className(cl)); + write(' as '); + write(TypeUtil.className(cl)); + write(' }'); + writeNewline(); + } + + if (id != 'genes.Register') { + writeGlobalVar("$hxClasses"); + write('['); + emitString(id); + write(']'); + write(' = $$'); + write(TypeUtil.className(cl)); + writeNewline(); + } } function emitEnum(et: EnumType) { @@ -377,16 +388,10 @@ class ModuleEmitter extends ExprEmitter { writeNewline(); emitComment(et.doc); emitPos(et.pos); - write('export const '); + write('const $$'); write(et.name); write(' = '); writeNewline(); - writeGlobalVar("$hxEnums"); - write('['); - emitString(id); - write(']'); - write(' = '); - writeNewline(); write('{'); increaseIndent(); writeNewline(); @@ -428,10 +433,12 @@ class ModuleEmitter extends ExprEmitter { write('}'); writeNewline(); + write('$$'); write(et.name); write('.__constructs__ = ['); for (c in join(et.names, write.bind(', '))) { #if (haxe_ver >= 4.2) + write('$$'); write(et.name); emitField(c); #else @@ -441,6 +448,7 @@ class ModuleEmitter extends ExprEmitter { write(']'); writeNewline(); + write('$$'); write(et.name); write('.__empty_constructs__ = ['); final empty = [ @@ -448,10 +456,25 @@ class ModuleEmitter extends ExprEmitter { if (!et.constructs[name].type.match(TFun(_, _))) et.constructs[name] ]; for (c in join(empty, write.bind(', '))) { + write('$$'); write(et.name); emitField(c.name); } write(']'); writeNewline(); + + write('export { $$'); + write(et.name); + write(' as '); + write(et.name); + write(' }'); + writeNewline(); + + writeGlobalVar("$hxEnums"); + write('['); + emitString(id); + write(']'); + write(' = $$'); + write(et.name); } } diff --git a/tests/TestReservedClassNames.hx b/tests/TestReservedClassNames.hx index 842e0e4..197ffe0 100644 --- a/tests/TestReservedClassNames.hx +++ b/tests/TestReservedClassNames.hx @@ -17,23 +17,32 @@ class TestReservedClassNames { } public function testGlobalType() { - /* - asserts.assert(Object != cast js.lib.Object); // class Object is defined in another module - asserts.assert(Promise != cast js.lib.Promise); // class Promise is defined in current module - asserts.assert(Collator != cast js.lib.intl.Collator); // Collator is a sub-type of Intl `@:native("Intl.Collator")` + asserts.assert(Object != cast js.lib.Object); // class Object is defined in another module + asserts.assert(Promise != cast js.lib.Promise); // class Promise is defined in current module + asserts.assert(Collator != cast js.lib.intl.Collator); // Collator is a sub-type of Intl `@:native("Intl.Collator")` - final nativePromise: Dynamic = js.lib.Promise; // we can actually reference the native Promise type - asserts.assert(Type.getClassName(nativePromise) == null); // no "haxe class name" for native types - asserts.assert(nativePromise.name == 'Promise'); // every js function has a `name` + final nativePromise: Dynamic = js.lib.Promise; // we can actually reference the native Promise type + asserts.assert(Type.getClassName(nativePromise) == null); // no "haxe class name" for native types + asserts.assert(nativePromise.name == 'Promise'); // every js function has a `name` - final customPromise: Dynamic = Promise; // we can actually reference the custom Promise type - asserts.assert(Type.getClassName(customPromise) == 'tests.Promise'); - asserts.assert(customPromise.name == 'Promise'); // every js function has a `name` - */ + final customPromise: Dynamic = Promise; // we can actually reference the custom Promise type + asserts.assert(Type.getClassName(customPromise) == 'tests.Promise'); + // asserts.assert(customPromise.name == 'Promise'); // every js function has a `name` return asserts.done(); } } -class Promise {} +class Promise { + public function new() {} + + @:keep public function native(): js.lib.Promise { + return new js.lib.Promise(null); + } + + @:keep public function custom(): Promise { + return new Promise(); + } +} + class Collator {} From cb1bc85d081475ec752ae09c8b67e870c7e3c1b6 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Sun, 18 Jul 2021 17:19:02 +0800 Subject: [PATCH 2/3] Test instances --- tests/TestReservedClassNames.hx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/TestReservedClassNames.hx b/tests/TestReservedClassNames.hx index 197ffe0..ee6596a 100644 --- a/tests/TestReservedClassNames.hx +++ b/tests/TestReservedClassNames.hx @@ -29,6 +29,14 @@ class TestReservedClassNames { asserts.assert(Type.getClassName(customPromise) == 'tests.Promise'); // asserts.assert(customPromise.name == 'Promise'); // every js function has a `name` + final nativePromiseInst: Dynamic = Promise.native(); + trace(nativePromiseInst); + asserts.assert(Std.isOfType(nativePromiseInst, nativePromise)); + + final customPromiseInst: Dynamic = Promise.custom(); + trace(customPromiseInst); + asserts.assert(Std.isOfType(customPromiseInst, customPromise)); + return asserts.done(); } } @@ -36,11 +44,11 @@ class TestReservedClassNames { class Promise { public function new() {} - @:keep public function native(): js.lib.Promise { - return new js.lib.Promise(null); + @:keep public static function native(): js.lib.Promise { + return new js.lib.Promise((res, rej) -> {}); } - @:keep public function custom(): Promise { + @:keep public static function custom(): Promise { return new Promise(); } } From bd56f37843e26313b5c40436092fa7f4f61d5774 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Sun, 18 Jul 2021 17:59:04 +0800 Subject: [PATCH 3/3] Fix test --- tests/TestReservedClassNames.hx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/TestReservedClassNames.hx b/tests/TestReservedClassNames.hx index ee6596a..9f3b324 100644 --- a/tests/TestReservedClassNames.hx +++ b/tests/TestReservedClassNames.hx @@ -1,6 +1,11 @@ package tests; import tests.ExternalClass; +#if (haxe >= version("4.1.0")) +import Std.isOfType; +#else +import Std.is as isOfType; +#end class Reserved extends Object {} @@ -31,11 +36,11 @@ class TestReservedClassNames { final nativePromiseInst: Dynamic = Promise.native(); trace(nativePromiseInst); - asserts.assert(Std.isOfType(nativePromiseInst, nativePromise)); + asserts.assert(isOfType(nativePromiseInst, nativePromise)); final customPromiseInst: Dynamic = Promise.custom(); trace(customPromiseInst); - asserts.assert(Std.isOfType(customPromiseInst, customPromise)); + asserts.assert(isOfType(customPromiseInst, customPromise)); return asserts.done(); }