diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/common_test/doc/src/cover_chapter.xml | 8 | ||||
-rw-r--r-- | lib/tools/doc/src/cover.xml | 18 | ||||
-rw-r--r-- | lib/tools/src/cover.erl | 86 |
3 files changed, 64 insertions, 48 deletions
diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml index 4fa92d5583..736486350b 100644 --- a/lib/common_test/doc/src/cover_chapter.xml +++ b/lib/common_test/doc/src/cover_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2012</year> + <year>2006</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -74,12 +74,6 @@ executed during the test. In overview mode, only the code coverage overview page gets printed.</p> - <p><em>Note:</em> Currently, for Common Test to be able to print - code coverage HTML files for the modules included in the - analysis, the source code files of these modules must be - located in the same directory as the corresponding <c>.beam</c> - files. This is a limitation that will be removed later.</p> - <p>You can choose to export and import code coverage data between tests. If you specify the name of an export file in the cover specification file, Common Test will export collected coverage diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml index a2444ec947..beefd4ee8d 100644 --- a/lib/tools/doc/src/cover.xml +++ b/lib/tools/doc/src/cover.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2001</year> - <year>2012</year> + <year>2013</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -214,7 +214,9 @@ <c>{no_abstract_code,BeamFile}</c> is returned. If the abstract code is encrypted, and no key is available for decrypting it, the error reason - <c><![CDATA[{encrypted_abstract_code,BeamFile} is returned. <p>If only the module name (i.e. not the full name of the <c>.beam]]></c> file) is given to this function, the + <c>{encrypted_abstract_code,BeamFile}</c> is returned.</p> + <p>If only the module name (i.e. not the full name of the + <c>.beam</c> file) is given to this function, the <c>.beam</c> file is found by calling <c>code:which(Module)</c>. If no <c>.beam</c> file is found, the error reason <c>non_existing</c> is returned. If the @@ -313,9 +315,15 @@ file, i.e. using <c>compile_beam/1</c> or <c>compile_beam_directory/0,1</c>, it is assumed that the source code can be found in the same directory as the - <c>.beam</c> file, or in <c>../src</c> relative to that - directory. If no source code is found, - <c>,{error,no_source_code_found}</c> is returned.</p> + <c>.beam</c> file, in <c>../src</c> relative to that + directory, or using the source path in + <c>Module:module_info(compile)</c>. When using the latter, + two paths are examined: first the one constructed by + joining <c>../src</c> and the tail of the compiled path + below a trailing <c>src</c> component, then the compiled + path itself. + If no source code is found, + <c>{error,no_source_code_found}</c> is returned.</p> <p>HINT: It is possible to issue multiple analyse_to_file commands at the same time. </p> </desc> diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 2579711dc7..dfcfc3675f 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1951,47 +1951,61 @@ move_clauses([{M,F,A,C,_L}|Clauses]) -> move_clauses(Clauses); move_clauses([]) -> ok. - %% Given a .beam file, find the .erl file. Look first in same directory as -%% the .beam file, then in <beamdir>/../src +%% the .beam file, then in ../src, then in compile info. find_source(Module, File0) -> - case filename:rootname(File0,".beam") of - File0 -> - File0; - File -> - InSameDir = File++".erl", - case filelib:is_file(InSameDir) of - true -> - InSameDir; - false -> - Dir = filename:dirname(File), - Mod = filename:basename(File), - InDotDotSrc = filename:join([Dir,"..","src",Mod++".erl"]), - case filelib:is_file(InDotDotSrc) of - true -> - InDotDotSrc; - false -> - find_source_from_module(Module, File0) - end - end + try + Root = filename:rootname(File0, ".beam"), + Root == File0 andalso throw(File0), %% not .beam + %% Look for .erl in pwd. + File = Root ++ ".erl", + throw_file(File), + %% Not in pwd: look in ../src. + BeamDir = filename:dirname(File), + Base = filename:basename(File), + throw_file(filename:join([BeamDir, "..", "src", Base])), + %% Not in ../src: look for source path in compile info, but + %% first look relative the beam directory. + Info = lists:keyfind(source, 1, Module:module_info(compile)), + false == Info andalso throw({beam, File0}), %% stripped + {source, SrcFile} = Info, + throw_file(splice(BeamDir, SrcFile)), %% below ../src + throw_file(SrcFile), %% or absolute + %% No success means that source is either not under ../src or + %% its relative path differs from that of compile info. (For + %% example, compiled under src/x but installed under src/y.) + %% An option to specify an arbitrary source path explicitly is + %% probably a better solution than either more heuristics or a + %% potentially slow filesystem search. + {beam, File0} + catch + Path -> Path end. -%% In case we can't find the file from the given .beam, -%% we try to get the information directly from the module source -find_source_from_module(Module, File) -> - Compile = Module:module_info(compile), - case lists:keyfind(source, 1, Compile) of - {source, Path} -> - case filelib:is_file(Path) of - true -> - Path; - false -> - {beam, File} - end; - false -> - {beam, File} - end. +throw_file(Path) -> + false /= Path andalso filelib:is_file(Path) andalso throw(Path). + +%% Splice the tail of a source path, starting from the last "src" +%% component, onto the parent of a beam directory, or return false if +%% no "src" component is found. +%% +%% Eg. splice("/path/to/app-1.0/ebin", "/compiled/path/to/app/src/x/y.erl") +%% --> "/path/to/app-1.0/ebin/../src/x/y.erl" +%% +%% This handles the case of source in subdirectories of ../src with +%% beams that have moved since compilation. +%% +splice(BeamDir, SrcFile) -> + case lists:splitwith(fun(C) -> C /= "src" end, revsplit(SrcFile)) of + {T, [_|_]} -> %% found src component + filename:join([BeamDir, "..", "src" | lists:reverse(T)]); + {_, []} -> %% or not + false + end. + +revsplit(Path) -> + lists:reverse(filename:split(Path)). do_parallel_analysis(Module, Analysis, Level, Loaded, From, State) -> analyse_info(Module,State#main_state.imported), |