Skip to content

Commit

Permalink
Merge branch 'raimo/triple-quoted-strings-warning' into maint
Browse files Browse the repository at this point in the history
* raimo/triple-quoted-strings-warning:
  Update primary bootstrap
  Shorten code by list comprehension
  Update primary bootstrap
  Emit warning for triple quote chars
  Emit warning for triple quote chars
  • Loading branch information
RaimoNiskanen committed Sep 1, 2023
2 parents 70397e0 + 581177c commit 924483c
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 9 deletions.
Binary file modified bootstrap/lib/stdlib/ebin/epp.beam
Binary file not shown.
Binary file modified bootstrap/lib/stdlib/ebin/erl_parse.beam
Binary file not shown.
Binary file modified bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary file not shown.
31 changes: 25 additions & 6 deletions lib/stdlib/src/epp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ format_error({warning,Term}) ->
io_lib:format("-warning(~tp).", [Term]);
format_error(ftr_after_prefix) ->
"feature directive not allowed after exports or record definitions";
format_error(tqstring) ->
"Triple-quoted (or more) strings will change meaning in OTP-27.0";
format_error(E) -> file:format_error(E).

-spec scan_file(FileName, Options) ->
Expand Down Expand Up @@ -345,15 +347,32 @@ parse_file(Ifile, Options) ->
WarningInfo :: warning_info().

parse_file(Epp) ->
case parse_erl_form(Epp) of
{ok,Form} ->
[Form|parse_file(Epp)];
%% Code duplicated from parse_erl_form(Epp), but with
%% added search for tokens to warn for
case epp_request(Epp, scan_erl_form) of
{ok,Toks} ->
Warnings =
[{warning, {erl_anno:location(Anno),?MODULE,tqstring}}
%% Warn about using 3 or more double qoutes
|| {tqstring,Anno,_} <- Toks],
case erl_parse:parse_form(Toks) of
{ok, Form} ->
[Form|Warnings] ++ parse_file(Epp);
Problem2 ->
parse_file_problem(Epp, Problem2, Warnings)
end;
Problem1 ->
parse_file_problem(Epp, Problem1, [])
end.

parse_file_problem(Epp, Problem, Warnings) ->
case Problem of
{error,E} ->
[{error,E}|parse_file(Epp)];
[{error,E}|Warnings] ++ parse_file(Epp);
{warning,W} ->
[{warning,W}|parse_file(Epp)];
[{warning,W}|Warnings] ++ parse_file(Epp);
{eof,Location} ->
[{eof,Location}]
[{eof,Location}|Warnings]
end.

-spec default_encoding() -> source_encoding().
Expand Down
5 changes: 4 additions & 1 deletion lib/stdlib/src/erl_parse.yrl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ ssa_check_when_clause
ssa_check_when_clauses.

Terminals
char integer float atom string var
char integer float atom tqstring string var

'(' ')' ',' '->' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
'after' 'begin' 'case' 'try' 'catch' 'end' 'fun' 'if' 'of' 'receive' 'when'
Expand Down Expand Up @@ -546,8 +546,11 @@ atomic -> atom : '$1'.
atomic -> strings : '$1'.

strings -> string : '$1'.
strings -> tqstring : {string,?anno('$1'),element(3, '$1')}.
strings -> string strings :
{string,?anno('$1'),element(3, '$1') ++ element(3, '$2')}.
strings -> tqstring strings :
{string,?anno('$1'),element(3, '$1') ++ element(3, '$2')}.

