Browse Source

[cs] enable auto-overload for opt args only on @:nativeGen classes; fix auto-overloading constructors (#4623)

Aleksandr Kuzmenko 6 years ago
parent
commit
4db3f1c71e
2 changed files with 44 additions and 7 deletions
  1. 22 7
      src/generators/gencs.ml
  2. 22 0
      tests/misc/cs/projects/Issue4623/Main.hx

+ 22 - 7
src/generators/gencs.ml

@@ -158,18 +158,24 @@ let get_overloads_for_optional_args gen cl cf is_static =
 	| [],Method (MethNormal | MethDynamic | MethInline) ->
 	| [],Method (MethNormal | MethDynamic | MethInline) ->
 		(match cf.cf_expr, follow cf.cf_type with
 		(match cf.cf_expr, follow cf.cf_type with
 		| Some ({ eexpr = TFunction fn } as method_expr), TFun (args, return_type) ->
 		| Some ({ eexpr = TFunction fn } as method_expr), TFun (args, return_type) ->
+			let type_params = List.map snd cl.cl_params in
 			let rec collect_overloads tf_args_rev args_rev default_values_rev =
 			let rec collect_overloads tf_args_rev args_rev default_values_rev =
 				match tf_args_rev, args_rev with
 				match tf_args_rev, args_rev with
 				| (_, Some default_value) :: rest_tf_args_rev, _ :: rest_args_rev ->
 				| (_, Some default_value) :: rest_tf_args_rev, _ :: rest_args_rev ->
 					let field_expr =
 					let field_expr =
-						if is_static then
-							make_static_field cl cf cf.cf_pos
-						else begin
+						let cl_type = TInst (cl,type_params) in
+						if cf.cf_name = "new" then
+							mk (TConst TThis) cl_type cf.cf_pos
+						else if is_static then
+							let class_expr =
+								mk (TTypeExpr (TClassDecl cl)) cl_type cf.cf_pos
+							in
+							mk (TField (class_expr, FStatic(cl,cf))) cf.cf_type cf.cf_pos
+						else
 							let this_expr =
 							let this_expr =
-								mk (TConst TThis) (type_of_module_type (TClassDecl cl)) cf.cf_pos
+								mk (TConst TThis) cl_type cf.cf_pos
 							in
 							in
-							mk_field_access gen this_expr cf.cf_name cf.cf_pos
-						end
+							mk (TField (this_expr, FInstance(cl,type_params,cf))) cf.cf_type cf.cf_pos
 					in
 					in
 					let default_values_rev = default_values_rev @ [default_value] in
 					let default_values_rev = default_values_rev @ [default_value] in
 					let args_exprs =
 					let args_exprs =
@@ -2206,7 +2212,8 @@ let generate con =
 					let overloads =
 					let overloads =
 						match cf.cf_overloads with
 						match cf.cf_overloads with
 						| [] when is_overload -> []
 						| [] when is_overload -> []
-						| [] -> get_overloads_for_optional_args gen cl cf is_static
+						| [] when has_meta Meta.NativeGen cl.cl_meta ->
+							get_overloads_for_optional_args gen cl cf is_static
 						| overloads -> overloads
 						| overloads -> overloads
 					in
 					in
 					List.iter (fun cf ->
 					List.iter (fun cf ->
@@ -2293,6 +2300,14 @@ let generate con =
 													None, el
 													None, el
 										in
 										in
 										match expr.eexpr with
 										match expr.eexpr with
+											(* auto-generated ctor overloading for optional args (see get_overloads_for_optional_args) *)
+											| TBlock([{ eexpr = TCall ({ eexpr = TConst TThis }, args) } as this_call]) ->
+												write w ": ";
+												let t = Timer.timer ["expression to string"] in
+												expr_s false w this_call;
+												write w " ";
+												t();
+												write w "{}"
 											| TBlock(bl) ->
 											| TBlock(bl) ->
 												let super_call, rest = get_super_call bl in
 												let super_call, rest = get_super_call bl in
 												(match super_call with
 												(match super_call with

+ 22 - 0
tests/misc/cs/projects/Issue4623/Main.hx

@@ -1,3 +1,4 @@
+@:nativeGen
 class Main {
 class Main {
 	static var voidResult:String;
 	static var voidResult:String;
 
 
@@ -33,5 +34,26 @@ class Main {
 		if(expected != result) {
 		if(expected != result) {
 			throw 'Invalid result of test(4). Expected: $expected. Got: $result';
 			throw 'Invalid result of test(4). Expected: $expected. Got: $result';
 		}
 		}
+
+		var n:CtorTest = untyped __cs__('new global::CtorTest(20);') ;
+		if(n.a != 20 || n.b != 'hello') {
+			throw 'Invalid result of new CtorTest(20)';
+		}
+
+		var n:CtorTest = untyped __cs__('new global::CtorTest();') ;
+		if(n.a != 10 || n.b != 'hello') {
+			throw 'Invalid result of new CtorTest()';
+		}
+	}
+}
+
+@:nativeGen
+class CtorTest {
+	public var a:Int;
+	public var b:String;
+
+	public function new(a:Int = 10, b:String = 'hello') {
+		this.a = a;
+		this.b = b;
 	}
 	}
 }
 }