aboutsummaryrefslogtreecommitdiffstats
path: root/lib/syntax_tools/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/syntax_tools/src')
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl34
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl13
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl39
-rw-r--r--lib/syntax_tools/src/syntax_tools.app.src3
4 files changed, 81 insertions, 8 deletions
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 131be4e8e4..3ca7a8197e 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -88,7 +88,7 @@
%% This is a so-called Erlang I/O ErrorInfo structure; see the {@link
%% //stdlib/io} module for details.
--type errorinfo() :: term(). % {integer(), atom(), term()}.
+-type errorinfo() :: {integer(), atom(), term()}.
-type option() :: atom() | {atom(), term()}.
@@ -184,16 +184,42 @@ quick_parse_file(File, Options) ->
parse_file(File, fun quick_parse/3, Options ++ [no_fail]).
parse_file(File, Parser, Options) ->
+ case do_parse_file(utf8, File, Parser, Options) of
+ {ok, Forms}=Ret ->
+ case find_invalid_unicode(Forms) of
+ none ->
+ Ret;
+ invalid_unicode ->
+ case epp:read_encoding(File) of
+ utf8 ->
+ Ret;
+ _ ->
+ do_parse_file(latin1, File, Parser, Options)
+ end
+ end;
+ Else ->
+ Else
+ end.
+
+do_parse_file(DefEncoding, File, Parser, Options) ->
case file:open(File, [read]) of
{ok, Dev} ->
- _ = epp:set_encoding(Dev),
+ _ = epp:set_encoding(Dev, DefEncoding),
try Parser(Dev, 1, Options)
after ok = file:close(Dev)
end;
- {error, _} = Error ->
- Error
+ {error, Error} ->
+ {error, {0, file, Error}} % defer to file:format_error/1
end.
+find_invalid_unicode([H|T]) ->
+ case H of
+ {error, {_Line, file_io_server, invalid_unicode}} ->
+ invalid_unicode;
+ _Other ->
+ find_invalid_unicode(T)
+ end;
+find_invalid_unicode([]) -> none.
%% =====================================================================
%% @spec parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index dae7530ce7..03429d4d42 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -72,13 +72,24 @@ file(Name) ->
{ok, V} ->
case V of
{ok, B} ->
- Enc = case epp:read_encoding(Name) of
+ Encoding = epp:read_encoding_from_binary(B),
+ Enc = case Encoding of
none -> epp:default_encoding();
Enc0 -> Enc0
end,
case catch unicode:characters_to_list(B, Enc) of
String when is_list(String) ->
string(String);
+ R when Encoding =:= none ->
+ case
+ catch unicode:characters_to_list(B, latin1)
+ of
+ String when is_list(String) ->
+ string(String);
+ _ ->
+ error_read_file(Name1),
+ exit(R)
+ end;
R ->
error_read_file(Name1),
exit(R)
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index c9996c954e..40372a2106 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -669,6 +669,9 @@ is_leaf(Node) ->
operator -> true; % nonstandard type
string -> true;
text -> true; % nonstandard type
+ map_expr ->
+ map_expr_fields(Node) =:= [] andalso
+ map_expr_argument(Node) =:= none;
tuple -> tuple_elements(Node) =:= [];
underscore -> true;
variable -> true;
@@ -2071,7 +2074,7 @@ map_field_assoc_value(Node) ->
{map_field_assoc, _, _, Value} ->
Value;
_ ->
- (data(Node))#map_field_assoc.name
+ (data(Node))#map_field_assoc.value
end.
@@ -2129,7 +2132,7 @@ map_field_exact_value(Node) ->
{map_field_exact, _, _, Value} ->
Value;
_ ->
- (data(Node))#map_field_exact.name
+ (data(Node))#map_field_exact.value
end.
@@ -6093,6 +6096,9 @@ abstract([]) ->
nil();
abstract(T) when is_tuple(T) ->
tuple(abstract_list(tuple_to_list(T)));
+abstract(T) when is_map(T) ->
+ map_expr([map_field_assoc(abstract(Key),abstract(Value))
+ || {Key,Value} <- maps:to_list(T)]);
abstract(T) when is_binary(T) ->
binary([binary_field(integer(B)) || B <- binary_to_list(T)]);
abstract(T) ->
@@ -6154,6 +6160,14 @@ concrete(Node) ->
| concrete(list_tail(Node))];
tuple ->
list_to_tuple(concrete_list(tuple_elements(Node)));
+ map_expr ->
+ As = [tuple([map_field_assoc_name(F),
+ map_field_assoc_value(F)]) || F <- map_expr_fields(Node)],
+ M0 = maps:from_list(concrete_list(As)),
+ case map_expr_argument(Node) of
+ none -> M0;
+ Node0 -> maps:merge(concrete(Node0),M0)
+ end;
binary ->
Fs = [revert_binary_field(
binary_field(binary_field_body(F),
@@ -6209,10 +6223,31 @@ is_literal(T) ->
is_literal(list_head(T)) andalso is_literal(list_tail(T));
tuple ->
lists:all(fun is_literal/1, tuple_elements(T));
+ map_expr ->
+ case map_expr_argument(T) of
+ none -> true;
+ Arg -> is_literal(Arg)
+ end andalso lists:all(fun is_literal_map_field/1, map_expr_fields(T));
+ binary ->
+ lists:all(fun is_literal_binary_field/1, binary_fields(T));
_ ->
false
end.
+is_literal_binary_field(F) ->
+ case binary_field_types(F) of
+ [] -> is_literal(binary_field_body(F));
+ _ -> false
+ end.
+
+is_literal_map_field(F) ->
+ case type(F) of
+ map_field_assoc ->
+ is_literal(map_field_assoc_name(F)) andalso
+ is_literal(map_field_assoc_value(F));
+ map_field_exact ->
+ false
+ end.
%% =====================================================================
%% @doc Returns an `erl_parse'-compatible representation of a
diff --git a/lib/syntax_tools/src/syntax_tools.app.src b/lib/syntax_tools/src/syntax_tools.app.src
index dc0b9edd62..83dcb5fe23 100644
--- a/lib/syntax_tools/src/syntax_tools.app.src
+++ b/lib/syntax_tools/src/syntax_tools.app.src
@@ -14,4 +14,5 @@
prettypr]},
{registered,[]},
{applications, [stdlib]},
- {env, []}]}.
+ {env, []},
+ {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}.