prefix_op -> '+' : '$1'.
prefix_op -> '-' : '$1'.
Expand Down
33 changes: 32 additions & 1 deletion lib/stdlib/src/erl_scan.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1996-2022. All Rights Reserved.
%% Copyright Ericsson AB 1996-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -425,6 +425,12 @@ scan1("."=Cs, St, Line, Col, Toks) ->
{more,{Cs,St,Col,Toks,Line,[],fun scan/6}};
scan1([$.=C|Cs], St, Line, Col, Toks) ->
scan_dot(Cs, St, Line, Col, Toks, [C]);
scan1([$",$",$"|Cs], St, Line, Col, Toks) -> %" Emacs
scan_tqstring(Cs, St, Line, Col, Toks, 3); % Number of quote chars
scan1([$",$"]=Cs, St, Line, Col, Toks) ->
{more,{Cs,St,Col,Toks,Line,[],fun scan/6}};
scan1([$"]=Cs, St, Line, Col, Toks) -> %" Emacs
{more,{Cs,St,Col,Toks,Line,[],fun scan/6}};
scan1([$"|Cs], St, Line, Col, Toks) -> %" Emacs
State0 = {[],[],Line,Col},
scan_string(Cs, St, Line, incr_column(Col, 1), Toks, State0);
Expand Down Expand Up @@ -828,6 +834,31 @@ scan_char([], St, Line, Col, Toks) ->
scan_char(eof, _St, Line, Col, _Toks) ->
scan_error(char, Line, Col, Line, incr_column(Col, 1), eof).

%% Scan leading $" characters until we have them all
%%
scan_tqstring(Cs, St, Line, Col, Toks, Qs) ->
case Cs of
[$"|Ncs] ->
scan_tqstring(Ncs, St, Line, Col, Toks, Qs+1);
[] ->
{more, {[], St, Col, Toks, Line, Qs, fun scan_tqstring/6}};
_ ->
scan_tqstring_finish(Cs, St, Line, Col, Toks, Qs, tqstring)
end.

scan_tqstring_finish(Cs, St, Line, Col, Toks, Qs, TokTag) when 1 < Qs ->
Anno = anno(Line, Col, St, ?STR(string, St, [$",$"])),
Tok = {TokTag, Anno, ""},
scan_tqstring_finish(
Cs, St, Line, incr_column(Col, 2), [Tok|Toks], Qs-2, string);
scan_tqstring_finish(Cs, St, Line, Col, Toks, Qs, _TokTag) ->
Ncs =
case Qs of
1 -> [$"|Cs];%"
0 -> Cs
end,
scan1(Ncs, St, Line, Col, Toks).

scan_string(Cs, #erl_scan{}=St, Line, Col, Toks, {Wcs,Str,Line0,Col0}) ->
case scan_string0(Cs, St, Line, Col, $\", Str, Wcs) of %"
{more,Ncs,Nline,Ncol,Nstr,Nwcs} ->
Expand Down
73 changes: 72 additions & 1 deletion lib/stdlib/test/epp_SUITE.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1998-2022. All Rights Reserved.
%% Copyright Ericsson AB 1998-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,6 +30,7 @@
otp_11728/1, encoding/1, extends/1, function_macro/1,
test_error/1, test_warning/1, otp_14285/1,
test_if/1,source_name/1,otp_16978/1,otp_16824/1,scan_file/1,file_macro/1,
triple_quotes_warning/1,
deterministic_include/1, nondeterministic_include/1]).

-export([epp_parse_erl_form/2]).
Expand Down Expand Up @@ -73,6 +74,7 @@ all() ->
otp_8665, otp_8911, otp_10302, otp_10820, otp_11728,
encoding, extends, function_macro, test_error, test_warning,
otp_14285, test_if, source_name, otp_16978, otp_16824, scan_file, file_macro,
triple_quotes_warning,
deterministic_include, nondeterministic_include].

groups() ->
Expand Down Expand Up @@ -2055,6 +2057,73 @@ otp_16824(Config) when is_list(Config) ->
[] = compile(Config, Cs),
ok.

triple_quotes_warning(Config) when is_list(Config) ->
Cs1 =
[{triple_quotes_warning_1,
<<"\n-doc \"foo\".\n">>,
[]},
{triple_quotes_warning_2,
<<"\n-doc \"\" \"foo\" \"\".\n">>,
[]},
{triple_quotes_warning_3,
<<"\n"
"-doc \"\"\"\n"
" foo\n"
" \"\"\".\n">>,
{warnings,[{{2,6},epp,tqstring}]}},
{triple_quotes_warning_4,
<<"\n"
"-doc \"\"\"\"\n"
" \"\"\"\".\n">>,
{warnings,
[{{2,7},epp,tqstring},
{{3,7},epp,tqstring}]}},
{triple_quotes_warning_5,
<<"\n"
"-doc \"\"\"\"\"\n"
" foo\n"
" \"\"\"\"\".\n">>,
{warnings,
[{{2,8},epp,tqstring},
{{4,9},epp,tqstring}]}}
],
[] = compile(Config, Cs1),

Cs2 =
[{triple_quotes_warning_10,
<<"\n"
"-export([foo/0]).\n"
"foo() ->\n"
" \"\"\"\n"
" bar\n"
" \"\"\".\n">>,
{warnings,[{{4,5},epp,tqstring}]}},
{triple_quotes_warning_11,
<<"\n"
"-export([foo/0]).\n"
"foo() ->\n"
" \"\"\"\"\n"
" ++ lists:duplicate(4, $x) ++\n"
" \"\"\"\".\n">>,
{warnings,
[{{4,5},epp,tqstring},
{{6,5},epp,tqstring}]}},
{triple_quotes_warning_12,
<<"\n"
"-export([foo/0]).\n"
"foo() ->\n"
" \"\"\"\"\"\n"
" bar\n"
" \"\"\"\"\".\n">>,
{warnings,
[{{4,5},epp,tqstring},
{{6,6},epp,tqstring}]}} ],
[] = compile(Config, Cs2),

ok.



%% Start location is 1.
check(Config, Tests) ->
eval_tests(Config, fun check_test/3, Tests).
Expand Down Expand Up @@ -2085,6 +2154,8 @@ eval_tests(Config, Fun, Tests) ->
case E of
{errors, Errors} ->
call_format_error(Errors);
{warnings, Errors} ->
call_format_error(Errors);
_ ->
ok
end,
Expand Down

0 comments on commit 924483c

Please sign in to comment.