From 34ed065b7ceb191811c675c9cfb1125687261a07 Mon Sep 17 00:00:00 2001 From: Marten/Qqwy Date: Wed, 13 Oct 2021 22:00:01 +0200 Subject: [PATCH 1/4] Adding a test case which highlights the problem. --- lib/type_check/internals/pre_expander.ex | 4 ++++ lib/type_check/macros.ex | 12 ++++++++++++ test/type_check/macros_test.exs | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/lib/type_check/internals/pre_expander.ex b/lib/type_check/internals/pre_expander.ex index f4f4826a..cbd4d335 100644 --- a/lib/type_check/internals/pre_expander.ex +++ b/lib/type_check/internals/pre_expander.ex @@ -10,6 +10,10 @@ defmodule TypeCheck.Internals.PreExpander do |> Macro.expand(env) |> TypeCheck.Internals.Overrides.rewrite_if_override(options.overrides, env) |> case do + {:__MODULE__, _meta, Elixir} -> + # Necessary to ensure that inside the 'TypeCheck.Internals.UserTypes' module + # we expand this still to the original module. + env.module ast = {:lazy_explicit, meta, args} -> if {:lazy_explicit, 3} in builtin_imports do ast diff --git a/lib/type_check/macros.ex b/lib/type_check/macros.ex index 88ed0f55..ddcb74c3 100644 --- a/lib/type_check/macros.ex +++ b/lib/type_check/macros.ex @@ -526,6 +526,18 @@ defmodule TypeCheck.Macros do end end + def define_type(other, kind, caller) do + raise TypeCheck.CompileError, """ + Compilation error encountered while attempting to create a `#{to_string(kind)}` + in `#{to_string(caller.module)}`. + + Cannot parse syntax: + #{Macro.to_string(other)} + + Maybe you forgot to give the type a name? + """ + end + defp append_typedoc(caller, extra_doc) do {_line, old_doc} = Module.get_attribute(caller.module, :typedoc) || {0, ""} newdoc = old_doc <> extra_doc diff --git a/test/type_check/macros_test.exs b/test/type_check/macros_test.exs index df240439..da7f7199 100644 --- a/test/type_check/macros_test.exs +++ b/test/type_check/macros_test.exs @@ -155,4 +155,23 @@ defmodule TypeCheck.MacrosTest do end end) end + + test "__MODULE__ is expanded correctly" do + defmodule ModuleExpansion do + use TypeCheck + + @type! t :: %__MODULE__{name: String.t()} + defstruct [:name] + + @spec! build(String.t()) :: t() + def build(name) do + %__MODULE__{name: name} + end + end + + assert ModuleExpansion.build("hello") == %{__struct__: ModuleExpansion, name: "hello"} + assert_raise TypeCheck.TypeError, fn -> + ModuleExpansion.build(:not_a_string) + end + end end From 364b241e1b4778b379e4be767b675939c6e106f7 Mon Sep 17 00:00:00 2001 From: Marten/Qqwy Date: Wed, 13 Oct 2021 22:03:25 +0200 Subject: [PATCH 2/4] Ensure the struct module name is always expanded correctly --- lib/type_check/internals/pre_expander.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/type_check/internals/pre_expander.ex b/lib/type_check/internals/pre_expander.ex index cbd4d335..b238ca6d 100644 --- a/lib/type_check/internals/pre_expander.ex +++ b/lib/type_check/internals/pre_expander.ex @@ -243,7 +243,7 @@ defmodule TypeCheck.Internals.PreExpander do # TODO wrap in struct-checker quote generated: true, location: :keep do TypeCheck.Builtin.fixed_map( - [__struct__: TypeCheck.Builtin.literal(unquote(struct_name))] ++ unquote(field_types) + [__struct__: unquote(rewrite(struct_name, env, options))] ++ unquote(field_types) ) end end From e08ec1cfe62583d236ede256e2879f1805eed29b Mon Sep 17 00:00:00 2001 From: Marten/Qqwy Date: Wed, 13 Oct 2021 22:04:06 +0200 Subject: [PATCH 3/4] remove superfluous code already caught by Macro.expand(code, env) --- lib/type_check/internals/pre_expander.ex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/type_check/internals/pre_expander.ex b/lib/type_check/internals/pre_expander.ex index b238ca6d..d44e2e5f 100644 --- a/lib/type_check/internals/pre_expander.ex +++ b/lib/type_check/internals/pre_expander.ex @@ -10,10 +10,6 @@ defmodule TypeCheck.Internals.PreExpander do |> Macro.expand(env) |> TypeCheck.Internals.Overrides.rewrite_if_override(options.overrides, env) |> case do - {:__MODULE__, _meta, Elixir} -> - # Necessary to ensure that inside the 'TypeCheck.Internals.UserTypes' module - # we expand this still to the original module. - env.module ast = {:lazy_explicit, meta, args} -> if {:lazy_explicit, 3} in builtin_imports do ast From fab9e9f93ea3f68833ac5aebdfac3414909d3764 Mon Sep 17 00:00:00 2001 From: Marten/Qqwy Date: Wed, 13 Oct 2021 22:06:06 +0200 Subject: [PATCH 4/4] update changelog --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4dbd0d50..facf2831 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,10 @@ Details: ### Changelog - master - + - Fixes: + - Wrapping private functions no longer make the function public. (c.f. #64) + - Wrapping macros now works correctly. (also related to #64) + - Using `__MODULE__` inside a struct inside a type now expands correctly. (c.f. #66) - 0.9.0 - - Support for bitstring type syntax: `<<>>`, `<<_ :: size>>`, `<<_ :: _ * unit>>`, `<<_ :: size, _ :: _ * unit>>` (both as types and as generators) - 0.8.2 -