Forráskód Böngészése

[typer] better error messages when importing nonexistent subtypes / fields (#10899)

* [tests] add more examples for #10897

* [typer] fail better when importing nonexistent field

* [typer] use more explicit variable name

* [typer] remove unneeded parens

* [ci] try cancel

* [tests] add failing tests

* [ci] update position in expected result

* [tests] Disable expression level tests for #10897

This reverts commit 659de5cb0d1fe292cbb109e69dfe17a29dfbe071.
Rudy Ges 2 éve
szülő
commit
eeb62ef43e

+ 35 - 6
src/context/display/importHandling.ml

@@ -86,15 +86,25 @@ let init_import ctx context_init path mode p =
 		let error_private p = typing_error "Importing private declarations from a module is not allowed" p in
 		let chk_private t p = if ctx.m.curmod != (t_infos t).mt_module && (t_infos t).mt_private then error_private p in
 		let has_name name t = snd (t_infos t).mt_path = name in
-		let fail_usefully name =
-			typing_error (StringError.string_error name (List.map (fun mt -> snd (t_infos mt).mt_path) types) ("Module " ^ s_type_path md.m_path ^ " does not define type " ^ name)) p_type
+
+		let fail_usefully name p =
+			let target_kind,candidates = match String.get name 0 with
+				(* TODO: cleaner way to get module fields? *)
+				| 'a'..'z' -> "field", PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
+				| _ -> "type", List.map (fun mt -> snd (t_infos mt).mt_path) types
+			in
+			typing_error (StringError.string_error name
+				candidates
+				("Module " ^ s_type_path md.m_path ^ " does not define " ^ target_kind ^ " " ^ name)
+			) p
 		in
+
 		let find_type tname = List.find (has_name tname) types in
 		let get_type tname =
 			let t = try
 				find_type tname
 			with Not_found ->
-				fail_usefully tname
+				fail_usefully tname p_type
 			in
 			chk_private t p_type;
 			t
@@ -160,11 +170,30 @@ let init_import ctx context_init path mode p =
 							begin try
 								add_static_init tmain name tsub
 							with Not_found ->
-								(* TODO: mention module-level declarations in the error message? *)
-								display_error ctx.com (s_type_path (t_infos tmain).mt_path ^ " has no field or subtype " ^ tsub) p
+								let parent,target_kind,candidates = match resolve_typedef tmain with
+									| TClassDecl c ->
+										"Class<" ^ (s_type_path c.cl_path) ^ ">",
+										"field",
+										PMap.foldi (fun name _ acc -> name :: acc) c.cl_statics []
+									| TAbstractDecl {a_impl = Some c} ->
+										"Abstract<" ^ (s_type_path md.m_path) ^ ">",
+										"field",
+										PMap.foldi (fun name _ acc -> name :: acc) c.cl_statics []
+									| TEnumDecl e ->
+										"Enum<" ^ s_type_path md.m_path ^ ">",
+										"field",
+										PMap.foldi (fun name _ acc -> name :: acc) e.e_constrs []
+									| _ ->
+										"Module " ^ s_type_path md.m_path,
+										"field or subtype",
+										(* TODO: cleaner way to get module fields? *)
+										PMap.foldi (fun n _ acc -> n :: acc) (try (Option.get md.m_statics).cl_statics with | _ -> PMap.empty) []
+								in
+
+								display_error ctx.com (StringError.string_error tsub candidates (parent ^ " has no " ^ target_kind ^ " " ^ tsub)) p
 							end
 						with Not_found ->
-							fail_usefully tsub
+							fail_usefully tsub p
 					in
 					context_init#add (fun() ->
 						match md.m_statics with

+ 3 - 0
tests/misc/projects/Issue10897/AbstractFields.hx

@@ -0,0 +1,3 @@
+abstract AbstractFields(Dynamic) {
+	static function bar() {}
+}

+ 3 - 0
tests/misc/projects/Issue10897/ClassFields.hx

@@ -0,0 +1,3 @@
+class ClassFields {
+	static function bar() {}
+}

+ 3 - 0
tests/misc/projects/Issue10897/EnumFields.hx

@@ -0,0 +1,3 @@
+enum EnumFields {
+	bar;
+}

+ 3 - 0
tests/misc/projects/Issue10897/ImportAbstractField.hx

@@ -0,0 +1,3 @@
+import AbstractFields.baz;
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue10897/ImportClassField.hx

@@ -0,0 +1,3 @@
+import ClassFields.baz;
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue10897/ImportEnumField.hx

@@ -0,0 +1,3 @@
+import EnumFields.baz;
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue10897/ImportModuleField.hx

@@ -0,0 +1,3 @@
+import ModuleFields.baz;
+
+function main() {}

+ 0 - 0
tests/misc/projects/Issue10897/Main.hx → tests/misc/projects/Issue10897/ImportSubtype.hx


+ 1 - 0
tests/misc/projects/Issue10897/ModuleFields.hx

@@ -0,0 +1 @@
+function bar() {}

+ 0 - 2
tests/misc/projects/Issue10897/compile-fail.hxml

@@ -1,2 +0,0 @@
---main Main
---interp

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

@@ -1 +0,0 @@
-Main.hx:1: characters 8-13 : Module Types does not define type Baz (Suggestion: Bar)

+ 2 - 0
tests/misc/projects/Issue10897/import-abstract-field-fail.hxml

@@ -0,0 +1,2 @@
+--main ImportAbstractField
+--interp

+ 1 - 0
tests/misc/projects/Issue10897/import-abstract-field-fail.hxml.stderr

@@ -0,0 +1 @@
+ImportAbstractField.hx:1: characters 1-27 : Abstract<AbstractFields> has no field baz (Suggestion: bar)

+ 2 - 0
tests/misc/projects/Issue10897/import-class-field-fail.hxml

@@ -0,0 +1,2 @@
+--main ImportClassField
+--interp

+ 1 - 0
tests/misc/projects/Issue10897/import-class-field-fail.hxml.stderr

@@ -0,0 +1 @@
+ImportClassField.hx:1: characters 1-24 : Class<ClassFields> has no field baz (Suggestion: bar)

+ 2 - 0
tests/misc/projects/Issue10897/import-enum-field-fail.hxml

@@ -0,0 +1,2 @@
+--main ImportEnumField
+--interp

+ 1 - 0
tests/misc/projects/Issue10897/import-enum-field-fail.hxml.stderr

@@ -0,0 +1 @@
+ImportEnumField.hx:1: characters 1-23 : Enum<EnumFields> has no field baz (Suggestion: bar)

+ 2 - 0
tests/misc/projects/Issue10897/import-module-field-fail.hxml

@@ -0,0 +1,2 @@
+--main ImportModuleField
+--interp

+ 1 - 0
tests/misc/projects/Issue10897/import-module-field-fail.hxml.stderr

@@ -0,0 +1 @@
+ImportModuleField.hx:1: characters 1-25 : Module ModuleFields does not define field baz (Suggestion: bar)

+ 2 - 0
tests/misc/projects/Issue10897/import-subtype-fail.hxml

@@ -0,0 +1,2 @@
+--main ImportSubtype
+--interp

+ 1 - 0
tests/misc/projects/Issue10897/import-subtype-fail.hxml.stderr

@@ -0,0 +1 @@
+ImportSubtype.hx:1: characters 1-18 : Module Types does not define type Baz (Suggestion: Bar)