-
-
Notifications
You must be signed in to change notification settings - Fork 8
Fix keyword list parsing crash #56
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
base: main
Are you sure you want to change the base?
Fix keyword list parsing crash #56
Conversation
lib/spitfire.ex
Outdated
parser = parser |> next_token() |> next_token() | ||
{item, parser} = parse_expression(parser, @kw_identifier, true, false, false) | ||
{item, parser} |
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 believe this case actually should result in an error,
iex(1)> Code.string_to_quoted("[foo: \"bar\", :baz]")
{:error,
{[line: 1, column: 12],
"unexpected expression after keyword list. Keyword lists must always come last in lists and maps. Therefore, this is not allowed:\n\n [some: :value, :another]\n %{some: :value, another => value}\n\nInstead, reorder it to be the last entry:\n\n [:another, some: :value]\n %{another => value, some: :value}\n\nSyntax error after: ",
"','"}}
code = ~S''' | ||
defmodule MyModule do | ||
IO.inspect( | ||
:stderr, | ||
label: "label", | ||
(__cursor__()) | ||
) | ||
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.
this is an interesting result from the builtin parser
iex(5)> Code.string_to_quoted(~S'''
...(5)> defmodule MyModule do
...(5)> IO.inspect(
...(5)> :stderr,
...(5)> label: "label",
...(5)> (__cursor__())
...(5)> )
...(5)> end
...(5)> ''')
{:ok,
{:defmodule, [line: 1],
[
{:__aliases__, [line: 1], [:MyModule]},
[
do: {{:., [line: 2], [{:__aliases__, [line: 2], [:IO]}, :inspect]},
[line: 2], [:stderr, [{:label, "label"}, {:__cursor__, [line: 5], []}]]}
]
]}}
iex(6)> Code.string_to_quoted(~S'''
...(6)> defmodule MyModule do
...(6)> IO.inspect(
...(6)> :stderr,
...(6)> label: "label",
...(6)> :foo
...(6)> )
...(6)> end
...(6)> '''
...(6)> )
{:error,
{[line: 4, column: 19],
"unexpected expression after keyword list. Keyword lists must always come as the last argument. Therefore, this is not allowed:\n\n function_call(1, some: :option, 2)\n\nInstead, wrap the keyword in brackets:\n\n function_call(1, [some: :option], 2)\n\nSyntax error after: ",
"','"}}
iex(7)>
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.
Either the builtin parser supports a macro call returning tuple AST node or this is an error
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.
Another possibility it is more forgiving for nodes with __cursor__()
special form
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.
@mhanberg We have two options here.
- Have a special handling for
__cursor__()
nodes in keyword lists - Make the parser error tolerant and either silently drop invalid list entries or produce invalid AST
Add test cases from elixir-tools#32
b169652
to
41c96eb
Compare
Fixes crash 3 from #48
Fixes #26
Supersedes #32