Browse Source

Specified and tested optional not nullable arguments (close #3826)

Nicolas Cannasse 6 years ago
parent
commit
0ceb3480b6

+ 0 - 1
src/context/common.ml

@@ -325,7 +325,6 @@ let get_config com =
 			default_config with
 			pf_capture_policy = CPWrapRef;
 			pf_pad_nulls = true;
-			pf_can_skip_non_nullable_argument = false;
 		}
 	| Eval ->
 		{

+ 12 - 0
src/generators/genhl.ml

@@ -1186,6 +1186,18 @@ and cast_to ?(force=false) ctx (r:reg) (t:ttype) p =
 		let out = alloc_tmp ctx t in
 		op ctx (OSafeCast (out, r));
 		out
+	| HNull _, HRef t2 ->
+		let out = alloc_tmp ctx t in
+		op ctx (OJNotNull (r,2));
+		op ctx (ONull out);
+		let j = jump ctx (fun n -> OJAlways n) in
+		let r = cast_to ctx r t2 p in
+		let r2 = alloc_tmp ctx t2 in
+		op ctx (OMov (r2, r));
+		hold ctx r2; (* retain *)
+		op ctx (ORef (out,r2));
+		j();
+		out
 	| _, HRef t2 ->
 		let r = cast_to ctx r t2 p in
 		let r2 = alloc_tmp ctx t2 in

+ 1 - 1
tests/unit/src/unit/TestType.hx

@@ -261,7 +261,7 @@ class TestType extends Test {
  		eq("foo0", f());
 
 		var foo = function(bar = 2) { return bar; };
-		#if (flash || hl) // Cannot skip not-nullable argument
+		#if flash // Cannot skip not-nullable argument
 		t(typeError(foo.bind(_)));
 		#else
 		var l = foo.bind(_);

+ 71 - 0
tests/unit/src/unit/issues/Issue3826.hx

@@ -0,0 +1,71 @@
+package unit.issues;
+
+class Issue3826 extends Test {
+
+	var inull : Null<Int> = null;
+	var fnull : Null<Float> = null;
+	var dnull : Dynamic = null;
+	var ival : Null<Int> = 5;
+	var fval : Null<Float> = 8.5;
+	var dval : Dynamic = 6;
+
+	function get( a = 2, b = 4.25 ) {
+		return ""+a+"/"+b;
+	}
+
+	public function test() {
+		eq( get(), "2/4.25" );
+		eq( get(5), "5/4.25" );
+		eq( get(5,8.5), "5/8.5" );
+
+		#if !flash
+		// flash does have two problems wrt these tests
+		// - not skippable nullable arg
+		// - explicit null args are cast to 0
+		eq( get(8.5), "2/8.5" );
+
+		eq( get(inull), "2/4.25" );
+		eq( get(inull,fnull), "2/4.25" );		
+		eq( get(inull,inull), "2/4.25" );		
+		eq( get(fnull), "2/4.25" );
+		eq( get(dnull,dnull), "2/4.25" );
+		eq( get(ival,fval), "5/8.5" );
+		eq( get(dval,dval), "6/6" );
+		
+		#end
+	}
+
+	public function testReflect() {
+		#if (java || cs || lua)
+		return; // TODO
+		#end
+			
+		#if !flash
+		eq( Reflect.callMethod(this, get, []), "2/4.25" );
+		eq( Reflect.callMethod(this, get, [5]), "5/4.25" );
+		eq( Reflect.callMethod(this, get, [5,8.5]), "5/8.5" );
+		eq( Reflect.callMethod(this, get, [null,8.5]), "2/8.5" );
+
+		eq( Reflect.callMethod(this, get, [null]), "2/4.25" );
+		eq( Reflect.callMethod(this, get, [null,null]), "2/4.25" );		
+		eq( Reflect.callMethod(this, get, [ival,fval]), "5/8.5" );		
+		eq( Reflect.callMethod(this, get, [dval,dval]), "6/6" );		
+		#end
+	}
+
+	function getOpt( ?a = 2, ?b = 4.25 ) {
+		return ""+a+"/"+b;
+	}
+
+	public function testOpt() {
+		eq( getOpt(), "2/4.25" );
+		eq( getOpt(5), "5/4.25" );
+		eq( getOpt(5,8.5), "5/8.5" );
+		eq( getOpt(8.5), "2/8.5" );
+
+		eq( getOpt(inull), "2/4.25");
+		eq( getOpt(inull,fnull), "2/4.25");
+		eq( getOpt(fnull), "2/4.25");
+	}
+
+}