Browse Source

start working on Void unit type

Dan Korostelev 4 years ago
parent
commit
af44917c7c

+ 2 - 0
src/generators/genjs.ml

@@ -1797,6 +1797,8 @@ let alloc_ctx com es_version =
 				dot_path p
 			else
 				s_path ctx p
+		| TAbstractDecl { a_path = [],"Void" } ->
+			"undefined"
 		| _ ->
 			s_path ctx (t_path t)
 	);

+ 2 - 0
src/macro/eval/evalJit.ml

@@ -219,6 +219,8 @@ and jit_expr jit return e =
 		let execs = List.map (jit_expr jit false) el in
 		let execs = Array.of_list execs in
 		emit_array_declaration execs
+	| TTypeExpr (TAbstractDecl { a_path = [],"Void" }) ->
+		emit_const vnull
 	| TTypeExpr mt ->
 		let key = path_hash (t_infos mt).mt_path in
 		let proto = get_static_prototype_as_value jit.ctx key e.epos in

+ 0 - 5
src/optimization/analyzerTexprTransformer.ml

@@ -88,9 +88,6 @@ let rec func ctx bb tf t p =
 		end;
 		if is_unbound_call_that_might_have_side_effects s el then ctx.has_unbound <- true;
 	in
-	let no_void t p =
-		if ExtType.is_void (follow t) then Error.error "Cannot use Void as value" p
-	in
 	let push_name s =
 		ctx.name_stack <- s :: ctx.name_stack;
 		(fun () -> ctx.name_stack <- List.tl ctx.name_stack)
@@ -182,7 +179,6 @@ let rec func ctx bb tf t p =
 			Error.error "Cannot use this expression as value" e.epos
 	and value bb e =
 		let bb,e = value' bb e in
-		no_void e.etype e.epos;
 		bb,e
 	and ordered_value_list bb el =
 		let might_be_affected,collect_modified_locals = create_affection_checker() in
@@ -247,7 +243,6 @@ let rec func ctx bb tf t p =
 		let e = List.fold_left (fun e f -> f e) e fl in
 		bb,e
 	and declare_var_and_assign bb v e p =
-		no_void v.v_type p;
 		(* TODO: this section shouldn't be here because it can be handled as part of the normal value processing *)
 		let rec loop bb e = match e.eexpr with
 			| TParenthesis e1 ->

+ 0 - 8
src/typing/typer.ml

@@ -625,14 +625,6 @@ and type_vars ctx vl p =
 				check_error ctx e p;
 				add_local ctx VGenerated n t_dynamic pv, None (* TODO: What to do with this... *)
 	) vl in
-	delay ctx PTypeField (fun() ->
-		List.iter
-			(fun (v,_) ->
-				if ExtType.is_void (follow v.v_type) then
-					error "Variables of type Void are not allowed" v.v_pos
-			)
-			vl
-	);
 	match vl with
 	| [v,eo] ->
 		mk (TVar (v,eo)) ctx.t.tvoid p

+ 2 - 0
src/typing/typerBase.ml

@@ -102,6 +102,8 @@ let rec type_module_type ctx t tparams p =
 			error (s_type_path s.t_path ^ " is not a value") p)
 	| TAbstractDecl { a_impl = Some c } ->
 		type_module_type ctx (TClassDecl c) tparams p
+	| TAbstractDecl { a_path = [],"Void" } ->
+		mk (TTypeExpr t) ctx.com.basic.tvoid p
 	| TAbstractDecl a ->
 		if not (Meta.has Meta.RuntimeValue a.a_meta) then error (s_type_path a.a_path ^ " is not a value") p;
 		let t_tmp = abstract_module_type a [] in

+ 0 - 3
std/StdTypes.hx

@@ -26,9 +26,6 @@
 
 	@see https://haxe.org/manual/types-void.html
 **/
-#if jvm
-@:runtimeValue
-#end
 @:coreType abstract Void {}
 
 /**

+ 1 - 0
tests/unit/src/unit/TestMain.hx

@@ -75,6 +75,7 @@ function main() {
 		new TestNumericCasts(),
 		new TestHashMap(),
 		new TestRest(),
+		new TestVoid(),
 		#if (!no_http && (!github || !(php && Windows)))
 		new TestHttp(),
 		#end

+ 70 - 0
tests/unit/src/unit/TestVoid.hx

@@ -0,0 +1,70 @@
+package unit;
+
+class TestVoid extends Test {
+	function testVoidLiteral() {
+		var v = Void;
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testVoidReturn() {
+		var v = voidReturn();
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testExplicitVoidReturn() {
+		var v = explicitVoidReturn();
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testVoidArg() {
+		var v = voidArg(Void);
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testGeneric() {
+		var v = generic(Void);
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testGenericCallback() {
+		var v = genericCallback(voidReturn);
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+
+	function testGenericClass() {
+		var v = new Signal<Void>().trigger(Void);
+		HelperMacros.typedAs(v, (null : Void));
+		eq(Void, v);
+	}
+}
+
+private function voidReturn() {}
+
+private function explicitVoidReturn() {
+	return Void;
+}
+
+private function generic<T>(v:T):T {
+	return v;
+}
+
+private function genericCallback<T>(f:()->T):T {
+	return f();
+}
+
+private function voidArg(arg:Void):Void {
+	return arg;
+}
+
+private class Signal<T> {
+	public function new() {}
+	public function trigger(payload:T):T {
+		return payload;
+	}
+}