Skip to content

Commit

Permalink
improvement: upgrade igniter to 0.4
Browse files Browse the repository at this point in the history
fix: smarter type detection, preferring more concrete types
  • Loading branch information
zachdaniel committed Nov 1, 2024
1 parent 9cc8c33 commit 6904a78
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 36 deletions.
57 changes: 54 additions & 3 deletions lib/ash/expr/expr.ex
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ defmodule Ash.Expr do
typeset == :same ||
length(typeset) == length(values)
end)
|> Enum.find_value({Enum.map(values, fn _ -> nil end), nil}, fn {typeset, returns} ->
|> Enum.map(fn {typeset, returns} ->
basis =
cond do
!returns ->
Expand Down Expand Up @@ -1072,7 +1072,7 @@ defmodule Ash.Expr do

%{basis: nil, must_adopt_basis: [], types: types} ->
if returns not in [:same, :any, {:array, :same}, {:array, :any}] do
{Enum.reverse(types), returns}
{Enum.reverse(types), returns, 0}
end

%{basis: nil, must_adopt_basis: _} ->
Expand All @@ -1098,9 +1098,60 @@ defmodule Ash.Expr do
fn {index, function_of_basis}, types ->
List.replace_at(types, index, function_of_basis.(basis))
end
), returns}
), returns, Enum.count(basis_adopters)}
end
end)
|> Enum.filter(& &1)
|> select_matches(length(values))
end

defp select_matches([], value_count) do
{Enum.map(1..value_count, fn _ -> nil end), nil}
end

defp select_matches(results, value_count) do
case Enum.find(results, fn
{_type, _returns, 0} ->
true

_ ->
false
end) do
{type, returns, 0} ->
{type, returns}

_ ->
results =
Enum.map(results, fn {types, {type, constraints}, _} ->
types =
Enum.map(types, fn {type, constraints} ->
{Ash.Type.get_type(type), constraints}
end)

{types, {Ash.Type.get_type(type), constraints}}
end)

arg_types =
1..value_count
|> Enum.map(fn i ->
possible_types =
Enum.map(results, fn {types, _} ->
Enum.at(types, i - 1)
end)

if Enum.uniq(possible_types) == possible_types do
Enum.at(possible_types, 0)
end
end)

all_returns = Enum.map(results, &elem(&1, 1))

if Enum.uniq(all_returns) == all_returns do
{arg_types, Enum.at(all_returns, 0)}
else
{arg_types, nil}
end
end
end

def determine_type(value) do
Expand Down
25 changes: 14 additions & 11 deletions lib/mix/tasks/gen/ash.gen.base_resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ defmodule Mix.Tasks.Ash.Gen.BaseResource do
@shortdoc "Generates a base resource. This is a module that you can use instead of `Ash.Resource`, for consistency."
use Igniter.Mix.Task

@impl true
def info(_argv, _parent) do
%Igniter.Mix.Task.Info{
positional: [:resource]
}
end

@impl Igniter.Mix.Task
def igniter(igniter, [base_resource | _argv]) do
def igniter(igniter) do
base_resource = igniter.args.positional.resource
base_resource = Igniter.Project.Module.parse(base_resource)
base_resource_file = Igniter.Project.Module.proper_location(igniter, base_resource)

glob = Path.join([base_resource_file, "..", "**", "*.ex"])

app_name = Igniter.Project.Application.app_name(igniter)

Expand All @@ -25,12 +30,10 @@ defmodule Mix.Tasks.Ash.Gen.BaseResource do
# replace what it uses with the new base resource

