Skip to content

Commit

Permalink
[typer] better error messages when importing nonexistent subtypes / f…
Browse files Browse the repository at this point in the history
…ields (#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 659de5c.
  • Loading branch information
kLabz authored Dec 27, 2022
1 parent 53f0757 commit eeb62ef
Show file tree
Hide file tree
Showing 22 changed files with 72 additions and 9 deletions.
41 changes: 35 additions & 6 deletions src/context/display/importHandling.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/AbstractFields.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
abstract AbstractFields(Dynamic) {
static function bar() {}
}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/ClassFields.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ClassFields {
static function bar() {}
}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/EnumFields.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
enum EnumFields {
bar;
}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/ImportAbstractField.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AbstractFields.baz;

function main() {}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/ImportClassField.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ClassFields.baz;

function main() {}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/ImportEnumField.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import EnumFields.baz;

function main() {}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue10897/ImportModuleField.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ModuleFields.baz;

function main() {}
File renamed without changes.
1 change: 1 addition & 0 deletions tests/misc/projects/Issue10897/ModuleFields.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
function bar() {}
2 changes: 0 additions & 2 deletions tests/misc/projects/Issue10897/compile-fail.hxml

This file was deleted.

1 change: 0 additions & 1 deletion tests/misc/projects/Issue10897/compile-fail.hxml.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main ImportAbstractField
--interp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportAbstractField.hx:1: characters 1-27 : Abstract<AbstractFields> has no field baz (Suggestion: bar)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue10897/import-class-field-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main ImportClassField
--interp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportClassField.hx:1: characters 1-24 : Class<ClassFields> has no field baz (Suggestion: bar)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue10897/import-enum-field-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main ImportEnumField
--interp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportEnumField.hx:1: characters 1-23 : Enum<EnumFields> has no field baz (Suggestion: bar)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue10897/import-module-field-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main ImportModuleField
--interp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportModuleField.hx:1: characters 1-25 : Module ModuleFields does not define field baz (Suggestion: bar)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue10897/import-subtype-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main ImportSubtype
--interp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportSubtype.hx:1: characters 1-18 : Module Types does not define type Baz (Suggestion: Bar)

0 comments on commit eeb62ef

Please sign in to comment.