PT-156466783 namespaces #516
@ -28,8 +28,8 @@
|
|||||||
| pp_icode
|
| pp_icode
|
||||||
| pp_assembler
|
| pp_assembler
|
||||||
| pp_bytecode
|
| pp_bytecode
|
||||||
| {include_path, [string()]}
|
| {include, {file_system, [string()]} |
|
||||||
| {allow_include, boolean()}
|
{explicit_files, #{string() => binary()}}}
|
||||||
| {src_file, string()}.
|
| {src_file, string()}.
|
||||||
-type options() :: [option()].
|
-type options() :: [option()].
|
||||||
|
|
||||||
@ -49,12 +49,13 @@ version() ->
|
|||||||
-spec file(string()) -> {ok, map()} | {error, binary()}.
|
-spec file(string()) -> {ok, map()} | {error, binary()}.
|
||||||
file(Filename) ->
|
file(Filename) ->
|
||||||
Dir = filename:dirname(Filename),
|
Dir = filename:dirname(Filename),
|
||||||
file(Filename, [{include_path, [Dir]}]).
|
{ok, Cwd} = file:get_cwd(),
|
||||||
|
file(Filename, [{include, {file_system, [Cwd, Dir]}}]).
|
||||||
|
|
||||||
-spec file(string(), options()) -> {ok, map()} | {error, binary()}.
|
-spec file(string(), options()) -> {ok, map()} | {error, binary()}.
|
||||||
file(File, Options) ->
|
file(File, Options) ->
|
||||||
case read_contract(File) of
|
case read_contract(File) of
|
||||||
{ok, Bin} -> from_string(Bin, [{src_file, File}, {allow_include, true} | Options]);
|
{ok, Bin} -> from_string(Bin, [{src_file, File} | Options]);
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
ErrorString = [File,": ",file:format_error(Error)],
|
ErrorString = [File,": ",file:format_error(Error)],
|
||||||
{error, join_errors("File errors", [ErrorString], fun(E) -> E end)}
|
{error, join_errors("File errors", [ErrorString], fun(E) -> E end)}
|
||||||
@ -288,10 +289,8 @@ parse(Text, Options) ->
|
|||||||
ErrorString = io_lib:format("Ambiguous ~p", [As]),
|
ErrorString = io_lib:format("Ambiguous ~p", [As]),
|
||||||
parse_error(Pos, ErrorString);
|
parse_error(Pos, ErrorString);
|
||||||
%% Include error
|
%% Include error
|
||||||
{error, {Pos, include_not_allowed}} ->
|
{error, {Pos, {include_error, File}}} ->
|
||||||
parse_error(Pos, "includes not allowed in this context");
|
parse_error(Pos, io_lib:format("could not find include file '~s'", [File]))
|
||||||
{error, {Pos, include_error}} ->
|
|
||||||
parse_error(Pos, "could not find include file")
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_error(Pos, ErrorString) ->
|
parse_error(Pos, ErrorString) ->
|
||||||
|
@ -483,9 +483,8 @@ expand_includes(AST, Opts) ->
|
|||||||
expand_includes([], Acc, _Opts) ->
|
expand_includes([], Acc, _Opts) ->
|
||||||
{ok, lists:reverse(Acc)};
|
{ok, lists:reverse(Acc)};
|
||||||
expand_includes([{include, S = {string, _, File}} | AST], Acc, Opts) ->
|
expand_includes([{include, S = {string, _, File}} | AST], Acc, Opts) ->
|
||||||
AllowInc = proplists:get_value(allow_include, Opts, false),
|
|
||||||
case read_file(File, Opts) of
|
case read_file(File, Opts) of
|
||||||
{ok, Bin} when AllowInc ->
|
{ok, Bin} ->
|
||||||
Opts1 = lists:keystore(src_file, 1, Opts, {src_file, File}),
|
Opts1 = lists:keystore(src_file, 1, Opts, {src_file, File}),
|
||||||
case string(binary_to_list(Bin), Opts1) of
|
case string(binary_to_list(Bin), Opts1) of
|
||||||
{ok, AST1} ->
|
{ok, AST1} ->
|
||||||
@ -493,17 +492,22 @@ expand_includes([{include, S = {string, _, File}} | AST], Acc, Opts) ->
|
|||||||
Err = {error, _} ->
|
Err = {error, _} ->
|
||||||
Err
|
Err
|
||||||
end;
|
end;
|
||||||
{ok, _} ->
|
|
||||||
{error, {get_pos(S), include_not_allowed}};
|
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
{error, {get_pos(S), include_error}}
|
{error, {get_pos(S), {include_error, File}}}
|
||||||
end;
|
end;
|
||||||
expand_includes([E | AST], Acc, Opts) ->
|
expand_includes([E | AST], Acc, Opts) ->
|
||||||
expand_includes(AST, [E | Acc], Opts).
|
expand_includes(AST, [E | Acc], Opts).
|
||||||
|
|
||||||
read_file(File, Opts) ->
|
read_file(File, Opts) ->
|
||||||
CandidateNames = [File] ++ [ filename:join(Dir, File)
|
case proplists:get_value(include, Opts, {explicit_files, #{}}) of
|
||||||
|| Dir <- proplists:get_value(include_path, Opts, []) ],
|
{file_system, Paths} ->
|
||||||
|
CandidateNames = [ filename:join(Dir, File) || Dir <- Paths ],
|
||||||
lists:foldr(fun(F, {error, _}) -> file:read_file(F);
|
lists:foldr(fun(F, {error, _}) -> file:read_file(F);
|
||||||
(_F, OK) -> OK end, {error, not_found}, CandidateNames).
|
(_F, OK) -> OK end, {error, not_found}, CandidateNames);
|
||||||
|
{explicit_files, Files} ->
|
||||||
|
case maps:get(binary_to_list(File), Files, not_found) of
|
||||||
|
not_found -> {error, not_found};
|
||||||
|
Src -> {ok, Src}
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ simple_compile_test_() ->
|
|||||||
end} || ContractName <- compilable_contracts() ] ++
|
end} || ContractName <- compilable_contracts() ] ++
|
||||||
[ {"Testing error messages of " ++ ContractName,
|
[ {"Testing error messages of " ++ ContractName,
|
||||||
fun() ->
|
fun() ->
|
||||||
case compile(ContractName, false) of
|
case compile(ContractName) of
|
||||||
<<"Type errors\n", ErrorString/binary>> ->
|
<<"Type errors\n", ErrorString/binary>> ->
|
||||||
check_errors(lists:sort(ExpectedErrors), ErrorString);
|
check_errors(lists:sort(ExpectedErrors), ErrorString);
|
||||||
<<"Parse errors\n", ErrorString/binary>> ->
|
<<"Parse errors\n", ErrorString/binary>> ->
|
||||||
@ -31,6 +31,17 @@ simple_compile_test_() ->
|
|||||||
end
|
end
|
||||||
end} ||
|
end} ||
|
||||||
{ContractName, ExpectedErrors} <- failing_contracts() ] ++
|
{ContractName, ExpectedErrors} <- failing_contracts() ] ++
|
||||||
|
[ {"Testing include with explicit files",
|
||||||
|
fun() ->
|
||||||
|
FileSystem = maps:from_list(
|
||||||
|
[ begin
|
||||||
|
{ok, Bin} = file:read_file(filename:join([aeso_test_utils:contract_path(), File])),
|
||||||
|
{File, Bin}
|
||||||
|
end || File <- ["included.aes", "../contracts/included2.aes"] ]),
|
||||||
|
#{byte_code := Code1} = compile("include", [{include, {explicit_files, FileSystem}}]),
|
||||||
|
#{byte_code := Code2} = compile("include"),
|
||||||
|
?assertMatch(true, Code1 == Code2)
|
||||||
|
end} ] ++
|
||||||
[ {"Testing deadcode elimination",
|
[ {"Testing deadcode elimination",
|
||||||
fun() ->
|
fun() ->
|
||||||
#{ byte_code := NoDeadCode } = compile("nodeadcode"),
|
#{ byte_code := NoDeadCode } = compile("nodeadcode"),
|
||||||
@ -50,13 +61,12 @@ check_errors(Expect, ErrorString) ->
|
|||||||
{Missing, Extra} -> ?assertEqual(Missing, Extra)
|
{Missing, Extra} -> ?assertEqual(Missing, Extra)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
compile(Name) -> compile(Name, true).
|
compile(Name) ->
|
||||||
|
compile(Name, [{include, {file_system, [aeso_test_utils:contract_path()]}}]).
|
||||||
|
|
||||||
compile(Name, AllowInc) ->
|
compile(Name, Options) ->
|
||||||
String = aeso_test_utils:read_contract(Name),
|
String = aeso_test_utils:read_contract(Name),
|
||||||
case aeso_compiler:from_string(String, [{include_path, [aeso_test_utils:contract_path()]},
|
case aeso_compiler:from_string(String, [{src_file, Name} | Options]) of
|
||||||
{allow_include, AllowInc},
|
|
||||||
{src_file, Name}]) of
|
|
||||||
{ok, Map} -> Map;
|
{ok, Map} -> Map;
|
||||||
{error, ErrorString} -> ErrorString
|
{error, ErrorString} -> ErrorString
|
||||||
end.
|
end.
|
||||||
@ -201,8 +211,6 @@ failing_contracts() ->
|
|||||||
" r.foo : (gas : int, value : int) => Remote.themap\n"
|
" r.foo : (gas : int, value : int) => Remote.themap\n"
|
||||||
"against the expected type\n"
|
"against the expected type\n"
|
||||||
" (gas : int, value : int) => map(string, int)">>]}
|
" (gas : int, value : int) => map(string, int)">>]}
|
||||||
, {"include",
|
|
||||||
[<<"file include, line 1, column 9: includes not allowed in this context\n">>]}
|
|
||||||
, {"bad_include_and_ns",
|
, {"bad_include_and_ns",
|
||||||
[<<"Include of 'included.aes' at line 2, column 11\nnot allowed, include only allowed at top level.">>,
|
[<<"Include of 'included.aes' at line 2, column 11\nnot allowed, include only allowed at top level.">>,
|
||||||
<<"Nested namespace not allowed\nNamespace 'Foo' at line 3, column 13 not defined at top level.">>]}
|
<<"Nested namespace not allowed\nNamespace 'Foo' at line 3, column 13 not defined at top level.">>]}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user