Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements #18

Merged
merged 18 commits into from
Jan 9, 2022
Merged

Various improvements #18

merged 18 commits into from
Jan 9, 2022

Conversation

dvic
Copy link
Collaborator

@dvic dvic commented Jan 7, 2022

This PR contains #15, #16, and #17.

Updates:

  • Support for modules that call a macro that eventually produces an AST that we known (e.g., an ecto field call). This is an example of such a module:
  defmodule MySchema do
     use TypedEctoSchema

     import MyMacros

     typed_schema "foo" do
       MyMacros.add_field(:foo, :integer)
     end
   end
  • Support for properly parsing "source" override types, e.g.:
  defmodule MyModule do
     use TypedEctoSchema

     typed_schema "foo" do
       has_many :items, {"some_source", SomeSchema}
     end

   end
  • Avoids introducing unnecessary compile-time dependencies

@dvic
Copy link
Collaborator Author

dvic commented Jan 7, 2022

I have some additional work todo where I need all three branches merged.

@dvic dvic marked this pull request as ready for review January 8, 2022 22:19
@dvic
Copy link
Collaborator Author

dvic commented Jan 8, 2022

@bamorim You have been probably busy and that’s ok :) but do you think you can check this PR anytime soon? I’d really like to get these changes published :) If you need help maintaining the library, let me know, I’m happy to help.

@bamorim
Copy link
Owner

bamorim commented Jan 8, 2022

Hey @dvic. I'm a little bit sick now but I'll be taking holidays soon so I'll have time to check this. I'll put it in my calendar so I don't forget.

@dvic
Copy link
Collaborator Author

dvic commented Jan 8, 2022

Hope you get better soon! I advertised a bit for the library earlier today ;) https://twitter.com/dvic87/status/1479895011189735425?s=21

Comment on lines +147 to +159
expanded = Macro.expand(unknown, env)

case expanded do
^unknown ->
unknown

{:__block__, block_context, calls} ->
new_calls = Enum.map(calls, &transform_expression(&1, env))
{:__block__, block_context, new_calls}

call ->
transform_expression(call, env)
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so this is the core of this PR, right?
You expand whatever call it is and:

  • If it's form does not change it means it is not a macro, so you just keep it like that (unknown)
  • If it expands into a block you get all expressions and transform the expressions recursively
  • Else it should be just one expression and then you recursively transform that again

Did I got it right?

Also, the test for the block case is the add_to_fields macro, right?

Comment on lines +92 to +102
defp base_type_for({:__aliases__, _, [:Ecto, :Enum]}, opts) do
opts
|> Keyword.get(:values, [])
|> disjunction_typespec()
end

defp base_type_for({:__aliases__, _, _} = ast, _opts) do
quote do
unquote(ast).t()
end
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this does?
Is it because the type generation was only working if no aliases were being used?
Do we have any testes for that to avoid regression?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, are this what solves the compile deps problem?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay, thanks for the explanation via Slack.
So for further reference, this is a required step because now we are calling TypedEctoSchema.TypeBuilder.add_field/5 with a escaped macro to remove the compile time dependency, therefore we don't necessarily have the resolved value and more often than not we have an alias, so this is required to make it work on that scenario while still not requiring a compile time dependency.

Thanks! That is a neat job!

# Gets the base type for a given Ecto.Type.t()
@spec base_type_for(Ecto.Type.t(), field_options()) :: Macro.t()
# Gets the base type for a given Ecto.Type.t() or an AST representing a referenced type
@spec base_type_for(Ecto.Type.t() | {String.t(), Ecto.Type.t()} | Macro.t(), field_options()) ::
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {String.t(), Ecto.Type.t()} is for the assoc case with custom source, right?
Do you think this type makes sense? Now that I think it is actually a Ecto.Queryable.t() isn't it? (which is sad because it is just a term())

@@ -1,6 +1,6 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need a config? Maybe we can remove config completely.

@bamorim
Copy link
Owner

bamorim commented Jan 9, 2022

All right, tested locally and it works.
We still missing (I'll create an issue to track that down and discuss):

  • Regression tests for the compile time deps
  • Removing config (we are not using)

@bamorim bamorim merged commit 194f4bc into bamorim:master Jan 9, 2022
@bamorim bamorim mentioned this pull request Jan 9, 2022
6 tasks
@randycoulman
Copy link

@dvic / @bamorim Thanks for figuring out the circular compile dependencies! We were able to start using this library again because of your work!

@bamorim
Copy link
Owner

bamorim commented Apr 7, 2022

It was 100% @dvic. <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants