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

Sorting the type declarations from needs so the nillable ones are las… #993

Merged
merged 4 commits into from
Dec 23, 2019

Conversation

jwoertink
Copy link
Member

Purpose

Fixes #992

Description

When you use needs that have both nilable and required values, the nilable ones had to come last otherwise there was a crystal compile error. This PR sorts the assignable type declarations putting the nilable ones last for the initialize method.

cc. @bdtomlin @wezm

It'd be great if y'all could look over this and see if there's any other cases this solution doesn't cover.

Checklist

  • - An issue already exists detailing the issue/or feature request that this PR fixes
  • - All specs are formatted with crystal tool format spec src
  • - Inline documentation has been added and/or updated
  • - Lucky builds on docker with ./script/setup
  • - All builds and specs pass on docker with ./script/test

@bdtomlin
Copy link
Contributor

I don't think this goes far enough. The problem is not just with nilable types, there is still a problem if you have needs macro that has a default value before a needs statement that doesn't.

In other words the following will fail just due to the order of the needs statements:

needs some_var : String = "whatever"
needs required_var : String

@jwoertink
Copy link
Member Author

Ah, good call. Luckily the implementation is easy now, so adding on to it shouldn't be too bad.

Moved the test spec to assignable where other needs are tested
Copy link
Member

@paulcsmith paulcsmith left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this. This would be awesome to get in. I think it may not be sorting the defaults quite right but I’m not sure. Adding in some other needs may expose a bug

@@ -41,11 +43,23 @@ class PageWithQuestionMark
end
end

class PageWithDefaultsFirst
include Lucky::HTMLPage
needs extra_css : String?
Copy link
Member

Choose a reason for hiding this comment

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

Could you add another needs above this one without a default and not nil? I’m not sure but I think that may show an issue

Copy link
Member

Choose a reason for hiding this comment

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

And maybe a default of false too

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding a required one above this and the spec still passes.

Copy link
Member

Choose a reason for hiding this comment

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

Ok cool! What about the false default?

Copy link
Member Author

Choose a reason for hiding this comment

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

Cool. I added a few more just for some added comfort. They look good!

@@ -45,8 +45,9 @@ module Lucky::HTMLBuilder

macro generate_needy_initializer
{% if !@type.abstract? %}
{% sorted_assigns = ASSIGNS.sort_by { |dec| dec.type.resolve.nilable? || dec.value ? 1 : 0 } %}
Copy link
Member

@paulcsmith paulcsmith Dec 23, 2019

Choose a reason for hiding this comment

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

I think something like this may work and ensure that false and nil defaults work too:

decl.value || decl.value == nil || decl.value == false

I’m not sure but that’s my hunch

Also I don’t think it needs the type.resolve anymore since it just needs to sort defaults

Copy link
Member Author

Choose a reason for hiding this comment

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

If the type is thing : String?, then there's no value at all. It doesn't seem to even equate to nil from what I can tell. Without the resolve, it won't compile. But I'll add in the check for it having a value of nil and false.

@@ -41,11 +43,23 @@ class PageWithQuestionMark
end
end

class PageWithDefaultsFirst
include Lucky::HTMLPage
needs extra_css : String?
Copy link
Member

Choose a reason for hiding this comment

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

Ok cool! What about the false default?

@@ -45,8 +45,11 @@ module Lucky::HTMLBuilder

macro generate_needy_initializer
{% if !@type.abstract? %}
{% sorted_assigns = ASSIGNS.sort_by { |dec|
dec.type.resolve.nilable? || dec.value || dec.value == nil || dec.value == false ? 1 : 0
Copy link
Member

Choose a reason for hiding this comment

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

I think this will work without the resolve now. That’d also be preferable because resolve can lead to weird loading issues like we used to have in models where you had to require models depending on alphabetic order

Copy link
Member

Choose a reason for hiding this comment

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

Actually maybe not...since that would break the type union when it’s nilable with no default. So I guess this has to stay 👍 my bad

@paulcsmith
Copy link
Member

I think this looks good. Just trying to think if there’s a way to do it without resolving the type. But we can try to optimize for that later!

LGTM

@jwoertink
Copy link
Member Author

Sweet. Once these checks pass, I'll merge it in!

@jwoertink jwoertink merged commit e421076 into master Dec 23, 2019
@jwoertink jwoertink deleted the bugs/992 branch December 23, 2019 21:48
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.

Error: argument must have a default value when nilable needs property precedes non-nillable properties
3 participants