Pārlūkot izejas kodu

[cpp] Do not generate toString in __scriptableFunctions (#12375)

* [cpp] Fix toString breaking scriptable mapping

The toString method is filtered out in the vtable mapping on line 973
and is already present in the `__scriptableFunctions` of hx::Object.
We need to filter it out here too to ensure a correct vtable can be
constructed from merging all `__scriptableFunctions` arrays.

* [tests] Add case for toString scriptable issue

* [tests] Clean up

Remove unnecessary public modifier

Fix order of expected vs actual equality values

* [cpp] Add comments to clarify toString handling

* [tests] Add issue number as suffix to avoid clash
tobil4sk 3 nedēļas atpakaļ
vecāks
revīzija
5a1d6f8697

+ 15 - 13
src/generators/cpp/gen/cppGenClassImplementation.ml

@@ -970,25 +970,27 @@ let generate_managed_class base_ctx tcpp_class =
     in
     in
 
 
     flatten_tcpp_class_functions
     flatten_tcpp_class_functions
-    |> List.filter (fun f -> f.tcf_name <> "toString")
+    |> List.filter (fun f -> f.tcf_name <> "toString") (* toString is provided by HX_DEFINE_SCRIPTABLE *)
     |> ExtList.List.iteri dump_script_func;
     |> ExtList.List.iteri dump_script_func;
     output_cpp "};\n\n";
     output_cpp "};\n\n";
 
 
     if List.length tcpp_class.tcl_functions > 0 || List.length tcpp_class.tcl_static_functions > 0 then (
     if List.length tcpp_class.tcl_functions > 0 || List.length tcpp_class.tcl_static_functions > 0 then (
 
 
       let dump_script is_static f acc =
       let dump_script is_static f acc =
-        let signature = generate_script_function is_static f.tcf_field ("__s_" ^ f.tcf_field.cf_name) f.tcf_name in
-        let superCall = if is_static then "0" else "__s_" ^ f.tcf_field.cf_name ^ "<true>" in
-        let named =
-          Printf.sprintf
-            "\t::hx::ScriptNamedFunction(\"%s\", __s_%s, \"%s\", %s HXCPP_CPPIA_SUPER_ARG(%s))"
-            f.tcf_field.cf_name
-            f.tcf_field.cf_name
-            signature
-            (if is_static then "true" else "false")
-            superCall in
-
-        named :: acc
+        if f.tcf_name <> "toString" then (* toString implicitly overrides hx::Object::toString *)
+          let signature = generate_script_function is_static f.tcf_field ("__s_" ^ f.tcf_field.cf_name) f.tcf_name in
+          let superCall = if is_static then "0" else "__s_" ^ f.tcf_field.cf_name ^ "<true>" in
+          let named =
+            Printf.sprintf
+              "\t::hx::ScriptNamedFunction(\"%s\", __s_%s, \"%s\", %s HXCPP_CPPIA_SUPER_ARG(%s))"
+              f.tcf_field.cf_name
+              f.tcf_field.cf_name
+              signature
+              (if is_static then "true" else "false")
+              superCall in
+
+          named :: acc
+        else acc
       in
       in
 
 
       let sigs =
       let sigs =

+ 19 - 0
tests/unit/src/scripthost/Issue12374.hx

@@ -0,0 +1,19 @@
+package scripthost;
+
+#if cpp
+@:keep class HostParent12374 {
+	public function new() {}
+
+	function toString() {
+		return "HostParent.toString()";
+	}
+
+	public function methodA() {
+		return 'HostParent.methodA()';
+	}
+
+	public function methodB() {
+		return 'HostParent.methodB()';
+	}
+}
+#end

+ 22 - 0
tests/unit/src/unit/issues/Issue12374.hx

@@ -0,0 +1,22 @@
+package unit.issues;
+
+import scripthost.Issue12374;
+
+class Issue12374 extends Test {
+	#if cppia
+	public function test() {
+		var child:ScriptChild = new ScriptChild();
+		eq('HostParent.toString()', Std.string(child));
+		eq('ScriptChild.methodA()', child.methodA());
+		eq('HostParent.methodB()', child.methodB());
+	}
+	#end
+}
+
+#if cppia
+private class ScriptChild extends HostParent12374 {
+	override function methodA() {
+		return 'ScriptChild.methodA()';
+	}
+}
+#end