Skip to content

Commit 213cba2

Browse files
committed
Default to including columns by default
This changes the default for Code.string_to_quoted/2 and friends, so it may break tests matching explicitly on the output, but the functionality wise the AST should still be the same. The reason why it is important to make this change is to provide better error messages throughout Elixir.
1 parent fe372a8 commit 213cba2

File tree

6 files changed

+41
-37
lines changed

6 files changed

+41
-37
lines changed

lib/elixir/lib/code.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,8 +820,8 @@ defmodule Code do
820820
* `:column` - (since v1.11.0) the starting column of the string being parsed.
821821
Defaults to 1.
822822
823-
* `:columns` - when `true`, attach a `:column` key to the quoted
824-
metadata. Defaults to `false`.
823+
* `:columns` - when `false`, does not attach a `:column` key to the quoted
824+
metadata. Defaults to `true` since v1.13.0.
825825
826826
* `:unescape` (since v1.10.0) - when `false`, preserves escaped sequences.
827827
For example, `"null byte\\t\\x00"` will be kept as is instead of being

lib/elixir/src/elixir.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ handle_parsing_opts(File, Opts) ->
413413
false -> false
414414
end,
415415
TokenMetadata = lists:keyfind(token_metadata, 1, Opts) == {token_metadata, true},
416-
Columns = lists:keyfind(columns, 1, Opts) == {columns, true},
416+
Columns = lists:keyfind(columns, 1, Opts) /= {columns, false},
417417
put(elixir_parser_file, File),
418418
put(elixir_parser_columns, Columns),
419419
put(elixir_token_metadata, TokenMetadata),

