Skip to content
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

Allow changing source paths presented in stack traces #1976

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lib/compiler/doc/src/compile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@
<tag><c>deterministic</c></tag>
<item>
<p>Omit the <c>options</c> and <c>source</c> tuples in
the list returned by <c>Module:module_info(compile)</c>.
the list returned by <c>Module:module_info(compile)</c>, and
reduce the paths in stack traces to the module name alone.
This option will make it easier to achieve reproducible builds.
</p>
</item>
Expand Down Expand Up @@ -347,8 +348,8 @@ module.beam: module.erl \

<tag><c>{source,FileName}</c></tag>
<item>
<p>Sets the value of the source, as returned by
<c>module_info(compile)</c>.</p>
<p>Overrides the source file name as presented in
<c>module_info(compile)</c> and stack traces.</p>
</item>

<tag><c>{outdir,Dir}</c></tag>
Expand Down
14 changes: 10 additions & 4 deletions lib/compiler/src/compile.erl
Original file line number Diff line number Diff line change
Expand Up @@ -931,11 +931,17 @@ parse_module(_Code, St0) ->
end.

do_parse_module(DefEncoding, #compile{ifile=File,options=Opts,dir=Dir}=St) ->
SourceName0 = proplists:get_value(source, Opts, File),
SourceName = case member(deterministic, Opts) of
true -> filename:basename(SourceName0);
false -> SourceName0
end,
R = epp:parse_file(File,
[{includes,[".",Dir|inc_paths(Opts)]},
{macros,pre_defs(Opts)},
{default_encoding,DefEncoding},
extra]),
[{includes,[".",Dir|inc_paths(Opts)]},
{source_name, SourceName},
{macros,pre_defs(Opts)},
{default_encoding,DefEncoding},
extra]),
case R of
{ok,Forms,Extra} ->
Encoding = proplists:get_value(encoding, Extra),
Expand Down
28 changes: 26 additions & 2 deletions lib/compiler/test/compile_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
core_roundtrip/1, asm/1, optimized_guards/1,
sys_pre_attributes/1, dialyzer/1,
warnings/1, pre_load_check/1, env_compiler_options/1,
bc_options/1, deterministic_include/1
bc_options/1, deterministic_include/1, deterministic_paths/1
]).

suite() -> [{ct_hooks,[ts_install_cth]}].
Expand All @@ -53,7 +53,7 @@ all() ->
cover, env, core_pp, core_roundtrip, asm, optimized_guards,
sys_pre_attributes, dialyzer, warnings, pre_load_check,
env_compiler_options, custom_debug_info, bc_options,
custom_compile_info, deterministic_include].
custom_compile_info, deterministic_include, deterministic_paths].

groups() ->
[].
Expand Down Expand Up @@ -1531,6 +1531,30 @@ deterministic_include(Config) when is_list(Config) ->

ok.

deterministic_paths(Config) when is_list(Config) ->
DataDir = proplists:get_value(data_dir, Config),

%% Files without +deterministic should differ if they were compiled from a
%% different directory.
true = deterministic_paths_1(DataDir, "simple", []),

%% ... but files with +deterministic shouldn't.
false = deterministic_paths_1(DataDir, "simple", [deterministic]),

ok.

deterministic_paths_1(DataDir, Name, Opts) ->
Simple = filename:join(DataDir, "simple"),
{ok, Cwd} = file:get_cwd(),
try
{ok,_,A} = compile:file(Simple, [binary | Opts]),
ok = file:set_cwd(DataDir),
{ok,_,B} = compile:file(Name, [binary | Opts]),
A =/= B
after
file:set_cwd(Cwd)
end.

