Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
6321-Add-annotate_in_place-mode-to-TypEr.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 6321-Add-annotate_in_place-mode-to-TypEr.patch of Package erlang
From f6f7d2fa2ee5a256249c13df0c969ccac439be78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Costas=20S=C3=A1nchez?= <pablo.costas@nextroll.com> Date: Tue, 8 Mar 2022 14:46:28 +0100 Subject: [PATCH] Add annotate_in_place mode to TypEr This commit adds a new analysis mode to be ran with TypEr, `annotate_in_place`, which can be used to annotate the specs that the tool inferred directly on the source code files. --- lib/dialyzer/doc/src/typer_cmd.xml | 9 +++- lib/dialyzer/src/typer.erl | 9 +++- lib/dialyzer/src/typer_core.erl | 76 +++++++++++++++++++----------- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/lib/dialyzer/doc/src/typer_cmd.xml b/lib/dialyzer/doc/src/typer_cmd.xml index 6217fce715..b0aada576d 100644 --- a/lib/dialyzer/doc/src/typer_cmd.xml +++ b/lib/dialyzer/doc/src/typer_cmd.xml @@ -52,7 +52,7 @@ typer --help</code> <code type="none"> typer [--help] [--version] [--plt PLT] [--edoc] - [--show | --show-exported | --annotate | --annotate-inc-files] + [--show | --show-exported | --annotate | --annotate-inc-files | --annotate-in-place] [-Ddefine]* [-I include_dir]* [-pa dir]* [-pz dir]* [-T application]* file* [-r directory*]</code> @@ -94,6 +94,13 @@ typer [--help] [--version] [--plt PLT] [--edoc] option with caution - it has not been tested much).</p> </item> + <tag><c>--annotate-in-place</c></tag> + <item> + <p>Annotate directly on the source code files, instead of dumping the + annotated files in a different directory (use this option with + caution - has not been tested much)</p> + </item> + <tag><c>--edoc</c></tag> <item> <p>Print type information as Edoc <c>@spec</c> comments, not diff --git a/lib/dialyzer/src/typer.erl b/lib/dialyzer/src/typer.erl index 5be2607e63..9fa2cd78a2 100644 --- a/lib/dialyzer/src/typer.erl +++ b/lib/dialyzer/src/typer.erl @@ -34,6 +34,7 @@ -define(SHOW, show). -define(SHOW_EXPORTED, show_exported). -define(ANNOTATE, annotate). +-define(ANNOTATE_IN_PLACE, annotate_in_place). -define(ANNOTATE_INC_FILES, annotate_inc_files). %%----------------------------------------------------------------------- @@ -81,6 +82,7 @@ cl(["--show_success_typings"|Opts]) -> {show_succ, Opts}; cl(["--show-success-typings"|Opts]) -> {show_succ, Opts}; cl(["--annotate"|Opts]) -> {{mode, ?ANNOTATE}, Opts}; cl(["--annotate-inc-files"|Opts]) -> {{mode, ?ANNOTATE_INC_FILES}, Opts}; +cl(["--annotate-in-place"|Opts]) -> {{mode, ?ANNOTATE_IN_PLACE}, Opts}; cl(["--no_spec"|Opts]) -> {no_spec, Opts}; cl(["--plt",Plt|Opts]) -> {{plt, Plt}, Opts}; cl(["-D"|_Opts]) -> fatal_error("no variable name specified after -D"); @@ -187,7 +189,7 @@ version_message() -> help_message() -> S = <<" Usage: typer [--help] [--version] [--plt PLT] [--edoc] - [--show | --show-exported | --annotate | --annotate-inc-files] + [--show | --show-exported | --annotate | --annotate-inc-files | --annotate-in-place] [-Ddefine]* [-I include_dir]* [-pa dir]* [-pz dir]* [-T application]* [-r] file* @@ -205,7 +207,10 @@ help_message() -> the resulting files into a new typer_ann folder. --annotate-inc-files Same as --annotate but annotates all -include() files as well as - all .erl files (use this option with caution - has not been tested much) + all .erl files + --annotate-in-place + Annotate directly on the source code files, instead of dumping the + annotated files in a different directory --edoc Prints type information as Edoc @spec comments, not as type specs --plt PLT diff --git a/lib/dialyzer/src/typer_core.erl b/lib/dialyzer/src/typer_core.erl index 76405775ef..4f97fe83e0 100644 --- a/lib/dialyzer/src/typer_core.erl +++ b/lib/dialyzer/src/typer_core.erl @@ -34,9 +34,10 @@ -define(SHOW, show). -define(SHOW_EXPORTED, show_exported). -define(ANNOTATE, annotate). +-define(ANNOTATE_IN_PLACE, annotate_in_place). -define(ANNOTATE_INC_FILES, annotate_inc_files). --type mode() :: ?SHOW | ?SHOW_EXPORTED | ?ANNOTATE | ?ANNOTATE_INC_FILES. +-type mode() :: ?SHOW | ?SHOW_EXPORTED | ?ANNOTATE | ?ANNOTATE_IN_PLACE | ?ANNOTATE_INC_FILES. %%----------------------------------------------------------------------- @@ -247,7 +248,7 @@ show_or_annotate(#analysis{mode = Mode, fms = Files} = Analysis) -> case Mode of ?SHOW -> show(Analysis); ?SHOW_EXPORTED -> show(Analysis); - ?ANNOTATE -> + Mode when Mode == ?ANNOTATE; Mode == ?ANNOTATE_IN_PLACE -> Fun = fun ({File, Module}) -> Info = get_final_info(File, Module, Analysis), write_typed_file(File, Info, Analysis) @@ -454,7 +455,7 @@ get_functions(File, Analysis) -> ?SHOW_EXPORTED -> Ex_Funcs = map__lookup(File, Analysis#analysis.ex_func), remove_module_info(Ex_Funcs); - ?ANNOTATE -> + Mode when Mode == ?ANNOTATE; Mode == ?ANNOTATE_IN_PLACE -> Funcs = map__lookup(File, Analysis#analysis.func), remove_module_info(Funcs); ?ANNOTATE_INC_FILES -> @@ -478,28 +479,33 @@ write_typed_file(File, Info, Analysis) -> Dir = filename:dirname(File), RootName = filename:basename(filename:rootname(File)), Ext = filename:extension(File), - TyperAnnDir = filename:join(Dir, ?TYPER_ANN_DIR), - TmpNewFilename = lists:concat([RootName, ".ann", Ext]), - NewFileName = filename:join(TyperAnnDir, TmpNewFilename), - case file:make_dir(TyperAnnDir) of - {error, Reason} -> - case Reason of - eexist -> %% TypEr dir exists; remove old typer files if they exist - delete_file(NewFileName, Analysis), - write_typed_file(File, Info, NewFileName, Analysis); - enospc -> - Msg = io_lib:format("Not enough space in ~tp", [Dir]), - fatal_error(Msg, Analysis); - eacces -> - Msg = io_lib:format("No write permission in ~tp", [Dir]), - fatal_error(Msg, Analysis); - _ -> - Msg = io_lib:format("Unhandled error ~ts when writing ~tp", - [Reason, Dir]), - fatal_error(Msg, Analysis) - end; - ok -> %% Typer dir does NOT exist - write_typed_file(File, Info, NewFileName, Analysis) + case Analysis#analysis.mode of + ?ANNOTATE_IN_PLACE -> + write_typed_file(File, Info, File, Analysis); + _ -> + TyperAnnDir = filename:join(Dir, ?TYPER_ANN_DIR), + TmpNewFilename = lists:concat([RootName, ".ann", Ext]), + NewFileName = filename:join(TyperAnnDir, TmpNewFilename), + case file:make_dir(TyperAnnDir) of + {error, Reason} -> + case Reason of + eexist -> %% TypEr dir exists; remove old typer files if they exist + delete_file(NewFileName, Analysis), + write_typed_file(File, Info, NewFileName, Analysis); + enospc -> + Msg = io_lib:format("Not enough space in ~tp", [Dir]), + fatal_error(Msg, Analysis); + eacces -> + Msg = io_lib:format("No write permission in ~tp", [Dir]), + fatal_error(Msg, Analysis); + _ -> + Msg = io_lib:format("Unhandled error ~ts when writing ~tp", + [Reason, Dir]), + fatal_error(Msg, Analysis) + end; + ok -> %% Typer dir does NOT exist + write_typed_file(File, Info, NewFileName, Analysis) + end end. -spec delete_file(file:filename_all(), analysis()) -> ok. @@ -516,6 +522,12 @@ delete_file(File, Analysis) -> write_typed_file(File, Info, NewFileName, Analysis) -> {ok, Binary} = file:read_file(File), + case Analysis#analysis.mode of + ?ANNOTATE_IN_PLACE -> + delete_file(NewFileName, Analysis); + _ -> + ok + end, Chars = unicode:characters_to_list(Binary), write_typed_file(Chars, NewFileName, Info, 1, [], Analysis), msg(info, " Saved as: ~tp", [NewFileName], Analysis). @@ -548,9 +560,19 @@ write_typed_file([Ch|Chs] = Chars, File, Info, LineNo, Acc, Analysis) -> end end. -raw_write(F, A, Info, File, Content, Analysis) -> +raw_write(F, A, Info, File, Content, #analysis{mode = Mode} = Analysis) -> TypeInfo = get_type_string(F, A, Info, file, Analysis), - ContentList = lists:reverse(Content) ++ TypeInfo ++ "\n", + ContentList = + case {TypeInfo, Mode} of + %% TypeInfo will be an empty string for functions that already have specs. + %% In this case, when annotating directly on the files (with annotate_in_place), + %% we don't want to add a newline character on the spec line, as presumably it should + %% already have one. + {"", ?ANNOTATE_IN_PLACE} -> + lists:reverse(Content) ++ TypeInfo; + _ -> + lists:reverse(Content) ++ TypeInfo ++ "\n" + end, ContentBin = unicode:characters_to_binary(ContentList), file:write_file(File, ContentBin, [append]). -- 2.34.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor