Browse Source

infer `Null` from `?` in `@:overload` signatures (fixes #7754)

Aleksandr Kuzmenko 5 năm trước cách đây
mục cha
commit
2d47649f29

+ 9 - 1
src/typing/typeload.ml

@@ -633,7 +633,15 @@ and init_meta_overloads ctx co cf =
 			let params = (!type_function_params_rec) ctx f cf.cf_name p in
 			ctx.type_params <- params @ ctx.type_params;
 			let topt = function None -> error "Explicit type required" p | Some t -> load_complex_type ctx true t in
-			let args = List.map (fun ((a,_),opt,_,t,cto) -> a,opt || cto <> None,topt t) f.f_args in
+			let args =
+				List.map
+					(fun ((a,_),opt,_,t,cto) ->
+						let t = if opt then ctx.t.tnull (topt t) else topt t in
+						let opt = opt || cto <> None in
+						a,opt,t
+					)
+					f.f_args
+			in
 			let cf = { cf with cf_type = TFun (args,topt f.f_type); cf_params = params; cf_meta = cf_meta} in
 			generate_args_meta ctx.com co (fun meta -> cf.cf_meta <- meta :: cf.cf_meta) f.f_args;
 			overloads := cf :: !overloads;

+ 1 - 1
tests/misc/projects/Issue4803/compile-fail.hxml.stderr

@@ -4,7 +4,7 @@ Main.hx:16: lines 16-19 : Too many arguments
 Main.hx:16: lines 16-19 : Overload resolution failed for (handler : (Event -> Void)) -> JQuery
 Main.hx:18: characters 8-17 : Object requires field y
 Main.hx:18: characters 8-17 : For function argument 'handler'
-Main.hx:16: lines 16-19 : Overload resolution failed for (?eventData : Dynamic, handler : (Event -> Void)) -> JQuery
+Main.hx:16: lines 16-19 : Overload resolution failed for (?eventData : Null<Dynamic>, handler : (Event -> Void)) -> JQuery
 Main.hx:18: characters 8-17 : Object requires field y
 Main.hx:18: characters 8-17 : For optional function argument 'eventData'
 Main.hx:16: lines 16-19 : End of overload failure reasons

+ 26 - 0
tests/server/src/DisplayTests.hx

@@ -442,4 +442,30 @@ typedef Foo = {
 		var result = parseHover();
 		Assert.equals("A", result.result.item.type.args.path.typeName /* lol */);
 	}
+
+	function testIssue7754() {
+		var content = '
+			class Main {
+				static function main() {
+					Foo.foo({-1-});
+				}
+			}
+			extern class Foo {
+				@:overload(function(?s:String):Void {})
+				static function foo(?i:Int):Void;
+			}
+		';
+		var transform = Marker.extractMarkers(content);
+		vfs.putContent("Main.hx", transform.source);
+		runHaxeJson([], DisplayMethods.SignatureHelp, {
+			file: new FsPath("Main.hx"),
+			offset: transform.markers[1],
+			wasAutoTriggered: true
+		});
+		var result = parseSignatureHelp();
+		var sigs = result.result.signatures;
+		Assert.equals(2, sigs.length);
+		Assert.equals('Null<String>', strType(sigs[0].args[0].t));
+		Assert.equals('Null<Int>', strType(sigs[1].args[0].t));
+	}
 }

+ 12 - 0
tests/server/src/HaxeServerTestCase.hx

@@ -190,4 +190,16 @@ class HaxeServerTestCase implements ITest {
 		}
 		Assert.pass();
 	}
+
+	function strType(t:JsonType<JsonTypePathWithParams>):String {
+		var path = t.args.path;
+		var params = t.args.params;
+		var parts = path.pack.concat([path.typeName]);
+		var s = parts.join('.');
+		if(params.length == 0) {
+			return s;
+		}
+		var sParams = params.map(strType).join('.');
+		return '$s<$sParams>';
+	}
 }