%%%
%%% Utilities.
%%%
Expand Down
8 changes: 8 additions & 0 deletions lib/stdlib/doc/src/epp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@
<fsummary>Open a file for preprocessing.</fsummary>
<desc>
<p>Opens a file for preprocessing.</p>
<p>If you want to change the file name of the implicit -file()
attributes inserted during preprocessing, you can do with
<c>{source_name, <anno>SourceName</anno>}</c>. If unset it will
default to the name of the opened file.</p>
<p>If <c>extra</c> is specified in
<c><anno>Options</anno></c>, the return value is
<c>{ok, <anno>Epp</anno>, <anno>Extra</anno>}</c> instead
Expand Down Expand Up @@ -169,6 +173,10 @@
<p>Preprocesses and parses an Erlang source file.
Notice that tuple <c>{eof, <anno>Line</anno>}</c> returned at the
end of the file is included as a "form".</p>
<p>If you want to change the file name of the implicit -file()
attributes inserted during preprocessing, you can do with
<c>{source_name, <anno>SourceName</anno>}</c>. If unset it will
default to the name of the opened file.</p>
<p>If <c>extra</c> is specified in
<c><anno>Options</anno></c>, the return value is
<c>{ok, [<anno>Form</anno>], <anno>Extra</anno>}</c> instead
Expand Down
13 changes: 8 additions & 5 deletions lib/stdlib/src/epp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ open(Name, File, StartLocation, Path, Pdm) ->
{'ok', Epp} | {'ok', Epp, Extra} | {'error', ErrorDescriptor} when
Options :: [{'default_encoding', DefEncoding :: source_encoding()} |
{'includes', IncludePath :: [DirectoryName :: file:name()]} |
{'source_name', SourceName :: file:name()} |
{'macros', PredefMacros :: macros()} |
{'name',FileName :: file:name()} |
'extra'],
Expand Down Expand Up @@ -248,6 +249,7 @@ parse_file(Ifile, Path, Predefs) ->
{'ok', [Form]} | {'ok', [Form], Extra} | {error, OpenError} when
FileName :: file:name(),
Options :: [{'includes', IncludePath :: [DirectoryName :: file:name()]} |
{'source_name', SourceName :: file:name()} |
{'macros', PredefMacros :: macros()} |
{'default_encoding', DefEncoding :: source_encoding()} |
'extra'],
Expand Down Expand Up @@ -540,9 +542,10 @@ server(Pid, Name, Options, #epp{pre_opened=PreOpened}=St) ->
init_server(Pid, Name, Options, St)
end.

init_server(Pid, Name, Options, St0) ->
init_server(Pid, FileName, Options, St0) ->
SourceName = proplists:get_value(source_name, Options, FileName),
Pdm = proplists:get_value(macros, Options, []),
Ms0 = predef_macros(Name),
Ms0 = predef_macros(FileName),
case user_predef(Pdm, Ms0) of
{ok,Ms1} ->
#epp{file = File, location = AtLocation} = St0,
Expand All @@ -552,14 +555,14 @@ init_server(Pid, Name, Options, St0) ->
epp_reply(Pid, {ok,self(),Encoding}),
%% ensure directory of current source file is
%% first in path
Path = [filename:dirname(Name) |
Path = [filename:dirname(FileName) |
proplists:get_value(includes, Options, [])],
St = St0#epp{delta=0, name=Name, name2=Name,
St = St0#epp{delta=0, name=SourceName, name2=SourceName,
path=Path, macs=Ms1,
default_encoding=DefEncoding},
From = wait_request(St),
Anno = erl_anno:new(AtLocation),
enter_file_reply(From, file_name(Name), Anno,
enter_file_reply(From, file_name(SourceName), Anno,
AtLocation, code),
wait_req_scan(St);
{error,E} ->
Expand Down
16 changes: 14 additions & 2 deletions lib/stdlib/test/epp_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
otp_11728/1, encoding/1, extends/1, function_macro/1,
test_error/1, test_warning/1, otp_14285/1,
test_if/1]).
test_if/1,source_name/1]).

-export([epp_parse_erl_form/2]).

Expand Down Expand Up @@ -70,7 +70,7 @@ all() ->
overload_mac, otp_8388, otp_8470, otp_8562,
otp_8665, otp_8911, otp_10302, otp_10820, otp_11728,
encoding, extends, function_macro, test_error, test_warning,
otp_14285, test_if].
otp_14285, test_if, source_name].

groups() ->
[{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
Expand Down Expand Up @@ -1702,6 +1702,18 @@ function_macro(Config) ->

ok.

source_name(Config) when is_list(Config) ->
DataDir = proplists:get_value(data_dir, Config),
File = filename:join(DataDir, "source_name.erl"),

source_name_1(File, "/test/gurka.erl"),
source_name_1(File, "gaffel.erl"),

ok.

source_name_1(File, Expected) ->
Res = epp:parse_file(File, [{source_name, Expected}]),
{ok, [{attribute,_,file,{Expected,_}} | _Forms]} = Res.

check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
Expand Down
27 changes: 27 additions & 0 deletions lib/stdlib/test/epp_SUITE_data/source_name.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2018. 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.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%

-module(source_name).
-export([ok/0]).

%% Changing source name should not affect headers
-include("bar.hrl").

ok() -> ok.