lib/elixir/src/elixir_quote.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,13 +510,13 @@ generated(Meta, #elixir_quote{generated=true}) -> [{generated, true} | Meta];
510510
generated(Meta, #elixir_quote{generated=false}) -> Meta.
511511

512512
keep(Meta, #elixir_quote{file=nil, line=Line}) ->
513-
line(Meta, Line);
513+
line(keydelete(column, Meta), Line);
514514
keep(Meta, #elixir_quote{file=File}) ->
515515
case lists:keytake(line, 1, Meta) of
516516
{value, {line, Line}, MetaNoLine} ->
517-
[{keep, {File, Line}} | MetaNoLine];
517+
[{keep, {File, Line}} | keydelete(column, MetaNoLine)];
518518
false ->
519-
[{keep, {File, 0}} | Meta]
519+
[{keep, {File, 0}} | keydelete(column, Meta)]
520520
end.
521521

522522
line(Meta, true) ->

lib/elixir/test/elixir/code_fragment_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -803,8 +803,8 @@ defmodule CodeFragmentTest do
803803
end
804804

805805
describe "container_cursor_to_quoted/2" do
806-
def s2q(arg, opts \\ []), do: Code.string_to_quoted(arg, opts)
807-
def cc2q(arg, opts \\ []), do: CF.container_cursor_to_quoted(arg, opts)
806+
def s2q(arg, opts \\ [columns: false]), do: Code.string_to_quoted(arg, opts)
807+
def cc2q(arg, opts \\ [columns: false]), do: CF.container_cursor_to_quoted(arg, opts)
808808

809809
test "completes terminators" do
810810
assert cc2q("(") == s2q("(__cursor__())")
@@ -913,7 +913,7 @@ defmodule CodeFragmentTest do
913913
assert cc2q("foo(", opts) == s2q("foo(__cursor__())", opts)
914914
assert cc2q("foo(123,", opts) == s2q("foo(123,__cursor__())", opts)
915915

916-
opts = [token_metadata: true]
916+
opts = [token_metadata: true, columns: false]
917917
assert cc2q("foo(", opts) == s2q("foo(__cursor__())", opts)
918918
assert cc2q("foo(123,", opts) == s2q("foo(123,__cursor__())", opts)
919919
end

lib/elixir/test/elixir/kernel/parser_test.exs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ defmodule Kernel.ParserTest do
5757

5858
describe "strings/sigils" do
5959
test "delimiter information for sigils is included" do
60-
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: false)
60+
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: false, columns: false)
6161

6262
assert parse!("~r/foo/") ==
6363
{:sigil_r, [delimiter: "/", line: 1], [{:<<>>, [line: 1], ["foo"]}, []]}
@@ -78,39 +78,37 @@ defmodule Kernel.ParserTest do
7878
end
7979

8080
test "sigil newlines" do
81-
assert {:sigil_s, _, [{:<<>>, _, ["here\ndoc"]}, []]} =
82-
Code.string_to_quoted!(~s|~s"here\ndoc"|)
81+
assert {:sigil_s, _, [{:<<>>, _, ["here\ndoc"]}, []]} = parse!(~s|~s"here\ndoc"|)
8382

84-
assert {:sigil_s, _, [{:<<>>, _, ["here\r\ndoc"]}, []]} =
85-
Code.string_to_quoted!(~s|~s"here\r\ndoc"|)
83+
assert {:sigil_s, _, [{:<<>>, _, ["here\r\ndoc"]}, []]} = parse!(~s|~s"here\r\ndoc"|)
8684
end
8785

8886
test "string newlines" do
89-
assert Code.string_to_quoted!(~s|"here\ndoc"|) == "here\ndoc"
90-
assert Code.string_to_quoted!(~s|"here\r\ndoc"|) == "here\r\ndoc"
91-
assert Code.string_to_quoted!(~s|"here\\\ndoc"|) == "heredoc"
92-
assert Code.string_to_quoted!(~s|"here\\\r\ndoc"|) == "heredoc"
87+
assert parse!(~s|"here\ndoc"|) == "here\ndoc"
88+
assert parse!(~s|"here\r\ndoc"|) == "here\r\ndoc"
89+
assert parse!(~s|"here\\\ndoc"|) == "heredoc"
90+
assert parse!(~s|"here\\\r\ndoc"|) == "heredoc"
9391
end
9492

9593
test "heredoc newlines" do
96-
assert Code.string_to_quoted!(~s|"""\nhere\ndoc\n"""|) == "here\ndoc\n"
97-
assert Code.string_to_quoted!(~s|"""\r\nhere\r\ndoc\r\n"""|) == "here\r\ndoc\r\n"
98-
assert Code.string_to_quoted!(~s| """\n here\n doc\n """|) == "here\ndoc\n"
99-
assert Code.string_to_quoted!(~s| """\r\n here\r\n doc\r\n """|) == "here\r\ndoc\r\n"
100-
assert Code.string_to_quoted!(~s|"""\nhere\\\ndoc\\\n"""|) == "heredoc"
101-
assert Code.string_to_quoted!(~s|"""\r\nhere\\\r\ndoc\\\r\n"""|) == "heredoc"
94+
assert parse!(~s|"""\nhere\ndoc\n"""|) == "here\ndoc\n"
95+
assert parse!(~s|"""\r\nhere\r\ndoc\r\n"""|) == "here\r\ndoc\r\n"
96+
assert parse!(~s| """\n here\n doc\n """|) == "here\ndoc\n"
97+
assert parse!(~s| """\r\n here\r\n doc\r\n """|) == "here\r\ndoc\r\n"
98+
assert parse!(~s|"""\nhere\\\ndoc\\\n"""|) == "heredoc"
99+
assert parse!(~s|"""\r\nhere\\\r\ndoc\\\r\n"""|) == "heredoc"
102100
end
103101

104102
test "heredoc indentation" do
105103
meta = [delimiter: "'''", line: 1]
106104
args = {:sigil_S, meta, [{:<<>>, [indentation: 2, line: 1], [" sigil heredoc\n"]}, []]}
107-
assert Code.string_to_quoted!("~S'''\n sigil heredoc\n '''") == args
105+
assert parse!("~S'''\n sigil heredoc\n '''") == args
108106
end
109107
end
110108

111109
describe "string_to_quoted/2" do
112110
test "converts strings to quoted expressions" do
113-
assert Code.string_to_quoted("1 + 2") == {:ok, {:+, [line: 1], [1, 2]}}
111+
assert Code.string_to_quoted("1 + 2") == {:ok, {:+, [line: 1, column: 3], [1, 2]}}
114112

115113
assert Code.string_to_quoted("a.1") ==
116114
{:error, {[line: 1, column: 3], "syntax error before: ", "\"1\""}}
@@ -150,7 +148,7 @@ defmodule Kernel.ParserTest do
150148
{:ok, {:my, "atom", ref}}
151149
end
152150

153-
assert {:ok, {{:my, "atom", ^ref}, [line: 1], nil}} =
151+
assert {:ok, {{:my, "atom", ^ref}, [line: 1, column: 1], nil}} =
154152
Code.string_to_quoted("there_is_no_such_var", static_atoms_encoder: encoder)
155153
end
156154

@@ -181,20 +179,21 @@ defmodule Kernel.ParserTest do
181179

182180
test "does not encode keywords" do
183181
encoder = fn atom, _meta -> raise "shouldn't be invoked for #{atom}" end
182+
string_to_quoted = &Code.string_to_quoted(&1, static_atoms_encoder: encoder, columns: false)
184183

185184
assert {:ok, {:fn, [line: 1], [{:->, [line: 1], [[1], 2]}]}} =
186-
Code.string_to_quoted("fn 1 -> 2 end", static_atoms_encoder: encoder)
185+
string_to_quoted.("fn 1 -> 2 end")
187186

188-
assert {:ok, {:or, [line: 1], [true, false]}} =
189-
Code.string_to_quoted("true or false", static_atoms_encoder: encoder)
187+
assert {:ok, {:or, [line: 1], [true, false]}} = string_to_quoted.("true or false")
190188

191189
encoder = fn atom, _meta -> {:ok, {:encoded, atom}} end
190+
string_to_quoted = &Code.string_to_quoted(&1, static_atoms_encoder: encoder, columns: false)
192191

193192
assert {:ok, [encoded: "true", encoded: "do", encoded: "and"]} =
194-
Code.string_to_quoted("[:true, :do, :and]", static_atoms_encoder: encoder)
193+
string_to_quoted.("[:true, :do, :and]")
195194

196195
assert {:ok, [{{:encoded, "do"}, 1}, {{:encoded, "true"}, 2}, {{:encoded, "end"}, 3}]} =
197-
Code.string_to_quoted("[do: 1, true: 2, end: 3]", static_atoms_encoder: encoder)
196+
string_to_quoted.("[do: 1, true: 2, end: 3]")
198197
end
199198

200199
test "returns errors on long atoms even when using static_atoms_encoder" do
@@ -304,7 +303,7 @@ defmodule Kernel.ParserTest do
304303
end
305304

306305
test "adds pairing information" do
307-
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: true)
306+
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: true, columns: false)
308307

