From e5de42fd87418ab995629f50f8ecf16f66678d9f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:31:26 +0100 Subject: [PATCH 001/103] Configuration for Refactor Erl Node --- apps/els_core/src/els_config.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 3fca71a2b..530f27cbd 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -55,7 +55,8 @@ | elvis_config_path | indexing_enabled | bsp_enabled - | compiler_telemetry_enabled. + | compiler_telemetry_enabled + | refactorerl. -type path() :: file:filename(). -type state() :: #{ apps_dirs => [path()] @@ -76,6 +77,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() + , refactorerl => {atom(), atom() | 'disabled'} }. %%============================================================================== @@ -126,6 +128,8 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), + RefactorErl = {config, maps:get("refactorerl", Config, disabled)}, + %% Passed by the LSP client ok = set(root_uri , RootUri), %% Read from the configuration file @@ -165,6 +169,8 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> %% Init Options ok = set(capabilities , Capabilities), ok = set(indexing_enabled, IndexingEnabled), + + ok = set(refactorerl, RefactorErl), ok. -spec start_link() -> {ok, pid()}. From 82dfd3bbf04dc04e2a642cbef95dff35f1d1014d Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:31:45 +0100 Subject: [PATCH 002/103] Referl unused macros with basic node detect --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../els_referl_unused_macros_diagnostics.erl | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 37101941e..9e02718e3 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -64,6 +64,7 @@ available_diagnostics() -> , <<"elvis">> , <<"unused_includes">> , <<"unused_macros">> + , <<"referl_unused_macros">> , <<"unused_record_fields">> ]. diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl new file mode 100644 index 000000000..9515abd2f --- /dev/null +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -0,0 +1,135 @@ +%%============================================================================== +%% Unused Macros diagnostics by Referl +%%============================================================================== +-module(els_referl_unused_macros_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). +-define(TIME_OUT, 3000). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + {badrpc, _} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), + []; + error -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + _ -> + ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], ?TIME_OUT), % TODO: Robi sq run második paramba @ utén + Pois = convertToPoi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois] + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"UnusedMacros_RefactorErl">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, MacroName} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom2, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, macro, Id, MacroName), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] +end. + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + MacroName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Unused macro: ", MacroName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Separate timeout issues + badrpc; + _ -> + error + end. From 10f88b8db7b3bfc4eca69e2f6784145bd223c792 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:53:50 +0100 Subject: [PATCH 003/103] source() formatted --- apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 9515abd2f..6600ce870 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -67,7 +67,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"UnusedMacros_RefactorErl">>. + <<"Unused Macros (Referl)">>. %%============================================================================== %% Internal Functions @@ -107,7 +107,7 @@ referl_node() -> error -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), disabled; - badrpc -> % TODO: Try other nodes. (default nodes like: referl@host) + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), disabled; Node -> @@ -128,7 +128,7 @@ referl_node(Node) -> Node; ok-> Node; - {badrpc, _} -> %TODO: Separate timeout issues + {badrpc, _} -> %TODO: Robi Separate timeout issues badrpc; _ -> error From 78c8a94d61ced96068a21c89d242db0a8f0ad99f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:54:04 +0100 Subject: [PATCH 004/103] Unsecure Calls by RefactorErl --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../els_referl_unsecure_calls_diagnostics.erl | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 9e02718e3..252cdef54 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -65,6 +65,7 @@ available_diagnostics() -> , <<"unused_includes">> , <<"unused_macros">> , <<"referl_unused_macros">> + , <<"referl_unsecure_calls">> , <<"unused_record_fields">> ]. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl new file mode 100644 index 000000000..34878caf8 --- /dev/null +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -0,0 +1,137 @@ +%%============================================================================== +%% Unsecure Calls by Referl +%%============================================================================== +-module(els_referl_unsecure_calls_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). +-define(TIME_OUT, 3000). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + {badrpc, _} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), + []; + error -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + _ -> + ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), + Pois = convertToPoi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois] + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"Unsecure Calls (Referl)">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Security Issue: ", IssueName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Robi Separate timeout issues + badrpc; + _ -> + error + end. \ No newline at end of file From 70ba79842da3293265084c35dc23b84cdaac4af7 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 22:17:13 +0100 Subject: [PATCH 005/103] Behaviour basic approach --- apps/els_lsp/src/els_referl.erl | 79 +++++++++++++++++++ .../els_referl_unused_macros_diagnostics.erl | 62 ++------------- 2 files changed, 85 insertions(+), 56 deletions(-) create mode 100644 apps/els_lsp/src/els_referl.erl diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_referl.erl new file mode 100644 index 000000000..76b5863ae --- /dev/null +++ b/apps/els_lsp/src/els_referl.erl @@ -0,0 +1,79 @@ +%%============================================================================== +%% Refactor Erl Behavior +%%============================================================================== +-module(els_referl). + +%%============================================================================== +%% API +%%============================================================================== +-export([ convertToPoi/1 + , referl_node/0 + , time_out/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). + +-define(TIME_OUT, 3000). + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Robi Separate timeout issues + badrpc; + _ -> + error + end. + +-spec time_out() -> number(). + time_out() -> + ?TIME_OUT. \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 6600ce870..db014dace 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -7,6 +7,7 @@ %% Behaviours %%============================================================================== -behaviour(els_diagnostics). +-behaviour(els_referl). %%============================================================================== %% Exports @@ -21,7 +22,7 @@ %%============================================================================== -include("els_lsp.hrl"). -define(MAX_RECURSION_DEPTH, 10). --define(TIME_OUT, 3000). + %%============================================================================== %% Callback Functions @@ -39,11 +40,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case referl_node() of + case els_referl:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:time_out()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -52,8 +53,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> run(Uri, RecursionDepth + 1); _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], ?TIME_OUT), % TODO: Robi sq run második paramba @ utén - Pois = convertToPoi(ReferlResult), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_referl:time_out()), % TODO: Robi sq run második paramba @ utén + Pois = els_referl:convertToPoi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; @@ -73,20 +74,6 @@ source() -> %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, MacroName} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom2, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, macro, Id, MacroName), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; - _ -> - [] -end. - -spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . Range = els_protocol:range(PoiRange), @@ -96,40 +83,3 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range Source = source(), els_diagnostics:make_diagnostic(Range, Message, Severity, Source). --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. From 4c0f14cbeaaacb16867979c49bc4b189ffde6753 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Tue, 23 Nov 2021 10:09:50 +0100 Subject: [PATCH 006/103] RefactorErl conversion module --- apps/els_lsp/src/els_referl.erl | 82 +++++++++++++++++++ .../els_referl_unsecure_calls_diagnostics.erl | 62 +------------- .../els_referl_unused_macros_diagnostics.erl | 64 ++------------- 3 files changed, 93 insertions(+), 115 deletions(-) create mode 100644 apps/els_lsp/src/els_referl.erl diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_referl.erl new file mode 100644 index 000000000..639095f9d --- /dev/null +++ b/apps/els_lsp/src/els_referl.erl @@ -0,0 +1,82 @@ +%%============================================================================== +%% Eralang LS & Refactor Erl conversion +%%============================================================================== +-module(els_referl). + +%%============================================================================== +%% API +%%============================================================================== +-export([ convertToPoi/1 + , referl_node/0 + , maxtimeout/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Robi Separate timeout issues + badrpc; + _ -> + error + end. + + +%%============================================================================== +%% Values +%%============================================================================== + +-spec maxtimeout() -> number(). +maxtimeout() -> + 3000. \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index 34878caf8..48a5ae39a 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -21,7 +21,6 @@ %%============================================================================== -include("els_lsp.hrl"). -define(MAX_RECURSION_DEPTH, 10). --define(TIME_OUT, 3000). %%============================================================================== %% Callback Functions @@ -40,11 +39,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case referl_node() of + case els_referl:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -54,7 +53,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = convertToPoi(ReferlResult), + Pois = els_referl:convertToPoi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; @@ -74,20 +73,6 @@ source() -> %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - -spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . Range = els_protocol:range(PoiRange), @@ -95,43 +80,4 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range Message = <<"Security Issue: ", IssueName/binary>>, Severity = ?DIAGNOSTIC_WARNING, Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - - --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. \ No newline at end of file + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 6600ce870..4da70591b 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -7,6 +7,7 @@ %% Behaviours %%============================================================================== -behaviour(els_diagnostics). +%-behaviour(els_referl). %%============================================================================== %% Exports @@ -21,7 +22,7 @@ %%============================================================================== -include("els_lsp.hrl"). -define(MAX_RECURSION_DEPTH, 10). --define(TIME_OUT, 3000). + %%============================================================================== %% Callback Functions @@ -39,11 +40,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case referl_node() of + case els_referl:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -52,8 +53,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> run(Uri, RecursionDepth + 1); _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], ?TIME_OUT), % TODO: Robi sq run második paramba @ utén - Pois = convertToPoi(ReferlResult), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_referl:time_out()), % TODO: Robi sq run második paramba @ utén + Pois = els_referl:convertToPoi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; @@ -62,7 +63,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Can't add module to RefactorErl!">> }), []. -spec source() -> binary(). @@ -73,20 +74,6 @@ source() -> %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, MacroName} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom2, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, macro, Id, MacroName), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; - _ -> - [] -end. - -spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . Range = els_protocol:range(PoiRange), @@ -96,40 +83,3 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range Source = source(), els_diagnostics:make_diagnostic(Range, Message, Severity, Source). --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. From 539b3923f9410c8fa8d786563335a2c532fcc385 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 00:36:33 +0100 Subject: [PATCH 007/103] Nameing conventions --- .../src/{els_referl.erl => els_refactorerl_utis.erl} | 12 ++++++------ .../src/els_referl_unsecure_calls_diagnostics.erl | 6 +++--- .../src/els_referl_unused_macros_diagnostics.erl | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) rename apps/els_lsp/src/{els_referl.erl => els_refactorerl_utis.erl} (93%) diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_refactorerl_utis.erl similarity index 93% rename from apps/els_lsp/src/els_referl.erl rename to apps/els_lsp/src/els_refactorerl_utis.erl index 84d3ee7c2..44c3f911e 100644 --- a/apps/els_lsp/src/els_referl.erl +++ b/apps/els_lsp/src/els_refactorerl_utis.erl @@ -1,12 +1,12 @@ %%============================================================================== %% Eralang LS & Refactor Erl conversion %%============================================================================== --module(els_referl). +-module(els_refactorerl_utis). %%============================================================================== %% API %%============================================================================== --export([ convertToPoi/1 +-export([ convert_to_poi/1 , referl_node/0 , maxtimeout/0 ]). @@ -20,16 +20,16 @@ %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> +-spec convert_to_poi(any()) -> poi(). +convert_to_poi(ReferlResult) -> case ReferlResult of [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); + convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; + [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index 48a5ae39a..f7c19aa35 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -39,11 +39,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_referl:referl_node() of + case els_refactorerl_utis:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -53,7 +53,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = els_referl:convertToPoi(ReferlResult), + Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 4da70591b..b168ae493 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -40,11 +40,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_referl:referl_node() of + case els_refactorerl_utis:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -53,8 +53,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> run(Uri, RecursionDepth + 1); _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_referl:time_out()), % TODO: Robi sq run második paramba @ utén - Pois = els_referl:convertToPoi(ReferlResult), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_refactorerl_utis:time_out()), % TODO: Robi sq run második paramba @ utén + Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; From 222ac7505e318e44b9398a49d972d1ffd687ad6c Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 18:42:43 +0100 Subject: [PATCH 008/103] Changed to map, to extend confiureability --- apps/els_core/src/els_config.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 530f27cbd..6d6d03a24 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -77,7 +77,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => {atom(), atom() | 'disabled'} + , refactorerl => { map() | 'disabled'} }. %%============================================================================== @@ -128,7 +128,7 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), - RefactorErl = {config, maps:get("refactorerl", Config, disabled)}, + RefactorErl = maps:get("refactorerl", Config, disabled), %% Passed by the LSP client ok = set(root_uri , RootUri), From 9e86bc524b9edf201750011be112d24162b68c3f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 18:43:05 +0100 Subject: [PATCH 009/103] Better node detection, utility module --- apps/els_lsp/src/els_refactorerl_utils.erl | 140 ++++++++++++++++++ apps/els_lsp/src/els_refactorerl_utis.erl | 82 ---------- .../els_referl_unsecure_calls_diagnostics.erl | 15 +- .../els_referl_unused_macros_diagnostics.erl | 15 +- 4 files changed, 154 insertions(+), 98 deletions(-) create mode 100644 apps/els_lsp/src/els_refactorerl_utils.erl delete mode 100644 apps/els_lsp/src/els_refactorerl_utis.erl diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl new file mode 100644 index 000000000..ee31af7ff --- /dev/null +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -0,0 +1,140 @@ +%%============================================================================== +%% Eralang LS & Refactor Erl conversion +%%============================================================================== +-module(els_refactorerl_utils). + +%%============================================================================== +%% API +%%============================================================================== +-export([ convert_to_poi/1 + , referl_node/0 + , maxtimeout/0 + , query/1 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec disable_node() -> atom(). +disable_node() -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), + xels_config:set(refactorerl, #{"node" => disabled}), + disabled. + +-spec try_connect_node({validate | retry, atom()}) -> atom(). +try_connect_node({Status, Node}) -> + case {Status, referl_node(Node)} of + {validate, {error, _}} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + disconnected; + {retry, {error, _}} -> + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + disconnected; + {_ ,Node} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, validated}}), + Node + end. + + +-spec query(any()) -> any(). +query(Query) -> + %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) + case referl_node() of + disabled -> + []; + disconnected -> + []; + error -> + []; + {error, _} -> + []; + Node -> + Response = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], Query], maxtimeout()), + case Response of + {badrpc, _} -> + disable_node(); % Returns disabled + error -> + busy; % RefactorErl node is probably busy. + A -> + log(A), + A + end + end. + +-spec log(any()) -> any(). +log(A) -> A. + + +-spec convert_to_poi(any()) -> poi(). +convert_to_poi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convert_to_poi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convert_to_poi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If the node once was validated there will be no display messages. +%% +%% Node can be: +%% - NodeStr +%% - {Status, Node} where both are atoms. +%% - Status can be: +%% - validated: node is running +%% - disconnected: node is not running +%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom(). % Can return: Node | disconnected | disabled +referl_node() -> + case els_config:get(refactorerl) of + #{"node" := {Node, validated}} -> + Node; + #{"node" := {Node, disconnected}} -> + try_connect_node({retry, Node}); + #{"node" := disabled} -> + disabled; + #{"node" := NodeStr} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + try_connect_node({validate, Node}); + A -> %TODO + log(A), + dis + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, timeout} -> + {error, timeout}; + {badrpc, _} -> + {error, badrpc}; + _ -> + {error, other} + end. + + +%%============================================================================== +%% Values +%%============================================================================== + +-spec maxtimeout() -> number(). +maxtimeout() -> + 3000. diff --git a/apps/els_lsp/src/els_refactorerl_utis.erl b/apps/els_lsp/src/els_refactorerl_utis.erl deleted file mode 100644 index 44c3f911e..000000000 --- a/apps/els_lsp/src/els_refactorerl_utis.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%============================================================================== -%% Eralang LS & Refactor Erl conversion -%%============================================================================== --module(els_refactorerl_utis). - -%%============================================================================== -%% API -%%============================================================================== --export([ convert_to_poi/1 - , referl_node/0 - , maxtimeout/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec convert_to_poi(any()) -> poi(). -convert_to_poi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convert_to_poi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. - - -%%============================================================================== -%% Values -%%============================================================================== - --spec maxtimeout() -> number(). -maxtimeout() -> - 3000. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index f7c19aa35..87c70d70d 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -39,21 +39,20 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_refactorerl_utis:referl_node() of + case els_refactorerl_utils:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of - {badrpc, _} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), - []; - error -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + busy -> timer:sleep(1000), run(Uri, RecursionDepth + 1); + disabled -> + []; _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), + ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index b168ae493..8c863d7fc 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -40,21 +40,20 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_refactorerl_utis:referl_node() of + case els_refactorerl_utils:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of - {badrpc, _} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), - []; - error -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + error -> % TODO R ezt is kiemelni timer:sleep(1000), run(Uri, RecursionDepth + 1); + disabled -> + []; _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_refactorerl_utis:time_out()), % TODO: Robi sq run második paramba @ utén - Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), + ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].macros[not .references]"), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; From cf4eaa75dccc5c4365d62c294cd0bbcbe440ce2a Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 19:05:37 +0100 Subject: [PATCH 010/103] Error management unifying. Code reorganisation --- apps/els_lsp/src/els_refactorerl_utils.erl | 117 ++++++++++----------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index ee31af7ff..7aef407fe 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -17,6 +17,36 @@ %%============================================================================== -include("els_lsp.hrl"). +%%============================================================================== +%% API +%%============================================================================== +%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If the node once was validated there will be no display messages. +%% +%% Node can be: +%% - NodeStr +%% - {Status, Node} where both are atoms. +%% - Status can be: +%% - validated: node is running +%% - disconnected: node is not running +%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom() | {error, disconnected} | {error, disabled} | {error, other}. +referl_node() -> + case els_config:get(refactorerl) of + #{"node" := {Node, validated}} -> + Node; + #{"node" := {Node, disconnected}} -> + try_connect_node({retry, Node}); + #{"node" := disabled} -> + {error, disabled}; + #{"node" := NodeStr} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + try_connect_node({validate, Node}); + _ -> + {error, other} + end. + + %%============================================================================== %% Internal Functions %%============================================================================== @@ -24,36 +54,13 @@ -spec disable_node() -> atom(). disable_node() -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), - xels_config:set(refactorerl, #{"node" => disabled}), - disabled. - --spec try_connect_node({validate | retry, atom()}) -> atom(). -try_connect_node({Status, Node}) -> - case {Status, referl_node(Node)} of - {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), - disconnected; - {retry, {error, _}} -> - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), - disconnected; - {_ ,Node} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - els_config:set(refactorerl, #{"node" => {Node, validated}}), - Node - end. - + els_config:set(refactorerl, #{"node" => disabled}), + {error, disabled}. --spec query(any()) -> any(). -query(Query) -> +-spec query(string()) -> list() | {error, disabled}. +query(Query) -> %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) case referl_node() of - disabled -> - []; - disconnected -> - []; - error -> - []; {error, _} -> []; Node -> @@ -63,16 +70,11 @@ query(Query) -> disable_node(); % Returns disabled error -> busy; % RefactorErl node is probably busy. - A -> - log(A), - A + _ -> + Response end end. --spec log(any()) -> any(). -log(A) -> A. - - -spec convert_to_poi(any()) -> poi(). convert_to_poi(ReferlResult) -> case ReferlResult of @@ -87,35 +89,8 @@ case ReferlResult of [] %TODO Robi notify end. -%% If called with no args try to get the node from config. Use the referl_node/1 to validate. -%% If the node once was validated there will be no display messages. -%% -%% Node can be: -%% - NodeStr -%% - {Status, Node} where both are atoms. -%% - Status can be: -%% - validated: node is running -%% - disconnected: node is not running -%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. --spec referl_node() -> atom(). % Can return: Node | disconnected | disabled -referl_node() -> - case els_config:get(refactorerl) of - #{"node" := {Node, validated}} -> - Node; - #{"node" := {Node, disconnected}} -> - try_connect_node({retry, Node}); - #{"node" := disabled} -> - disabled; - #{"node" := NodeStr} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - try_connect_node({validate, Node}); - A -> %TODO - log(A), - dis - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> +-spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). +check_node(Node) -> Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive case Response of {{ok, _}, {error, _}} -> @@ -130,6 +105,22 @@ referl_node(Node) -> {error, other} end. +-spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom() . +try_connect_node({Status, Node}) -> + case {Status, check_node(Node)} of + {validate, {error, _}} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + {error, disconnected}; + {retry, {error, _}} -> + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + {error, disconnected}; + {_ ,Node} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, validated}}), + Node + end. + %%============================================================================== %% Values From c10e70ff6a00cd62f1f06a7976b402886ed45095 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 09:06:27 +0100 Subject: [PATCH 011/103] First run for a common diagnostic module --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../src/els_refactorerl_diagnostics.erl | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 apps/els_lsp/src/els_refactorerl_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 252cdef54..6518a51ec 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -67,6 +67,7 @@ available_diagnostics() -> , <<"referl_unused_macros">> , <<"referl_unsecure_calls">> , <<"unused_record_fields">> + , <<"refactorerl">> ]. -spec default_diagnostics() -> [diagnostic_id()]. diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl new file mode 100644 index 000000000..0e20f3f4a --- /dev/null +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -0,0 +1,114 @@ +%%============================================================================== +%% Unsecure Calls by Referl +%%============================================================================== +-module(els_refactorerl_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + + +%%======================================= +%%======================================= + +%% {id, pre, after} +%% +%% +%% -type diagnostic_id() :: binary(). + +-type refactorerl_diagnostic_id() :: {atom(), [char()], [char()]}. +-type refactorerl_query() :: [char()]. + +-spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. +refactorerl_diagnostics() -> + [ {unused_macros, "mods[name=", "].funs.unsecure_calls"} + , {unsecure_calls, "mods[name=", "].macros[not .references]"} + ]. + + +-spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). +make_query({_, Before, After}, Module) -> + ModuleStr = atom_to_binary(Module), + Before ++ ModuleStr ++ After. + + +-spec run_query(module(),refactorerl_diagnostic_id()) -> ([els_diagnostics:diagnostic()]). +run_query(Module, DiagnosticId) -> + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois]. + + +%%======================================= +%%======================================= +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case els_refactorerl_utils:referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + busy -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + disabled -> + []; + _ -> + Module = list_to_atom(filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri))))), + lists:concat([run_query(Module, DiagnosticId) || DiagnosticId <- refactorerl_diagnostics()]) + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"RefactorErl Diagnostics">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Security Issue: ", IssueName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file From b4f1302683ba2e884e2b963bd52d6f62f4338596 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 09:49:50 +0100 Subject: [PATCH 012/103] Minor fix --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 0e20f3f4a..d31db6cba 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -47,7 +47,7 @@ refactorerl_diagnostics() -> -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). make_query({_, Before, After}, Module) -> - ModuleStr = atom_to_binary(Module), + ModuleStr = atom_to_list(Module), Before ++ ModuleStr ++ After. @@ -71,6 +71,7 @@ run(Uri)-> -spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"HERH!">> }), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of From 44ead24295cff686e1a9889faac054716763c308 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 10:10:46 +0100 Subject: [PATCH 013/103] Commond diagnostic backend --- apps/els_lsp/src/els_diagnostics.erl | 2 - .../src/els_refactorerl_diagnostics.erl | 1 - .../els_referl_unsecure_calls_diagnostics.erl | 82 ------------------ .../els_referl_unused_macros_diagnostics.erl | 84 ------------------- 4 files changed, 169 deletions(-) delete mode 100644 apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl delete mode 100644 apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index df8df271b..f0112b3ca 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -65,8 +65,6 @@ available_diagnostics() -> , <<"elvis">> , <<"unused_includes">> , <<"unused_macros">> - , <<"referl_unused_macros">> - , <<"referl_unsecure_calls">> , <<"unused_record_fields">> , <<"refactorerl">> ]. diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d31db6cba..d99403c38 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -71,7 +71,6 @@ run(Uri)-> -spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"HERH!">> }), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl deleted file mode 100644 index 87c70d70d..000000000 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%============================================================================== -%% Unsecure Calls by Referl -%%============================================================================== --module(els_referl_unsecure_calls_diagnostics). - -%%============================================================================== -%% Behaviours -%%============================================================================== --behaviour(els_diagnostics). - -%%============================================================================== -%% Exports -%%============================================================================== --export([ is_default/0 - , run/1 - , source/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). - -%%============================================================================== -%% Callback Functions -%%============================================================================== - --spec is_default() -> boolean(). -is_default() -> - true. - --spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> - run(Uri, 0). - - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - case filename:extension(Uri) of - <<".erl">> -> - case els_refactorerl_utils:referl_node() of - disabled -> - []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of - busy -> - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> - []; - _ -> - ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois] - end - end; - _ -> - [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), - []. - --spec source() -> binary(). -source() -> - <<"Unsecure Calls (Referl)">>. - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . - Range = els_protocol:range(PoiRange), - IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Security Issue: ", IssueName/binary>>, - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl deleted file mode 100644 index 8c863d7fc..000000000 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ /dev/null @@ -1,84 +0,0 @@ -%%============================================================================== -%% Unused Macros diagnostics by Referl -%%============================================================================== --module(els_referl_unused_macros_diagnostics). - -%%============================================================================== -%% Behaviours -%%============================================================================== --behaviour(els_diagnostics). -%-behaviour(els_referl). - -%%============================================================================== -%% Exports -%%============================================================================== --export([ is_default/0 - , run/1 - , source/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). - - -%%============================================================================== -%% Callback Functions -%%============================================================================== - --spec is_default() -> boolean(). -is_default() -> - true. - --spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> - run(Uri, 0). - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - case filename:extension(Uri) of - <<".erl">> -> - case els_refactorerl_utils:referl_node() of - disabled -> - []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of - error -> % TODO R ezt is kiemelni - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> - []; - _ -> - ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].macros[not .references]"), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois] - end - end; - _ -> - [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Can't add module to RefactorErl!">> }), - []. - --spec source() -> binary(). -source() -> - <<"Unused Macros (Referl)">>. - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . - Range = els_protocol:range(PoiRange), - MacroName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Unused macro: ", MacroName/binary>>, - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - From 5c9e80e40de08a3cf1594aead34c922379aa42e5 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 19:32:58 +0100 Subject: [PATCH 014/103] Styling conventions --- .../src/els_refactorerl_diagnostics.erl | 77 ++++++++++--------- apps/els_lsp/src/els_refactorerl_utils.erl | 72 ++++++++++------- 2 files changed, 86 insertions(+), 63 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d99403c38..5e5b49f4c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -23,69 +23,59 @@ -define(MAX_RECURSION_DEPTH, 10). %%============================================================================== -%% Callback Functions +%% Types %%============================================================================== - - -%%======================================= -%%======================================= - -%% {id, pre, after} -%% -%% -%% -type diagnostic_id() :: binary(). - --type refactorerl_diagnostic_id() :: {atom(), [char()], [char()]}. +-type refactorerl_diagnostic_id() :: {atom(), [char()], [char()], [char()]}. -type refactorerl_query() :: [char()]. --spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unused_macros, "mods[name=", "].funs.unsecure_calls"} - , {unsecure_calls, "mods[name=", "].macros[not .references]"} - ]. +%%============================================================================== +%% Callback Functions +%%============================================================================== + -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, Before, After}, Module) -> +make_query({_, _, Before, After}, Module) -> ModuleStr = atom_to_list(Module), Before ++ ModuleStr ++ After. --spec run_query(module(),refactorerl_diagnostic_id()) -> ([els_diagnostics:diagnostic()]). +-spec run_query(module(), refactorerl_diagnostic_id()) -> + ([els_diagnostics:diagnostic()]). run_query(Module, DiagnosticId) -> + {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois]. + [make_diagnostic(Poi, Message) || Poi <- Pois]. - -%%======================================= -%%======================================= -spec is_default() -> boolean(). is_default() -> true. -spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> +run(Uri) -> run(Uri, 0). --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of - <<".erl">> -> + <<".erl">> -> case els_refactorerl_utils:referl_node() of disabled -> []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + _ -> + case add(Uri) of busy -> timer:sleep(1000), run(Uri, RecursionDepth + 1); disabled -> []; _ -> - Module = list_to_atom(filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri))))), - lists:concat([run_query(Module, DiagnosticId) || DiagnosticId <- refactorerl_diagnostics()]) + FileName = filename:basename(binary_to_list(els_uri:path(Uri))), + Module = list_to_atom(filename:rootname(FileName)), + Diagnostics = refactorerl_diagnostics(), + lists:concat([run_query(Module, DiagId) || DiagId <- Diagnostics]) end end; _ -> @@ -93,7 +83,9 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + Param = #{ type => ?MESSAGE_TYPE_ERROR, + message => <<"Cannot add module to RefactorErl!">> }, + els_server:send_notification(<<"window/showMessage">>, Param), []. -spec source() -> binary(). @@ -104,11 +96,24 @@ source() -> %% Internal Functions %%============================================================================== --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . +-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Range = els_protocol:range(PoiRange), - IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Security Issue: ", IssueName/binary>>, + Message = list_to_binary(DiagMessage ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + +-spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. +refactorerl_diagnostics() -> + [ {unused_macros, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unsecure_calls + , "Unused Macros:" + , "mods[name=" + , "].macros[not .references]" } + ]. + +-spec add(any()) -> atom(). +add(Uri) -> + Param = [binary_to_list(els_uri:path(Uri))], + rpc:call(node(), ri, add, Param, els_refactorerl_utils:maxtimeout()). \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 7aef407fe..b1d4631ae 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -20,18 +20,23 @@ %%============================================================================== %% API %%============================================================================== -%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If called with no args try to get the node from config. +%% Use the referl_node/1 to validate. %% If the node once was validated there will be no display messages. -%% +%% %% Node can be: %% - NodeStr -%% - {Status, Node} where both are atoms. +%% - {Status, Node} where both are atoms. %% - Status can be: %% - validated: node is running %% - disconnected: node is not running -%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. --spec referl_node() -> atom() | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +%% - disabled: RefactorErl is turned off for this session. T +%% his can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom() + | {error, disconnected} + | {error, disabled} + | {error, other}. +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> Node; @@ -40,62 +45,70 @@ referl_node() -> #{"node" := disabled} -> {error, disabled}; #{"node" := NodeStr} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + RT = els_config_runtime:get_name_type(), + Node = els_utils:compose_node_name(NodeStr, RT), try_connect_node({validate, Node}); - _ -> + _ -> {error, other} end. - + %%============================================================================== %% Internal Functions %%============================================================================== -spec disable_node() -> atom(). disable_node() -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_ERROR, + message => <<"RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!">> }), els_config:set(refactorerl, #{"node" => disabled}), {error, disabled}. -spec query(string()) -> list() | {error, disabled}. -query(Query) -> - %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) +query(Query) -> case referl_node() of {error, _} -> []; Node -> - Response = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], Query], maxtimeout()), + P = [{positions, linecol}, {output, msg}], + Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), case Response of {badrpc, _} -> disable_node(); % Returns disabled error -> - busy; % RefactorErl node is probably busy. + busy; % RefactorErl node is probably busy. _ -> Response end end. --spec convert_to_poi(any()) -> poi(). +-spec convert_to_poi(any()) -> poi(). convert_to_poi(ReferlResult) -> case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + [{_, _, _, DataList}] -> convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + Poi = els_poi:new(Range, application, Id, Name), [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. - --spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). + +-spec check_node(atom()) -> {error, timeout} + | {error, badrpc} + | {error, other} + | atom(). check_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive + % Calls the RefactorErl node, to check if it's alive + Response = rpc:call(Node, ri, ls, [], 10000), case Response of {{ok, _}, {error, _}} -> Node; - ok-> + ok -> Node; {badrpc, timeout} -> {error, timeout}; @@ -105,18 +118,23 @@ check_node(Node) -> {error, other} end. --spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom() . +-spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} + | atom(). try_connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_INFO, + message => <<"RefactorErl is not connected!">> }), els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; - {_ ,Node} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + {_, Node} -> + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_INFO, + message => <<"RefactorErl is connected!">> }), els_config:set(refactorerl, #{"node" => {Node, validated}}), Node end. @@ -127,5 +145,5 @@ try_connect_node({Status, Node}) -> %%============================================================================== -spec maxtimeout() -> number(). -maxtimeout() -> +maxtimeout() -> 3000. From ddc2975a5aae15bb2b9dd366181a0e199d580e87 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:15:44 +0100 Subject: [PATCH 015/103] Change 'disabled' to 'notconfigured' This is needed to avoid confusion between disabled which should means, that the node is disabled *on purpose of bad behavior* from notconfigured which self-descriptive --- apps/els_core/src/els_config.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 32f94a8ed..e4102285c 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -77,7 +77,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => { map() | 'disabled'} + , refactorerl => { map() | 'notconfigured'} }. %%============================================================================== @@ -128,7 +128,7 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), - RefactorErl = maps:get("refactorerl", Config, disabled), + RefactorErl = maps:get("refactorerl", Config, notconfigured), %% Passed by the LSP client ok = set(root_uri , RootUri), From a402ea6547b829ad191558fb9d258945b7753516 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:17:52 +0100 Subject: [PATCH 016/103] Documentation and utility functions, fixes Heavy documentation added and new notification utility function The syntax of Node recognition is re-taught to make more sense --- apps/els_lsp/src/els_refactorerl_utils.erl | 97 ++++++++++++++++------ 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index b1d4631ae..f37f157a1 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -10,6 +10,8 @@ , referl_node/0 , maxtimeout/0 , query/1 + , notification/1 + , notification/2 ]). %%============================================================================== @@ -20,10 +22,23 @@ %%============================================================================== %% API %%============================================================================== -%% If called with no args try to get the node from config. -%% Use the referl_node/1 to validate. + +%% @doc +%% Returns the RefactorErl node, if it cannot, it will return error and the cause. +%% It returns the node given in config, if it is alive. +%% First it runs the validation functions, the result of validation will be +%% notified to the user. %% If the node once was validated there will be no display messages. %% +%% The configuration can store the node and its status. +%% - Either a simple NodeString, which needs to be checked and configure +%% - {Node, Status} where boths are atoms +%% Possible statuses: validated, disconnected, disabled +%% 'disabled', when it won't try to reconnect +%% 'disconnected', when it will try to reconnect +%% - notconfigured, the node is not configured in the config file +%% +%% %% Node can be: %% - NodeStr %% - {Status, Node} where both are atoms. @@ -32,22 +47,30 @@ %% - disconnected: node is not running %% - disabled: RefactorErl is turned off for this session. T %% his can happen after an unsuccessfull query attempt. --spec referl_node() -> atom() +-spec referl_node() -> {ok, atom()} | {error, disconnected} | {error, disabled} | {error, other}. referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> - Node; + {ok, Node}; + #{"node" := {Node, disconnected}} -> try_connect_node({retry, Node}); - #{"node" := disabled} -> + + #{"node" := {_, disabled}} -> {error, disabled}; + #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), try_connect_node({validate, Node}); + + disabled -> + notification("RefactorErl is not configured!"), + {error, disabled}; + _ -> {error, other} end. @@ -57,53 +80,66 @@ referl_node() -> %% Internal Functions %%============================================================================== --spec disable_node() -> atom(). -disable_node() -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_ERROR, - message => <<"RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!">> }), - els_config:set(refactorerl, #{"node" => disabled}), +-spec disable_node(atom()) -> atom(). +%%@doc +%% Disables the node given in paramter, also notifes the user. +disable_node(Node) -> + Msg = "RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!", + notification(Msg, ?MESSAGE_TYPE_ERROR), + + els_config:set(refactorerl, #{"node" => {Node, disabled}}), {error, disabled}. + + %%@doc + %% Runs a Query on the RefactorErl node, returns its result if successfull + %% If error happens, it just returns an empty list, as most of times the + %% result then is directly converted to POIs. + %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. query(Query) -> case referl_node() of {error, _} -> []; - Node -> + {ok, Node} -> P = [{positions, linecol}, {output, msg}], Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), case Response of {badrpc, _} -> - disable_node(); % Returns disabled + disable_node(Node); % Returns disabled error -> - busy; % RefactorErl node is probably busy. + []; _ -> Response end end. -spec convert_to_poi(any()) -> poi(). +%%@doc +%% Convert a RefactorErl result to a POI, for the LS system +%% The RefactorErl format is how the refusr_sq:run\3 returns convert_to_poi(ReferlResult) -> case ReferlResult of [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Id = refactorerl_poi, %"{module(), 'atom()', 'arity()''}", Poi = els_poi:new(Range, application, Id, Name), [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. + +%%@doc +%% Calls the RefactorErl node, to check if it's alive using ri:ls() -spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). check_node(Node) -> - % Calls the RefactorErl node, to check if it's alive Response = rpc:call(Node, ri, ls, [], 10000), case Response of {{ok, _}, {error, _}} -> @@ -118,27 +154,38 @@ check_node(Node) -> {error, other} end. +%%@doc +%% Tries to connect to a node +%% When statues is validate, it reports the success, and failure as well, when retry, it won't report. -spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). try_connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_INFO, - message => <<"RefactorErl is not connected!">> }), + notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {_, Node} -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_INFO, - message => <<"RefactorErl is connected!">> }), + notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, #{"node" => {Node, validated}}), - Node + {ok, Node} end. +%%@doc +%% Util for popping up notifications +-spec notification(string(), number()) -> atom(). +notification(Msg, Severity) -> + Param = #{ type => Severity, + message => list_to_binary(Msg) }, + els_server:send_notification(<<"window/showMessage">>, Param). + +-spec notification(string()) -> atom(). +notification(Msg) -> + notification(Msg, ?MESSAGE_TYPE_INFO). + %%============================================================================== %% Values @@ -146,4 +193,4 @@ try_connect_node({Status, Node}) -> -spec maxtimeout() -> number(). maxtimeout() -> - 3000. + 10000. From b3ca287d6247a0c7ecf5031993903b1b01202dd2 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:18:14 +0100 Subject: [PATCH 017/103] Documentation added --- .../src/els_refactorerl_diagnostics.erl | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5e5b49f4c..c0fbdbb7c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -33,7 +33,8 @@ %%============================================================================== - +%%@doc +%% Creates a RefactorErl query from a diagnostic identifier and a module name -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). make_query({_, _, Before, After}, Module) -> ModuleStr = atom_to_list(Module), @@ -83,9 +84,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - Param = #{ type => ?MESSAGE_TYPE_ERROR, - message => <<"Cannot add module to RefactorErl!">> }, - els_server:send_notification(<<"window/showMessage">>, Param), + Msg = "Cannot add module to RefactorErl!", + els_refactorerl_utils:notification(Msg, ?MESSAGE_TYPE_ERROR), []. -spec source() -> binary(). @@ -96,6 +96,9 @@ source() -> %% Internal Functions %%============================================================================== +%%@doc +%% Creates a diagnostic form the Poi data and a Message +%% The severity is only warning. -spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Range = els_protocol:range(PoiRange), @@ -104,16 +107,25 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Source = source(), els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + %%@doc + %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unused_macros, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unsecure_calls +refactorerl_diagnostics() -> % TODO: Make it configureable + [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unsecure_macros , "Unused Macros:" , "mods[name=" , "].macros[not .references]" } ]. --spec add(any()) -> atom(). + %%@doc + %% Adds a module to the RefactorErl node. +-spec add(any()) -> atom(). %TODO: Add .hrl files add(Uri) -> Param = [binary_to_list(els_uri:path(Uri))], - rpc:call(node(), ri, add, Param, els_refactorerl_utils:maxtimeout()). \ No newline at end of file + case els_refactorerl_utils:referl_node() of + {ok, Node} -> + rpc:call(Node, ri, add, Param, els_refactorerl_utils:maxtimeout()); + _ -> + error + end. \ No newline at end of file From 4401ef54fce5e89666dbb2954f793af00fe83393 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 28 Jan 2022 09:20:26 +0100 Subject: [PATCH 018/103] Line length changes --- apps/els_lsp/src/els_refactorerl_utils.erl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index f37f157a1..21b983c21 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -24,10 +24,10 @@ %%============================================================================== %% @doc -%% Returns the RefactorErl node, if it cannot, it will return error and the cause. +%% Returns the RefactorErl node, if it can't, it returns error and its cause. %% It returns the node given in config, if it is alive. -%% First it runs the validation functions, the result of validation will be -%% notified to the user. +%% First it runs the validation functions, the result of validation will be +%% notified to the user. %% If the node once was validated there will be no display messages. %% %% The configuration can store the node and its status. @@ -37,7 +37,7 @@ %% 'disabled', when it won't try to reconnect %% 'disconnected', when it will try to reconnect %% - notconfigured, the node is not configured in the config file -%% +%% %% %% Node can be: %% - NodeStr @@ -61,7 +61,7 @@ referl_node() -> #{"node" := {_, disabled}} -> {error, disabled}; - + #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), @@ -156,7 +156,8 @@ check_node(Node) -> %%@doc %% Tries to connect to a node -%% When statues is validate, it reports the success, and failure as well, when retry, it won't report. +%% When statues is validate, it reports the success, and failure as well, +%% when retry, it won't report. -spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). try_connect_node({Status, Node}) -> From cb0c5fa12431a78641fb50bbee24954ea56b95be Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 2 Feb 2022 19:30:19 +0100 Subject: [PATCH 019/103] Minor changes --- .../src/els_refactorerl_diagnostics.erl | 43 +++++++++---------- apps/els_lsp/src/els_refactorerl_utils.erl | 13 +++--- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index c0fbdbb7c..e992f6403 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Unsecure Calls by Referl +%% RefactorErl Diagnostics %%============================================================================== -module(els_refactorerl_diagnostics). @@ -32,23 +32,6 @@ %% Callback Functions %%============================================================================== - -%%@doc -%% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, _, Before, After}, Module) -> - ModuleStr = atom_to_list(Module), - Before ++ ModuleStr ++ After. - - --spec run_query(module(), refactorerl_diagnostic_id()) -> - ([els_diagnostics:diagnostic()]). -run_query(Module, DiagnosticId) -> - {_, Message, _, _} = DiagnosticId, - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi, Message) || Poi <- Pois]. - -spec is_default() -> boolean(). is_default() -> true. @@ -90,7 +73,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"RefactorErl Diagnostics">>. + <<"RefactorErl">>. %%============================================================================== %% Internal Functions @@ -122,10 +105,26 @@ refactorerl_diagnostics() -> % TODO: Make it configureable %% Adds a module to the RefactorErl node. -spec add(any()) -> atom(). %TODO: Add .hrl files add(Uri) -> - Param = [binary_to_list(els_uri:path(Uri))], + Params = [binary_to_list(els_uri:path(Uri))], case els_refactorerl_utils:referl_node() of {ok, Node} -> - rpc:call(Node, ri, add, Param, els_refactorerl_utils:maxtimeout()); + rpc:call(Node, ri, add, Params, els_refactorerl_utils:maxtimeout()); _ -> error - end. \ No newline at end of file + end. + +%%@doc +%% Creates a RefactorErl query from a diagnostic identifier and a module name +-spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). +make_query({_, _, Before, After}, Module) -> + ModuleStr = atom_to_list(Module), + Before ++ ModuleStr ++ After. + + +-spec run_query(module(), refactorerl_diagnostic_id()) -> + ([els_diagnostics:diagnostic()]). +run_query(Module, DiagnosticId) -> + {_, Message, _, _} = DiagnosticId, + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 21b983c21..b8a8086bc 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Eralang LS & Refactor Erl conversion +%% Erlang LS & Refactor Erl conversion %%============================================================================== -module(els_refactorerl_utils). @@ -57,7 +57,7 @@ referl_node() -> {ok, Node}; #{"node" := {Node, disconnected}} -> - try_connect_node({retry, Node}); + connect_node({retry, Node}); #{"node" := {_, disabled}} -> {error, disabled}; @@ -65,7 +65,7 @@ referl_node() -> #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), - try_connect_node({validate, Node}); + connect_node({validate, Node}); disabled -> notification("RefactorErl is not configured!"), @@ -120,7 +120,7 @@ query(Query) -> %% Convert a RefactorErl result to a POI, for the LS system %% The RefactorErl format is how the refusr_sq:run\3 returns convert_to_poi(ReferlResult) -> -case ReferlResult of +case ReferlResult of % TODO Robi !!! [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> @@ -158,9 +158,9 @@ check_node(Node) -> %% Tries to connect to a node %% When statues is validate, it reports the success, and failure as well, %% when retry, it won't report. --spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} +-spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). -try_connect_node({Status, Node}) -> +connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), @@ -195,3 +195,4 @@ notification(Msg) -> -spec maxtimeout() -> number(). maxtimeout() -> 10000. + From aa5c7870cf0bc979b5a90fb1c9d1cb524f5cad47 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 4 Feb 2022 07:57:37 +0100 Subject: [PATCH 020/103] New, recieve based communication is working --- .../src/els_refactorerl_diagnostics.erl | 2 +- apps/els_lsp/src/els_refactorerl_utils.erl | 54 ++++++++++++++----- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e992f6403..7ef33373e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -126,5 +126,5 @@ make_query({_, _, Before, After}, Module) -> run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + Pois = els_refactorerl_utils:process_result(ReferlResult), [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index b8a8086bc..aedc95652 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -12,6 +12,7 @@ , query/1 , notification/1 , notification/2 + , process_result/1 ]). %%============================================================================== @@ -51,7 +52,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +referl_node() -> % TODO R: use envs case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -98,29 +99,41 @@ disable_node(Node) -> %% result then is directly converted to POIs. %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. -query(Query) -> - case referl_node() of +query(Query) -> % TODO R: remove the case + case referl_node() of {error, _} -> []; {ok, Node} -> - P = [{positions, linecol}, {output, msg}], - Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), - case Response of + DisplayOpt = [{positions, linecol}, {output, msg}], + ReqID = request_id(), + Opts = [ self() + , ReqID + , {transform, semantic_query + , [{ask_missing, false} + , {display_opt, DisplayOpt} + , {start_opt, []} + , {querystr, Query}]} + ], + Resp = rpc:call(Node, reflib_ui_router, request, Opts), + case Resp of {badrpc, _} -> disable_node(Node); % Returns disabled - error -> - []; - _ -> - Response + ok -> + receive + {ReqID, reply, Result} -> Result + end; + deny -> + notification("Query is denied!"), + [] end end. -spec convert_to_poi(any()) -> poi(). %%@doc %% Convert a RefactorErl result to a POI, for the LS system -%% The RefactorErl format is how the refusr_sq:run\3 returns +%% The RefactorErl format is how the refusr_sq:run\3 returns TODO convert_to_poi(ReferlResult) -> -case ReferlResult of % TODO Robi !!! +case ReferlResult of % TODO Robi !!! function clauses [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> @@ -132,6 +145,11 @@ case ReferlResult of % TODO Robi !!! [] %TODO Robi notify end. +%TODO R spec +-spec process_result(any()) -> any(). +process_result({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}) -> + convert_to_poi(L). + %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() @@ -188,6 +206,18 @@ notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). +-spec request_id() -> any(). +request_id() -> % TODO R spec + case referl_node() of + {error, _} -> + nodedown; + {ok, Node} -> + rpc:call(Node, reflib_ui_router, getid, []) + end. + + + + %%============================================================================== %% Values %%============================================================================== From d523dd4fda8663fe2ee9c320c3c328bb03ef353f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:13:11 +0100 Subject: [PATCH 021/103] Working with double diagnositc processing --- .../src/els_refactorerl_diagnostics.erl | 5 ++- apps/els_lsp/src/els_refactorerl_utils.erl | 39 ++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 7ef33373e..1cbcecf8c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -73,7 +73,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"RefactorErl">>. + els_refactorerl_utils:source_name(). %%============================================================================== %% Internal Functions @@ -127,4 +127,5 @@ run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), Pois = els_refactorerl_utils:process_result(ReferlResult), - [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file + Diags = els_refactorerl_utils:make_diagnostics(ReferlResult, Message), + [make_diagnostic(Poi, Message) || Poi <- Pois] ++ Diags. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index aedc95652..c699b2d53 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -13,7 +13,9 @@ , notification/1 , notification/2 , process_result/1 - ]). + , make_diagnostics/2 + , source_name/0 + ]). % TODO exports??? %%============================================================================== %% Includes & Defines @@ -52,7 +54,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> % TODO R: use envs +referl_node() -> % TODO Might be better to use envs in the future case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -99,7 +101,7 @@ disable_node(Node) -> %% result then is directly converted to POIs. %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. -query(Query) -> % TODO R: remove the case +query(Query) -> % TODO: give a second tought to the case case referl_node() of {error, _} -> []; @@ -128,6 +130,28 @@ query(Query) -> % TODO R: remove the case end end. + +%TODO spec + + +-spec make_diagnostics(any(), string()) -> any(). +make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> + Range = #{ from => From, to => To }, + Id = refactorerl_poi, + #{ data := PoiData, range := PoiRange} = els_poi:new(Range, application, Id, Name), % TODO: How to make this line shorter??? + RangeLS = els_protocol:range(PoiRange), + Message = list_to_binary(DiagMsg ++ " " ++ PoiData), + Severity = ?DIAGNOSTIC_WARNING, + Source = source_name(), + Diagnostic = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), % TODO: How to make this line shorter??? + [ Diagnostic | make_diagnostics(Tail, DiagMsg) ]; + +make_diagnostics([], _) -> + []; + +make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? + make_diagnostics(L, DiagMsg). + -spec convert_to_poi(any()) -> poi(). %%@doc %% Convert a RefactorErl result to a POI, for the LS system @@ -206,8 +230,8 @@ notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). --spec request_id() -> any(). -request_id() -> % TODO R spec +-spec request_id() -> nodedown | {reqid | string()}. +request_id() -> case referl_node() of {error, _} -> nodedown; @@ -226,3 +250,8 @@ request_id() -> % TODO R spec maxtimeout() -> 10000. +%TODOcode organisation + +-spec source_name() -> binary(). +source_name() -> + <<"RefactorErl">>. \ No newline at end of file From d0c18bb23b16a7fb3c8c9dad48400fe2ca69d633 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:20:46 +0100 Subject: [PATCH 022/103] Poi conversion and diagnostic making merged --- .../src/els_refactorerl_diagnostics.erl | 18 ++-------- apps/els_lsp/src/els_refactorerl_utils.erl | 33 ++++--------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 1cbcecf8c..28e047a5d 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -79,19 +79,9 @@ source() -> %% Internal Functions %%============================================================================== -%%@doc -%% Creates a diagnostic form the Poi data and a Message -%% The severity is only warning. --spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> - Range = els_protocol:range(PoiRange), - Message = list_to_binary(DiagMessage ++ " " ++ PoiData), - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - %%@doc - %% Returns the available diagnostics of RefactorErl. +%%@doc +%% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. refactorerl_diagnostics() -> % TODO: Make it configureable [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} @@ -126,6 +116,4 @@ make_query({_, _, Before, After}, Module) -> run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:process_result(ReferlResult), - Diags = els_refactorerl_utils:make_diagnostics(ReferlResult, Message), - [make_diagnostic(Poi, Message) || Poi <- Pois] ++ Diags. \ No newline at end of file + els_refactorerl_utils:make_diagnostics(ReferlResult, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index c699b2d53..a37e99746 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -6,13 +6,11 @@ %%============================================================================== %% API %%============================================================================== --export([ convert_to_poi/1 - , referl_node/0 +-export([ referl_node/0 , maxtimeout/0 , query/1 , notification/1 , notification/2 - , process_result/1 , make_diagnostics/2 , source_name/0 ]). % TODO exports??? @@ -132,8 +130,13 @@ query(Query) -> % TODO: give a second tought to the case %TODO spec +% TODO doku +% - +%%@doc +%% Creates a diagnostic form the Poi data and a Message +%% The severity is only warning. +%-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). -spec make_diagnostics(any(), string()) -> any(). make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, @@ -152,28 +155,6 @@ make_diagnostics([], _) -> make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? make_diagnostics(L, DiagMsg). --spec convert_to_poi(any()) -> poi(). -%%@doc -%% Convert a RefactorErl result to a POI, for the LS system -%% The RefactorErl format is how the refusr_sq:run\3 returns TODO -convert_to_poi(ReferlResult) -> -case ReferlResult of % TODO Robi !!! function clauses - [{_, _, _, DataList}] -> - convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = refactorerl_poi, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), - [ Poi | convert_to_poi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - -%TODO R spec --spec process_result(any()) -> any(). -process_result({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}) -> - convert_to_poi(L). - %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() From 73dc49b40907bb0ef91daf8a75ffa61aab501f1f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:42:37 +0100 Subject: [PATCH 023/103] Set default to false --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 28e047a5d..e520a234e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - true. + false. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> From 0119595d2370409b25f11dce8403d39719e3b97d Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:47:17 +0100 Subject: [PATCH 024/103] Get the config out of tuple --- apps/els_core/src/els_config.erl | 2 +- apps/els_lsp/src/els_refactorerl_utils.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index e4102285c..01647408d 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -77,7 +77,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => { map() | 'notconfigured'} + , refactorerl => map() | 'notconfigured' }. %%============================================================================== diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index a37e99746..134131b86 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -73,7 +73,7 @@ referl_node() -> % TODO Might be better to use envs in the future {error, disabled}; _ -> - {error, other} + {error, other} % TODO: maybe check for 'notconfigured' end. From a5748203006b35129f8ff2d12ad7221d376c0896 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:51:20 +0100 Subject: [PATCH 025/103] Specifyng case mathces and no-match cases --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e520a234e..84dac4d41 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -46,9 +46,9 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of - disabled -> + {error, _} -> []; - _ -> + {ok, _} -> case add(Uri) of busy -> timer:sleep(1000), From cd437fa0260012a926f0e84f195b6a72a7e61381 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 14:47:25 +0100 Subject: [PATCH 026/103] Add as a request Moving the adding mechanism under the new communciation model --- .../src/els_refactorerl_diagnostics.erl | 12 ++---- apps/els_lsp/src/els_refactorerl_utils.erl | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 84dac4d41..5bf0059a1 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -83,7 +83,7 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> % TODO: Make it configureable +refactorerl_diagnostics() -> [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} , {unsecure_macros , "Unused Macros:" @@ -93,15 +93,9 @@ refactorerl_diagnostics() -> % TODO: Make it configureable %%@doc %% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). %TODO: Add .hrl files +-spec add(any()) -> atom(). add(Uri) -> - Params = [binary_to_list(els_uri:path(Uri))], - case els_refactorerl_utils:referl_node() of - {ok, Node} -> - rpc:call(Node, ri, add, Params, els_refactorerl_utils:maxtimeout()); - _ -> - error - end. + els_refactorerl_utils:add(Uri). %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 134131b86..598592ce1 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -13,6 +13,7 @@ , notification/2 , make_diagnostics/2 , source_name/0 + , add/1 ]). % TODO exports??? %%============================================================================== @@ -76,6 +77,42 @@ referl_node() -> % TODO Might be better to use envs in the future {error, other} % TODO: maybe check for 'notconfigured' end. +%%@doc +%% Adds a module to the RefactorErl node. +-spec add(any()) -> atom(). +add(Uri) -> + case els_refactorerl_utils:referl_node() of + {ok, Node} -> + Path = [binary_to_list(els_uri:path(Uri))], + ReqID = request_id(), + Resp = rpc:call( Node + , reflib_ui_router + , request + , [self(), ReqID, {add_dir, Path}] ), + case Resp of + {badrpc, _} -> + disable_node(Node); % Returns disabled + ok -> + receive + {ReqID, reply, {ok, _}} -> ok + end; + deny -> + notification("Query is denied!"), + [] + end; + _ -> + error + end. + + + + + + + + + + %%============================================================================== %% Internal Functions From f6517c4671365e46004b9c3ce9b6ee7c1c7999c7 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 15:45:46 +0100 Subject: [PATCH 027/103] Code clearing --- .../src/els_refactorerl_diagnostics.erl | 27 +-- apps/els_lsp/src/els_refactorerl_utils.erl | 173 +++++++++--------- 2 files changed, 95 insertions(+), 105 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5bf0059a1..3f05aaa6c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -20,7 +20,6 @@ %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% Types @@ -38,24 +37,16 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> - run(Uri, 0). - - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> []; {ok, _} -> - case add(Uri) of - busy -> - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> + case els_refactorerl_utils:add(Uri) of + error -> []; - _ -> + ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), Diagnostics = refactorerl_diagnostics(), @@ -64,12 +55,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; _ -> [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - Msg = "Cannot add module to RefactorErl!", - els_refactorerl_utils:notification(Msg, ?MESSAGE_TYPE_ERROR), - []. + end. -spec source() -> binary(). source() -> @@ -91,11 +77,6 @@ refactorerl_diagnostics() -> , "].macros[not .references]" } ]. - %%@doc - %% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). -add(Uri) -> - els_refactorerl_utils:add(Uri). %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 598592ce1..197a44b61 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -7,19 +7,19 @@ %% API %%============================================================================== -export([ referl_node/0 - , maxtimeout/0 , query/1 , notification/1 , notification/2 , make_diagnostics/2 , source_name/0 , add/1 - ]). % TODO exports??? - + ]). + %%============================================================================== %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% API @@ -53,7 +53,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> % TODO Might be better to use envs in the future +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -61,7 +61,7 @@ referl_node() -> % TODO Might be better to use envs in the future #{"node" := {Node, disconnected}} -> connect_node({retry, Node}); - #{"node" := {_, disabled}} -> + #{"node" := {_Node, disabled}} -> {error, disabled}; #{"node" := NodeStr} -> @@ -69,18 +69,25 @@ referl_node() -> % TODO Might be better to use envs in the future Node = els_utils:compose_node_name(NodeStr, RT), connect_node({validate, Node}); - disabled -> + notconfigured -> notification("RefactorErl is not configured!"), {error, disabled}; _ -> - {error, other} % TODO: maybe check for 'notconfigured' + {error, other} end. + %%@doc -%% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). -add(Uri) -> +%% Adds a module to the RefactorErl node. Using the UI router +%% Returns 'ok' if successfull +%% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries +-spec add(uri()) -> atom(). +add(Uri) -> + add(Uri, 0). + +-spec add(uri(), number()) -> atom(). +add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], @@ -91,52 +98,38 @@ add(Uri) -> , [self(), ReqID, {add_dir, Path}] ), case Resp of {badrpc, _} -> - disable_node(Node); % Returns disabled + disable_node(Node), + error; ok -> receive {ReqID, reply, {ok, _}} -> ok end; deny -> - notification("Query is denied!"), - [] + notification("Adding is deined, retry!"), % TODO: Take this out overtime stability proves itself + timer:sleep(1000), + add(Uri, RecursionDepth + 1) end; _ -> error - end. - - - - - + end; +add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), + error. - - - - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec disable_node(atom()) -> atom(). + %%@doc -%% Disables the node given in paramter, also notifes the user. -disable_node(Node) -> - Msg = "RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!", - notification(Msg, ?MESSAGE_TYPE_ERROR), - - els_config:set(refactorerl, #{"node" => {Node, disabled}}), - {error, disabled}. - - - %%@doc - %% Runs a Query on the RefactorErl node, returns its result if successfull - %% If error happens, it just returns an empty list, as most of times the - %% result then is directly converted to POIs. - %% If the node timeouts or badrpc will come back, it disables the node --spec query(string()) -> list() | {error, disabled}. -query(Query) -> % TODO: give a second tought to the case +%% Runs a Query on the RefactorErl node, returns its result if successfull +%% If error happens, it just returns an empty list, as most of times the +%% result then is directly converted to POIs. +%% If the node timeouts or badrpc will come back, it disables the node and +%% stills returns an empty list +-spec query(string()) -> list(). +query(Query) -> + query(Query, 0). + +-spec query(string(), number()) -> list(). +query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> case referl_node() of {error, _} -> []; @@ -154,44 +147,74 @@ query(Query) -> % TODO: give a second tought to the case Resp = rpc:call(Node, reflib_ui_router, request, Opts), case Resp of {badrpc, _} -> - disable_node(Node); % Returns disabled + disable_node(Node), + []; % As most of times it is going to be processed right after. ok -> receive {ReqID, reply, Result} -> Result end; deny -> - notification("Query is denied!"), - [] + timer:sleep(1000), + query(Query, RecursionDepth + 1) end - end. + end; + +query(_Query, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + notification("Cannot execute query on RefactorErl!", ?MESSAGE_TYPE_ERROR), + []. + + +%%@doc +%% Util for popping up notifications +-spec notification(string(), number()) -> atom(). +notification(Msg, Severity) -> + Param = #{ type => Severity, + message => list_to_binary(Msg) }, + els_server:send_notification(<<"window/showMessage">>, Param). +-spec notification(string()) -> atom(). +notification(Msg) -> + notification(Msg, ?MESSAGE_TYPE_INFO). -%TODO spec -% TODO doku -% %%@doc -%% Creates a diagnostic form the Poi data and a Message +%% Creates a list of diagnostics form the RefactorErl results and a message +%% Message can be the same, as this is called per diagnsotic type. %% The severity is only warning. -%-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). --spec make_diagnostics(any(), string()) -> any(). -make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> +-spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. +make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, Id = refactorerl_poi, - #{ data := PoiData, range := PoiRange} = els_poi:new(Range, application, Id, Name), % TODO: How to make this line shorter??? + #{ data := PoiData, range := PoiRange} = + els_poi:new(Range, application, Id, Name), RangeLS = els_protocol:range(PoiRange), Message = list_to_binary(DiagMsg ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), - Diagnostic = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), % TODO: How to make this line shorter??? - [ Diagnostic | make_diagnostics(Tail, DiagMsg) ]; + Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), + [ Diag | make_diagnostics(Tail, DiagMsg) ]; make_diagnostics([], _) -> []; -make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? +make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, + DiagMsg) -> make_diagnostics(L, DiagMsg). +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec disable_node(atom()) -> atom(). +%%@doc +%% Disables the node given in paramter, also notifes the user. +disable_node(Node) -> + Msg = "RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!", + notification(Msg, ?MESSAGE_TYPE_ERROR), + + els_config:set(refactorerl, #{"node" => {Node, disabled}}), + {error, disabled}. %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() @@ -215,8 +238,10 @@ check_node(Node) -> end. %%@doc -%% Tries to connect to a node -%% When statues is validate, it reports the success, and failure as well, +%% Tries to connect to a node. +%% When it status is validate, the node hasn't been checked yet, +%% so it will reports the success, and failure as well, +%% %% when retry, it won't report. -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). @@ -236,18 +261,7 @@ connect_node({Status, Node}) -> end. %%@doc -%% Util for popping up notifications --spec notification(string(), number()) -> atom(). -notification(Msg, Severity) -> - Param = #{ type => Severity, - message => list_to_binary(Msg) }, - els_server:send_notification(<<"window/showMessage">>, Param). - --spec notification(string()) -> atom(). -notification(Msg) -> - notification(Msg, ?MESSAGE_TYPE_INFO). - - +%% Gets a request id from the RefactorErl node, and returns it -spec request_id() -> nodedown | {reqid | string()}. request_id() -> case referl_node() of @@ -257,19 +271,14 @@ request_id() -> rpc:call(Node, reflib_ui_router, getid, []) end. - - + %%============================================================================== %% Values %%============================================================================== --spec maxtimeout() -> number(). -maxtimeout() -> - 10000. - -%TODOcode organisation - +%%@doc +%% Common soruce name for all RefactorErl based backend(s) -spec source_name() -> binary(). source_name() -> <<"RefactorErl">>. \ No newline at end of file From 06bb47c8fc9d0749f87d58cf9c2e20d715e204aa Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sat, 12 Feb 2022 13:10:05 +0100 Subject: [PATCH 028/103] make_diagnostic no result clause This function clause has an importance, when a diagnostic has no result --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 4 ++-- apps/els_lsp/src/els_refactorerl_utils.erl | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 3f05aaa6c..a503b6807 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -70,8 +70,8 @@ source() -> %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. refactorerl_diagnostics() -> - [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unsecure_macros + [ {unsecure_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unused_macros , "Unused Macros:" , "mods[name=" , "].macros[not .references]" } diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 197a44b61..ff5ecb6c0 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -197,6 +197,10 @@ make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> make_diagnostics([], _) -> []; +% This is needed when there is no result from RefactorErl +make_diagnostics({ok,{result,[{result,[{list,[]}]}]}}, _) -> + []; + make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> make_diagnostics(L, DiagMsg). From 7e8cac58e694345eb43dfa539052cfc2ee456a87 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 16:37:03 +0100 Subject: [PATCH 029/103] Diagnostic description made --- .../src/els_refactorerl_diagnostics.erl | 67 ++++++++++++++----- apps/els_lsp/src/els_refactorerl_utils.erl | 15 +++-- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index a503b6807..d128c092a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_id() :: {atom(), [char()], [char()], [char()]}. +-type refactorerl_diagnostic_description() :: {[char()], [char()]}. -type refactorerl_query() :: [char()]. %%============================================================================== @@ -49,8 +49,8 @@ run(Uri) -> ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), - Diagnostics = refactorerl_diagnostics(), - lists:concat([run_query(Module, DiagId) || DiagId <- Diagnostics]) + Diagnostics = enabled_diagnostics(), + lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diagnostics]) end end; _ -> @@ -68,27 +68,58 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. --spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unsecure_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unused_macros - , "Unused Macros:" - , "mods[name=" - , "].macros[not .references]" } - ]. +-spec refactorerl_diagnostics() -> + #{ atom() => refactorerl_diagnostic_description() }. +refactorerl_diagnostics() -> %//? Kérdés: atom szebb kulcsként vagy stringként, mert config stringként adja vissza, konvertáljuk? + #{ + % Unused Macros + "unused_macros" => + {"Unused Macros:", "].macros[not .references]"}, + % Detecting vulnerabilities + "unsecure_calls" => + {"Security Issue", "].funs.unsecure_calls"} + } +. + +-spec diagnostics_config() -> list(). +diagnostics_config() -> + case els_config:get(refactorerl) of + #{"diagnostics" := List} -> + List; + _ -> + [] + end. + +-spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. +enabled_diagnostics() -> + Diagnostics = refactorerl_diagnostics(), + EnabledDiagnostics = diagnostics_config(), + enabled_diagnostics(EnabledDiagnostics, Diagnostics). + + +-spec enabled_diagnostics(list(), map()) -> [refactorerl_diagnostic_description()]. +enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> + case maps:find(ConfigDiag, Diagnostics) of + {ok, Value} -> + [Value] ++ enabled_diagnostics(RemainingDiags, Diagnostics); + error -> + enabled_diagnostics(RemainingDiags, Diagnostics) + end; + +enabled_diagnostics([], _) -> + []. %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, _, Before, After}, Module) -> +-spec make_query(refactorerl_diagnostic_description(), module()) -> refactorerl_query(). +make_query({_, After}, Module) -> ModuleStr = atom_to_list(Module), - Before ++ ModuleStr ++ After. + "mods[name=" ++ ModuleStr ++ After. --spec run_query(module(), refactorerl_diagnostic_id()) -> +-spec run_query(module(), refactorerl_diagnostic_description()) -> ([els_diagnostics:diagnostic()]). -run_query(Module, DiagnosticId) -> - {_, Message, _, _} = DiagnosticId, - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), +run_query(Module, {Message, _} = DiagnosticDesc) -> + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), els_refactorerl_utils:make_diagnostics(ReferlResult, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index ff5ecb6c0..e23964d3e 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -105,7 +105,10 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, {ok, _}} -> ok end; deny -> - notification("Adding is deined, retry!"), % TODO: Take this out overtime stability proves itself + case RecursionDepth of + 0 -> + notification("Adding is deined, retry!") + end, timer:sleep(1000), add(Uri, RecursionDepth + 1) end; @@ -217,7 +220,8 @@ disable_node(Node) -> Reload ELS after you fixed theRefactorErl node!", notification(Msg, ?MESSAGE_TYPE_ERROR), - els_config:set(refactorerl, #{"node" => {Node, disabled}}), + Config = els_config:get(refactorerl), + els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), {error, disabled}. %%@doc @@ -250,17 +254,18 @@ check_node(Node) -> -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). connect_node({Status, Node}) -> + Config = els_config:get(refactorerl), case {Status, check_node(Node)} of {validate, {error, _}} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {_, Node} -> notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), - els_config:set(refactorerl, #{"node" => {Node, validated}}), + els_config:set(refactorerl, Config#{"node" => {Node, validated}}), {ok, Node} end. From 510cd376a2039db16093ac56e94b3b992258fc34 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 16:50:47 +0100 Subject: [PATCH 030/103] Coding conventions --- .../src/els_refactorerl_diagnostics.erl | 22 ++++++------ apps/els_lsp/src/els_refactorerl_utils.erl | 34 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d128c092a..cd73ffce3 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -49,8 +49,8 @@ run(Uri) -> ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), - Diagnostics = enabled_diagnostics(), - lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diagnostics]) + Diags = enabled_diagnostics(), + lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end end; _ -> @@ -70,20 +70,20 @@ source() -> %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> #{ atom() => refactorerl_diagnostic_description() }. -refactorerl_diagnostics() -> %//? Kérdés: atom szebb kulcsként vagy stringként, mert config stringként adja vissza, konvertáljuk? +refactorerl_diagnostics() -> #{ % Unused Macros "unused_macros" => {"Unused Macros:", "].macros[not .references]"}, % Detecting vulnerabilities - "unsecure_calls" => + "unsecure_calls" => {"Security Issue", "].funs.unsecure_calls"} } . -spec diagnostics_config() -> list(). -diagnostics_config() -> +diagnostics_config() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> List; @@ -97,8 +97,9 @@ enabled_diagnostics() -> EnabledDiagnostics = diagnostics_config(), enabled_diagnostics(EnabledDiagnostics, Diagnostics). - --spec enabled_diagnostics(list(), map()) -> [refactorerl_diagnostic_description()]. + +-spec enabled_diagnostics(list(), map()) -> + [refactorerl_diagnostic_description()]. enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> case maps:find(ConfigDiag, Diagnostics) of {ok, Value} -> @@ -112,7 +113,8 @@ enabled_diagnostics([], _) -> %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_description(), module()) -> refactorerl_query(). +-spec make_query(refactorerl_diagnostic_description(), module()) -> + refactorerl_query(). make_query({_, After}, Module) -> ModuleStr = atom_to_list(Module), "mods[name=" ++ ModuleStr ++ After. @@ -121,5 +123,5 @@ make_query({_, After}, Module) -> -spec run_query(module(), refactorerl_diagnostic_description()) -> ([els_diagnostics:diagnostic()]). run_query(Module, {Message, _} = DiagnosticDesc) -> - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), - els_refactorerl_utils:make_diagnostics(ReferlResult, Message). + Result = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), + els_refactorerl_utils:make_diagnostics(Result, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index e23964d3e..d98cf6678 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -14,7 +14,7 @@ , source_name/0 , add/1 ]). - + %%============================================================================== %% Includes & Defines %%============================================================================== @@ -53,7 +53,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -83,7 +83,7 @@ referl_node() -> %% Returns 'ok' if successfull %% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries -spec add(uri()) -> atom(). -add(Uri) -> +add(Uri) -> add(Uri, 0). -spec add(uri(), number()) -> atom(). @@ -120,7 +120,7 @@ add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), error. - + %%@doc %% Runs a Query on the RefactorErl node, returns its result if successfull %% If error happens, it just returns an empty list, as most of times the @@ -132,8 +132,8 @@ query(Query) -> query(Query, 0). -spec query(string(), number()) -> list(). -query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> - case referl_node() of +query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case referl_node() of {error, _} -> []; {ok, Node} -> @@ -141,7 +141,7 @@ query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> ReqID = request_id(), Opts = [ self() , ReqID - , {transform, semantic_query + , {transform, semantic_query , [{ask_missing, false} , {display_opt, DisplayOpt} , {start_opt, []} @@ -189,22 +189,22 @@ make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, Id = refactorerl_poi, #{ data := PoiData, range := PoiRange} = - els_poi:new(Range, application, Id, Name), + els_poi:new(Range, application, Id, Name), RangeLS = els_protocol:range(PoiRange), Message = list_to_binary(DiagMsg ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), - Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), + Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), [ Diag | make_diagnostics(Tail, DiagMsg) ]; make_diagnostics([], _) -> []; % This is needed when there is no result from RefactorErl -make_diagnostics({ok,{result,[{result,[{list,[]}]}]}}, _) -> +make_diagnostics({ok, {result, [{result, [{list, []}]}]}}, _) -> []; -make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, +make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> make_diagnostics(L, DiagMsg). @@ -246,10 +246,10 @@ check_node(Node) -> end. %%@doc -%% Tries to connect to a node. -%% When it status is validate, the node hasn't been checked yet, +%% Tries to connect to a node. +%% When it status is validate, the node hasn't been checked yet, %% so it will reports the success, and failure as well, -%% +%% %% when retry, it won't report. -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). @@ -270,7 +270,7 @@ connect_node({Status, Node}) -> end. %%@doc -%% Gets a request id from the RefactorErl node, and returns it +%% Gets a request id from the RefactorErl node, and returns it -spec request_id() -> nodedown | {reqid | string()}. request_id() -> case referl_node() of @@ -280,14 +280,12 @@ request_id() -> rpc:call(Node, reflib_ui_router, getid, []) end. - - %%============================================================================== %% Values %%============================================================================== %%@doc -%% Common soruce name for all RefactorErl based backend(s) +%% Common soruce name for all RefactorErl based backend(s) -spec source_name() -> binary(). source_name() -> <<"RefactorErl">>. \ No newline at end of file From 177662931f48ea291e449b3b1acc737f555ff9eb Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:32:18 +0100 Subject: [PATCH 031/103] a few dyalizer errors --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 6 +++--- apps/els_lsp/src/els_refactorerl_utils.erl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index cd73ffce3..eef1bcce7 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_description() :: {[char()], [char()]}. +-type refactorerl_diagnostic_description() :: {string(), string()}. -type refactorerl_query() :: [char()]. %%============================================================================== @@ -35,7 +35,7 @@ is_default() -> false. --spec run(uri()) -> [els_diagnostics:diagnostic()]. + -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> case filename:extension(Uri) of <<".erl">> -> @@ -50,7 +50,7 @@ run(Uri) -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), Diags = enabled_diagnostics(), - lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diags]) + lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end end; _ -> diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index d98cf6678..fc5694a11 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -212,7 +212,7 @@ make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, %% Internal Functions %%============================================================================== --spec disable_node(atom()) -> atom(). +-spec disable_node(atom()) -> {error, disabled}. %%@doc %% Disables the node given in paramter, also notifes the user. disable_node(Node) -> From 135e0c17d303527735ec95bff2dba2ab2e6aec1c Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:59:30 +0100 Subject: [PATCH 032/103] Case clause --- apps/els_lsp/src/els_refactorerl_utils.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index fc5694a11..a06a4dfd9 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -107,7 +107,9 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> deny -> case RecursionDepth of 0 -> - notification("Adding is deined, retry!") + notification("Adding is deined, retry!"); + _ -> + notified_already end, timer:sleep(1000), add(Uri, RecursionDepth + 1) From 5f22e9bdc7562e82a24efd2b719665f767aadeda Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:59:42 +0100 Subject: [PATCH 033/103] Function spec --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index eef1bcce7..e0d61acb8 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -69,7 +69,7 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> - #{ atom() => refactorerl_diagnostic_description() }. + #{ string() => refactorerl_diagnostic_description() }. refactorerl_diagnostics() -> #{ % Unused Macros From 7e0a3d4364e6fdac48bccb6d8b1f27ecde25a31d Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 17 Feb 2022 07:56:25 +0100 Subject: [PATCH 034/103] POI removal --- apps/els_lsp/src/els_refactorerl_utils.erl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index a06a4dfd9..747d43a60 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -189,11 +189,8 @@ notification(Msg) -> -spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, - Id = refactorerl_poi, - #{ data := PoiData, range := PoiRange} = - els_poi:new(Range, application, Id, Name), - RangeLS = els_protocol:range(PoiRange), - Message = list_to_binary(DiagMsg ++ " " ++ PoiData), + RangeLS = els_protocol:range(Range), + Message = list_to_binary(DiagMsg ++ " " ++ Name), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), From cbee72a5b71a74aac76681b90a0a8ed4bb253969 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 17 Feb 2022 07:57:31 +0100 Subject: [PATCH 035/103] Diagnostic descriptor change This is due to preparing to new diagnostics --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e0d61acb8..f2a80a1b5 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -76,9 +76,9 @@ refactorerl_diagnostics() -> "unused_macros" => {"Unused Macros:", "].macros[not .references]"}, - % Detecting vulnerabilities - "unsecure_calls" => - {"Security Issue", "].funs.unsecure_calls"} + % Checks for OS injection + "unsecure_os_call" => + {"Unsecure OS call:", "].funs.unsecure_os_call"} } . From ef7480a1e1c98f5dffd9685a23ce34bc0a8022d2 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 17 Feb 2022 21:23:03 +0100 Subject: [PATCH 036/103] Retry removal, smaller fixes --- .../src/els_refactorerl_diagnostics.erl | 3 +- apps/els_lsp/src/els_refactorerl_utils.erl | 47 +++++-------------- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index f2a80a1b5..52a6abd65 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -47,8 +47,7 @@ run(Uri) -> error -> []; ok -> - FileName = filename:basename(binary_to_list(els_uri:path(Uri))), - Module = list_to_atom(filename:rootname(FileName)), + Module = els_uri:module(Uri), Diags = enabled_diagnostics(), lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 747d43a60..9971adc10 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -19,7 +19,6 @@ %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% API @@ -82,16 +81,12 @@ referl_node() -> %% Adds a module to the RefactorErl node. Using the UI router %% Returns 'ok' if successfull %% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries --spec add(uri()) -> atom(). +-spec add(uri()) -> error | ok. add(Uri) -> - add(Uri, 0). - --spec add(uri(), number()) -> atom(). -add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], - ReqID = request_id(), + {ok, ReqID} = request_id(), Resp = rpc:call( Node , reflib_ui_router , request @@ -105,22 +100,12 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, {ok, _}} -> ok end; deny -> - case RecursionDepth of - 0 -> - notification("Adding is deined, retry!"); - _ -> - notified_already - end, - timer:sleep(1000), - add(Uri, RecursionDepth + 1) + error end; _ -> error - end; + end. -add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), - error. %%@doc @@ -130,17 +115,13 @@ add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> %% If the node timeouts or badrpc will come back, it disables the node and %% stills returns an empty list -spec query(string()) -> list(). -query(Query) -> - query(Query, 0). - --spec query(string(), number()) -> list(). -query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> +query(Query) -> case referl_node() of {error, _} -> []; {ok, Node} -> DisplayOpt = [{positions, linecol}, {output, msg}], - ReqID = request_id(), + {ok, ReqID} = request_id(), Opts = [ self() , ReqID , {transform, semantic_query @@ -159,15 +140,9 @@ query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, Result} -> Result end; deny -> - timer:sleep(1000), - query(Query, RecursionDepth + 1) + [] end - end; - -query(_Query, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - notification("Cannot execute query on RefactorErl!", ?MESSAGE_TYPE_ERROR), - []. - + end. %%@doc %% Util for popping up notifications @@ -270,13 +245,13 @@ connect_node({Status, Node}) -> %%@doc %% Gets a request id from the RefactorErl node, and returns it --spec request_id() -> nodedown | {reqid | string()}. +-spec request_id() -> {error, nodedown} | {ok, {reqid | string()}}. request_id() -> case referl_node() of {error, _} -> - nodedown; + {error, nodedown}; {ok, Node} -> - rpc:call(Node, reflib_ui_router, getid, []) + {ok, rpc:call(Node, reflib_ui_router, getid, [])} end. %%============================================================================== From 42d0a4cbfe79db3504886e802ca1fae621662690 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:15:00 +0100 Subject: [PATCH 037/103] Working logic, cleaning out... --- .../src/els_refactorerl_diagnostics.erl | 57 ++------ apps/els_lsp/src/els_refactorerl_utils.erl | 137 +++++------------- 2 files changed, 50 insertions(+), 144 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 52a6abd65..5f99b9281 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -25,7 +25,7 @@ %% Types %%============================================================================== -type refactorerl_diagnostic_description() :: {string(), string()}. --type refactorerl_query() :: [char()]. +%-type refactorerl_query() :: [char()]. %%============================================================================== %% Callback Functions @@ -49,7 +49,8 @@ run(Uri) -> ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), - lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) + Results = els_refactorerl_utils:run_diagnostics(Diags, Module), + make_diagnostics(Results) end end; _ -> @@ -65,21 +66,9 @@ source() -> %%============================================================================== -%%@doc -%% Returns the available diagnostics of RefactorErl. --spec refactorerl_diagnostics() -> - #{ string() => refactorerl_diagnostic_description() }. -refactorerl_diagnostics() -> - #{ - % Unused Macros - "unused_macros" => - {"Unused Macros:", "].macros[not .references]"}, - % Checks for OS injection - "unsecure_os_call" => - {"Unsecure OS call:", "].funs.unsecure_os_call"} - } -. + +%TODO: add default diagnostics -spec diagnostics_config() -> list(). diagnostics_config() -> @@ -92,35 +81,21 @@ diagnostics_config() -> -spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. enabled_diagnostics() -> - Diagnostics = refactorerl_diagnostics(), + %%Diagnostics = refactorerl_diagnostics(), EnabledDiagnostics = diagnostics_config(), - enabled_diagnostics(EnabledDiagnostics, Diagnostics). + %%enabled_diagnostics(EnabledDiagnostics, Diagnostics). + EnabledDiagnostics. --spec enabled_diagnostics(list(), map()) -> - [refactorerl_diagnostic_description()]. -enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> - case maps:find(ConfigDiag, Diagnostics) of - {ok, Value} -> - [Value] ++ enabled_diagnostics(RemainingDiags, Diagnostics); - error -> - enabled_diagnostics(RemainingDiags, Diagnostics) - end; -enabled_diagnostics([], _) -> - []. -%%@doc -%% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_description(), module()) -> - refactorerl_query(). -make_query({_, After}, Module) -> - ModuleStr = atom_to_list(Module), - "mods[name=" ++ ModuleStr ++ After. +-spec make_diagnostics(any()) -> any(). +make_diagnostics([{Range, Message} | Tail]) -> + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + Diag = els_diagnostics:make_diagnostic(Range, Message, Severity, Source), + [ Diag | make_diagnostics(Tail) ]; --spec run_query(module(), refactorerl_diagnostic_description()) -> - ([els_diagnostics:diagnostic()]). -run_query(Module, {Message, _} = DiagnosticDesc) -> - Result = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), - els_refactorerl_utils:make_diagnostics(Result, Message). +make_diagnostics([]) -> + []. diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 9971adc10..2d57cc2f9 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -7,10 +7,11 @@ %% API %%============================================================================== -export([ referl_node/0 - , query/1 + %, query/1 , notification/1 , notification/2 - , make_diagnostics/2 + %, make_diagnostics/2 + , run_diagnostics/2 , source_name/0 , add/1 ]). @@ -86,64 +87,23 @@ add(Uri) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], - {ok, ReqID} = request_id(), - Resp = rpc:call( Node - , reflib_ui_router - , request - , [self(), ReqID, {add_dir, Path}] ), - case Resp of - {badrpc, _} -> - disable_node(Node), - error; - ok -> - receive - {ReqID, reply, {ok, _}} -> ok - end; - deny -> - error - end; + rpc:call(Node, referl_els, add, [Path]); %% returns error | ok _ -> error end. -%%@doc -%% Runs a Query on the RefactorErl node, returns its result if successfull -%% If error happens, it just returns an empty list, as most of times the -%% result then is directly converted to POIs. -%% If the node timeouts or badrpc will come back, it disables the node and -%% stills returns an empty list --spec query(string()) -> list(). -query(Query) -> - case referl_node() of - {error, _} -> - []; +-spec run_diagnostics(any(), any()) -> any(). %TODO: typing +run_diagnostics(DiagnosticAliases, Module) -> + case els_refactorerl_utils:referl_node() of {ok, Node} -> - DisplayOpt = [{positions, linecol}, {output, msg}], - {ok, ReqID} = request_id(), - Opts = [ self() - , ReqID - , {transform, semantic_query - , [{ask_missing, false} - , {display_opt, DisplayOpt} - , {start_opt, []} - , {querystr, Query}]} - ], - Resp = rpc:call(Node, reflib_ui_router, request, Opts), - case Resp of - {badrpc, _} -> - disable_node(Node), - []; % As most of times it is going to be processed right after. - ok -> - receive - {ReqID, reply, Result} -> Result - end; - deny -> - [] - end + rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); %% returns error | ok + _ -> % In this case there was probably error. + [] end. + %%@doc %% Util for popping up notifications -spec notification(string(), number()) -> atom(). @@ -161,64 +121,46 @@ notification(Msg) -> %% Creates a list of diagnostics form the RefactorErl results and a message %% Message can be the same, as this is called per diagnsotic type. %% The severity is only warning. --spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. -make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> - Range = #{ from => From, to => To }, - RangeLS = els_protocol:range(Range), - Message = list_to_binary(DiagMsg ++ " " ++ Name), - Severity = ?DIAGNOSTIC_WARNING, - Source = source_name(), - Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), - [ Diag | make_diagnostics(Tail, DiagMsg) ]; - -make_diagnostics([], _) -> - []; - -% This is needed when there is no result from RefactorErl -make_diagnostics({ok, {result, [{result, [{list, []}]}]}}, _) -> - []; -make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, - DiagMsg) -> - make_diagnostics(L, DiagMsg). %%============================================================================== %% Internal Functions %%============================================================================== --spec disable_node(atom()) -> {error, disabled}. +%-spec disable_node(atom()) -> {error, disabled}. %%@doc %% Disables the node given in paramter, also notifes the user. -disable_node(Node) -> - Msg = "RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!", - notification(Msg, ?MESSAGE_TYPE_ERROR), +%%disable_node(Node) -> +%% Msg = "RefactorErl is disconnected! +%% Reload ELS after you fixed theRefactorErl node!", +%% notification(Msg, ?MESSAGE_TYPE_ERROR), +%% +%% Config = els_config:get(refactorerl), +%% els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), +%% {error, disabled}. + +-spec is_refactorerl(atom()) -> boolean(). +is_refactorerl(Node) -> + case pc:call(Node, referl_els, ping, [], 500) of + {refactorerl_els, pong} -> true; + _ -> false + end. - Config = els_config:get(refactorerl), - els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), - {error, disabled}. %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() --spec check_node(atom()) -> {error, timeout} - | {error, badrpc} - | {error, other} +-spec check_node(atom()) -> error | atom(). check_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), - case Response of - {{ok, _}, {error, _}} -> - Node; - ok -> + case is_refactorerl(Node) of + true -> Node; - {badrpc, timeout} -> - {error, timeout}; - {badrpc, _} -> - {error, badrpc}; - _ -> - {error, other} + false -> + error end. + + %%@doc %% Tries to connect to a node. %% When it status is validate, the node hasn't been checked yet, @@ -243,17 +185,6 @@ connect_node({Status, Node}) -> {ok, Node} end. -%%@doc -%% Gets a request id from the RefactorErl node, and returns it --spec request_id() -> {error, nodedown} | {ok, {reqid | string()}}. -request_id() -> - case referl_node() of - {error, _} -> - {error, nodedown}; - {ok, Node} -> - {ok, rpc:call(Node, reflib_ui_router, getid, [])} - end. - %%============================================================================== %% Values %%============================================================================== From ca7e3a6d778a6b8ebc28f35dee06a7f27ffe147e Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:38:15 +0100 Subject: [PATCH 038/103] Cleaned out --- .../src/els_refactorerl_diagnostics.erl | 42 +++++++------- apps/els_lsp/src/els_refactorerl_utils.erl | 55 ++++--------------- 2 files changed, 33 insertions(+), 64 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5f99b9281..8a15d1b74 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,8 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_description() :: {string(), string()}. +-type refactorerl_diagnostic_alias() :: string(). +-type refactorerl_diagnostic_result() :: {range(), string()}. %-type refactorerl_query() :: [char()]. %%============================================================================== @@ -35,7 +36,7 @@ is_default() -> false. - -spec run(uri()) -> [els_diagnostics:diagnostic()]. +-spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> case filename:extension(Uri) of <<".erl">> -> @@ -64,33 +65,36 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== - - - - -%TODO: add default diagnostics - --spec diagnostics_config() -> list(). -diagnostics_config() -> +%% +% @doc +% Returns the enabled diagnostic aliases from config +-spec configured_diagnostics() -> sets:set(). +configured_diagnostics() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> - List; + sets:from_list(List); _ -> [] end. --spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. -enabled_diagnostics() -> - %%Diagnostics = refactorerl_diagnostics(), - EnabledDiagnostics = diagnostics_config(), - %%enabled_diagnostics(EnabledDiagnostics, Diagnostics). - EnabledDiagnostics. - +% @doc +% Returns the default diagnostic aliases +-spec default_diagnostics() -> sets:set(). +default_diagnostics() -> + ets:from_list(["unused_macros", "unsecure_os_calls"]). +% @doc +% Returns the enabled diagnostics by merging default and configed +-spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. +enabled_diagnostics() -> + Set = sets:union(default_diagnostics(), configured_diagnostics()), + sets:to_list(Set). --spec make_diagnostics(any()) -> any(). +% @doc +% Constructs the ELS diagnostic from RefactorErl result +-spec make_diagnostics([refactorerl_diagnostic_result()]) -> any(). make_diagnostics([{Range, Message} | Tail]) -> Severity = ?DIAGNOSTIC_WARNING, Source = source(), diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 2d57cc2f9..85895807a 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Erlang LS & Refactor Erl conversion +%% Erlang LS & Refactor Erl communication %%============================================================================== -module(els_refactorerl_utils). @@ -7,10 +7,8 @@ %% API %%============================================================================== -export([ referl_node/0 - %, query/1 , notification/1 , notification/2 - %, make_diagnostics/2 , run_diagnostics/2 , source_name/0 , add/1 @@ -81,7 +79,7 @@ referl_node() -> %%@doc %% Adds a module to the RefactorErl node. Using the UI router %% Returns 'ok' if successfull -%% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries +%% Returns 'error' if it fails -spec add(uri()) -> error | ok. add(Uri) -> case els_refactorerl_utils:referl_node() of @@ -92,9 +90,9 @@ add(Uri) -> error end. - - --spec run_diagnostics(any(), any()) -> any(). %TODO: typing +%%@doc +%% Runs list of diagnostic aliases on refactorerl +-spec run_diagnostics(list(), atom()) -> list(). run_diagnostics(DiagnosticAliases, Module) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> @@ -103,7 +101,6 @@ run_diagnostics(DiagnosticAliases, Module) -> [] end. - %%@doc %% Util for popping up notifications -spec notification(string(), number()) -> atom(). @@ -116,29 +113,12 @@ notification(Msg, Severity) -> notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). - -%%@doc -%% Creates a list of diagnostics form the RefactorErl results and a message -%% Message can be the same, as this is called per diagnsotic type. -%% The severity is only warning. - - %%============================================================================== %% Internal Functions %%============================================================================== -%-spec disable_node(atom()) -> {error, disabled}. %%@doc -%% Disables the node given in paramter, also notifes the user. -%%disable_node(Node) -> -%% Msg = "RefactorErl is disconnected! -%% Reload ELS after you fixed theRefactorErl node!", -%% notification(Msg, ?MESSAGE_TYPE_ERROR), -%% -%% Config = els_config:get(refactorerl), -%% els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), -%% {error, disabled}. - +%% Checks if the given node is running RefactorErl with ELS interface -spec is_refactorerl(atom()) -> boolean(). is_refactorerl(Node) -> case pc:call(Node, referl_els, ping, [], 500) of @@ -146,21 +126,6 @@ is_refactorerl(Node) -> _ -> false end. - -%%@doc -%% Calls the RefactorErl node, to check if it's alive using ri:ls() --spec check_node(atom()) -> error - | atom(). -check_node(Node) -> - case is_refactorerl(Node) of - true -> - Node; - false -> - error - end. - - - %%@doc %% Tries to connect to a node. %% When it status is validate, the node hasn't been checked yet, @@ -171,15 +136,15 @@ check_node(Node) -> | atom(). connect_node({Status, Node}) -> Config = els_config:get(refactorerl), - case {Status, check_node(Node)} of - {validate, {error, _}} -> + case {Status, is_refactorerl(Node)} of + {validate, false} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; - {retry, {error, _}} -> + {retry, false} -> els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; - {_, Node} -> + {_, true} -> notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, validated}}), {ok, Node} From 9ff8845b8aa755db6cdd653202c7b33f1d140f53 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:55:21 +0100 Subject: [PATCH 039/103] Linting --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 8 ++++---- apps/els_lsp/src/els_refactorerl_utils.erl | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 8a15d1b74..e1cee0c9e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -65,7 +65,7 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== -%% + % @doc % Returns the enabled diagnostic aliases from config -spec configured_diagnostics() -> sets:set(). @@ -78,14 +78,14 @@ configured_diagnostics() -> end. % @doc -% Returns the default diagnostic aliases +% Returns the default diagnostic aliases -spec default_diagnostics() -> sets:set(). default_diagnostics() -> - ets:from_list(["unused_macros", "unsecure_os_calls"]). + sets:from_list(["unused_macros", "unsecure_os_calls"]). % @doc -% Returns the enabled diagnostics by merging default and configed +% Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> Set = sets:union(default_diagnostics(), configured_diagnostics()), diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 85895807a..94a64c508 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -92,11 +92,12 @@ add(Uri) -> %%@doc %% Runs list of diagnostic aliases on refactorerl --spec run_diagnostics(list(), atom()) -> list(). +-spec run_diagnostics(list(), atom()) -> list(). run_diagnostics(DiagnosticAliases, Module) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> - rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); %% returns error | ok + %% returns error | ok + rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); _ -> % In this case there was probably error. [] end. @@ -121,7 +122,7 @@ notification(Msg) -> %% Checks if the given node is running RefactorErl with ELS interface -spec is_refactorerl(atom()) -> boolean(). is_refactorerl(Node) -> - case pc:call(Node, referl_els, ping, [], 500) of + case rpc:call(Node, referl_els, ping, [], 500) of {refactorerl_els, pong} -> true; _ -> false end. From e17a4ef3070db9f82fca167f9d335629640de328 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 24 Feb 2022 07:33:25 +0100 Subject: [PATCH 040/103] Test drafts --- apps/els_lsp/test/els_diagnostics_SUITE.erl | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 928c82205..7e7de016a 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -39,6 +39,7 @@ , unused_includes_compiler_attribute/1 , exclude_unused_includes/1 , unused_macros/1 + , unused_macros_refactorerl/1 , unused_record_fields/1 , gradualizer/1 ]). @@ -123,6 +124,12 @@ init_per_testcase(TestCase, Config) when TestCase =:= gradualizer -> meck:expect(els_gradualizer_diagnostics, is_default, 0, true), els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config); + +% RefactorErl +init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> + io:format("INIT"), + els_test_utils:init_per_testcase(TestCase, Config); + init_per_testcase(TestCase, Config) -> els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config). @@ -654,6 +661,24 @@ gradualizer(_Config) -> Hints = [], els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). + + +% RefactorErl test cases +-spec unused_macros_refactorerl(config()) -> ok. +unused_macros_refactorerl(_Config) -> + Path = src_path("diagnostics_unused_macros.erl"), + Source = <<"RefactorErl">>, + Errors = [], + Warnings = [ #{ message => <<"Unused macro: UNUSED_MACRO">> + , range => {{5, 8}, {5, 20}} + }, + #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG/1">> + , range => {{6, 8}, {6, 29}} + } + ], + Hints = [], + els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). + %%============================================================================== %% Internal Functions %%============================================================================== From c68589fa14465ff909b5b3401e903115de101b6e Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 24 Feb 2022 08:17:46 +0100 Subject: [PATCH 041/103] Timeouting test cases --- .../src/els_refactorerl_diagnostics.erl | 11 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 90 ++++++++++++++++++- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e1cee0c9e..cbfbca45b 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - false. + true. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> @@ -42,20 +42,21 @@ run(Uri) -> <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> - []; + ["error2"]; {ok, _} -> case els_refactorerl_utils:add(Uri) of error -> - []; + ["error1"]; ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - make_diagnostics(Results) + make_diagnostics(Results), + ["alma"] end end; _ -> - [] + ["korte"] end. -spec source() -> binary(). diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 7e7de016a..c227f7acc 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -127,7 +127,7 @@ init_per_testcase(TestCase, Config) when TestCase =:= gradualizer -> % RefactorErl init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> - io:format("INIT"), + mock_refactorerl(), els_test_utils:init_per_testcase(TestCase, Config); init_per_testcase(TestCase, Config) -> @@ -171,11 +171,19 @@ end_per_testcase(TestCase, Config) when TestCase =:= gradualizer -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok; +end_per_testcase(TestCase, Config) + when TestCase =:= unused_macros_refactorerl -> + unmock_refactoerl(), + els_test_utils:end_per_testcase(TestCase, Config), + els_mock_diagnostics:teardown(); end_per_testcase(TestCase, Config) -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok. +% RefactorErl + + %%============================================================================== %% Testcases %%============================================================================== @@ -752,3 +760,83 @@ src_path(Module) -> include_path(Header) -> filename:join(["code_navigation", "include", Header]). + + +% Mock RefactorErl utils +mock_refactorerl() -> + %meck:new(rpc, [passthrough, no_link, unstick]), + %{ok, HostName} = inet:gethostname(), + %NodeName = list_to_atom("fakenode@" ++ HostName), + %meck:expect( rpc + % , call + % , fun(PNode, c, c, [Module]) when PNode =:= NodeName -> + % {ok, Module}; + % (Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + % end + % ). + meck:new(els_refactorerl_utils), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, ["Hello"]), + meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), + meck:expect(els_refactorerl_utils, add, 1, ok), + % + + + + % rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); + meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + [{#{'end' => #{character => 12,line => 16}, + start => #{character => 4,line => 16}}, + <<"Unsecure OS call: os:cmd(A)">>}, + {#{'end' => #{character => 35,line => 5}, + start => #{character => 0,line => 5}}, + <<"Unused macros: UNUSED_MACRO">>}, + {#{'end' => #{character => 36,line => 6}, + start => #{character => 0,line => 6}}, + <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] + %; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ), + + + % rpc:call(Node, referl_els, add, [Path]); %% returns error | ok + %meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + ok%; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ), + + % rpc:call(Node, referl_els, ping, [], 500) + %meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, ping, [], 500) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + {refactorerl_els, pong}%; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ). + +unmock_refactoerl() -> + meck:unload(rpc), + meck:unload(refactorerl_els). \ No newline at end of file From 2f9faf14b6c495b6a1338fc56acd3836393c7c67 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 20:13:50 +0100 Subject: [PATCH 042/103] Tests --- .../src/els_refactorerl_diagnostics.erl | 41 +++---- apps/els_lsp/test/els_diagnostics_SUITE.erl | 100 ++++++++---------- 2 files changed, 68 insertions(+), 73 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index cbfbca45b..6889ad78a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -38,25 +38,29 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> + %TODO TEST + io:format(">>>>>> Diagnostics begin"), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> - ["error2"]; + []; {ok, _} -> case els_refactorerl_utils:add(Uri) of error -> - ["error1"]; + []; ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - make_diagnostics(Results), - ["alma"] + io:format("Result"), + io:format("~p", [Results]), + make_diagnostics(Results) + end end; _ -> - ["korte"] + [] end. -spec source() -> binary(). @@ -69,28 +73,29 @@ source() -> % @doc % Returns the enabled diagnostic aliases from config --spec configured_diagnostics() -> sets:set(). -configured_diagnostics() -> - case els_config:get(refactorerl) of - #{"diagnostics" := List} -> - sets:from_list(List); - _ -> - [] - end. +%-spec configured_diagnostics() -> sets:set(). +%configured_diagnostics() -> +% case els_config:get(refactorerl) of +% #{"diagnostics" := List} -> +% sets:from_list(List); +% _ -> +% [] +% end. % @doc % Returns the default diagnostic aliases --spec default_diagnostics() -> sets:set(). -default_diagnostics() -> - sets:from_list(["unused_macros", "unsecure_os_calls"]). +%-spec default_diagnostics() -> sets:set(). +%default_diagnostics() -> +% sets:from_list(["unused_macros", "unsecure_os_calls"]). % @doc % Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> - Set = sets:union(default_diagnostics(), configured_diagnostics()), - sets:to_list(Set). + %Set = sets:union(default_diagnostics(), configured_diagnostics()), + %sets:to_list(Set), %TODO Set operation + ["unused_macros", "unsecure_os_calls"]. % @doc diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index c227f7acc..615add4c7 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -175,7 +175,8 @@ end_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> unmock_refactoerl(), els_test_utils:end_per_testcase(TestCase, Config), - els_mock_diagnostics:teardown(); + els_mock_diagnostics:teardown(), + ok; end_per_testcase(TestCase, Config) -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), @@ -763,80 +764,69 @@ include_path(Header) -> % Mock RefactorErl utils -mock_refactorerl() -> - %meck:new(rpc, [passthrough, no_link, unstick]), - %{ok, HostName} = inet:gethostname(), - %NodeName = list_to_atom("fakenode@" ++ HostName), - %meck:expect( rpc - % , call - % , fun(PNode, c, c, [Module]) when PNode =:= NodeName -> - % {ok, Module}; - % (Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - % end - % ). - meck:new(els_refactorerl_utils), +mock_refactorerl() -> {ok, HostName} = inet:gethostname(), NodeName = list_to_atom("referl_fake@" ++ HostName), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, ["Hello"]), + + meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, [{#{'end' => #{character => 12,line => 16}, + start => #{character => 4,line => 16}}, + <<"Unsecure OS call: os:cmd(A)">>}]), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - % - + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), - - % rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); + + %rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), meck:expect( rpc , call - , fun(_RPCNode, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - [{#{'end' => #{character => 12,line => 16}, - start => #{character => 4,line => 16}}, - <<"Unsecure OS call: os:cmd(A)">>}, - {#{'end' => #{character => 35,line => 5}, + , fun(Node, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) when Node =:= NodeName -> + io:format("RunDiag"), + [{#{'end' => #{character => 35,line => 5}, start => #{character => 0,line => 5}}, <<"Unused macros: UNUSED_MACRO">>}, {#{'end' => #{character => 36,line => 6}, start => #{character => 0,line => 6}}, - <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] + <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] ; %; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) end ), - - - % rpc:call(Node, referl_els, add, [Path]); %% returns error | ok + + + %rpc:call(Node, referl_els, add, [Path]); %% returns error | ok %meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), meck:expect( rpc - , call - , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - ok%; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - end - ), + , call + , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), + io:format("Add"), + + ok; + + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) + end + ), % rpc:call(Node, referl_els, ping, [], 500) %meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), + % + meck:expect( rpc - , call - , fun(_RPCNode, referl_els, ping, [], 500) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - {refactorerl_els, pong}%; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - end - ). + , call + , fun(_RPCNode, referl_els, ping, ["_Path"]) -> %{ok, HostName} = inet:gethostname(), + io:format("Ping"), + + {refactorerl_els, pong}; + + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) + end + ). + unmock_refactoerl() -> - meck:unload(rpc), - meck:unload(refactorerl_els). \ No newline at end of file + meck:unload(rpc). + %meck:unload(els_refactorerl_utils). \ No newline at end of file From 113f3f22369b885a32f9c49d1a6c31214444f3bc Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:01:33 +0100 Subject: [PATCH 043/103] Passing tests, draft --- .../src/els_refactorerl_diagnostics.erl | 9 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 72 ++++--------------- 2 files changed, 16 insertions(+), 65 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 6889ad78a..16f310a0e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -38,8 +38,6 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> - %TODO TEST - io:format(">>>>>> Diagnostics begin"), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of @@ -53,8 +51,6 @@ run(Uri) -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - io:format("Result"), - io:format("~p", [Results]), make_diagnostics(Results) end @@ -86,7 +82,7 @@ source() -> % Returns the default diagnostic aliases %-spec default_diagnostics() -> sets:set(). %default_diagnostics() -> -% sets:from_list(["unused_macros", "unsecure_os_calls"]). +% sets:from_list(["unused_macros", "unsecure_os_call"]). % @doc @@ -95,7 +91,8 @@ source() -> enabled_diagnostics() -> %Set = sets:union(default_diagnostics(), configured_diagnostics()), %sets:to_list(Set), %TODO Set operation - ["unused_macros", "unsecure_os_calls"]. + %["unused_macros", "unsecure_os_call"]. + [unused_macros, unsecure_os_call]. % @doc diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 615add4c7..45e3b40b7 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -679,10 +679,10 @@ unused_macros_refactorerl(_Config) -> Source = <<"RefactorErl">>, Errors = [], Warnings = [ #{ message => <<"Unused macro: UNUSED_MACRO">> - , range => {{5, 8}, {5, 20}} + , range => {{5, 0}, {5, 35}} }, - #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG/1">> - , range => {{6, 8}, {6, 29}} + #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG">> + , range => {{6, 0}, {6, 36}} } ], Hints = [], @@ -769,64 +769,18 @@ mock_refactorerl() -> NodeName = list_to_atom("referl_fake@" ++ HostName), meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, [{#{'end' => #{character => 12,line => 16}, - start => #{character => 4,line => 16}}, - <<"Unsecure OS call: os:cmd(A)">>}]), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, + [ {# {'end' => #{character => 35,line => 5}, + start => #{character => 0,line => 5}}, + <<"Unused macro: UNUSED_MACRO">>}, + {# {'end' => #{character => 36,line => 6}, + start => #{character => 0,line => 6}}, + <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] + ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), - - - %rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); - meck:new(rpc, [passthrough, no_link, unstick]), - meck:expect( rpc - , call - , fun(Node, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) when Node =:= NodeName -> - io:format("RunDiag"), - [{#{'end' => #{character => 35,line => 5}, - start => #{character => 0,line => 5}}, - <<"Unused macros: UNUSED_MACRO">>}, - {#{'end' => #{character => 36,line => 6}, - start => #{character => 0,line => 6}}, - <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] ; - %; - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ), + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>). - %rpc:call(Node, referl_els, add, [Path]); %% returns error | ok - %meck:new(rpc, [passthrough, no_link, unstick]), - meck:expect( rpc - , call - , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), - io:format("Add"), - - ok; - - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ), - - % rpc:call(Node, referl_els, ping, [], 500) - %meck:new(rpc, [passthrough, no_link, unstick]), - % - - meck:expect( rpc - , call - , fun(_RPCNode, referl_els, ping, ["_Path"]) -> %{ok, HostName} = inet:gethostname(), - io:format("Ping"), - - {refactorerl_els, pong}; - - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ). - - unmock_refactoerl() -> - meck:unload(rpc). - %meck:unload(els_refactorerl_utils). \ No newline at end of file + meck:unload(els_refactorerl_utils). \ No newline at end of file From 800ac40984293ceeec74ef653a828c049965ad9d Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:17:25 +0100 Subject: [PATCH 044/103] Conventions and dialyzer --- .../src/els_refactorerl_diagnostics.erl | 3 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 20 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 16f310a0e..c75626f3c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_alias() :: string(). +-type refactorerl_diagnostic_alias() :: atom(). -type refactorerl_diagnostic_result() :: {range(), string()}. %-type refactorerl_query() :: [char()]. @@ -52,7 +52,6 @@ run(Uri) -> Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), make_diagnostics(Results) - end end; _ -> diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 45e3b40b7..0f2decddd 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -126,7 +126,8 @@ init_per_testcase(TestCase, Config) when TestCase =:= gradualizer -> els_test_utils:init_per_testcase(TestCase, Config); % RefactorErl -init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> +init_per_testcase(TestCase, Config) + when TestCase =:= unused_macros_refactorerl -> mock_refactorerl(), els_test_utils:init_per_testcase(TestCase, Config); @@ -171,7 +172,7 @@ end_per_testcase(TestCase, Config) when TestCase =:= gradualizer -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok; -end_per_testcase(TestCase, Config) +end_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> unmock_refactoerl(), els_test_utils:end_per_testcase(TestCase, Config), @@ -762,20 +763,19 @@ src_path(Module) -> include_path(Header) -> filename:join(["code_navigation", "include", Header]). - % Mock RefactorErl utils -mock_refactorerl() -> +mock_refactorerl() -> {ok, HostName} = inet:gethostname(), NodeName = list_to_atom("referl_fake@" ++ HostName), meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, - [ {# {'end' => #{character => 35,line => 5}, - start => #{character => 0,line => 5}}, + meck:expect(els_refactorerl_utils, run_diagnostics, 2, + [ {# {'end' => #{character => 35, line => 5}, + start => #{character => 0, line => 5}}, <<"Unused macro: UNUSED_MACRO">>}, - {# {'end' => #{character => 36,line => 6}, - start => #{character => 0,line => 6}}, - <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] + {# {'end' => #{character => 36, line => 6}, + start => #{character => 0, line => 6}}, + <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), From 66809e5c043356dd62a1285a9703879d11992890 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:47:21 +0100 Subject: [PATCH 045/103] Test failing due to it is not configured --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index c75626f3c..96705fc6a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - true. + false. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> From 20fbe63134908318707d0f7f41b2739dc9ebd61e Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 3 Mar 2022 21:37:29 +0100 Subject: [PATCH 046/103] Test --- apps/els_lsp/test/els_diagnostics_SUITE.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 0f2decddd..bb7b237ed 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -779,8 +779,12 @@ mock_refactorerl() -> ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>). + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), + + meck:new(els_refactorerl_diagnostics, [passthrough, no_link, unstick]), + meck:expect(els_refactorerl_diagnostics, is_default, 0, true). unmock_refactoerl() -> + meck:unload(els_refactorerl_diagnostics), meck:unload(els_refactorerl_utils). \ No newline at end of file From 23a4bcd4b2237dcb25819295b49584c66d5816e3 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:04:29 +0100 Subject: [PATCH 047/103] @doc tag fix --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 96705fc6a..5b4784c0f 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -77,7 +77,7 @@ source() -> % [] % end. -% @doc +% ddoocc % Returns the default diagnostic aliases %-spec default_diagnostics() -> sets:set(). %default_diagnostics() -> From 967da508289b5e78b8423564340635458ff42a38 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:41:11 +0100 Subject: [PATCH 048/103] doc fix2 --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5b4784c0f..e7f52612f 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -66,7 +66,7 @@ source() -> %% Internal Functions %%============================================================================== -% @doc +% ddoocc % Returns the enabled diagnostic aliases from config %-spec configured_diagnostics() -> sets:set(). %configured_diagnostics() -> From e5a29be263336c19f11b9a78d429d7cc5e66bc5e Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:07:17 +0100 Subject: [PATCH 049/103] Diagnostic config option --- .../src/els_refactorerl_diagnostics.erl | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e7f52612f..eb4e19f75 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -66,32 +66,31 @@ source() -> %% Internal Functions %%============================================================================== -% ddoocc +% @doc % Returns the enabled diagnostic aliases from config -%-spec configured_diagnostics() -> sets:set(). -%configured_diagnostics() -> -% case els_config:get(refactorerl) of -% #{"diagnostics" := List} -> -% sets:from_list(List); -% _ -> -% [] -% end. - -% ddoocc +-spec configured_diagnostics() -> sets:set(). +configured_diagnostics() -> + case els_config:get(refactorerl) of + #{"diagnostics" := List} -> + AtomList = [list_to_atom(Element) || Element <- List], + sets:from_list(AtomList); + _ -> + [] + end. + +% @doc % Returns the default diagnostic aliases -%-spec default_diagnostics() -> sets:set(). -%default_diagnostics() -> -% sets:from_list(["unused_macros", "unsecure_os_call"]). +-spec default_diagnostics() -> sets:set(). +default_diagnostics() -> + sets:from_list([unused_macros, unsecure_os_call]). % @doc % Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> - %Set = sets:union(default_diagnostics(), configured_diagnostics()), - %sets:to_list(Set), %TODO Set operation - %["unused_macros", "unsecure_os_call"]. - [unused_macros, unsecure_os_call]. + Set = sets:union(default_diagnostics(), configured_diagnostics()), + sets:to_list(Set). % @doc From 3b26449915c656f8dda3100b9fd65be89390da29 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:18:12 +0100 Subject: [PATCH 050/103] Code clearing and diagnostic config --- .../src/els_refactorerl_diagnostics.erl | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index eb4e19f75..8e837d79e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -65,33 +65,17 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== - % @doc -% Returns the enabled diagnostic aliases from config --spec configured_diagnostics() -> sets:set(). -configured_diagnostics() -> +% Returns the enabled diagnostics by merging default and configed +-spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. +enabled_diagnostics() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> - AtomList = [list_to_atom(Element) || Element <- List], - sets:from_list(AtomList); + [list_to_atom(Element) || Element <- List]; _ -> [] end. -% @doc -% Returns the default diagnostic aliases --spec default_diagnostics() -> sets:set(). -default_diagnostics() -> - sets:from_list([unused_macros, unsecure_os_call]). - - -% @doc -% Returns the enabled diagnostics by merging default and configed --spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. -enabled_diagnostics() -> - Set = sets:union(default_diagnostics(), configured_diagnostics()), - sets:to_list(Set). - % @doc % Constructs the ELS diagnostic from RefactorErl result From 667c4dcd3297b9e6bf1ca8ee83761daed7d0aab2 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 18:14:39 +0200 Subject: [PATCH 051/103] Less error handling --- apps/els_core/src/els_config.erl | 3 ++- apps/els_lsp/src/els_refactorerl_utils.erl | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 01647408d..de4b844eb 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -56,7 +56,8 @@ | indexing_enabled | bsp_enabled | compiler_telemetry_enabled - | refactorerl. + | refactorerl + | edoc_custom_tags. -type path() :: file:filename(). -type state() :: #{ apps_dirs => [path()] diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 94a64c508..3a666e168 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -68,7 +68,6 @@ referl_node() -> connect_node({validate, Node}); notconfigured -> - notification("RefactorErl is not configured!"), {error, disabled}; _ -> @@ -139,7 +138,6 @@ connect_node({Status, Node}) -> Config = els_config:get(refactorerl), case {Status, is_refactorerl(Node)} of {validate, false} -> - notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {retry, false} -> From 8b9ac4a5948d6fcfd7e14cb219a967a7d19e1774 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:04:33 +0200 Subject: [PATCH 052/103] Resolved conflict with edoc --- apps/els_core/src/els_config.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 7c7facf5f..cc971fcad 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -56,7 +56,8 @@ | indexing_enabled | bsp_enabled | compiler_telemetry_enabled - | edoc_custom_tags. + | edoc_custom_tags + | refactorerl. -type path() :: file:filename(). -type state() :: #{ apps_dirs => [path()] @@ -77,6 +78,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() + , refactorerl => {atom(), atom() | 'disabled'} }. %%============================================================================== @@ -138,6 +140,8 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), + RefactorErl = {config, maps:get("refactorerl", Config, disabled)}, + %% Passed by the LSP client ok = set(root_uri , RootUri), %% Read from the configuration file @@ -180,6 +184,8 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> %% Init Options ok = set(capabilities , Capabilities), ok = set(indexing_enabled, IndexingEnabled), + + ok = set(refactorerl, RefactorErl), ok. -spec start_link() -> {ok, pid()}. From f9775e980d3373298db4ff99b19a512adf85aee7 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:31:45 +0100 Subject: [PATCH 053/103] Referl unused macros with basic node detect --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../els_referl_unused_macros_diagnostics.erl | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index bc25d44e5..616dbfe04 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -68,6 +68,7 @@ available_diagnostics() -> , <<"elvis">> , <<"unused_includes">> , <<"unused_macros">> + , <<"referl_unused_macros">> , <<"unused_record_fields">> ]. diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl new file mode 100644 index 000000000..9515abd2f --- /dev/null +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -0,0 +1,135 @@ +%%============================================================================== +%% Unused Macros diagnostics by Referl +%%============================================================================== +-module(els_referl_unused_macros_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). +-define(TIME_OUT, 3000). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + {badrpc, _} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), + []; + error -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + _ -> + ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], ?TIME_OUT), % TODO: Robi sq run második paramba @ utén + Pois = convertToPoi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois] + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"UnusedMacros_RefactorErl">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, MacroName} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom2, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, macro, Id, MacroName), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] +end. + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + MacroName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Unused macro: ", MacroName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Separate timeout issues + badrpc; + _ -> + error + end. From ed6d143fad8b4207a774df91f82a738162318816 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:53:50 +0100 Subject: [PATCH 054/103] source() formatted --- apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 9515abd2f..6600ce870 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -67,7 +67,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"UnusedMacros_RefactorErl">>. + <<"Unused Macros (Referl)">>. %%============================================================================== %% Internal Functions @@ -107,7 +107,7 @@ referl_node() -> error -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), disabled; - badrpc -> % TODO: Try other nodes. (default nodes like: referl@host) + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), disabled; Node -> @@ -128,7 +128,7 @@ referl_node(Node) -> Node; ok-> Node; - {badrpc, _} -> %TODO: Separate timeout issues + {badrpc, _} -> %TODO: Robi Separate timeout issues badrpc; _ -> error From 653347af6cbf7bf2d61957995094c39d9a2385b6 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 22 Nov 2021 21:54:04 +0100 Subject: [PATCH 055/103] Unsecure Calls by RefactorErl --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../els_referl_unsecure_calls_diagnostics.erl | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 616dbfe04..3c0f056ef 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -69,6 +69,7 @@ available_diagnostics() -> , <<"unused_includes">> , <<"unused_macros">> , <<"referl_unused_macros">> + , <<"referl_unsecure_calls">> , <<"unused_record_fields">> ]. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl new file mode 100644 index 000000000..34878caf8 --- /dev/null +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -0,0 +1,137 @@ +%%============================================================================== +%% Unsecure Calls by Referl +%%============================================================================== +-module(els_referl_unsecure_calls_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). +-define(TIME_OUT, 3000). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + {badrpc, _} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), + []; + error -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + _ -> + ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), + Pois = convertToPoi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois] + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"Unsecure Calls (Referl)">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Security Issue: ", IssueName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Robi Separate timeout issues + badrpc; + _ -> + error + end. \ No newline at end of file From f6c0fa8d20c32ac1a824309c4db5f25ca5df4e53 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Tue, 23 Nov 2021 10:09:50 +0100 Subject: [PATCH 056/103] RefactorErl conversion module --- apps/els_lsp/src/els_referl.erl | 82 +++++++++++++++++++ .../els_referl_unsecure_calls_diagnostics.erl | 62 +------------- .../els_referl_unused_macros_diagnostics.erl | 64 ++------------- 3 files changed, 93 insertions(+), 115 deletions(-) create mode 100644 apps/els_lsp/src/els_referl.erl diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_referl.erl new file mode 100644 index 000000000..639095f9d --- /dev/null +++ b/apps/els_lsp/src/els_referl.erl @@ -0,0 +1,82 @@ +%%============================================================================== +%% Eralang LS & Refactor Erl conversion +%%============================================================================== +-module(els_referl). + +%%============================================================================== +%% API +%%============================================================================== +-export([ convertToPoi/1 + , referl_node/0 + , maxtimeout/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec convertToPoi(any()) -> poi(). +convertToPoi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convertToPoi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convertToPoi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +-spec referl_node() -> atom(). % If called with no args, then try to get it from config +referl_node() -> + case els_config:get(refactorerl) of + {checked, #{"node" := Node}} -> + Node; + {config, #{"node" := NodeStr}} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + case referl_node(Node) of + error -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), + disabled; + badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), + disabled; + Node -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + Node + end; + {config, disabled} -> + disabled; + {error, _} -> + disabled + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, _} -> %TODO: Robi Separate timeout issues + badrpc; + _ -> + error + end. + + +%%============================================================================== +%% Values +%%============================================================================== + +-spec maxtimeout() -> number(). +maxtimeout() -> + 3000. \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index 34878caf8..48a5ae39a 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -21,7 +21,6 @@ %%============================================================================== -include("els_lsp.hrl"). -define(MAX_RECURSION_DEPTH, 10). --define(TIME_OUT, 3000). %%============================================================================== %% Callback Functions @@ -40,11 +39,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case referl_node() of + case els_referl:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -54,7 +53,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = convertToPoi(ReferlResult), + Pois = els_referl:convertToPoi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; @@ -74,20 +73,6 @@ source() -> %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - -spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . Range = els_protocol:range(PoiRange), @@ -95,43 +80,4 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range Message = <<"Security Issue: ", IssueName/binary>>, Severity = ?DIAGNOSTIC_WARNING, Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - - --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. \ No newline at end of file + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 6600ce870..4da70591b 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -7,6 +7,7 @@ %% Behaviours %%============================================================================== -behaviour(els_diagnostics). +%-behaviour(els_referl). %%============================================================================== %% Exports @@ -21,7 +22,7 @@ %%============================================================================== -include("els_lsp.hrl"). -define(MAX_RECURSION_DEPTH, 10). --define(TIME_OUT, 3000). + %%============================================================================== %% Callback Functions @@ -39,11 +40,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case referl_node() of + case els_referl:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], ?TIME_OUT) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -52,8 +53,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> run(Uri, RecursionDepth + 1); _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], ?TIME_OUT), % TODO: Robi sq run második paramba @ utén - Pois = convertToPoi(ReferlResult), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_referl:time_out()), % TODO: Robi sq run második paramba @ utén + Pois = els_referl:convertToPoi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; @@ -62,7 +63,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Can't add module to RefactorErl!">> }), []. -spec source() -> binary(). @@ -73,20 +74,6 @@ source() -> %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, MacroName} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom2, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, macro, Id, MacroName), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; - _ -> - [] -end. - -spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . Range = els_protocol:range(PoiRange), @@ -96,40 +83,3 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range Source = source(), els_diagnostics:make_diagnostic(Range, Message, Severity, Source). --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. From bc7a0cad08b500478759787627283e006bbd81f2 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:06:30 +0200 Subject: [PATCH 057/103] Resolved conflict --- apps/els_lsp/src/els_referl.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_referl.erl index 639095f9d..84d3ee7c2 100644 --- a/apps/els_lsp/src/els_referl.erl +++ b/apps/els_lsp/src/els_referl.erl @@ -79,4 +79,4 @@ referl_node(Node) -> -spec maxtimeout() -> number(). maxtimeout() -> - 3000. \ No newline at end of file + 3000. From 0f7e0ccd4d2f3e0e4fb65cb137cab4aab1774934 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 00:36:33 +0100 Subject: [PATCH 058/103] Nameing conventions --- .../src/{els_referl.erl => els_refactorerl_utis.erl} | 12 ++++++------ .../src/els_referl_unsecure_calls_diagnostics.erl | 6 +++--- .../src/els_referl_unused_macros_diagnostics.erl | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) rename apps/els_lsp/src/{els_referl.erl => els_refactorerl_utis.erl} (93%) diff --git a/apps/els_lsp/src/els_referl.erl b/apps/els_lsp/src/els_refactorerl_utis.erl similarity index 93% rename from apps/els_lsp/src/els_referl.erl rename to apps/els_lsp/src/els_refactorerl_utis.erl index 84d3ee7c2..44c3f911e 100644 --- a/apps/els_lsp/src/els_referl.erl +++ b/apps/els_lsp/src/els_refactorerl_utis.erl @@ -1,12 +1,12 @@ %%============================================================================== %% Eralang LS & Refactor Erl conversion %%============================================================================== --module(els_referl). +-module(els_refactorerl_utis). %%============================================================================== %% API %%============================================================================== --export([ convertToPoi/1 +-export([ convert_to_poi/1 , referl_node/0 , maxtimeout/0 ]). @@ -20,16 +20,16 @@ %% Internal Functions %%============================================================================== --spec convertToPoi(any()) -> poi(). -convertToPoi(ReferlResult) -> +-spec convert_to_poi(any()) -> poi(). +convert_to_poi(ReferlResult) -> case ReferlResult of [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convertToPoi(DataList); + convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convertToPoi(Tail) ]; + [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index 48a5ae39a..f7c19aa35 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -39,11 +39,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_referl:referl_node() of + case els_refactorerl_utis:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -53,7 +53,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = els_referl:convertToPoi(ReferlResult), + Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index 4da70591b..b168ae493 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -40,11 +40,11 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_referl:referl_node() of + case els_refactorerl_utis:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_referl:maxtimeout()) of + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of {badrpc, _} -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), []; @@ -53,8 +53,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> run(Uri, RecursionDepth + 1); _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_referl:time_out()), % TODO: Robi sq run második paramba @ utén - Pois = els_referl:convertToPoi(ReferlResult), + ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_refactorerl_utis:time_out()), % TODO: Robi sq run második paramba @ utén + Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; From 596cf397659a73342a996ba7a20719b087bb8f6d Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 18:42:43 +0100 Subject: [PATCH 059/103] Changed to map, to extend confiureability --- apps/els_core/src/els_config.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index cc971fcad..4ec38dcea 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -78,7 +78,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => {atom(), atom() | 'disabled'} + , refactorerl => { map() | 'disabled'} }. %%============================================================================== @@ -140,7 +140,7 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), - RefactorErl = {config, maps:get("refactorerl", Config, disabled)}, + RefactorErl = maps:get("refactorerl", Config, disabled), %% Passed by the LSP client ok = set(root_uri , RootUri), From 8d334bbdca91e4eea14bc82e608ebab11747139c Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 18:43:05 +0100 Subject: [PATCH 060/103] Better node detection, utility module --- apps/els_lsp/src/els_refactorerl_utils.erl | 140 ++++++++++++++++++ apps/els_lsp/src/els_refactorerl_utis.erl | 82 ---------- .../els_referl_unsecure_calls_diagnostics.erl | 15 +- .../els_referl_unused_macros_diagnostics.erl | 15 +- 4 files changed, 154 insertions(+), 98 deletions(-) create mode 100644 apps/els_lsp/src/els_refactorerl_utils.erl delete mode 100644 apps/els_lsp/src/els_refactorerl_utis.erl diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl new file mode 100644 index 000000000..ee31af7ff --- /dev/null +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -0,0 +1,140 @@ +%%============================================================================== +%% Eralang LS & Refactor Erl conversion +%%============================================================================== +-module(els_refactorerl_utils). + +%%============================================================================== +%% API +%%============================================================================== +-export([ convert_to_poi/1 + , referl_node/0 + , maxtimeout/0 + , query/1 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec disable_node() -> atom(). +disable_node() -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), + xels_config:set(refactorerl, #{"node" => disabled}), + disabled. + +-spec try_connect_node({validate | retry, atom()}) -> atom(). +try_connect_node({Status, Node}) -> + case {Status, referl_node(Node)} of + {validate, {error, _}} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + disconnected; + {retry, {error, _}} -> + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + disconnected; + {_ ,Node} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, validated}}), + Node + end. + + +-spec query(any()) -> any(). +query(Query) -> + %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) + case referl_node() of + disabled -> + []; + disconnected -> + []; + error -> + []; + {error, _} -> + []; + Node -> + Response = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], Query], maxtimeout()), + case Response of + {badrpc, _} -> + disable_node(); % Returns disabled + error -> + busy; % RefactorErl node is probably busy. + A -> + log(A), + A + end + end. + +-spec log(any()) -> any(). +log(A) -> A. + + +-spec convert_to_poi(any()) -> poi(). +convert_to_poi(ReferlResult) -> +case ReferlResult of + [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + convert_to_poi(DataList); + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, + Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + [ Poi | convert_to_poi(Tail) ]; + _ -> + [] %TODO Robi notify +end. + +%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If the node once was validated there will be no display messages. +%% +%% Node can be: +%% - NodeStr +%% - {Status, Node} where both are atoms. +%% - Status can be: +%% - validated: node is running +%% - disconnected: node is not running +%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom(). % Can return: Node | disconnected | disabled +referl_node() -> + case els_config:get(refactorerl) of + #{"node" := {Node, validated}} -> + Node; + #{"node" := {Node, disconnected}} -> + try_connect_node({retry, Node}); + #{"node" := disabled} -> + disabled; + #{"node" := NodeStr} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + try_connect_node({validate, Node}); + A -> %TODO + log(A), + dis + end. + +-spec referl_node(atom()) -> atom(). +referl_node(Node) -> + Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive + case Response of + {{ok, _}, {error, _}} -> + Node; + ok-> + Node; + {badrpc, timeout} -> + {error, timeout}; + {badrpc, _} -> + {error, badrpc}; + _ -> + {error, other} + end. + + +%%============================================================================== +%% Values +%%============================================================================== + +-spec maxtimeout() -> number(). +maxtimeout() -> + 3000. diff --git a/apps/els_lsp/src/els_refactorerl_utis.erl b/apps/els_lsp/src/els_refactorerl_utis.erl deleted file mode 100644 index 44c3f911e..000000000 --- a/apps/els_lsp/src/els_refactorerl_utis.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%============================================================================== -%% Eralang LS & Refactor Erl conversion -%%============================================================================== --module(els_refactorerl_utis). - -%%============================================================================== -%% API -%%============================================================================== --export([ convert_to_poi/1 - , referl_node/0 - , maxtimeout/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec convert_to_poi(any()) -> poi(). -convert_to_poi(ReferlResult) -> -case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out - convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added - [ Poi | convert_to_poi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - --spec referl_node() -> atom(). % If called with no args, then try to get it from config -referl_node() -> - case els_config:get(refactorerl) of - {checked, #{"node" := Node}} -> - Node; - {config, #{"node" := NodeStr}} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - case referl_node(Node) of - error -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (error)">> }), - disabled; - badrpc -> % TODO: Robi Try other nodes. (default nodes like: referl@host) - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected! (badrpc/timeout)!">> }), - disabled; - Node -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - Node - end; - {config, disabled} -> - disabled; - {error, _} -> - disabled - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % TODO: ROBI van e valami referl ping? - case Response of - {{ok, _}, {error, _}} -> - Node; - ok-> - Node; - {badrpc, _} -> %TODO: Robi Separate timeout issues - badrpc; - _ -> - error - end. - - -%%============================================================================== -%% Values -%%============================================================================== - --spec maxtimeout() -> number(). -maxtimeout() -> - 3000. diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl index f7c19aa35..87c70d70d 100644 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl @@ -39,21 +39,20 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_refactorerl_utis:referl_node() of + case els_refactorerl_utils:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of - {badrpc, _} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), - []; - error -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + busy -> timer:sleep(1000), run(Uri, RecursionDepth + 1); + disabled -> + []; _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"]), - Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), + ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl index b168ae493..8c863d7fc 100644 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl @@ -40,21 +40,20 @@ run(Uri)-> run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> - case els_refactorerl_utis:referl_node() of + case els_refactorerl_utils:referl_node() of disabled -> []; Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utis:maxtimeout()) of - {badrpc, _} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Refactor Erl node is down {badrpc}!">> }), - []; - error -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + error -> % TODO R ezt is kiemelni timer:sleep(1000), run(Uri, RecursionDepth + 1); + disabled -> + []; _ -> ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods[name=" ++ ModuleName ++ "].macros[not .references]"], els_refactorerl_utis:time_out()), % TODO: Robi sq run második paramba @ utén - Pois = els_refactorerl_utis:convert_to_poi(ReferlResult), + ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].macros[not .references]"), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), [make_diagnostic(Poi) || Poi <- Pois] end end; From 3b37faad439aa8d374fde4bbc9813d8761c9c9f7 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 26 Nov 2021 19:05:37 +0100 Subject: [PATCH 061/103] Error management unifying. Code reorganisation --- apps/els_lsp/src/els_refactorerl_utils.erl | 117 ++++++++++----------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index ee31af7ff..7aef407fe 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -17,6 +17,36 @@ %%============================================================================== -include("els_lsp.hrl"). +%%============================================================================== +%% API +%%============================================================================== +%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If the node once was validated there will be no display messages. +%% +%% Node can be: +%% - NodeStr +%% - {Status, Node} where both are atoms. +%% - Status can be: +%% - validated: node is running +%% - disconnected: node is not running +%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom() | {error, disconnected} | {error, disabled} | {error, other}. +referl_node() -> + case els_config:get(refactorerl) of + #{"node" := {Node, validated}} -> + Node; + #{"node" := {Node, disconnected}} -> + try_connect_node({retry, Node}); + #{"node" := disabled} -> + {error, disabled}; + #{"node" := NodeStr} -> + Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + try_connect_node({validate, Node}); + _ -> + {error, other} + end. + + %%============================================================================== %% Internal Functions %%============================================================================== @@ -24,36 +54,13 @@ -spec disable_node() -> atom(). disable_node() -> els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), - xels_config:set(refactorerl, #{"node" => disabled}), - disabled. - --spec try_connect_node({validate | retry, atom()}) -> atom(). -try_connect_node({Status, Node}) -> - case {Status, referl_node(Node)} of - {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), - disconnected; - {retry, {error, _}} -> - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), - disconnected; - {_ ,Node} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), - els_config:set(refactorerl, #{"node" => {Node, validated}}), - Node - end. - + els_config:set(refactorerl, #{"node" => disabled}), + {error, disabled}. --spec query(any()) -> any(). -query(Query) -> +-spec query(string()) -> list() | {error, disabled}. +query(Query) -> %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) case referl_node() of - disabled -> - []; - disconnected -> - []; - error -> - []; {error, _} -> []; Node -> @@ -63,16 +70,11 @@ query(Query) -> disable_node(); % Returns disabled error -> busy; % RefactorErl node is probably busy. - A -> - log(A), - A + _ -> + Response end end. --spec log(any()) -> any(). -log(A) -> A. - - -spec convert_to_poi(any()) -> poi(). convert_to_poi(ReferlResult) -> case ReferlResult of @@ -87,35 +89,8 @@ case ReferlResult of [] %TODO Robi notify end. -%% If called with no args try to get the node from config. Use the referl_node/1 to validate. -%% If the node once was validated there will be no display messages. -%% -%% Node can be: -%% - NodeStr -%% - {Status, Node} where both are atoms. -%% - Status can be: -%% - validated: node is running -%% - disconnected: node is not running -%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. --spec referl_node() -> atom(). % Can return: Node | disconnected | disabled -referl_node() -> - case els_config:get(refactorerl) of - #{"node" := {Node, validated}} -> - Node; - #{"node" := {Node, disconnected}} -> - try_connect_node({retry, Node}); - #{"node" := disabled} -> - disabled; - #{"node" := NodeStr} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), - try_connect_node({validate, Node}); - A -> %TODO - log(A), - dis - end. - --spec referl_node(atom()) -> atom(). -referl_node(Node) -> +-spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). +check_node(Node) -> Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive case Response of {{ok, _}, {error, _}} -> @@ -130,6 +105,22 @@ referl_node(Node) -> {error, other} end. +-spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom() . +try_connect_node({Status, Node}) -> + case {Status, check_node(Node)} of + {validate, {error, _}} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + {error, disconnected}; + {retry, {error, _}} -> + els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + {error, disconnected}; + {_ ,Node} -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + els_config:set(refactorerl, #{"node" => {Node, validated}}), + Node + end. + %%============================================================================== %% Values From 44038d171076039cd2f6e32eaa98801d5879ef22 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 09:06:27 +0100 Subject: [PATCH 062/103] First run for a common diagnostic module --- apps/els_lsp/src/els_diagnostics.erl | 1 + .../src/els_refactorerl_diagnostics.erl | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 apps/els_lsp/src/els_refactorerl_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 3c0f056ef..284d41116 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -71,6 +71,7 @@ available_diagnostics() -> , <<"referl_unused_macros">> , <<"referl_unsecure_calls">> , <<"unused_record_fields">> + , <<"refactorerl">> ]. -spec default_diagnostics() -> [diagnostic_id()]. diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl new file mode 100644 index 000000000..0e20f3f4a --- /dev/null +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -0,0 +1,114 @@ +%%============================================================================== +%% Unsecure Calls by Referl +%%============================================================================== +-module(els_refactorerl_diagnostics). + +%%============================================================================== +%% Behaviours +%%============================================================================== +-behaviour(els_diagnostics). + +%%============================================================================== +%% Exports +%%============================================================================== +-export([ is_default/0 + , run/1 + , source/0 + ]). + +%%============================================================================== +%% Includes & Defines +%%============================================================================== +-include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). + +%%============================================================================== +%% Callback Functions +%%============================================================================== + + +%%======================================= +%%======================================= + +%% {id, pre, after} +%% +%% +%% -type diagnostic_id() :: binary(). + +-type refactorerl_diagnostic_id() :: {atom(), [char()], [char()]}. +-type refactorerl_query() :: [char()]. + +-spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. +refactorerl_diagnostics() -> + [ {unused_macros, "mods[name=", "].funs.unsecure_calls"} + , {unsecure_calls, "mods[name=", "].macros[not .references]"} + ]. + + +-spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). +make_query({_, Before, After}, Module) -> + ModuleStr = atom_to_binary(Module), + Before ++ ModuleStr ++ After. + + +-spec run_query(module(),refactorerl_diagnostic_id()) -> ([els_diagnostics:diagnostic()]). +run_query(Module, DiagnosticId) -> + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + [make_diagnostic(Poi) || Poi <- Pois]. + + +%%======================================= +%%======================================= +-spec is_default() -> boolean(). +is_default() -> + true. + +-spec run(uri()) -> [els_diagnostics:diagnostic()]. +run(Uri)-> + run(Uri, 0). + + +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case filename:extension(Uri) of + <<".erl">> -> + case els_refactorerl_utils:referl_node() of + disabled -> + []; + Node -> + case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + busy -> + timer:sleep(1000), + run(Uri, RecursionDepth + 1); + disabled -> + []; + _ -> + Module = list_to_atom(filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri))))), + lists:concat([run_query(Module, DiagnosticId) || DiagnosticId <- refactorerl_diagnostics()]) + end + end; + _ -> + [] + end; + +run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + []. + +-spec source() -> binary(). +source() -> + <<"RefactorErl Diagnostics">>. + +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . + Range = els_protocol:range(PoiRange), + IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID + Message = <<"Security Issue: ", IssueName/binary>>, + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file From 555a1313bf866f5712f414cbd06e90fa759f5859 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 09:49:50 +0100 Subject: [PATCH 063/103] Minor fix --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 0e20f3f4a..d31db6cba 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -47,7 +47,7 @@ refactorerl_diagnostics() -> -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). make_query({_, Before, After}, Module) -> - ModuleStr = atom_to_binary(Module), + ModuleStr = atom_to_list(Module), Before ++ ModuleStr ++ After. @@ -71,6 +71,7 @@ run(Uri)-> -spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"HERH!">> }), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of From 3ea4bcce5f3f392f3ca202fc31645cef073874b3 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 10:10:46 +0100 Subject: [PATCH 064/103] Commond diagnostic backend --- apps/els_lsp/src/els_diagnostics.erl | 2 - .../src/els_refactorerl_diagnostics.erl | 1 - .../els_referl_unsecure_calls_diagnostics.erl | 82 ------------------ .../els_referl_unused_macros_diagnostics.erl | 84 ------------------- 4 files changed, 169 deletions(-) delete mode 100644 apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl delete mode 100644 apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl diff --git a/apps/els_lsp/src/els_diagnostics.erl b/apps/els_lsp/src/els_diagnostics.erl index 284d41116..6f76fe639 100644 --- a/apps/els_lsp/src/els_diagnostics.erl +++ b/apps/els_lsp/src/els_diagnostics.erl @@ -68,8 +68,6 @@ available_diagnostics() -> , <<"elvis">> , <<"unused_includes">> , <<"unused_macros">> - , <<"referl_unused_macros">> - , <<"referl_unsecure_calls">> , <<"unused_record_fields">> , <<"refactorerl">> ]. diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d31db6cba..d99403c38 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -71,7 +71,6 @@ run(Uri)-> -spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"HERH!">> }), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of diff --git a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl b/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl deleted file mode 100644 index 87c70d70d..000000000 --- a/apps/els_lsp/src/els_referl_unsecure_calls_diagnostics.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%============================================================================== -%% Unsecure Calls by Referl -%%============================================================================== --module(els_referl_unsecure_calls_diagnostics). - -%%============================================================================== -%% Behaviours -%%============================================================================== --behaviour(els_diagnostics). - -%%============================================================================== -%% Exports -%%============================================================================== --export([ is_default/0 - , run/1 - , source/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). - -%%============================================================================== -%% Callback Functions -%%============================================================================== - --spec is_default() -> boolean(). -is_default() -> - true. - --spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> - run(Uri, 0). - - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - case filename:extension(Uri) of - <<".erl">> -> - case els_refactorerl_utils:referl_node() of - disabled -> - []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of - busy -> - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> - []; - _ -> - ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].funs.unsecure_calls"), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois] - end - end; - _ -> - [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), - []. - --spec source() -> binary(). -source() -> - <<"Unsecure Calls (Referl)">>. - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . - Range = els_protocol:range(PoiRange), - IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Security Issue: ", IssueName/binary>>, - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file diff --git a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl b/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl deleted file mode 100644 index 8c863d7fc..000000000 --- a/apps/els_lsp/src/els_referl_unused_macros_diagnostics.erl +++ /dev/null @@ -1,84 +0,0 @@ -%%============================================================================== -%% Unused Macros diagnostics by Referl -%%============================================================================== --module(els_referl_unused_macros_diagnostics). - -%%============================================================================== -%% Behaviours -%%============================================================================== --behaviour(els_diagnostics). -%-behaviour(els_referl). - -%%============================================================================== -%% Exports -%%============================================================================== --export([ is_default/0 - , run/1 - , source/0 - ]). - -%%============================================================================== -%% Includes & Defines -%%============================================================================== --include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). - - -%%============================================================================== -%% Callback Functions -%%============================================================================== - --spec is_default() -> boolean(). -is_default() -> - true. - --spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> - run(Uri, 0). - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> - case filename:extension(Uri) of - <<".erl">> -> - case els_refactorerl_utils:referl_node() of - disabled -> - []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of - error -> % TODO R ezt is kiemelni - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> - []; - _ -> - ModuleName = filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri)))), - ReferlResult = els_refactorerl_utils:query("mods[name=" ++ ModuleName ++ "].macros[not .references]"), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois] - end - end; - _ -> - [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Can't add module to RefactorErl!">> }), - []. - --spec source() -> binary(). -source() -> - <<"Unused Macros (Referl)">>. - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . - Range = els_protocol:range(PoiRange), - MacroName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Unused macro: ", MacroName/binary>>, - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - From 67a06dcc01e374e69d1b59997394b503772f9bf6 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 8 Dec 2021 19:32:58 +0100 Subject: [PATCH 065/103] Styling conventions --- .../src/els_refactorerl_diagnostics.erl | 77 ++++++++++--------- apps/els_lsp/src/els_refactorerl_utils.erl | 72 ++++++++++------- 2 files changed, 86 insertions(+), 63 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d99403c38..5e5b49f4c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -23,69 +23,59 @@ -define(MAX_RECURSION_DEPTH, 10). %%============================================================================== -%% Callback Functions +%% Types %%============================================================================== - - -%%======================================= -%%======================================= - -%% {id, pre, after} -%% -%% -%% -type diagnostic_id() :: binary(). - --type refactorerl_diagnostic_id() :: {atom(), [char()], [char()]}. +-type refactorerl_diagnostic_id() :: {atom(), [char()], [char()], [char()]}. -type refactorerl_query() :: [char()]. --spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unused_macros, "mods[name=", "].funs.unsecure_calls"} - , {unsecure_calls, "mods[name=", "].macros[not .references]"} - ]. +%%============================================================================== +%% Callback Functions +%%============================================================================== + -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, Before, After}, Module) -> +make_query({_, _, Before, After}, Module) -> ModuleStr = atom_to_list(Module), Before ++ ModuleStr ++ After. --spec run_query(module(),refactorerl_diagnostic_id()) -> ([els_diagnostics:diagnostic()]). +-spec run_query(module(), refactorerl_diagnostic_id()) -> + ([els_diagnostics:diagnostic()]). run_query(Module, DiagnosticId) -> + {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi) || Poi <- Pois]. + [make_diagnostic(Poi, Message) || Poi <- Pois]. - -%%======================================= -%%======================================= -spec is_default() -> boolean(). is_default() -> true. -spec run(uri()) -> [els_diagnostics:diagnostic()]. -run(Uri)-> +run(Uri) -> run(Uri, 0). --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. +-spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of - <<".erl">> -> + <<".erl">> -> case els_refactorerl_utils:referl_node() of disabled -> []; - Node -> - case rpc:call(Node, ri, add, [binary_to_list(els_uri:path(Uri))], els_refactorerl_utils:maxtimeout()) of + _ -> + case add(Uri) of busy -> timer:sleep(1000), run(Uri, RecursionDepth + 1); disabled -> []; _ -> - Module = list_to_atom(filename:rootname(filename:basename(binary_to_list(els_uri:path(Uri))))), - lists:concat([run_query(Module, DiagnosticId) || DiagnosticId <- refactorerl_diagnostics()]) + FileName = filename:basename(binary_to_list(els_uri:path(Uri))), + Module = list_to_atom(filename:rootname(FileName)), + Diagnostics = refactorerl_diagnostics(), + lists:concat([run_query(Module, DiagId) || DiagId <- Diagnostics]) end end; _ -> @@ -93,7 +83,9 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"Cannot add module to RefactorErl!">> }), + Param = #{ type => ?MESSAGE_TYPE_ERROR, + message => <<"Cannot add module to RefactorErl!">> }, + els_server:send_notification(<<"window/showMessage">>, Param), []. -spec source() -> binary(). @@ -104,11 +96,24 @@ source() -> %% Internal Functions %%============================================================================== --spec make_diagnostic(poi()) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}) -> %#{id := POIId, range := POIRange} . +-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). +make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Range = els_protocol:range(PoiRange), - IssueName = list_to_binary(PoiData), % TODO Robi: the ID and the arity should be encoded to the ID - Message = <<"Security Issue: ", IssueName/binary>>, + Message = list_to_binary(DiagMessage ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). \ No newline at end of file + els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + +-spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. +refactorerl_diagnostics() -> + [ {unused_macros, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unsecure_calls + , "Unused Macros:" + , "mods[name=" + , "].macros[not .references]" } + ]. + +-spec add(any()) -> atom(). +add(Uri) -> + Param = [binary_to_list(els_uri:path(Uri))], + rpc:call(node(), ri, add, Param, els_refactorerl_utils:maxtimeout()). \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 7aef407fe..b1d4631ae 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -20,18 +20,23 @@ %%============================================================================== %% API %%============================================================================== -%% If called with no args try to get the node from config. Use the referl_node/1 to validate. +%% If called with no args try to get the node from config. +%% Use the referl_node/1 to validate. %% If the node once was validated there will be no display messages. -%% +%% %% Node can be: %% - NodeStr -%% - {Status, Node} where both are atoms. +%% - {Status, Node} where both are atoms. %% - Status can be: %% - validated: node is running %% - disconnected: node is not running -%% - disabled: RefactorErl is turned off for this session. This can happen after an unsuccessfull query attempt. --spec referl_node() -> atom() | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +%% - disabled: RefactorErl is turned off for this session. T +%% his can happen after an unsuccessfull query attempt. +-spec referl_node() -> atom() + | {error, disconnected} + | {error, disabled} + | {error, other}. +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> Node; @@ -40,62 +45,70 @@ referl_node() -> #{"node" := disabled} -> {error, disabled}; #{"node" := NodeStr} -> - Node = els_utils:compose_node_name(NodeStr, els_config_runtime:get_name_type()), + RT = els_config_runtime:get_name_type(), + Node = els_utils:compose_node_name(NodeStr, RT), try_connect_node({validate, Node}); - _ -> + _ -> {error, other} end. - + %%============================================================================== %% Internal Functions %%============================================================================== -spec disable_node() -> atom(). disable_node() -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_ERROR, message => <<"RefactorErl is disconnected! Reload ELS after you fixed theRefactorErl node!">> }), + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_ERROR, + message => <<"RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!">> }), els_config:set(refactorerl, #{"node" => disabled}), {error, disabled}. -spec query(string()) -> list() | {error, disabled}. -query(Query) -> - %% rpc:call(referl@fikoMac, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], "mods.fun"], 3000) +query(Query) -> case referl_node() of {error, _} -> []; Node -> - Response = rpc:call(Node, refusr_sq, run, [[{positions, linecol}, {output, msg}], [], Query], maxtimeout()), + P = [{positions, linecol}, {output, msg}], + Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), case Response of {badrpc, _} -> disable_node(); % Returns disabled error -> - busy; % RefactorErl node is probably busy. + busy; % RefactorErl node is probably busy. _ -> Response end end. --spec convert_to_poi(any()) -> poi(). +-spec convert_to_poi(any()) -> poi(). convert_to_poi(ReferlResult) -> case ReferlResult of - [{_, _, _, DataList}] -> % [{Option, Tuple, Atom, DataList}] = Out + [{_, _, _, DataList}] -> convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> % [ {{Path, StartPos, EndPos}, MacroName} | Tail] = DataList + [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), % Additional Data param can be added + Poi = els_poi:new(Range, application, Id, Name), [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. - --spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). + +-spec check_node(atom()) -> {error, timeout} + | {error, badrpc} + | {error, other} + | atom(). check_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), % Calls the RefactorErl node, to check if it's alive + % Calls the RefactorErl node, to check if it's alive + Response = rpc:call(Node, ri, ls, [], 10000), case Response of {{ok, _}, {error, _}} -> Node; - ok-> + ok -> Node; {badrpc, timeout} -> {error, timeout}; @@ -105,18 +118,23 @@ check_node(Node) -> {error, other} end. --spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom() . +-spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} + | atom(). try_connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is not connected!">> }), + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_INFO, + message => <<"RefactorErl is not connected!">> }), els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; - {_ ,Node} -> - els_server:send_notification(<<"window/showMessage">>, #{ type => ?MESSAGE_TYPE_INFO, message => <<"RefactorErl is connected!">> }), + {_, Node} -> + els_server:send_notification(<<"window/showMessage">>, + #{ type => ?MESSAGE_TYPE_INFO, + message => <<"RefactorErl is connected!">> }), els_config:set(refactorerl, #{"node" => {Node, validated}}), Node end. @@ -127,5 +145,5 @@ try_connect_node({Status, Node}) -> %%============================================================================== -spec maxtimeout() -> number(). -maxtimeout() -> +maxtimeout() -> 3000. From cc9ae372433bd92e59959d8b120fa2c6dce70e98 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:15:44 +0100 Subject: [PATCH 066/103] Change 'disabled' to 'notconfigured' This is needed to avoid confusion between disabled which should means, that the node is disabled *on purpose of bad behavior* from notconfigured which self-descriptive --- apps/els_core/src/els_config.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 4ec38dcea..3ff4c23ec 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -78,7 +78,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => { map() | 'disabled'} + , refactorerl => { map() | 'notconfigured'} }. %%============================================================================== @@ -140,7 +140,7 @@ do_initialize(RootUri, Capabilities, InitOptions, {ConfigPath, Config}) -> IndexingEnabled = maps:get(<<"indexingEnabled">>, InitOptions, true), - RefactorErl = maps:get("refactorerl", Config, disabled), + RefactorErl = maps:get("refactorerl", Config, notconfigured), %% Passed by the LSP client ok = set(root_uri , RootUri), From c53711657553a7f856a90f58349aa89903bde34a Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:17:52 +0100 Subject: [PATCH 067/103] Documentation and utility functions, fixes Heavy documentation added and new notification utility function The syntax of Node recognition is re-taught to make more sense --- apps/els_lsp/src/els_refactorerl_utils.erl | 97 ++++++++++++++++------ 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index b1d4631ae..f37f157a1 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -10,6 +10,8 @@ , referl_node/0 , maxtimeout/0 , query/1 + , notification/1 + , notification/2 ]). %%============================================================================== @@ -20,10 +22,23 @@ %%============================================================================== %% API %%============================================================================== -%% If called with no args try to get the node from config. -%% Use the referl_node/1 to validate. + +%% @doc +%% Returns the RefactorErl node, if it cannot, it will return error and the cause. +%% It returns the node given in config, if it is alive. +%% First it runs the validation functions, the result of validation will be +%% notified to the user. %% If the node once was validated there will be no display messages. %% +%% The configuration can store the node and its status. +%% - Either a simple NodeString, which needs to be checked and configure +%% - {Node, Status} where boths are atoms +%% Possible statuses: validated, disconnected, disabled +%% 'disabled', when it won't try to reconnect +%% 'disconnected', when it will try to reconnect +%% - notconfigured, the node is not configured in the config file +%% +%% %% Node can be: %% - NodeStr %% - {Status, Node} where both are atoms. @@ -32,22 +47,30 @@ %% - disconnected: node is not running %% - disabled: RefactorErl is turned off for this session. T %% his can happen after an unsuccessfull query attempt. --spec referl_node() -> atom() +-spec referl_node() -> {ok, atom()} | {error, disconnected} | {error, disabled} | {error, other}. referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> - Node; + {ok, Node}; + #{"node" := {Node, disconnected}} -> try_connect_node({retry, Node}); - #{"node" := disabled} -> + + #{"node" := {_, disabled}} -> {error, disabled}; + #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), try_connect_node({validate, Node}); + + disabled -> + notification("RefactorErl is not configured!"), + {error, disabled}; + _ -> {error, other} end. @@ -57,53 +80,66 @@ referl_node() -> %% Internal Functions %%============================================================================== --spec disable_node() -> atom(). -disable_node() -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_ERROR, - message => <<"RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!">> }), - els_config:set(refactorerl, #{"node" => disabled}), +-spec disable_node(atom()) -> atom(). +%%@doc +%% Disables the node given in paramter, also notifes the user. +disable_node(Node) -> + Msg = "RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!", + notification(Msg, ?MESSAGE_TYPE_ERROR), + + els_config:set(refactorerl, #{"node" => {Node, disabled}}), {error, disabled}. + + %%@doc + %% Runs a Query on the RefactorErl node, returns its result if successfull + %% If error happens, it just returns an empty list, as most of times the + %% result then is directly converted to POIs. + %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. query(Query) -> case referl_node() of {error, _} -> []; - Node -> + {ok, Node} -> P = [{positions, linecol}, {output, msg}], Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), case Response of {badrpc, _} -> - disable_node(); % Returns disabled + disable_node(Node); % Returns disabled error -> - busy; % RefactorErl node is probably busy. + []; _ -> Response end end. -spec convert_to_poi(any()) -> poi(). +%%@doc +%% Convert a RefactorErl result to a POI, for the LS system +%% The RefactorErl format is how the refusr_sq:run\3 returns convert_to_poi(ReferlResult) -> case ReferlResult of [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = referl_atom_unsec, %"{module(), 'atom()', 'arity()''}", + Id = refactorerl_poi, %"{module(), 'atom()', 'arity()''}", Poi = els_poi:new(Range, application, Id, Name), [ Poi | convert_to_poi(Tail) ]; _ -> [] %TODO Robi notify end. + +%%@doc +%% Calls the RefactorErl node, to check if it's alive using ri:ls() -spec check_node(atom()) -> {error, timeout} | {error, badrpc} | {error, other} | atom(). check_node(Node) -> - % Calls the RefactorErl node, to check if it's alive Response = rpc:call(Node, ri, ls, [], 10000), case Response of {{ok, _}, {error, _}} -> @@ -118,27 +154,38 @@ check_node(Node) -> {error, other} end. +%%@doc +%% Tries to connect to a node +%% When statues is validate, it reports the success, and failure as well, when retry, it won't report. -spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). try_connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_INFO, - message => <<"RefactorErl is not connected!">> }), + notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> els_config:set(refactorerl, #{"node" => {Node, disconnected}}), {error, disconnected}; {_, Node} -> - els_server:send_notification(<<"window/showMessage">>, - #{ type => ?MESSAGE_TYPE_INFO, - message => <<"RefactorErl is connected!">> }), + notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, #{"node" => {Node, validated}}), - Node + {ok, Node} end. +%%@doc +%% Util for popping up notifications +-spec notification(string(), number()) -> atom(). +notification(Msg, Severity) -> + Param = #{ type => Severity, + message => list_to_binary(Msg) }, + els_server:send_notification(<<"window/showMessage">>, Param). + +-spec notification(string()) -> atom(). +notification(Msg) -> + notification(Msg, ?MESSAGE_TYPE_INFO). + %%============================================================================== %% Values @@ -146,4 +193,4 @@ try_connect_node({Status, Node}) -> -spec maxtimeout() -> number(). maxtimeout() -> - 3000. + 10000. From 66dd3e8debc1eeddd0f54162f9f6cbbe421bac32 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 27 Jan 2022 21:18:14 +0100 Subject: [PATCH 068/103] Documentation added --- .../src/els_refactorerl_diagnostics.erl | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5e5b49f4c..c0fbdbb7c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -33,7 +33,8 @@ %%============================================================================== - +%%@doc +%% Creates a RefactorErl query from a diagnostic identifier and a module name -spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). make_query({_, _, Before, After}, Module) -> ModuleStr = atom_to_list(Module), @@ -83,9 +84,8 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - Param = #{ type => ?MESSAGE_TYPE_ERROR, - message => <<"Cannot add module to RefactorErl!">> }, - els_server:send_notification(<<"window/showMessage">>, Param), + Msg = "Cannot add module to RefactorErl!", + els_refactorerl_utils:notification(Msg, ?MESSAGE_TYPE_ERROR), []. -spec source() -> binary(). @@ -96,6 +96,9 @@ source() -> %% Internal Functions %%============================================================================== +%%@doc +%% Creates a diagnostic form the Poi data and a Message +%% The severity is only warning. -spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Range = els_protocol:range(PoiRange), @@ -104,16 +107,25 @@ make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> Source = source(), els_diagnostics:make_diagnostic(Range, Message, Severity, Source). + %%@doc + %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unused_macros, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unsecure_calls +refactorerl_diagnostics() -> % TODO: Make it configureable + [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unsecure_macros , "Unused Macros:" , "mods[name=" , "].macros[not .references]" } ]. --spec add(any()) -> atom(). + %%@doc + %% Adds a module to the RefactorErl node. +-spec add(any()) -> atom(). %TODO: Add .hrl files add(Uri) -> Param = [binary_to_list(els_uri:path(Uri))], - rpc:call(node(), ri, add, Param, els_refactorerl_utils:maxtimeout()). \ No newline at end of file + case els_refactorerl_utils:referl_node() of + {ok, Node} -> + rpc:call(Node, ri, add, Param, els_refactorerl_utils:maxtimeout()); + _ -> + error + end. \ No newline at end of file From 60d7effb08c6be287818c61849a440b88cc3e281 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 28 Jan 2022 09:20:26 +0100 Subject: [PATCH 069/103] Line length changes --- apps/els_lsp/src/els_refactorerl_utils.erl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index f37f157a1..21b983c21 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -24,10 +24,10 @@ %%============================================================================== %% @doc -%% Returns the RefactorErl node, if it cannot, it will return error and the cause. +%% Returns the RefactorErl node, if it can't, it returns error and its cause. %% It returns the node given in config, if it is alive. -%% First it runs the validation functions, the result of validation will be -%% notified to the user. +%% First it runs the validation functions, the result of validation will be +%% notified to the user. %% If the node once was validated there will be no display messages. %% %% The configuration can store the node and its status. @@ -37,7 +37,7 @@ %% 'disabled', when it won't try to reconnect %% 'disconnected', when it will try to reconnect %% - notconfigured, the node is not configured in the config file -%% +%% %% %% Node can be: %% - NodeStr @@ -61,7 +61,7 @@ referl_node() -> #{"node" := {_, disabled}} -> {error, disabled}; - + #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), @@ -156,7 +156,8 @@ check_node(Node) -> %%@doc %% Tries to connect to a node -%% When statues is validate, it reports the success, and failure as well, when retry, it won't report. +%% When statues is validate, it reports the success, and failure as well, +%% when retry, it won't report. -spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). try_connect_node({Status, Node}) -> From fadc0649ab38cacba5a9a62aa616f680769bbcc0 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Wed, 2 Feb 2022 19:30:19 +0100 Subject: [PATCH 070/103] Minor changes --- .../src/els_refactorerl_diagnostics.erl | 43 +++++++++---------- apps/els_lsp/src/els_refactorerl_utils.erl | 13 +++--- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index c0fbdbb7c..e992f6403 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Unsecure Calls by Referl +%% RefactorErl Diagnostics %%============================================================================== -module(els_refactorerl_diagnostics). @@ -32,23 +32,6 @@ %% Callback Functions %%============================================================================== - -%%@doc -%% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, _, Before, After}, Module) -> - ModuleStr = atom_to_list(Module), - Before ++ ModuleStr ++ After. - - --spec run_query(module(), refactorerl_diagnostic_id()) -> - ([els_diagnostics:diagnostic()]). -run_query(Module, DiagnosticId) -> - {_, Message, _, _} = DiagnosticId, - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), - [make_diagnostic(Poi, Message) || Poi <- Pois]. - -spec is_default() -> boolean(). is_default() -> true. @@ -90,7 +73,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"RefactorErl Diagnostics">>. + <<"RefactorErl">>. %%============================================================================== %% Internal Functions @@ -122,10 +105,26 @@ refactorerl_diagnostics() -> % TODO: Make it configureable %% Adds a module to the RefactorErl node. -spec add(any()) -> atom(). %TODO: Add .hrl files add(Uri) -> - Param = [binary_to_list(els_uri:path(Uri))], + Params = [binary_to_list(els_uri:path(Uri))], case els_refactorerl_utils:referl_node() of {ok, Node} -> - rpc:call(Node, ri, add, Param, els_refactorerl_utils:maxtimeout()); + rpc:call(Node, ri, add, Params, els_refactorerl_utils:maxtimeout()); _ -> error - end. \ No newline at end of file + end. + +%%@doc +%% Creates a RefactorErl query from a diagnostic identifier and a module name +-spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). +make_query({_, _, Before, After}, Module) -> + ModuleStr = atom_to_list(Module), + Before ++ ModuleStr ++ After. + + +-spec run_query(module(), refactorerl_diagnostic_id()) -> + ([els_diagnostics:diagnostic()]). +run_query(Module, DiagnosticId) -> + {_, Message, _, _} = DiagnosticId, + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), + Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 21b983c21..b8a8086bc 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Eralang LS & Refactor Erl conversion +%% Erlang LS & Refactor Erl conversion %%============================================================================== -module(els_refactorerl_utils). @@ -57,7 +57,7 @@ referl_node() -> {ok, Node}; #{"node" := {Node, disconnected}} -> - try_connect_node({retry, Node}); + connect_node({retry, Node}); #{"node" := {_, disabled}} -> {error, disabled}; @@ -65,7 +65,7 @@ referl_node() -> #{"node" := NodeStr} -> RT = els_config_runtime:get_name_type(), Node = els_utils:compose_node_name(NodeStr, RT), - try_connect_node({validate, Node}); + connect_node({validate, Node}); disabled -> notification("RefactorErl is not configured!"), @@ -120,7 +120,7 @@ query(Query) -> %% Convert a RefactorErl result to a POI, for the LS system %% The RefactorErl format is how the refusr_sq:run\3 returns convert_to_poi(ReferlResult) -> -case ReferlResult of +case ReferlResult of % TODO Robi !!! [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> @@ -158,9 +158,9 @@ check_node(Node) -> %% Tries to connect to a node %% When statues is validate, it reports the success, and failure as well, %% when retry, it won't report. --spec try_connect_node({validate | retry, atom()}) -> {error, disconnected} +-spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). -try_connect_node({Status, Node}) -> +connect_node({Status, Node}) -> case {Status, check_node(Node)} of {validate, {error, _}} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), @@ -195,3 +195,4 @@ notification(Msg) -> -spec maxtimeout() -> number(). maxtimeout() -> 10000. + From 77dd860fa6a0d4e0f89264ea0472baedd1a90599 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Fri, 4 Feb 2022 07:57:37 +0100 Subject: [PATCH 071/103] New, recieve based communication is working --- .../src/els_refactorerl_diagnostics.erl | 2 +- apps/els_lsp/src/els_refactorerl_utils.erl | 54 ++++++++++++++----- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e992f6403..7ef33373e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -126,5 +126,5 @@ make_query({_, _, Before, After}, Module) -> run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:convert_to_poi(ReferlResult), + Pois = els_refactorerl_utils:process_result(ReferlResult), [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index b8a8086bc..aedc95652 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -12,6 +12,7 @@ , query/1 , notification/1 , notification/2 + , process_result/1 ]). %%============================================================================== @@ -51,7 +52,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +referl_node() -> % TODO R: use envs case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -98,29 +99,41 @@ disable_node(Node) -> %% result then is directly converted to POIs. %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. -query(Query) -> - case referl_node() of +query(Query) -> % TODO R: remove the case + case referl_node() of {error, _} -> []; {ok, Node} -> - P = [{positions, linecol}, {output, msg}], - Response = rpc:call(Node, refusr_sq, run, [P, [], Query], maxtimeout()), - case Response of + DisplayOpt = [{positions, linecol}, {output, msg}], + ReqID = request_id(), + Opts = [ self() + , ReqID + , {transform, semantic_query + , [{ask_missing, false} + , {display_opt, DisplayOpt} + , {start_opt, []} + , {querystr, Query}]} + ], + Resp = rpc:call(Node, reflib_ui_router, request, Opts), + case Resp of {badrpc, _} -> disable_node(Node); % Returns disabled - error -> - []; - _ -> - Response + ok -> + receive + {ReqID, reply, Result} -> Result + end; + deny -> + notification("Query is denied!"), + [] end end. -spec convert_to_poi(any()) -> poi(). %%@doc %% Convert a RefactorErl result to a POI, for the LS system -%% The RefactorErl format is how the refusr_sq:run\3 returns +%% The RefactorErl format is how the refusr_sq:run\3 returns TODO convert_to_poi(ReferlResult) -> -case ReferlResult of % TODO Robi !!! +case ReferlResult of % TODO Robi !!! function clauses [{_, _, _, DataList}] -> convert_to_poi(DataList); [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> @@ -132,6 +145,11 @@ case ReferlResult of % TODO Robi !!! [] %TODO Robi notify end. +%TODO R spec +-spec process_result(any()) -> any(). +process_result({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}) -> + convert_to_poi(L). + %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() @@ -188,6 +206,18 @@ notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). +-spec request_id() -> any(). +request_id() -> % TODO R spec + case referl_node() of + {error, _} -> + nodedown; + {ok, Node} -> + rpc:call(Node, reflib_ui_router, getid, []) + end. + + + + %%============================================================================== %% Values %%============================================================================== From ffb0bea833709a14a475695e75990b0970f86c5f Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:13:11 +0100 Subject: [PATCH 072/103] Working with double diagnositc processing --- .../src/els_refactorerl_diagnostics.erl | 5 ++- apps/els_lsp/src/els_refactorerl_utils.erl | 39 ++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 7ef33373e..1cbcecf8c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -73,7 +73,7 @@ run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> -spec source() -> binary(). source() -> - <<"RefactorErl">>. + els_refactorerl_utils:source_name(). %%============================================================================== %% Internal Functions @@ -127,4 +127,5 @@ run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), Pois = els_refactorerl_utils:process_result(ReferlResult), - [make_diagnostic(Poi, Message) || Poi <- Pois]. \ No newline at end of file + Diags = els_refactorerl_utils:make_diagnostics(ReferlResult, Message), + [make_diagnostic(Poi, Message) || Poi <- Pois] ++ Diags. \ No newline at end of file diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index aedc95652..c699b2d53 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -13,7 +13,9 @@ , notification/1 , notification/2 , process_result/1 - ]). + , make_diagnostics/2 + , source_name/0 + ]). % TODO exports??? %%============================================================================== %% Includes & Defines @@ -52,7 +54,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> % TODO R: use envs +referl_node() -> % TODO Might be better to use envs in the future case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -99,7 +101,7 @@ disable_node(Node) -> %% result then is directly converted to POIs. %% If the node timeouts or badrpc will come back, it disables the node -spec query(string()) -> list() | {error, disabled}. -query(Query) -> % TODO R: remove the case +query(Query) -> % TODO: give a second tought to the case case referl_node() of {error, _} -> []; @@ -128,6 +130,28 @@ query(Query) -> % TODO R: remove the case end end. + +%TODO spec + + +-spec make_diagnostics(any(), string()) -> any(). +make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> + Range = #{ from => From, to => To }, + Id = refactorerl_poi, + #{ data := PoiData, range := PoiRange} = els_poi:new(Range, application, Id, Name), % TODO: How to make this line shorter??? + RangeLS = els_protocol:range(PoiRange), + Message = list_to_binary(DiagMsg ++ " " ++ PoiData), + Severity = ?DIAGNOSTIC_WARNING, + Source = source_name(), + Diagnostic = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), % TODO: How to make this line shorter??? + [ Diagnostic | make_diagnostics(Tail, DiagMsg) ]; + +make_diagnostics([], _) -> + []; + +make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? + make_diagnostics(L, DiagMsg). + -spec convert_to_poi(any()) -> poi(). %%@doc %% Convert a RefactorErl result to a POI, for the LS system @@ -206,8 +230,8 @@ notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). --spec request_id() -> any(). -request_id() -> % TODO R spec +-spec request_id() -> nodedown | {reqid | string()}. +request_id() -> case referl_node() of {error, _} -> nodedown; @@ -226,3 +250,8 @@ request_id() -> % TODO R spec maxtimeout() -> 10000. +%TODOcode organisation + +-spec source_name() -> binary(). +source_name() -> + <<"RefactorErl">>. \ No newline at end of file From 314dfae0690575d06b99e8274878d7421f086219 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:20:46 +0100 Subject: [PATCH 073/103] Poi conversion and diagnostic making merged --- .../src/els_refactorerl_diagnostics.erl | 18 ++-------- apps/els_lsp/src/els_refactorerl_utils.erl | 33 ++++--------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 1cbcecf8c..28e047a5d 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -79,19 +79,9 @@ source() -> %% Internal Functions %%============================================================================== -%%@doc -%% Creates a diagnostic form the Poi data and a Message -%% The severity is only warning. --spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). -make_diagnostic(#{ data := PoiData, range := PoiRange}, DiagMessage) -> - Range = els_protocol:range(PoiRange), - Message = list_to_binary(DiagMessage ++ " " ++ PoiData), - Severity = ?DIAGNOSTIC_WARNING, - Source = source(), - els_diagnostics:make_diagnostic(Range, Message, Severity, Source). - %%@doc - %% Returns the available diagnostics of RefactorErl. +%%@doc +%% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. refactorerl_diagnostics() -> % TODO: Make it configureable [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} @@ -126,6 +116,4 @@ make_query({_, _, Before, After}, Module) -> run_query(Module, DiagnosticId) -> {_, Message, _, _} = DiagnosticId, ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), - Pois = els_refactorerl_utils:process_result(ReferlResult), - Diags = els_refactorerl_utils:make_diagnostics(ReferlResult, Message), - [make_diagnostic(Poi, Message) || Poi <- Pois] ++ Diags. \ No newline at end of file + els_refactorerl_utils:make_diagnostics(ReferlResult, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index c699b2d53..a37e99746 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -6,13 +6,11 @@ %%============================================================================== %% API %%============================================================================== --export([ convert_to_poi/1 - , referl_node/0 +-export([ referl_node/0 , maxtimeout/0 , query/1 , notification/1 , notification/2 - , process_result/1 , make_diagnostics/2 , source_name/0 ]). % TODO exports??? @@ -132,8 +130,13 @@ query(Query) -> % TODO: give a second tought to the case %TODO spec +% TODO doku +% - +%%@doc +%% Creates a diagnostic form the Poi data and a Message +%% The severity is only warning. +%-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). -spec make_diagnostics(any(), string()) -> any(). make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, @@ -152,28 +155,6 @@ make_diagnostics([], _) -> make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? make_diagnostics(L, DiagMsg). --spec convert_to_poi(any()) -> poi(). -%%@doc -%% Convert a RefactorErl result to a POI, for the LS system -%% The RefactorErl format is how the refusr_sq:run\3 returns TODO -convert_to_poi(ReferlResult) -> -case ReferlResult of % TODO Robi !!! function clauses - [{_, _, _, DataList}] -> - convert_to_poi(DataList); - [{{_, {FromLine, FromCol}, {ToLine, ToCol}}, Name} | Tail] -> - Range = #{ from => {FromLine, FromCol}, to => {ToLine, ToCol} }, - Id = refactorerl_poi, %"{module(), 'atom()', 'arity()''}", - Poi = els_poi:new(Range, application, Id, Name), - [ Poi | convert_to_poi(Tail) ]; - _ -> - [] %TODO Robi notify -end. - -%TODO R spec --spec process_result(any()) -> any(). -process_result({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}) -> - convert_to_poi(L). - %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() From f9bc32c53faa5e3f3545f372e52bfaedb98b2c48 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:42:37 +0100 Subject: [PATCH 074/103] Set default to false --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 28e047a5d..e520a234e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - true. + false. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> From eec840ce0eff9695e758c1fedc121c992ba3b70e Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:47:17 +0100 Subject: [PATCH 075/103] Get the config out of tuple --- apps/els_core/src/els_config.erl | 2 +- apps/els_lsp/src/els_refactorerl_utils.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index 3ff4c23ec..b984da761 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -78,7 +78,7 @@ , indexing_enabled => boolean() , bsp_enabled => boolean() | auto , compiler_telemetry_enabled => boolean() - , refactorerl => { map() | 'notconfigured'} + , refactorerl => map() | 'notconfigured' }. %%============================================================================== diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index a37e99746..134131b86 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -73,7 +73,7 @@ referl_node() -> % TODO Might be better to use envs in the future {error, disabled}; _ -> - {error, other} + {error, other} % TODO: maybe check for 'notconfigured' end. From 239c9593d0805102f988fc961ae74718286e9f26 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 13:51:20 +0100 Subject: [PATCH 076/103] Specifyng case mathces and no-match cases --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e520a234e..84dac4d41 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -46,9 +46,9 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of - disabled -> + {error, _} -> []; - _ -> + {ok, _} -> case add(Uri) of busy -> timer:sleep(1000), From 5d72ecb3d03970c0c0d76967c470ef45e1a93066 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 14:47:25 +0100 Subject: [PATCH 077/103] Add as a request Moving the adding mechanism under the new communciation model --- .../src/els_refactorerl_diagnostics.erl | 12 ++---- apps/els_lsp/src/els_refactorerl_utils.erl | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 84dac4d41..5bf0059a1 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -83,7 +83,7 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> % TODO: Make it configureable +refactorerl_diagnostics() -> [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} , {unsecure_macros , "Unused Macros:" @@ -93,15 +93,9 @@ refactorerl_diagnostics() -> % TODO: Make it configureable %%@doc %% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). %TODO: Add .hrl files +-spec add(any()) -> atom(). add(Uri) -> - Params = [binary_to_list(els_uri:path(Uri))], - case els_refactorerl_utils:referl_node() of - {ok, Node} -> - rpc:call(Node, ri, add, Params, els_refactorerl_utils:maxtimeout()); - _ -> - error - end. + els_refactorerl_utils:add(Uri). %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 134131b86..598592ce1 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -13,6 +13,7 @@ , notification/2 , make_diagnostics/2 , source_name/0 + , add/1 ]). % TODO exports??? %%============================================================================== @@ -76,6 +77,42 @@ referl_node() -> % TODO Might be better to use envs in the future {error, other} % TODO: maybe check for 'notconfigured' end. +%%@doc +%% Adds a module to the RefactorErl node. +-spec add(any()) -> atom(). +add(Uri) -> + case els_refactorerl_utils:referl_node() of + {ok, Node} -> + Path = [binary_to_list(els_uri:path(Uri))], + ReqID = request_id(), + Resp = rpc:call( Node + , reflib_ui_router + , request + , [self(), ReqID, {add_dir, Path}] ), + case Resp of + {badrpc, _} -> + disable_node(Node); % Returns disabled + ok -> + receive + {ReqID, reply, {ok, _}} -> ok + end; + deny -> + notification("Query is denied!"), + [] + end; + _ -> + error + end. + + + + + + + + + + %%============================================================================== %% Internal Functions From a6cef1266cd8a94dde0873394f7e768629546ae3 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sun, 6 Feb 2022 15:45:46 +0100 Subject: [PATCH 078/103] Code clearing --- .../src/els_refactorerl_diagnostics.erl | 27 +-- apps/els_lsp/src/els_refactorerl_utils.erl | 173 +++++++++--------- 2 files changed, 95 insertions(+), 105 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5bf0059a1..3f05aaa6c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -20,7 +20,6 @@ %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% Types @@ -38,24 +37,16 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> - run(Uri, 0). - - --spec run(uri(), number()) -> [els_diagnostics:diagnostic()]. -run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> []; {ok, _} -> - case add(Uri) of - busy -> - timer:sleep(1000), - run(Uri, RecursionDepth + 1); - disabled -> + case els_refactorerl_utils:add(Uri) of + error -> []; - _ -> + ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), Diagnostics = refactorerl_diagnostics(), @@ -64,12 +55,7 @@ run(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> end; _ -> [] - end; - -run(_, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - Msg = "Cannot add module to RefactorErl!", - els_refactorerl_utils:notification(Msg, ?MESSAGE_TYPE_ERROR), - []. + end. -spec source() -> binary(). source() -> @@ -91,11 +77,6 @@ refactorerl_diagnostics() -> , "].macros[not .references]" } ]. - %%@doc - %% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). -add(Uri) -> - els_refactorerl_utils:add(Uri). %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 598592ce1..197a44b61 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -7,19 +7,19 @@ %% API %%============================================================================== -export([ referl_node/0 - , maxtimeout/0 , query/1 , notification/1 , notification/2 , make_diagnostics/2 , source_name/0 , add/1 - ]). % TODO exports??? - + ]). + %%============================================================================== %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). +-define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% API @@ -53,7 +53,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> % TODO Might be better to use envs in the future +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -61,7 +61,7 @@ referl_node() -> % TODO Might be better to use envs in the future #{"node" := {Node, disconnected}} -> connect_node({retry, Node}); - #{"node" := {_, disabled}} -> + #{"node" := {_Node, disabled}} -> {error, disabled}; #{"node" := NodeStr} -> @@ -69,18 +69,25 @@ referl_node() -> % TODO Might be better to use envs in the future Node = els_utils:compose_node_name(NodeStr, RT), connect_node({validate, Node}); - disabled -> + notconfigured -> notification("RefactorErl is not configured!"), {error, disabled}; _ -> - {error, other} % TODO: maybe check for 'notconfigured' + {error, other} end. + %%@doc -%% Adds a module to the RefactorErl node. --spec add(any()) -> atom(). -add(Uri) -> +%% Adds a module to the RefactorErl node. Using the UI router +%% Returns 'ok' if successfull +%% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries +-spec add(uri()) -> atom(). +add(Uri) -> + add(Uri, 0). + +-spec add(uri(), number()) -> atom(). +add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], @@ -91,52 +98,38 @@ add(Uri) -> , [self(), ReqID, {add_dir, Path}] ), case Resp of {badrpc, _} -> - disable_node(Node); % Returns disabled + disable_node(Node), + error; ok -> receive {ReqID, reply, {ok, _}} -> ok end; deny -> - notification("Query is denied!"), - [] + notification("Adding is deined, retry!"), % TODO: Take this out overtime stability proves itself + timer:sleep(1000), + add(Uri, RecursionDepth + 1) end; _ -> error - end. - - - - - + end; +add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), + error. - - - - -%%============================================================================== -%% Internal Functions -%%============================================================================== - --spec disable_node(atom()) -> atom(). + %%@doc -%% Disables the node given in paramter, also notifes the user. -disable_node(Node) -> - Msg = "RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!", - notification(Msg, ?MESSAGE_TYPE_ERROR), - - els_config:set(refactorerl, #{"node" => {Node, disabled}}), - {error, disabled}. - - - %%@doc - %% Runs a Query on the RefactorErl node, returns its result if successfull - %% If error happens, it just returns an empty list, as most of times the - %% result then is directly converted to POIs. - %% If the node timeouts or badrpc will come back, it disables the node --spec query(string()) -> list() | {error, disabled}. -query(Query) -> % TODO: give a second tought to the case +%% Runs a Query on the RefactorErl node, returns its result if successfull +%% If error happens, it just returns an empty list, as most of times the +%% result then is directly converted to POIs. +%% If the node timeouts or badrpc will come back, it disables the node and +%% stills returns an empty list +-spec query(string()) -> list(). +query(Query) -> + query(Query, 0). + +-spec query(string(), number()) -> list(). +query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> case referl_node() of {error, _} -> []; @@ -154,44 +147,74 @@ query(Query) -> % TODO: give a second tought to the case Resp = rpc:call(Node, reflib_ui_router, request, Opts), case Resp of {badrpc, _} -> - disable_node(Node); % Returns disabled + disable_node(Node), + []; % As most of times it is going to be processed right after. ok -> receive {ReqID, reply, Result} -> Result end; deny -> - notification("Query is denied!"), - [] + timer:sleep(1000), + query(Query, RecursionDepth + 1) end - end. + end; + +query(_Query, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> + notification("Cannot execute query on RefactorErl!", ?MESSAGE_TYPE_ERROR), + []. + + +%%@doc +%% Util for popping up notifications +-spec notification(string(), number()) -> atom(). +notification(Msg, Severity) -> + Param = #{ type => Severity, + message => list_to_binary(Msg) }, + els_server:send_notification(<<"window/showMessage">>, Param). +-spec notification(string()) -> atom(). +notification(Msg) -> + notification(Msg, ?MESSAGE_TYPE_INFO). -%TODO spec -% TODO doku -% %%@doc -%% Creates a diagnostic form the Poi data and a Message +%% Creates a list of diagnostics form the RefactorErl results and a message +%% Message can be the same, as this is called per diagnsotic type. %% The severity is only warning. -%-spec make_diagnostic(poi(), [char()]) -> els_diagnostics:diagnostic(). --spec make_diagnostics(any(), string()) -> any(). -make_diagnostics([{{_, From, To}, Name} | Tail], DiagMsg) -> +-spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. +make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, Id = refactorerl_poi, - #{ data := PoiData, range := PoiRange} = els_poi:new(Range, application, Id, Name), % TODO: How to make this line shorter??? + #{ data := PoiData, range := PoiRange} = + els_poi:new(Range, application, Id, Name), RangeLS = els_protocol:range(PoiRange), Message = list_to_binary(DiagMsg ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), - Diagnostic = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), % TODO: How to make this line shorter??? - [ Diagnostic | make_diagnostics(Tail, DiagMsg) ]; + Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), + [ Diag | make_diagnostics(Tail, DiagMsg) ]; make_diagnostics([], _) -> []; -make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> % TODO: How to make this line shorter??? +make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, + DiagMsg) -> make_diagnostics(L, DiagMsg). +%%============================================================================== +%% Internal Functions +%%============================================================================== + +-spec disable_node(atom()) -> atom(). +%%@doc +%% Disables the node given in paramter, also notifes the user. +disable_node(Node) -> + Msg = "RefactorErl is disconnected! + Reload ELS after you fixed theRefactorErl node!", + notification(Msg, ?MESSAGE_TYPE_ERROR), + + els_config:set(refactorerl, #{"node" => {Node, disabled}}), + {error, disabled}. %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() @@ -215,8 +238,10 @@ check_node(Node) -> end. %%@doc -%% Tries to connect to a node -%% When statues is validate, it reports the success, and failure as well, +%% Tries to connect to a node. +%% When it status is validate, the node hasn't been checked yet, +%% so it will reports the success, and failure as well, +%% %% when retry, it won't report. -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). @@ -236,18 +261,7 @@ connect_node({Status, Node}) -> end. %%@doc -%% Util for popping up notifications --spec notification(string(), number()) -> atom(). -notification(Msg, Severity) -> - Param = #{ type => Severity, - message => list_to_binary(Msg) }, - els_server:send_notification(<<"window/showMessage">>, Param). - --spec notification(string()) -> atom(). -notification(Msg) -> - notification(Msg, ?MESSAGE_TYPE_INFO). - - +%% Gets a request id from the RefactorErl node, and returns it -spec request_id() -> nodedown | {reqid | string()}. request_id() -> case referl_node() of @@ -257,19 +271,14 @@ request_id() -> rpc:call(Node, reflib_ui_router, getid, []) end. - - + %%============================================================================== %% Values %%============================================================================== --spec maxtimeout() -> number(). -maxtimeout() -> - 10000. - -%TODOcode organisation - +%%@doc +%% Common soruce name for all RefactorErl based backend(s) -spec source_name() -> binary(). source_name() -> <<"RefactorErl">>. \ No newline at end of file From 88aaccf0ed60dec4688cd021e38516b368b696ed Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Sat, 12 Feb 2022 13:10:05 +0100 Subject: [PATCH 079/103] make_diagnostic no result clause This function clause has an importance, when a diagnostic has no result --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 4 ++-- apps/els_lsp/src/els_refactorerl_utils.erl | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 3f05aaa6c..a503b6807 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -70,8 +70,8 @@ source() -> %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. refactorerl_diagnostics() -> - [ {unused_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unsecure_macros + [ {unsecure_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} + , {unused_macros , "Unused Macros:" , "mods[name=" , "].macros[not .references]" } diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 197a44b61..ff5ecb6c0 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -197,6 +197,10 @@ make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> make_diagnostics([], _) -> []; +% This is needed when there is no result from RefactorErl +make_diagnostics({ok,{result,[{result,[{list,[]}]}]}}, _) -> + []; + make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> make_diagnostics(L, DiagMsg). From 84e436a88a222cdc580144e70a6c381858ed9da0 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 16:37:03 +0100 Subject: [PATCH 080/103] Diagnostic description made --- .../src/els_refactorerl_diagnostics.erl | 67 ++++++++++++++----- apps/els_lsp/src/els_refactorerl_utils.erl | 15 +++-- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index a503b6807..d128c092a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_id() :: {atom(), [char()], [char()], [char()]}. +-type refactorerl_diagnostic_description() :: {[char()], [char()]}. -type refactorerl_query() :: [char()]. %%============================================================================== @@ -49,8 +49,8 @@ run(Uri) -> ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), - Diagnostics = refactorerl_diagnostics(), - lists:concat([run_query(Module, DiagId) || DiagId <- Diagnostics]) + Diagnostics = enabled_diagnostics(), + lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diagnostics]) end end; _ -> @@ -68,27 +68,58 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. --spec refactorerl_diagnostics() -> [refactorerl_diagnostic_id()]. -refactorerl_diagnostics() -> - [ {unsecure_calls, "Security Issue", "mods[name=", "].funs.unsecure_calls"} - , {unused_macros - , "Unused Macros:" - , "mods[name=" - , "].macros[not .references]" } - ]. +-spec refactorerl_diagnostics() -> + #{ atom() => refactorerl_diagnostic_description() }. +refactorerl_diagnostics() -> %//? Kérdés: atom szebb kulcsként vagy stringként, mert config stringként adja vissza, konvertáljuk? + #{ + % Unused Macros + "unused_macros" => + {"Unused Macros:", "].macros[not .references]"}, + % Detecting vulnerabilities + "unsecure_calls" => + {"Security Issue", "].funs.unsecure_calls"} + } +. + +-spec diagnostics_config() -> list(). +diagnostics_config() -> + case els_config:get(refactorerl) of + #{"diagnostics" := List} -> + List; + _ -> + [] + end. + +-spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. +enabled_diagnostics() -> + Diagnostics = refactorerl_diagnostics(), + EnabledDiagnostics = diagnostics_config(), + enabled_diagnostics(EnabledDiagnostics, Diagnostics). + + +-spec enabled_diagnostics(list(), map()) -> [refactorerl_diagnostic_description()]. +enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> + case maps:find(ConfigDiag, Diagnostics) of + {ok, Value} -> + [Value] ++ enabled_diagnostics(RemainingDiags, Diagnostics); + error -> + enabled_diagnostics(RemainingDiags, Diagnostics) + end; + +enabled_diagnostics([], _) -> + []. %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_id(), module()) -> refactorerl_query(). -make_query({_, _, Before, After}, Module) -> +-spec make_query(refactorerl_diagnostic_description(), module()) -> refactorerl_query(). +make_query({_, After}, Module) -> ModuleStr = atom_to_list(Module), - Before ++ ModuleStr ++ After. + "mods[name=" ++ ModuleStr ++ After. --spec run_query(module(), refactorerl_diagnostic_id()) -> +-spec run_query(module(), refactorerl_diagnostic_description()) -> ([els_diagnostics:diagnostic()]). -run_query(Module, DiagnosticId) -> - {_, Message, _, _} = DiagnosticId, - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticId, Module)), +run_query(Module, {Message, _} = DiagnosticDesc) -> + ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), els_refactorerl_utils:make_diagnostics(ReferlResult, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index ff5ecb6c0..e23964d3e 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -105,7 +105,10 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, {ok, _}} -> ok end; deny -> - notification("Adding is deined, retry!"), % TODO: Take this out overtime stability proves itself + case RecursionDepth of + 0 -> + notification("Adding is deined, retry!") + end, timer:sleep(1000), add(Uri, RecursionDepth + 1) end; @@ -217,7 +220,8 @@ disable_node(Node) -> Reload ELS after you fixed theRefactorErl node!", notification(Msg, ?MESSAGE_TYPE_ERROR), - els_config:set(refactorerl, #{"node" => {Node, disabled}}), + Config = els_config:get(refactorerl), + els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), {error, disabled}. %%@doc @@ -250,17 +254,18 @@ check_node(Node) -> -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). connect_node({Status, Node}) -> + Config = els_config:get(refactorerl), case {Status, check_node(Node)} of {validate, {error, _}} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {retry, {error, _}} -> - els_config:set(refactorerl, #{"node" => {Node, disconnected}}), + els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {_, Node} -> notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), - els_config:set(refactorerl, #{"node" => {Node, validated}}), + els_config:set(refactorerl, Config#{"node" => {Node, validated}}), {ok, Node} end. From f5b7518807a89646997ea7e205f7f2b9d4eb3f27 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 16:50:47 +0100 Subject: [PATCH 081/103] Coding conventions --- .../src/els_refactorerl_diagnostics.erl | 22 ++++++------ apps/els_lsp/src/els_refactorerl_utils.erl | 34 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index d128c092a..cd73ffce3 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -49,8 +49,8 @@ run(Uri) -> ok -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), - Diagnostics = enabled_diagnostics(), - lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diagnostics]) + Diags = enabled_diagnostics(), + lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end end; _ -> @@ -70,20 +70,20 @@ source() -> %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> #{ atom() => refactorerl_diagnostic_description() }. -refactorerl_diagnostics() -> %//? Kérdés: atom szebb kulcsként vagy stringként, mert config stringként adja vissza, konvertáljuk? +refactorerl_diagnostics() -> #{ % Unused Macros "unused_macros" => {"Unused Macros:", "].macros[not .references]"}, % Detecting vulnerabilities - "unsecure_calls" => + "unsecure_calls" => {"Security Issue", "].funs.unsecure_calls"} } . -spec diagnostics_config() -> list(). -diagnostics_config() -> +diagnostics_config() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> List; @@ -97,8 +97,9 @@ enabled_diagnostics() -> EnabledDiagnostics = diagnostics_config(), enabled_diagnostics(EnabledDiagnostics, Diagnostics). - --spec enabled_diagnostics(list(), map()) -> [refactorerl_diagnostic_description()]. + +-spec enabled_diagnostics(list(), map()) -> + [refactorerl_diagnostic_description()]. enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> case maps:find(ConfigDiag, Diagnostics) of {ok, Value} -> @@ -112,7 +113,8 @@ enabled_diagnostics([], _) -> %%@doc %% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_description(), module()) -> refactorerl_query(). +-spec make_query(refactorerl_diagnostic_description(), module()) -> + refactorerl_query(). make_query({_, After}, Module) -> ModuleStr = atom_to_list(Module), "mods[name=" ++ ModuleStr ++ After. @@ -121,5 +123,5 @@ make_query({_, After}, Module) -> -spec run_query(module(), refactorerl_diagnostic_description()) -> ([els_diagnostics:diagnostic()]). run_query(Module, {Message, _} = DiagnosticDesc) -> - ReferlResult = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), - els_refactorerl_utils:make_diagnostics(ReferlResult, Message). + Result = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), + els_refactorerl_utils:make_diagnostics(Result, Message). diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index e23964d3e..d98cf6678 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -14,7 +14,7 @@ , source_name/0 , add/1 ]). - + %%============================================================================== %% Includes & Defines %%============================================================================== @@ -53,7 +53,7 @@ | {error, disconnected} | {error, disabled} | {error, other}. -referl_node() -> +referl_node() -> case els_config:get(refactorerl) of #{"node" := {Node, validated}} -> {ok, Node}; @@ -83,7 +83,7 @@ referl_node() -> %% Returns 'ok' if successfull %% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries -spec add(uri()) -> atom(). -add(Uri) -> +add(Uri) -> add(Uri, 0). -spec add(uri(), number()) -> atom(). @@ -120,7 +120,7 @@ add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), error. - + %%@doc %% Runs a Query on the RefactorErl node, returns its result if successfull %% If error happens, it just returns an empty list, as most of times the @@ -132,8 +132,8 @@ query(Query) -> query(Query, 0). -spec query(string(), number()) -> list(). -query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> - case referl_node() of +query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> + case referl_node() of {error, _} -> []; {ok, Node} -> @@ -141,7 +141,7 @@ query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH-> ReqID = request_id(), Opts = [ self() , ReqID - , {transform, semantic_query + , {transform, semantic_query , [{ask_missing, false} , {display_opt, DisplayOpt} , {start_opt, []} @@ -189,22 +189,22 @@ make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, Id = refactorerl_poi, #{ data := PoiData, range := PoiRange} = - els_poi:new(Range, application, Id, Name), + els_poi:new(Range, application, Id, Name), RangeLS = els_protocol:range(PoiRange), Message = list_to_binary(DiagMsg ++ " " ++ PoiData), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), - Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), + Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), [ Diag | make_diagnostics(Tail, DiagMsg) ]; make_diagnostics([], _) -> []; % This is needed when there is no result from RefactorErl -make_diagnostics({ok,{result,[{result,[{list,[]}]}]}}, _) -> +make_diagnostics({ok, {result, [{result, [{list, []}]}]}}, _) -> []; -make_diagnostics({ok, {result, [{result,[{group_by, {nopos, _}, list, L}]}]}}, +make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, DiagMsg) -> make_diagnostics(L, DiagMsg). @@ -246,10 +246,10 @@ check_node(Node) -> end. %%@doc -%% Tries to connect to a node. -%% When it status is validate, the node hasn't been checked yet, +%% Tries to connect to a node. +%% When it status is validate, the node hasn't been checked yet, %% so it will reports the success, and failure as well, -%% +%% %% when retry, it won't report. -spec connect_node({validate | retry, atom()}) -> {error, disconnected} | atom(). @@ -270,7 +270,7 @@ connect_node({Status, Node}) -> end. %%@doc -%% Gets a request id from the RefactorErl node, and returns it +%% Gets a request id from the RefactorErl node, and returns it -spec request_id() -> nodedown | {reqid | string()}. request_id() -> case referl_node() of @@ -280,14 +280,12 @@ request_id() -> rpc:call(Node, reflib_ui_router, getid, []) end. - - %%============================================================================== %% Values %%============================================================================== %%@doc -%% Common soruce name for all RefactorErl based backend(s) +%% Common soruce name for all RefactorErl based backend(s) -spec source_name() -> binary(). source_name() -> <<"RefactorErl">>. \ No newline at end of file From 6527f1ef9e7134ec3766e1d03c0a4ed93e0b7ccb Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:32:18 +0100 Subject: [PATCH 082/103] a few dyalizer errors --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 6 +++--- apps/els_lsp/src/els_refactorerl_utils.erl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index cd73ffce3..eef1bcce7 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_description() :: {[char()], [char()]}. +-type refactorerl_diagnostic_description() :: {string(), string()}. -type refactorerl_query() :: [char()]. %%============================================================================== @@ -35,7 +35,7 @@ is_default() -> false. --spec run(uri()) -> [els_diagnostics:diagnostic()]. + -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> case filename:extension(Uri) of <<".erl">> -> @@ -50,7 +50,7 @@ run(Uri) -> FileName = filename:basename(binary_to_list(els_uri:path(Uri))), Module = list_to_atom(filename:rootname(FileName)), Diags = enabled_diagnostics(), - lists:concat([run_query(Module, DiagDesc) || DiagDesc <- Diags]) + lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end end; _ -> diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index d98cf6678..fc5694a11 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -212,7 +212,7 @@ make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, %% Internal Functions %%============================================================================== --spec disable_node(atom()) -> atom(). +-spec disable_node(atom()) -> {error, disabled}. %%@doc %% Disables the node given in paramter, also notifes the user. disable_node(Node) -> From 9aa18f9d9b275fcf9f3545f05cda07b14957a5ef Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:59:30 +0100 Subject: [PATCH 083/103] Case clause --- apps/els_lsp/src/els_refactorerl_utils.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index fc5694a11..a06a4dfd9 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -107,7 +107,9 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> deny -> case RecursionDepth of 0 -> - notification("Adding is deined, retry!") + notification("Adding is deined, retry!"); + _ -> + notified_already end, timer:sleep(1000), add(Uri, RecursionDepth + 1) From ce85588caed473db7346745126461cef65976d58 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Mon, 14 Feb 2022 17:59:42 +0100 Subject: [PATCH 084/103] Function spec --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index eef1bcce7..e0d61acb8 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -69,7 +69,7 @@ source() -> %%@doc %% Returns the available diagnostics of RefactorErl. -spec refactorerl_diagnostics() -> - #{ atom() => refactorerl_diagnostic_description() }. + #{ string() => refactorerl_diagnostic_description() }. refactorerl_diagnostics() -> #{ % Unused Macros From 52683944e4630cd5f8c3b94e3f9b5801814a3ec2 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 17 Feb 2022 07:56:25 +0100 Subject: [PATCH 085/103] POI removal --- apps/els_lsp/src/els_refactorerl_utils.erl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index a06a4dfd9..747d43a60 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -189,11 +189,8 @@ notification(Msg) -> -spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> Range = #{ from => From, to => To }, - Id = refactorerl_poi, - #{ data := PoiData, range := PoiRange} = - els_poi:new(Range, application, Id, Name), - RangeLS = els_protocol:range(PoiRange), - Message = list_to_binary(DiagMsg ++ " " ++ PoiData), + RangeLS = els_protocol:range(Range), + Message = list_to_binary(DiagMsg ++ " " ++ Name), Severity = ?DIAGNOSTIC_WARNING, Source = source_name(), Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), From fc7fc1f68f207a0868611f076504d26a7ab346a0 Mon Sep 17 00:00:00 2001 From: Robert Fiko Date: Thu, 17 Feb 2022 07:57:31 +0100 Subject: [PATCH 086/103] Diagnostic descriptor change This is due to preparing to new diagnostics --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e0d61acb8..f2a80a1b5 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -76,9 +76,9 @@ refactorerl_diagnostics() -> "unused_macros" => {"Unused Macros:", "].macros[not .references]"}, - % Detecting vulnerabilities - "unsecure_calls" => - {"Security Issue", "].funs.unsecure_calls"} + % Checks for OS injection + "unsecure_os_call" => + {"Unsecure OS call:", "].funs.unsecure_os_call"} } . From 26bc7ad0ade94ea999d9ab13f821039b6a446206 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 17 Feb 2022 21:23:03 +0100 Subject: [PATCH 087/103] Retry removal, smaller fixes --- .../src/els_refactorerl_diagnostics.erl | 3 +- apps/els_lsp/src/els_refactorerl_utils.erl | 47 +++++-------------- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index f2a80a1b5..52a6abd65 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -47,8 +47,7 @@ run(Uri) -> error -> []; ok -> - FileName = filename:basename(binary_to_list(els_uri:path(Uri))), - Module = list_to_atom(filename:rootname(FileName)), + Module = els_uri:module(Uri), Diags = enabled_diagnostics(), lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) end diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 747d43a60..9971adc10 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -19,7 +19,6 @@ %% Includes & Defines %%============================================================================== -include("els_lsp.hrl"). --define(MAX_RECURSION_DEPTH, 10). %%============================================================================== %% API @@ -82,16 +81,12 @@ referl_node() -> %% Adds a module to the RefactorErl node. Using the UI router %% Returns 'ok' if successfull %% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries --spec add(uri()) -> atom(). +-spec add(uri()) -> error | ok. add(Uri) -> - add(Uri, 0). - --spec add(uri(), number()) -> atom(). -add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], - ReqID = request_id(), + {ok, ReqID} = request_id(), Resp = rpc:call( Node , reflib_ui_router , request @@ -105,22 +100,12 @@ add(Uri, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, {ok, _}} -> ok end; deny -> - case RecursionDepth of - 0 -> - notification("Adding is deined, retry!"); - _ -> - notified_already - end, - timer:sleep(1000), - add(Uri, RecursionDepth + 1) + error end; _ -> error - end; + end. -add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - notification("Cannot add module to RefactorErl!", ?MESSAGE_TYPE_ERROR), - error. %%@doc @@ -130,17 +115,13 @@ add(_Uri, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> %% If the node timeouts or badrpc will come back, it disables the node and %% stills returns an empty list -spec query(string()) -> list(). -query(Query) -> - query(Query, 0). - --spec query(string(), number()) -> list(). -query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> +query(Query) -> case referl_node() of {error, _} -> []; {ok, Node} -> DisplayOpt = [{positions, linecol}, {output, msg}], - ReqID = request_id(), + {ok, ReqID} = request_id(), Opts = [ self() , ReqID , {transform, semantic_query @@ -159,15 +140,9 @@ query(Query, RecursionDepth) when RecursionDepth < ?MAX_RECURSION_DEPTH -> {ReqID, reply, Result} -> Result end; deny -> - timer:sleep(1000), - query(Query, RecursionDepth + 1) + [] end - end; - -query(_Query, RecursionDepth) when RecursionDepth >= ?MAX_RECURSION_DEPTH -> - notification("Cannot execute query on RefactorErl!", ?MESSAGE_TYPE_ERROR), - []. - + end. %%@doc %% Util for popping up notifications @@ -270,13 +245,13 @@ connect_node({Status, Node}) -> %%@doc %% Gets a request id from the RefactorErl node, and returns it --spec request_id() -> nodedown | {reqid | string()}. +-spec request_id() -> {error, nodedown} | {ok, {reqid | string()}}. request_id() -> case referl_node() of {error, _} -> - nodedown; + {error, nodedown}; {ok, Node} -> - rpc:call(Node, reflib_ui_router, getid, []) + {ok, rpc:call(Node, reflib_ui_router, getid, [])} end. %%============================================================================== From 9ef5cebfc62573dcdfecb626c2b75936e8888aa0 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:15:00 +0100 Subject: [PATCH 088/103] Working logic, cleaning out... --- .../src/els_refactorerl_diagnostics.erl | 57 ++------ apps/els_lsp/src/els_refactorerl_utils.erl | 137 +++++------------- 2 files changed, 50 insertions(+), 144 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 52a6abd65..5f99b9281 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -25,7 +25,7 @@ %% Types %%============================================================================== -type refactorerl_diagnostic_description() :: {string(), string()}. --type refactorerl_query() :: [char()]. +%-type refactorerl_query() :: [char()]. %%============================================================================== %% Callback Functions @@ -49,7 +49,8 @@ run(Uri) -> ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), - lists:append([run_query(Module, DiagDesc) || DiagDesc <- Diags]) + Results = els_refactorerl_utils:run_diagnostics(Diags, Module), + make_diagnostics(Results) end end; _ -> @@ -65,21 +66,9 @@ source() -> %%============================================================================== -%%@doc -%% Returns the available diagnostics of RefactorErl. --spec refactorerl_diagnostics() -> - #{ string() => refactorerl_diagnostic_description() }. -refactorerl_diagnostics() -> - #{ - % Unused Macros - "unused_macros" => - {"Unused Macros:", "].macros[not .references]"}, - % Checks for OS injection - "unsecure_os_call" => - {"Unsecure OS call:", "].funs.unsecure_os_call"} - } -. + +%TODO: add default diagnostics -spec diagnostics_config() -> list(). diagnostics_config() -> @@ -92,35 +81,21 @@ diagnostics_config() -> -spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. enabled_diagnostics() -> - Diagnostics = refactorerl_diagnostics(), + %%Diagnostics = refactorerl_diagnostics(), EnabledDiagnostics = diagnostics_config(), - enabled_diagnostics(EnabledDiagnostics, Diagnostics). + %%enabled_diagnostics(EnabledDiagnostics, Diagnostics). + EnabledDiagnostics. --spec enabled_diagnostics(list(), map()) -> - [refactorerl_diagnostic_description()]. -enabled_diagnostics([ ConfigDiag | RemainingDiags ], Diagnostics) -> - case maps:find(ConfigDiag, Diagnostics) of - {ok, Value} -> - [Value] ++ enabled_diagnostics(RemainingDiags, Diagnostics); - error -> - enabled_diagnostics(RemainingDiags, Diagnostics) - end; -enabled_diagnostics([], _) -> - []. -%%@doc -%% Creates a RefactorErl query from a diagnostic identifier and a module name --spec make_query(refactorerl_diagnostic_description(), module()) -> - refactorerl_query(). -make_query({_, After}, Module) -> - ModuleStr = atom_to_list(Module), - "mods[name=" ++ ModuleStr ++ After. +-spec make_diagnostics(any()) -> any(). +make_diagnostics([{Range, Message} | Tail]) -> + Severity = ?DIAGNOSTIC_WARNING, + Source = source(), + Diag = els_diagnostics:make_diagnostic(Range, Message, Severity, Source), + [ Diag | make_diagnostics(Tail) ]; --spec run_query(module(), refactorerl_diagnostic_description()) -> - ([els_diagnostics:diagnostic()]). -run_query(Module, {Message, _} = DiagnosticDesc) -> - Result = els_refactorerl_utils:query(make_query(DiagnosticDesc, Module)), - els_refactorerl_utils:make_diagnostics(Result, Message). +make_diagnostics([]) -> + []. diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 9971adc10..2d57cc2f9 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -7,10 +7,11 @@ %% API %%============================================================================== -export([ referl_node/0 - , query/1 + %, query/1 , notification/1 , notification/2 - , make_diagnostics/2 + %, make_diagnostics/2 + , run_diagnostics/2 , source_name/0 , add/1 ]). @@ -86,64 +87,23 @@ add(Uri) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> Path = [binary_to_list(els_uri:path(Uri))], - {ok, ReqID} = request_id(), - Resp = rpc:call( Node - , reflib_ui_router - , request - , [self(), ReqID, {add_dir, Path}] ), - case Resp of - {badrpc, _} -> - disable_node(Node), - error; - ok -> - receive - {ReqID, reply, {ok, _}} -> ok - end; - deny -> - error - end; + rpc:call(Node, referl_els, add, [Path]); %% returns error | ok _ -> error end. -%%@doc -%% Runs a Query on the RefactorErl node, returns its result if successfull -%% If error happens, it just returns an empty list, as most of times the -%% result then is directly converted to POIs. -%% If the node timeouts or badrpc will come back, it disables the node and -%% stills returns an empty list --spec query(string()) -> list(). -query(Query) -> - case referl_node() of - {error, _} -> - []; +-spec run_diagnostics(any(), any()) -> any(). %TODO: typing +run_diagnostics(DiagnosticAliases, Module) -> + case els_refactorerl_utils:referl_node() of {ok, Node} -> - DisplayOpt = [{positions, linecol}, {output, msg}], - {ok, ReqID} = request_id(), - Opts = [ self() - , ReqID - , {transform, semantic_query - , [{ask_missing, false} - , {display_opt, DisplayOpt} - , {start_opt, []} - , {querystr, Query}]} - ], - Resp = rpc:call(Node, reflib_ui_router, request, Opts), - case Resp of - {badrpc, _} -> - disable_node(Node), - []; % As most of times it is going to be processed right after. - ok -> - receive - {ReqID, reply, Result} -> Result - end; - deny -> - [] - end + rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); %% returns error | ok + _ -> % In this case there was probably error. + [] end. + %%@doc %% Util for popping up notifications -spec notification(string(), number()) -> atom(). @@ -161,64 +121,46 @@ notification(Msg) -> %% Creates a list of diagnostics form the RefactorErl results and a message %% Message can be the same, as this is called per diagnsotic type. %% The severity is only warning. --spec make_diagnostics(any(), string()) -> [els_diagnostics:diagnostic()]. -make_diagnostics([{{_Path, From, To}, Name} | Tail], DiagMsg) -> - Range = #{ from => From, to => To }, - RangeLS = els_protocol:range(Range), - Message = list_to_binary(DiagMsg ++ " " ++ Name), - Severity = ?DIAGNOSTIC_WARNING, - Source = source_name(), - Diag = els_diagnostics:make_diagnostic(RangeLS, Message, Severity, Source), - [ Diag | make_diagnostics(Tail, DiagMsg) ]; - -make_diagnostics([], _) -> - []; - -% This is needed when there is no result from RefactorErl -make_diagnostics({ok, {result, [{result, [{list, []}]}]}}, _) -> - []; -make_diagnostics({ok, {result, [{result, [{group_by, {nopos, _}, list, L}]}]}}, - DiagMsg) -> - make_diagnostics(L, DiagMsg). %%============================================================================== %% Internal Functions %%============================================================================== --spec disable_node(atom()) -> {error, disabled}. +%-spec disable_node(atom()) -> {error, disabled}. %%@doc %% Disables the node given in paramter, also notifes the user. -disable_node(Node) -> - Msg = "RefactorErl is disconnected! - Reload ELS after you fixed theRefactorErl node!", - notification(Msg, ?MESSAGE_TYPE_ERROR), +%%disable_node(Node) -> +%% Msg = "RefactorErl is disconnected! +%% Reload ELS after you fixed theRefactorErl node!", +%% notification(Msg, ?MESSAGE_TYPE_ERROR), +%% +%% Config = els_config:get(refactorerl), +%% els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), +%% {error, disabled}. + +-spec is_refactorerl(atom()) -> boolean(). +is_refactorerl(Node) -> + case pc:call(Node, referl_els, ping, [], 500) of + {refactorerl_els, pong} -> true; + _ -> false + end. - Config = els_config:get(refactorerl), - els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), - {error, disabled}. %%@doc %% Calls the RefactorErl node, to check if it's alive using ri:ls() --spec check_node(atom()) -> {error, timeout} - | {error, badrpc} - | {error, other} +-spec check_node(atom()) -> error | atom(). check_node(Node) -> - Response = rpc:call(Node, ri, ls, [], 10000), - case Response of - {{ok, _}, {error, _}} -> - Node; - ok -> + case is_refactorerl(Node) of + true -> Node; - {badrpc, timeout} -> - {error, timeout}; - {badrpc, _} -> - {error, badrpc}; - _ -> - {error, other} + false -> + error end. + + %%@doc %% Tries to connect to a node. %% When it status is validate, the node hasn't been checked yet, @@ -243,17 +185,6 @@ connect_node({Status, Node}) -> {ok, Node} end. -%%@doc -%% Gets a request id from the RefactorErl node, and returns it --spec request_id() -> {error, nodedown} | {ok, {reqid | string()}}. -request_id() -> - case referl_node() of - {error, _} -> - {error, nodedown}; - {ok, Node} -> - {ok, rpc:call(Node, reflib_ui_router, getid, [])} - end. - %%============================================================================== %% Values %%============================================================================== From 5cdde723a62204a8f45df52ef21a4f0d7fd2e1a5 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:38:15 +0100 Subject: [PATCH 089/103] Cleaned out --- .../src/els_refactorerl_diagnostics.erl | 42 +++++++------- apps/els_lsp/src/els_refactorerl_utils.erl | 55 ++++--------------- 2 files changed, 33 insertions(+), 64 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5f99b9281..8a15d1b74 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,8 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_description() :: {string(), string()}. +-type refactorerl_diagnostic_alias() :: string(). +-type refactorerl_diagnostic_result() :: {range(), string()}. %-type refactorerl_query() :: [char()]. %%============================================================================== @@ -35,7 +36,7 @@ is_default() -> false. - -spec run(uri()) -> [els_diagnostics:diagnostic()]. +-spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> case filename:extension(Uri) of <<".erl">> -> @@ -64,33 +65,36 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== - - - - -%TODO: add default diagnostics - --spec diagnostics_config() -> list(). -diagnostics_config() -> +%% +% @doc +% Returns the enabled diagnostic aliases from config +-spec configured_diagnostics() -> sets:set(). +configured_diagnostics() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> - List; + sets:from_list(List); _ -> [] end. --spec enabled_diagnostics() -> [refactorerl_diagnostic_description()]. -enabled_diagnostics() -> - %%Diagnostics = refactorerl_diagnostics(), - EnabledDiagnostics = diagnostics_config(), - %%enabled_diagnostics(EnabledDiagnostics, Diagnostics). - EnabledDiagnostics. - +% @doc +% Returns the default diagnostic aliases +-spec default_diagnostics() -> sets:set(). +default_diagnostics() -> + ets:from_list(["unused_macros", "unsecure_os_calls"]). +% @doc +% Returns the enabled diagnostics by merging default and configed +-spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. +enabled_diagnostics() -> + Set = sets:union(default_diagnostics(), configured_diagnostics()), + sets:to_list(Set). --spec make_diagnostics(any()) -> any(). +% @doc +% Constructs the ELS diagnostic from RefactorErl result +-spec make_diagnostics([refactorerl_diagnostic_result()]) -> any(). make_diagnostics([{Range, Message} | Tail]) -> Severity = ?DIAGNOSTIC_WARNING, Source = source(), diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 2d57cc2f9..85895807a 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -1,5 +1,5 @@ %%============================================================================== -%% Erlang LS & Refactor Erl conversion +%% Erlang LS & Refactor Erl communication %%============================================================================== -module(els_refactorerl_utils). @@ -7,10 +7,8 @@ %% API %%============================================================================== -export([ referl_node/0 - %, query/1 , notification/1 , notification/2 - %, make_diagnostics/2 , run_diagnostics/2 , source_name/0 , add/1 @@ -81,7 +79,7 @@ referl_node() -> %%@doc %% Adds a module to the RefactorErl node. Using the UI router %% Returns 'ok' if successfull -%% Returns 'error' if it fails after ?MAX_RECURSION_DEPTH number of tries +%% Returns 'error' if it fails -spec add(uri()) -> error | ok. add(Uri) -> case els_refactorerl_utils:referl_node() of @@ -92,9 +90,9 @@ add(Uri) -> error end. - - --spec run_diagnostics(any(), any()) -> any(). %TODO: typing +%%@doc +%% Runs list of diagnostic aliases on refactorerl +-spec run_diagnostics(list(), atom()) -> list(). run_diagnostics(DiagnosticAliases, Module) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> @@ -103,7 +101,6 @@ run_diagnostics(DiagnosticAliases, Module) -> [] end. - %%@doc %% Util for popping up notifications -spec notification(string(), number()) -> atom(). @@ -116,29 +113,12 @@ notification(Msg, Severity) -> notification(Msg) -> notification(Msg, ?MESSAGE_TYPE_INFO). - -%%@doc -%% Creates a list of diagnostics form the RefactorErl results and a message -%% Message can be the same, as this is called per diagnsotic type. -%% The severity is only warning. - - %%============================================================================== %% Internal Functions %%============================================================================== -%-spec disable_node(atom()) -> {error, disabled}. %%@doc -%% Disables the node given in paramter, also notifes the user. -%%disable_node(Node) -> -%% Msg = "RefactorErl is disconnected! -%% Reload ELS after you fixed theRefactorErl node!", -%% notification(Msg, ?MESSAGE_TYPE_ERROR), -%% -%% Config = els_config:get(refactorerl), -%% els_config:set(refactorerl, Config#{"node" => {Node, disabled}}), -%% {error, disabled}. - +%% Checks if the given node is running RefactorErl with ELS interface -spec is_refactorerl(atom()) -> boolean(). is_refactorerl(Node) -> case pc:call(Node, referl_els, ping, [], 500) of @@ -146,21 +126,6 @@ is_refactorerl(Node) -> _ -> false end. - -%%@doc -%% Calls the RefactorErl node, to check if it's alive using ri:ls() --spec check_node(atom()) -> error - | atom(). -check_node(Node) -> - case is_refactorerl(Node) of - true -> - Node; - false -> - error - end. - - - %%@doc %% Tries to connect to a node. %% When it status is validate, the node hasn't been checked yet, @@ -171,15 +136,15 @@ check_node(Node) -> | atom(). connect_node({Status, Node}) -> Config = els_config:get(refactorerl), - case {Status, check_node(Node)} of - {validate, {error, _}} -> + case {Status, is_refactorerl(Node)} of + {validate, false} -> notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; - {retry, {error, _}} -> + {retry, false} -> els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; - {_, Node} -> + {_, true} -> notification("RefactorErl is connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, validated}}), {ok, Node} From 694c47a9d6e065648e7fce0f1bd2851909a3cd94 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Wed, 23 Feb 2022 23:55:21 +0100 Subject: [PATCH 090/103] Linting --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 8 ++++---- apps/els_lsp/src/els_refactorerl_utils.erl | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 8a15d1b74..e1cee0c9e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -65,7 +65,7 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== -%% + % @doc % Returns the enabled diagnostic aliases from config -spec configured_diagnostics() -> sets:set(). @@ -78,14 +78,14 @@ configured_diagnostics() -> end. % @doc -% Returns the default diagnostic aliases +% Returns the default diagnostic aliases -spec default_diagnostics() -> sets:set(). default_diagnostics() -> - ets:from_list(["unused_macros", "unsecure_os_calls"]). + sets:from_list(["unused_macros", "unsecure_os_calls"]). % @doc -% Returns the enabled diagnostics by merging default and configed +% Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> Set = sets:union(default_diagnostics(), configured_diagnostics()), diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 85895807a..94a64c508 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -92,11 +92,12 @@ add(Uri) -> %%@doc %% Runs list of diagnostic aliases on refactorerl --spec run_diagnostics(list(), atom()) -> list(). +-spec run_diagnostics(list(), atom()) -> list(). run_diagnostics(DiagnosticAliases, Module) -> case els_refactorerl_utils:referl_node() of {ok, Node} -> - rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); %% returns error | ok + %% returns error | ok + rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); _ -> % In this case there was probably error. [] end. @@ -121,7 +122,7 @@ notification(Msg) -> %% Checks if the given node is running RefactorErl with ELS interface -spec is_refactorerl(atom()) -> boolean(). is_refactorerl(Node) -> - case pc:call(Node, referl_els, ping, [], 500) of + case rpc:call(Node, referl_els, ping, [], 500) of {refactorerl_els, pong} -> true; _ -> false end. From 65842d6b5617e9fe082bf4417b2f38d71f7f6962 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 24 Feb 2022 07:33:25 +0100 Subject: [PATCH 091/103] Test drafts --- apps/els_lsp/test/els_diagnostics_SUITE.erl | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index ee53775ae..bbfd0cef5 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -39,6 +39,7 @@ , unused_includes_compiler_attribute/1 , exclude_unused_includes/1 , unused_macros/1 + , unused_macros_refactorerl/1 , unused_record_fields/1 , gradualizer/1 , module_name_check/1 @@ -135,6 +136,11 @@ init_per_testcase(TestCase, Config) when TestCase =:= edoc_main; meck:expect(els_edoc_diagnostics, is_default, 0, true), els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config); + +% RefactorErl +init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> + els_test_utils:init_per_testcase(TestCase, Config); + init_per_testcase(TestCase, Config) -> els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config). @@ -740,6 +746,23 @@ edoc_custom_tags(_Config) -> Warnings = [ #{ message => <<"tag @docc not recognized.">> , range => {{9, 0}, {10, 0}} + } + ], + Hints = [], + els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). + + +% RefactorErl test cases +-spec unused_macros_refactorerl(config()) -> ok. +unused_macros_refactorerl(_Config) -> + Path = src_path("diagnostics_unused_macros.erl"), + Source = <<"RefactorErl">>, + Errors = [], + Warnings = [ #{ message => <<"Unused macro: UNUSED_MACRO">> + , range => {{5, 8}, {5, 20}} + }, + #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG/1">> + , range => {{6, 8}, {6, 29}} } ], Hints = [], From cc8b487aa8a6f90c288930f5b1d3aea139173386 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:16:03 +0200 Subject: [PATCH 092/103] Rebase conflict --- .../src/els_refactorerl_diagnostics.erl | 11 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 89 +++++++++++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e1cee0c9e..cbfbca45b 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - false. + true. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> @@ -42,20 +42,21 @@ run(Uri) -> <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> - []; + ["error2"]; {ok, _} -> case els_refactorerl_utils:add(Uri) of error -> - []; + ["error1"]; ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - make_diagnostics(Results) + make_diagnostics(Results), + ["alma"] end end; _ -> - [] + ["korte"] end. -spec source() -> binary(). diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index bbfd0cef5..873c82a85 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -139,6 +139,7 @@ init_per_testcase(TestCase, Config) when TestCase =:= edoc_main; % RefactorErl init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> + mock_refactorerl(), els_test_utils:init_per_testcase(TestCase, Config); init_per_testcase(TestCase, Config) -> @@ -189,11 +190,19 @@ end_per_testcase(TestCase, Config) when TestCase =:= edoc_main; els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok; +end_per_testcase(TestCase, Config) + when TestCase =:= unused_macros_refactorerl -> + unmock_refactoerl(), + els_test_utils:end_per_testcase(TestCase, Config), + els_mock_diagnostics:teardown(); end_per_testcase(TestCase, Config) -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok. +% RefactorErl + + %%============================================================================== %% Testcases %%============================================================================== @@ -841,3 +850,83 @@ src_path(Module) -> include_path(Header) -> filename:join(["code_navigation", "include", Header]). + + +% Mock RefactorErl utils +mock_refactorerl() -> + %meck:new(rpc, [passthrough, no_link, unstick]), + %{ok, HostName} = inet:gethostname(), + %NodeName = list_to_atom("fakenode@" ++ HostName), + %meck:expect( rpc + % , call + % , fun(PNode, c, c, [Module]) when PNode =:= NodeName -> + % {ok, Module}; + % (Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + % end + % ). + meck:new(els_refactorerl_utils), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, ["Hello"]), + meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), + meck:expect(els_refactorerl_utils, add, 1, ok), + % + + + + % rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); + meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + [{#{'end' => #{character => 12,line => 16}, + start => #{character => 4,line => 16}}, + <<"Unsecure OS call: os:cmd(A)">>}, + {#{'end' => #{character => 35,line => 5}, + start => #{character => 0,line => 5}}, + <<"Unused macros: UNUSED_MACRO">>}, + {#{'end' => #{character => 36,line => 6}, + start => #{character => 0,line => 6}}, + <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] + %; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ), + + + % rpc:call(Node, referl_els, add, [Path]); %% returns error | ok + %meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + ok%; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ), + + % rpc:call(Node, referl_els, ping, [], 500) + %meck:new(rpc, [passthrough, no_link, unstick]), + {ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + meck:expect( rpc + , call + , fun(_RPCNode, referl_els, ping, [], 500) -> %{ok, HostName} = inet:gethostname(), + NodeName = list_to_atom("referl_fake@" ++ HostName), + {refactorerl_els, pong}%; + %(Node, Mod, Fun, Args) -> + % meck:passthrough([Node, Mod, Fun, Args]) + end + ). + +unmock_refactoerl() -> + meck:unload(rpc), + meck:unload(refactorerl_els). \ No newline at end of file From 167e6a9e7eb09893ceb41212e98e34ccd8e7365b Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 20:13:50 +0100 Subject: [PATCH 093/103] Tests --- .../src/els_refactorerl_diagnostics.erl | 41 +++---- apps/els_lsp/test/els_diagnostics_SUITE.erl | 100 ++++++++---------- 2 files changed, 68 insertions(+), 73 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index cbfbca45b..6889ad78a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -38,25 +38,29 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> + %TODO TEST + io:format(">>>>>> Diagnostics begin"), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of {error, _} -> - ["error2"]; + []; {ok, _} -> case els_refactorerl_utils:add(Uri) of error -> - ["error1"]; + []; ok -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - make_diagnostics(Results), - ["alma"] + io:format("Result"), + io:format("~p", [Results]), + make_diagnostics(Results) + end end; _ -> - ["korte"] + [] end. -spec source() -> binary(). @@ -69,28 +73,29 @@ source() -> % @doc % Returns the enabled diagnostic aliases from config --spec configured_diagnostics() -> sets:set(). -configured_diagnostics() -> - case els_config:get(refactorerl) of - #{"diagnostics" := List} -> - sets:from_list(List); - _ -> - [] - end. +%-spec configured_diagnostics() -> sets:set(). +%configured_diagnostics() -> +% case els_config:get(refactorerl) of +% #{"diagnostics" := List} -> +% sets:from_list(List); +% _ -> +% [] +% end. % @doc % Returns the default diagnostic aliases --spec default_diagnostics() -> sets:set(). -default_diagnostics() -> - sets:from_list(["unused_macros", "unsecure_os_calls"]). +%-spec default_diagnostics() -> sets:set(). +%default_diagnostics() -> +% sets:from_list(["unused_macros", "unsecure_os_calls"]). % @doc % Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> - Set = sets:union(default_diagnostics(), configured_diagnostics()), - sets:to_list(Set). + %Set = sets:union(default_diagnostics(), configured_diagnostics()), + %sets:to_list(Set), %TODO Set operation + ["unused_macros", "unsecure_os_calls"]. % @doc diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 873c82a85..474596161 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -194,7 +194,8 @@ end_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> unmock_refactoerl(), els_test_utils:end_per_testcase(TestCase, Config), - els_mock_diagnostics:teardown(); + els_mock_diagnostics:teardown(), + ok; end_per_testcase(TestCase, Config) -> els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), @@ -853,80 +854,69 @@ include_path(Header) -> % Mock RefactorErl utils -mock_refactorerl() -> - %meck:new(rpc, [passthrough, no_link, unstick]), - %{ok, HostName} = inet:gethostname(), - %NodeName = list_to_atom("fakenode@" ++ HostName), - %meck:expect( rpc - % , call - % , fun(PNode, c, c, [Module]) when PNode =:= NodeName -> - % {ok, Module}; - % (Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - % end - % ). - meck:new(els_refactorerl_utils), +mock_refactorerl() -> {ok, HostName} = inet:gethostname(), NodeName = list_to_atom("referl_fake@" ++ HostName), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, ["Hello"]), + + meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, [{#{'end' => #{character => 12,line => 16}, + start => #{character => 4,line => 16}}, + <<"Unsecure OS call: os:cmd(A)">>}]), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - % - + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), - - % rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); + + %rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), meck:expect( rpc , call - , fun(_RPCNode, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - [{#{'end' => #{character => 12,line => 16}, - start => #{character => 4,line => 16}}, - <<"Unsecure OS call: os:cmd(A)">>}, - {#{'end' => #{character => 35,line => 5}, + , fun(Node, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) when Node =:= NodeName -> + io:format("RunDiag"), + [{#{'end' => #{character => 35,line => 5}, start => #{character => 0,line => 5}}, <<"Unused macros: UNUSED_MACRO">>}, {#{'end' => #{character => 36,line => 6}, start => #{character => 0,line => 6}}, - <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] + <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] ; %; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) end ), - - - % rpc:call(Node, referl_els, add, [Path]); %% returns error | ok + + + %rpc:call(Node, referl_els, add, [Path]); %% returns error | ok %meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), meck:expect( rpc - , call - , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - ok%; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - end - ), + , call + , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), + io:format("Add"), + + ok; + + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) + end + ), % rpc:call(Node, referl_els, ping, [], 500) %meck:new(rpc, [passthrough, no_link, unstick]), - {ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), + % + meck:expect( rpc - , call - , fun(_RPCNode, referl_els, ping, [], 500) -> %{ok, HostName} = inet:gethostname(), - NodeName = list_to_atom("referl_fake@" ++ HostName), - {refactorerl_els, pong}%; - %(Node, Mod, Fun, Args) -> - % meck:passthrough([Node, Mod, Fun, Args]) - end - ). + , call + , fun(_RPCNode, referl_els, ping, ["_Path"]) -> %{ok, HostName} = inet:gethostname(), + io:format("Ping"), + + {refactorerl_els, pong}; + + (Node, Mod, Fun, Args) -> + meck:passthrough([Node, Mod, Fun, Args]) + end + ). + unmock_refactoerl() -> - meck:unload(rpc), - meck:unload(refactorerl_els). \ No newline at end of file + meck:unload(rpc). + %meck:unload(els_refactorerl_utils). \ No newline at end of file From d9f89e2807f55c3c0a27bbc397f83b6f4e87e672 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:01:33 +0100 Subject: [PATCH 094/103] Passing tests, draft --- .../src/els_refactorerl_diagnostics.erl | 9 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 72 ++++--------------- 2 files changed, 16 insertions(+), 65 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 6889ad78a..16f310a0e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -38,8 +38,6 @@ is_default() -> -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> - %TODO TEST - io:format(">>>>>> Diagnostics begin"), case filename:extension(Uri) of <<".erl">> -> case els_refactorerl_utils:referl_node() of @@ -53,8 +51,6 @@ run(Uri) -> Module = els_uri:module(Uri), Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), - io:format("Result"), - io:format("~p", [Results]), make_diagnostics(Results) end @@ -86,7 +82,7 @@ source() -> % Returns the default diagnostic aliases %-spec default_diagnostics() -> sets:set(). %default_diagnostics() -> -% sets:from_list(["unused_macros", "unsecure_os_calls"]). +% sets:from_list(["unused_macros", "unsecure_os_call"]). % @doc @@ -95,7 +91,8 @@ source() -> enabled_diagnostics() -> %Set = sets:union(default_diagnostics(), configured_diagnostics()), %sets:to_list(Set), %TODO Set operation - ["unused_macros", "unsecure_os_calls"]. + %["unused_macros", "unsecure_os_call"]. + [unused_macros, unsecure_os_call]. % @doc diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 474596161..00accbdae 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -769,10 +769,10 @@ unused_macros_refactorerl(_Config) -> Source = <<"RefactorErl">>, Errors = [], Warnings = [ #{ message => <<"Unused macro: UNUSED_MACRO">> - , range => {{5, 8}, {5, 20}} + , range => {{5, 0}, {5, 35}} }, - #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG/1">> - , range => {{6, 8}, {6, 29}} + #{ message => <<"Unused macro: UNUSED_MACRO_WITH_ARG">> + , range => {{6, 0}, {6, 36}} } ], Hints = [], @@ -859,64 +859,18 @@ mock_refactorerl() -> NodeName = list_to_atom("referl_fake@" ++ HostName), meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, [{#{'end' => #{character => 12,line => 16}, - start => #{character => 4,line => 16}}, - <<"Unsecure OS call: os:cmd(A)">>}]), + meck:expect(els_refactorerl_utils, run_diagnostics, 2, + [ {# {'end' => #{character => 35,line => 5}, + start => #{character => 0,line => 5}}, + <<"Unused macro: UNUSED_MACRO">>}, + {# {'end' => #{character => 36,line => 6}, + start => #{character => 0,line => 6}}, + <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] + ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), - - - %rpc:call(Node, referl_els, run_diagnostics, [DiagnosticAliases, Module]); - meck:new(rpc, [passthrough, no_link, unstick]), - meck:expect( rpc - , call - , fun(Node, referl_els, run_diagnostics, [_DiagnosticAliases, _Module]) when Node =:= NodeName -> - io:format("RunDiag"), - [{#{'end' => #{character => 35,line => 5}, - start => #{character => 0,line => 5}}, - <<"Unused macros: UNUSED_MACRO">>}, - {#{'end' => #{character => 36,line => 6}, - start => #{character => 0,line => 6}}, - <<"Unused macros: UNUSED_MACRO_WITH_ARG">>}] ; - %; - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ), + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>). - %rpc:call(Node, referl_els, add, [Path]); %% returns error | ok - %meck:new(rpc, [passthrough, no_link, unstick]), - meck:expect( rpc - , call - , fun(_RPCNode, referl_els, add, [_Path]) -> %{ok, HostName} = inet:gethostname(), - io:format("Add"), - - ok; - - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ), - - % rpc:call(Node, referl_els, ping, [], 500) - %meck:new(rpc, [passthrough, no_link, unstick]), - % - - meck:expect( rpc - , call - , fun(_RPCNode, referl_els, ping, ["_Path"]) -> %{ok, HostName} = inet:gethostname(), - io:format("Ping"), - - {refactorerl_els, pong}; - - (Node, Mod, Fun, Args) -> - meck:passthrough([Node, Mod, Fun, Args]) - end - ). - - unmock_refactoerl() -> - meck:unload(rpc). - %meck:unload(els_refactorerl_utils). \ No newline at end of file + meck:unload(els_refactorerl_utils). \ No newline at end of file From 1a0e7b88909171704599044094c81a273032b5ad Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:16:55 +0200 Subject: [PATCH 095/103] rebase conflict resolve --- .../src/els_refactorerl_diagnostics.erl | 3 +-- apps/els_lsp/test/els_diagnostics_SUITE.erl | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 16f310a0e..c75626f3c 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -24,7 +24,7 @@ %%============================================================================== %% Types %%============================================================================== --type refactorerl_diagnostic_alias() :: string(). +-type refactorerl_diagnostic_alias() :: atom(). -type refactorerl_diagnostic_result() :: {range(), string()}. %-type refactorerl_query() :: [char()]. @@ -52,7 +52,6 @@ run(Uri) -> Diags = enabled_diagnostics(), Results = els_refactorerl_utils:run_diagnostics(Diags, Module), make_diagnostics(Results) - end end; _ -> diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 00accbdae..0fb33676d 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -138,7 +138,8 @@ init_per_testcase(TestCase, Config) when TestCase =:= edoc_main; els_test_utils:init_per_testcase(TestCase, Config); % RefactorErl -init_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> +init_per_testcase(TestCase, Config) + when TestCase =:= unused_macros_refactorerl -> mock_refactorerl(), els_test_utils:init_per_testcase(TestCase, Config); @@ -191,6 +192,7 @@ end_per_testcase(TestCase, Config) when TestCase =:= edoc_main; els_mock_diagnostics:teardown(), ok; end_per_testcase(TestCase, Config) +end_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> unmock_refactoerl(), els_test_utils:end_per_testcase(TestCase, Config), @@ -852,20 +854,19 @@ src_path(Module) -> include_path(Header) -> filename:join(["code_navigation", "include", Header]). - % Mock RefactorErl utils -mock_refactorerl() -> +mock_refactorerl() -> {ok, HostName} = inet:gethostname(), NodeName = list_to_atom("referl_fake@" ++ HostName), meck:new(els_refactorerl_utils, [passthrough, no_link, unstick]), - meck:expect(els_refactorerl_utils, run_diagnostics, 2, - [ {# {'end' => #{character => 35,line => 5}, - start => #{character => 0,line => 5}}, + meck:expect(els_refactorerl_utils, run_diagnostics, 2, + [ {# {'end' => #{character => 35, line => 5}, + start => #{character => 0, line => 5}}, <<"Unused macro: UNUSED_MACRO">>}, - {# {'end' => #{character => 36,line => 6}, - start => #{character => 0,line => 6}}, - <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] + {# {'end' => #{character => 36, line => 6}, + start => #{character => 0, line => 6}}, + <<"Unused macro: UNUSED_MACRO_WITH_ARG">>}] ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), From 862870520d183c9db7a8726c9871239e311812c0 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:47:21 +0100 Subject: [PATCH 096/103] Test failing due to it is not configured --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index c75626f3c..96705fc6a 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -34,7 +34,7 @@ -spec is_default() -> boolean(). is_default() -> - true. + false. -spec run(uri()) -> [els_diagnostics:diagnostic()]. run(Uri) -> From c4c8a3f77a6b39042937a19983a28052fb7e015b Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Thu, 3 Mar 2022 21:37:29 +0100 Subject: [PATCH 097/103] Test --- apps/els_lsp/test/els_diagnostics_SUITE.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 0fb33676d..83062e079 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -870,8 +870,12 @@ mock_refactorerl() -> ), meck:expect(els_refactorerl_utils, referl_node, 0, {ok, NodeName}), meck:expect(els_refactorerl_utils, add, 1, ok), - meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>). + meck:expect(els_refactorerl_utils, source_name, 0, <<"RefactorErl">>), + + meck:new(els_refactorerl_diagnostics, [passthrough, no_link, unstick]), + meck:expect(els_refactorerl_diagnostics, is_default, 0, true). unmock_refactoerl() -> + meck:unload(els_refactorerl_diagnostics), meck:unload(els_refactorerl_utils). \ No newline at end of file From 0fb3ba679f7b7a4ddc43efc4418cc721c36e8b91 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:04:29 +0100 Subject: [PATCH 098/103] @doc tag fix --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 96705fc6a..5b4784c0f 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -77,7 +77,7 @@ source() -> % [] % end. -% @doc +% ddoocc % Returns the default diagnostic aliases %-spec default_diagnostics() -> sets:set(). %default_diagnostics() -> From a0e65bd7bfd5c36107eb8403cc1a2bb3e50103cb Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:41:11 +0100 Subject: [PATCH 099/103] doc fix2 --- apps/els_lsp/src/els_refactorerl_diagnostics.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index 5b4784c0f..e7f52612f 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -66,7 +66,7 @@ source() -> %% Internal Functions %%============================================================================== -% @doc +% ddoocc % Returns the enabled diagnostic aliases from config %-spec configured_diagnostics() -> sets:set(). %configured_diagnostics() -> From 1389a3089096173e992e524f83be0183f6227210 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:07:17 +0100 Subject: [PATCH 100/103] Diagnostic config option --- .../src/els_refactorerl_diagnostics.erl | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index e7f52612f..eb4e19f75 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -66,32 +66,31 @@ source() -> %% Internal Functions %%============================================================================== -% ddoocc +% @doc % Returns the enabled diagnostic aliases from config -%-spec configured_diagnostics() -> sets:set(). -%configured_diagnostics() -> -% case els_config:get(refactorerl) of -% #{"diagnostics" := List} -> -% sets:from_list(List); -% _ -> -% [] -% end. - -% ddoocc +-spec configured_diagnostics() -> sets:set(). +configured_diagnostics() -> + case els_config:get(refactorerl) of + #{"diagnostics" := List} -> + AtomList = [list_to_atom(Element) || Element <- List], + sets:from_list(AtomList); + _ -> + [] + end. + +% @doc % Returns the default diagnostic aliases -%-spec default_diagnostics() -> sets:set(). -%default_diagnostics() -> -% sets:from_list(["unused_macros", "unsecure_os_call"]). +-spec default_diagnostics() -> sets:set(). +default_diagnostics() -> + sets:from_list([unused_macros, unsecure_os_call]). % @doc % Returns the enabled diagnostics by merging default and configed -spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. enabled_diagnostics() -> - %Set = sets:union(default_diagnostics(), configured_diagnostics()), - %sets:to_list(Set), %TODO Set operation - %["unused_macros", "unsecure_os_call"]. - [unused_macros, unsecure_os_call]. + Set = sets:union(default_diagnostics(), configured_diagnostics()), + sets:to_list(Set). % @doc From faf05048c6717fd95d0384af6a9e3637349a4840 Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:18:12 +0100 Subject: [PATCH 101/103] Code clearing and diagnostic config --- .../src/els_refactorerl_diagnostics.erl | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/apps/els_lsp/src/els_refactorerl_diagnostics.erl b/apps/els_lsp/src/els_refactorerl_diagnostics.erl index eb4e19f75..8e837d79e 100644 --- a/apps/els_lsp/src/els_refactorerl_diagnostics.erl +++ b/apps/els_lsp/src/els_refactorerl_diagnostics.erl @@ -65,33 +65,17 @@ source() -> %%============================================================================== %% Internal Functions %%============================================================================== - % @doc -% Returns the enabled diagnostic aliases from config --spec configured_diagnostics() -> sets:set(). -configured_diagnostics() -> +% Returns the enabled diagnostics by merging default and configed +-spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. +enabled_diagnostics() -> case els_config:get(refactorerl) of #{"diagnostics" := List} -> - AtomList = [list_to_atom(Element) || Element <- List], - sets:from_list(AtomList); + [list_to_atom(Element) || Element <- List]; _ -> [] end. -% @doc -% Returns the default diagnostic aliases --spec default_diagnostics() -> sets:set(). -default_diagnostics() -> - sets:from_list([unused_macros, unsecure_os_call]). - - -% @doc -% Returns the enabled diagnostics by merging default and configed --spec enabled_diagnostics() -> [refactorerl_diagnostic_alias()]. -enabled_diagnostics() -> - Set = sets:union(default_diagnostics(), configured_diagnostics()), - sets:to_list(Set). - % @doc % Constructs the ELS diagnostic from RefactorErl result From d5e490dfae1e10c58ce99f3ac7e394366a148cee Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:17:25 +0200 Subject: [PATCH 102/103] rebase conflict resolve --- apps/els_core/src/els_config.erl | 4 ++-- apps/els_lsp/src/els_refactorerl_utils.erl | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/els_core/src/els_config.erl b/apps/els_core/src/els_config.erl index b984da761..6fac5b758 100644 --- a/apps/els_core/src/els_config.erl +++ b/apps/els_core/src/els_config.erl @@ -56,8 +56,8 @@ | indexing_enabled | bsp_enabled | compiler_telemetry_enabled - | edoc_custom_tags - | refactorerl. + | refactorerl + | edoc_custom_tags. -type path() :: file:filename(). -type state() :: #{ apps_dirs => [path()] diff --git a/apps/els_lsp/src/els_refactorerl_utils.erl b/apps/els_lsp/src/els_refactorerl_utils.erl index 94a64c508..3a666e168 100644 --- a/apps/els_lsp/src/els_refactorerl_utils.erl +++ b/apps/els_lsp/src/els_refactorerl_utils.erl @@ -68,7 +68,6 @@ referl_node() -> connect_node({validate, Node}); notconfigured -> - notification("RefactorErl is not configured!"), {error, disabled}; _ -> @@ -139,7 +138,6 @@ connect_node({Status, Node}) -> Config = els_config:get(refactorerl), case {Status, is_refactorerl(Node)} of {validate, false} -> - notification("RefactorErl is not connected!", ?MESSAGE_TYPE_INFO), els_config:set(refactorerl, Config#{"node" => {Node, disconnected}}), {error, disconnected}; {retry, false} -> From e9b8dfa2cab649118d488e23582cb11aac934f9f Mon Sep 17 00:00:00 2001 From: Robert Fiko <64466886+robertfiko@users.noreply.github.com> Date: Sun, 27 Mar 2022 20:58:36 +0200 Subject: [PATCH 103/103] lint --- apps/els_lsp/test/els_diagnostics_SUITE.erl | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 83062e079..a7c7b7aaf 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -191,7 +191,6 @@ end_per_testcase(TestCase, Config) when TestCase =:= edoc_main; els_test_utils:end_per_testcase(TestCase, Config), els_mock_diagnostics:teardown(), ok; -end_per_testcase(TestCase, Config) end_per_testcase(TestCase, Config) when TestCase =:= unused_macros_refactorerl -> unmock_refactoerl(),