diff --git a/src/erlang_ls_server.erl b/src/erlang_ls_server.erl index 6efe9ff38..b5c7a328b 100644 --- a/src/erlang_ls_server.erl +++ b/src/erlang_ls_server.erl @@ -26,6 +26,11 @@ -export([ connected/3 ]). +%% TODO: Move to separate module +-export([ definition/1 + , search/3 + ]). + %%============================================================================== %% Includes %%============================================================================== @@ -202,6 +207,7 @@ send_notification(Socket, Method, Params) -> lager:debug("[SERVER] Sending notification [notification=~p]", [Notification]), gen_tcp:send(Socket, Notification). +%% TODO: definition/2 should probably not take the Uri, but a path. -spec definition(uri(), erlang_ls_parser:poi()) -> null | map(). definition(_Uri, #{ info := {application, {M, _F, _A}} = Info }) -> case annotated_tree(erlang_ls_uri:filename(M)) of diff --git a/test/erlang_ls_code_navigation_SUITE.erl b/test/erlang_ls_code_navigation_SUITE.erl index c9e691d96..92aded7bd 100644 --- a/test/erlang_ls_code_navigation_SUITE.erl +++ b/test/erlang_ls_code_navigation_SUITE.erl @@ -13,7 +13,8 @@ ]). %% Test cases --export([ main/1 +-export([ macro/1 + , record/1 ]). %%============================================================================== @@ -36,7 +37,13 @@ suite() -> -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> - Config. + DataDir = ?config(data_dir, Config), + DataDirBin = list_to_binary(DataDir), + [ {data_dir_bin, DataDirBin} + , {include_path, [ filename:join([DataDirBin, "src"]) + , filename:join([DataDirBin, "include"]) + ]} + |Config]. -spec end_per_suite(config()) -> ok. end_per_suite(_Config) -> @@ -52,18 +59,45 @@ end_per_testcase(_TestCase, _Config) -> -spec all() -> [atom()]. all() -> - [main]. + [macro, record]. %%============================================================================== %% Testcases %%============================================================================== +-spec macro(config()) -> ok. +macro(Config) -> + FileName = <<"code_navigation.erl">>, + Thing = {macro, 'MACRO_A'}, + Definition = definition(?config(data_dir_bin, Config), Thing), + ?assertEqual( Definition + , erlang_ls_server:search( FileName + , ?config(include_path, Config) + , erlang_ls_server:definition(Thing))), + ok. --spec main(config()) -> ok. -main(_Config) -> - %% First stream allowed - ?assert(true), +-spec record(config()) -> ok. +record(Config) -> + FileName = <<"code_navigation.erl">>, + Thing = {record_expr, "record_a"}, + Definition = definition(?config(data_dir_bin, Config), Thing), + ?assertEqual( Definition + , erlang_ls_server:search( FileName + , ?config(include_path, Config) + , erlang_ls_server:definition(Thing))), ok. %%============================================================================== %% Internal Functions %%============================================================================== +definition(DataDir, {record_expr, "record_a"}) -> + FilePath = filename:join([DataDir, <<"src">>, <<"code_navigation.erl">>]), + #{ range => erlang_ls_protocol:range(#{from => {4, 0}, to => {4, 0}}) + , uri => erlang_ls_uri:uri(FilePath) + }; +definition(DataDir, {macro, 'MACRO_A'}) -> + FilePath = filename:join([DataDir, <<"src">>, <<"code_navigation.erl">>]), + #{ range => erlang_ls_protocol:range(#{from => {6, 0}, to => {6, 0}}) + , uri => erlang_ls_uri:uri(FilePath) + }. + +%% TODO: Armonize strings vs atoms in definitions diff --git a/test/erlang_ls_code_navigation_SUITE_data/src/code_navigation.erl b/test/erlang_ls_code_navigation_SUITE_data/src/code_navigation.erl new file mode 100644 index 000000000..e760c5704 --- /dev/null +++ b/test/erlang_ls_code_navigation_SUITE_data/src/code_navigation.erl @@ -0,0 +1,14 @@ +-module(code_navigation). + +-export([ function_a/0 ]). + +-record(record_a, {field_a, field_b}). + +-define(MACRO_A, macro_a). + +function_a() -> + function_b(), + #record_a{}. + +function_b() -> + ?MACRO_A.