igniter
|> Igniter.create_new_file(base_resource_file, """
defmodule #{inspect(base_resource)} do
defmacro __using__(opts) do
quote do
use Ash.Resource, unquote(opts)
end
|> Igniter.Project.Module.create_module(base_resource, """
defmacro __using__(opts) do
quote do
use Ash.Resource, unquote(opts)
end
end
""")
Expand All @@ -46,7 +49,7 @@ defmodule Mix.Tasks.Ash.Gen.BaseResource do
)
end
)
|> Igniter.update_glob(glob, fn zipper ->
|> Igniter.update_all_elixir_files(fn zipper ->
with {:ok, zipper} <- Igniter.Code.Module.move_to_module_using(zipper, Ash.Resource),
{:ok, zipper} <-
Igniter.Code.Function.move_to_function_call_in_current_scope(
Expand Down
7 changes: 3 additions & 4 deletions lib/mix/tasks/gen/ash.gen.domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ defmodule Mix.Tasks.Ash.Gen.Domain do
end

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
{%{domain: domain}, argv} = positional_args!(argv)
domain = Igniter.Project.Module.parse(domain)
def igniter(igniter) do
domain = Igniter.Project.Module.parse(igniter.args.positional.domain)

app_name = Igniter.Project.Application.app_name(igniter)
{exists?, igniter} = Igniter.Project.Module.module_exists(igniter, domain)

if "--ignore-if-exists" in argv && exists? do
if "--ignore-if-exists" in igniter.args.argv_flags && exists? do
igniter
else
igniter
Expand Down
8 changes: 4 additions & 4 deletions lib/mix/tasks/gen/ash.gen.enum.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ defmodule Mix.Tasks.Ash.Gen.Enum do
end

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
{%{module_name: module_name, types: types}, argv} = positional_args!(argv)
def igniter(igniter) do
module_name = igniter.args.positional.module_name
types = igniter.args.positional.types
opts = igniter.args.options

enum = Igniter.Project.Module.parse(module_name)
file_name = Igniter.Project.Module.proper_location(igniter, enum)

opts = options!(argv)

short_name =
if opts[:short_name] do
String.to_atom(opts[:short_name])
Expand Down
11 changes: 6 additions & 5 deletions lib/mix/tasks/gen/ash.gen.resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,13 @@ defmodule Mix.Tasks.Ash.Gen.Resource do
end

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
{%{resource: resource}, argv} = positional_args!(argv)
resource = Igniter.Project.Module.parse(resource)
app_name = Igniter.Project.Application.app_name(igniter)
def igniter(igniter) do
arguments = igniter.args.positional
options = igniter.args.options
argv = igniter.args.argv_flags

options = options!(argv)
resource = Igniter.Project.Module.parse(arguments.resource)
app_name = Igniter.Project.Application.app_name(igniter)

domain =
case options[:domain] do
Expand Down
6 changes: 3 additions & 3 deletions lib/mix/tasks/install/ash.install.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ defmodule Mix.Tasks.Ash.Install do
end

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
def igniter(igniter) do
igniter
|> Igniter.compose_task("spark.install")
|> Igniter.Project.Formatter.import_dep(:ash)
Expand Down Expand Up @@ -72,8 +72,8 @@ defmodule Mix.Tasks.Ash.Install do
false
)
|> then(fn igniter ->
if "--example" in argv do
generate_example(igniter, argv)
if "--example" in igniter.args.argv_flags do
generate_example(igniter, igniter.args.argv_flags)
else
igniter
end
Expand Down
13 changes: 10 additions & 3 deletions lib/mix/tasks/patch/ash.patch.extend.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ defmodule Mix.Tasks.Ash.Patch.Extend do
end

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
def igniter(igniter) do
Mix.Task.run("compile")
{%{subject: subject, extensions: extensions}, argv} = positional_args!(argv)
subject = igniter.args.positional.subject
extensions = igniter.args.positional.extensions

opts =
[
Expand All @@ -70,7 +71,13 @@ defmodule Mix.Tasks.Ash.Patch.Extend do
{igniter, patchers, _install} =
Enum.reduce(extensions, {igniter, [], []}, fn extension,
{igniter, patchers, install} ->
case patcher(kind_of_thing, subject, extension, source.path, argv) do
case patcher(
kind_of_thing,
subject,
extension,
source.path,
igniter.args.argv_flags
) do
{fun, new_install} when is_function(fun, 1) ->
{igniter, [fun | patchers], install ++ new_install}

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ defmodule Ash.MixProject do
{:simple_sat, "~> 0.1 and >= 0.1.1", optional: true},

# Code Generators
{:igniter, "~> 0.3 and >= 0.3.61"},
{:igniter, "~> 0.4"},

# IO Utilities
{:owl, "~> 0.11"},
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"git_ops": {:hex, :git_ops, "2.6.3", "38c6e381b8281b86e2911fa39bea4eab2d171c86d7428786566891efb73b68c3", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a81cb6c6a2a026a4d48cb9a2e1dfca203f9283a3a70aa0c7bc171970c44f23f8"},
"glob_ex": {:hex, :glob_ex, "0.1.10", "d819a368637495a5c1962ef34f48fe4e9a09032410b96ade5758f2cd1cc5fcde", [:mix], [], "hexpm", "c75357e57d71c85ef8ef7269b6e787dce3f0ff71e585f79a90e4d5477c532b90"},
"ham": {:hex, :ham, "0.3.0", "7cd031b4a55fba219c11553e7b13ba73bd86eab4034518445eff1e038cb9a44d", [:mix], [], "hexpm", "7d6c6b73d7a6a83233876cc1b06a4d9b5de05562b228effda4532f9a49852bf6"},
"igniter": {:hex, :igniter, "0.3.76", "ff283416402f4d1ef3f79ab57d38aac08389b3768fc81da03795ce5347f1167f", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "4692f874f969dc4856167469a3415a5a57a362314f37e1cdb14431316a74e896"},
"igniter": {:hex, :igniter, "0.4.0", "6f8eb6dce25c3641a73846922a15c0783061e8e0febec742452569a2f53f1641", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "8a0c44ae3e05f06a167ba561c760ae83a961ec8f824f23e174b4f95bf4c7fd8e"},
"iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"},
Expand All @@ -39,7 +39,7 @@
"rewrite": {:hex, :rewrite, "0.10.5", "6afadeae0b9d843b27ac6225e88e165884875e0aed333ef4ad3bf36f9c101bed", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "51cc347a4269ad3a1e7a2c4122dbac9198302b082f5615964358b4635ebf3d4f"},
"simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"},
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
"sourceror": {:hex, :sourceror, "1.6.0", "9907884e1449a4bd7dbaabe95088ed4d9a09c3c791fb0103964e6316bc9448a7", [:mix], [], "hexpm", "e90aef8c82dacf32c89c8ef83d1416fc343cd3e5556773eeffd2c1e3f991f699"},
"sourceror": {:hex, :sourceror, "1.7.0", "62c34f4e3a109d837edd652730219b6332745e0ec7db34d5d350a5cdf30b376a", [:mix], [], "hexpm", "3dd2b1bd780fd0df48089f48480a54fd065bf815b63ef8046219d7784e7435f3"},
"spark": {:hex, :spark, "2.2.35", "1c0bb30f340151eca24164885935de39e6ada4010555f444c813d0488990f8f3", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "f242d6385c287389034a0e146d8f025b5c9ab777f1ae5cf0fdfc9209db6ae748"},
"spitfire": {:hex, :spitfire, "0.1.3", "7ea0f544005dfbe48e615ed90250c9a271bfe126914012023fd5e4b6b82b7ec7", [:mix], [], "hexpm", "d53b5107bcff526a05c5bb54c95e77b36834550affd5830c9f58760e8c543657"},
"splode": {:hex, :splode, "0.2.7", "ed042fa9bd8fe7b66dd0a0faabdb97352058420d90cd1c7c1537f609deb7ef6d", [:mix], [], "hexpm", "267f1f51d5a5ac988cda0649498294844988c5086916fed5a8aff297d69a2059"},
Expand Down

0 comments on commit 6904a78

Please sign in to comment.