309308
assert string_to_quoted.("foo") == {:foo, [line: 1], nil}
310309
assert string_to_quoted.("foo()") == {:foo, [closing: [line: 1], line: 1], []}
@@ -320,7 +319,12 @@ defmodule Kernel.ParserTest do
320319
end
321320

322321
test "with :literal_encoder" do
323-
opts = [literal_encoder: &{:ok, {:__block__, &2, [&1]}}, token_metadata: true]
322+
opts = [
323+
literal_encoder: &{:ok, {:__block__, &2, [&1]}},
324+
token_metadata: true,
325+
columns: false
326+
]
327+
324328
string_to_quoted = &Code.string_to_quoted!(&1, opts)
325329

326330
assert string_to_quoted.(~s("one")) == {:__block__, [delimiter: "\"", line: 1], ["one"]}
@@ -392,7 +396,7 @@ defmodule Kernel.ParserTest do
392396
end
393397

394398
test "adds metadata for the last alias segment" do
395-
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: true)
399+
string_to_quoted = &Code.string_to_quoted!(&1, token_metadata: true, columns: false)
396400

397401
assert string_to_quoted.("Foo") == {:__aliases__, [last: [line: 1], line: 1], [:Foo]}
398402

@@ -845,7 +849,7 @@ defmodule Kernel.ParserTest do
845849
end
846850
end
847851

848-
defp parse!(string), do: Code.string_to_quoted!(string)
852+
defp parse!(string), do: Code.string_to_quoted!(string, columns: false)
849853

850854
defp assert_token_missing(given_message, string) do
851855
assert_raise TokenMissingError, given_message, fn -> parse!(string) end

lib/elixir/test/elixir/kernel/quote_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ defmodule Kernel.QuoteTest do
235235
# The exception to this rule is an empty (). While empty expressions
236236
# are allowed, an empty () is ambiguous. We also can't use quote here,
237237
# since the formatter will rewrite (;) to something else.
238-
assert {:ok, {:__block__, [line: 1], []}} = Code.string_to_quoted("(;)")
238+
assert {:ok, {:__block__, [line: 1, column: 1], []}} = Code.string_to_quoted("(;)")
239239
end
240240

241241
test "bind quoted" do

0 commit comments

Comments
 (0)