Can typespec be added to the function like comments are? #71
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 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
All reactions