-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add macro methods to ProcNotation and ProcLiteral #5206
Conversation
Some tests would be nice. |
@@ -1197,6 +1197,30 @@ describe "macro methods" do | |||
end | |||
end | |||
|
|||
describe "proc notation tests" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that tests
is redundant here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "methods" to fit in with other tests.
@@ -1197,6 +1197,30 @@ describe "macro methods" do | |||
end | |||
end | |||
|
|||
describe "proc notation methods" do | |||
it "gets single input" do | |||
assert_macro "x", %({{x.inputs}}), [ProcNotation.new([Path.new("SomeType")] of ASTNode, Path.new("SomeResut"))] of ASTNode, "[SomeType]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: SomeResut
-> SomeResult
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, fixed.
src/compiler/crystal/macros.cr
Outdated
class ProcLiteral < ASTNode | ||
# Return the function declaration for this proc. | ||
# The name of the function will be "->" | ||
def method : Def |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually the way a ProcLiteral is implemented. This shouldn't leak to the macros API. A ProcLiteral should have the usual methods a def
has. The macro logic just needs to forward some methods to the internal def
.
What I mean is, ProcLiteral
should have a body
, args
, etc. methods. It shouldn't have a name
, though, because proc literals don't have a name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the way I have done that now ok, or should I do every method explicitly?
(Is there some consequence of the way that I've done it that isn't desirable?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. There are many methods in the base ASTNode class. The safest thing to do is to only forward the names that Def
also handles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've altered that to pass through all the current methods on Def
, otherwise call super
.
"return_type", | ||
"body", | ||
"receiver", | ||
"visibility" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I see the list, I'm pretty sure all of these don't make sense in a ProcLiteral: splat_index
, double_splat
, block_arg
, return_type
, visibility
. So it seems only receiver
, args
and body
make sense. And please use case ... when
instead of {..}.includes?(...)
. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amended to just include those methods. I'm not super familiar with Crystal yet so didn't catch that those didn't make sense!
class ProcLiteral | ||
def interpret(method, args, block, interpreter) | ||
case method | ||
when "args" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can simplify it to:
case method
when "args", "receiver", "body"
@def.interpret(method, args, block, interpreter)
else
super
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, thanks!
Not sure why Travis is failng, the tests are passing on my machine. |
@javanut13 Probably some hiccup. In any case, I'm sorry but I confused ProcNotation with ProcLiteral. Now I remember there's no |
I remembered there is also |
For example: |
Also add documentation to proc literal and proc notation macro methods
Is there anything else that needs attention here? |
Bump, could we have this soon? edit: I was wrong :) |
@asterite ping for review 😃 |
Fixes #4485.
I can't see where tests for macros live, so I've only briefly tested this manually. I will happily write some real tests before merging.
Also unsure about whether
NilLiteral
is the best thing to return in the case of no return type - is there already a convention for this?