From 8474fa6180de0d5dfcde7424518d84b0bf5d3685 Mon Sep 17 00:00:00 2001 From: Yoshihiro Imai Date: Tue, 29 Jan 2019 14:58:02 +0900 Subject: [PATCH 1/2] [issue-168] auto import --- lib/bif.ml | 2 ++ lib/context.ml | 17 ++++++++++++----- lib/context.mli | 2 +- lib/type_check.ml | 5 +++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/bif.ml b/lib/bif.ml index aca61a67..d517e62e 100644 --- a/lib/bif.ml +++ b/lib/bif.ml @@ -36,4 +36,6 @@ let type_sigs = [ Type.(of_elem (TyFun ([Type.bool; Type.bool], Type.bool)))); ({module_name="erlang"; function_name="not"; arity=1}, Type.(of_elem (TyFun ([Type.bool], Type.bool)))); + ({module_name="erlang"; function_name="abs"; arity=1}, + Type.(of_elem (TyFun ([of_elem TyNumber], of_elem TyNumber)))); ] diff --git a/lib/context.ml b/lib/context.ml index cf86ee48..cd8478a0 100644 --- a/lib/context.ml +++ b/lib/context.ml @@ -1,4 +1,5 @@ open Base +open Polymorphic_compare module Format = Caml.Format module Key = struct @@ -20,11 +21,17 @@ let add key data t = Log.debug [%here] "variable '%s' shadowed" (Key.show key); t -let add_bif_signatures ctx0 : t = +let add_bif_signatures imports ctx0 : t = + let update ctx (mfa, ty) = + if List.mem imports mfa.Mfa.module_name ~equal:(=) then + add (Key.MFA mfa) ty ctx + |> add (Key.LocalFun {function_name=mfa.Mfa.function_name; arity=mfa.Mfa.arity}) ty + else + add (Key.MFA mfa) ty ctx + in Bif.type_sigs - |> List.fold_left ~f:(fun ctx (mfa, ty) -> - add (Key.MFA mfa) ty ctx) ~init:ctx0 + |> List.fold_left ~f:update ~init:ctx0 -let init () = +let create ~import_modules = empty - |> add_bif_signatures + |> add_bif_signatures import_modules diff --git a/lib/context.mli b/lib/context.mli index 086f8fd7..79c67b7b 100644 --- a/lib/context.mli +++ b/lib/context.mli @@ -11,4 +11,4 @@ type t val empty : t val find : t -> Key.t -> Type.t option val add : Key.t -> Type.t -> t -> t -val init : unit -> t +val create : import_modules : string list -> t diff --git a/lib/type_check.ml b/lib/type_check.ml index ab9668f0..3da6f13a 100644 --- a/lib/type_check.ml +++ b/lib/type_check.ml @@ -5,14 +5,15 @@ let check_module plt ctx m = let open Result in Log.debug [%here] "Checking module: %s" (m.Ast.name); From_erlang.module_to_expr m >>= fun expr -> - Derivation.derive (Context.init ()) expr >>= fun (ty, c) -> + Derivation.derive ctx expr >>= fun (ty, c) -> Log.debug [%here] "Constraints:\n%s" (Type.show_constraint c); Solver.solve Solver.init c >>= fun sol -> Log.debug [%here] "Types:\n%s" (Solver.lookup_type sol ty |> Type.pp); Ok () let check_modules plt modules = - let ctx = Context.init () in (*TODO: make type context from specs of the modules *) + let import_modules = ["erlang"] in (*TODO: https://github.com/dwango/fialyzer/issues/166 *) + let ctx = Context.create ~import_modules in (*TODO: https://github.com/dwango/fialyzer/issues/167 *) let open Result in result_map_m ~f:(check_module plt ctx) modules >>= fun _ -> Result.return () From 59fda9ec1cca2a9766e4d524509b8de53a564a7a Mon Sep 17 00:00:00 2001 From: Yoshihiro Imai Date: Tue, 29 Jan 2019 14:58:43 +0900 Subject: [PATCH 2/2] [issue-168] introduce a test using auto imported function --- test/blackbox-test/test-cases/auto_import.erl | 7 +++++++ test/blackbox-test/test-cases/auto_import.expected | 1 + 2 files changed, 8 insertions(+) create mode 100644 test/blackbox-test/test-cases/auto_import.erl create mode 100644 test/blackbox-test/test-cases/auto_import.expected diff --git a/test/blackbox-test/test-cases/auto_import.erl b/test/blackbox-test/test-cases/auto_import.erl new file mode 100644 index 00000000..74f30daa --- /dev/null +++ b/test/blackbox-test/test-cases/auto_import.erl @@ -0,0 +1,7 @@ +-module(auto_import). + +-export([foo/1]). + +-spec foo(number()) -> number(). +foo(X) -> + abs(X). diff --git a/test/blackbox-test/test-cases/auto_import.expected b/test/blackbox-test/test-cases/auto_import.expected new file mode 100644 index 00000000..d7831928 --- /dev/null +++ b/test/blackbox-test/test-cases/auto_import.expected @@ -0,0 +1 @@ +done (passed successfully)