Can typespec be added to the function like comments are? #71
Unanswered
ivan-srsen
asked this question in
Q&A
Replies: 1 comment 4 replies
|
Yes, and a good way to do it is by using Zippers: As always with AST, it can be a bit tricky: code = """
defmodule Hello do
def foo do
:ok
end
end
"""
ast = Sourceror.parse_string!(code)alias Sourceror.Zipper
modified =
ast
|> Zipper.zip()
|> Zipper.traverse(fn
{{:def, _, [{:foo, _, _}, _]}, _path} = zipper ->
spec =
quote do
@spec foo() :: :ok
end
case Zipper.up(zipper) do
{{{:__block__, _, _} = do_block, content}, path} ->
# This is the only expression inside the `do` block, so we need to wrap it in a block
# We're at {do_block, content}
{{do_block, {:__block__, [], [content]}}, path}
# Go down to do_block
|> Zipper.down()
# Go right to [content]
|> Zipper.right()
# We're in [content], which is a list, so we go down inside of it
|> Zipper.down()
# Finally, we can insert the spec
|> Zipper.insert_left(spec)
_ ->
# We're inside a block, so we can just insert the spec
Zipper.insert_left(zipper, spec)
end
other ->
other
end)
|> Zipper.node()
|> Sourceror.to_string()
|> IO.puts()The hassle here is that the AST is represented differently depending on if the I encourage you to parse the AST you're interested in and experiment a bit with it, as most of the time you want to recognize a pattern, or a set of patterns, and match against them to manipulate them. There's also room for improvement for instance to avoid having to do the |
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
All reactions