@@ -25,8 +25,9 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
2525 % Reducer { } = reducer
2626 )
2727 when is_list ( arg_list ) and is_atom ( function_name ) do
28- entry = entry ( reducer , apply_meta , apply_meta , module , function_name , arg_list )
29- { :ok , entry , nil }
28+ reducer
29+ |> entry ( apply_meta , apply_meta , module , function_name , arg_list )
30+ |> without_further_analysis ( )
3031 end
3132
3233 # Dynamic call via Kernel.apply Kernel.apply(Module, :function, [1, 2])
@@ -40,8 +41,9 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
4041 % Reducer { } = reducer
4142 )
4243 when is_list ( arg_list ) and is_atom ( function_name ) do
43- entry = entry ( reducer , start_metadata , apply_meta , module , function_name , arg_list )
44- { :ok , entry , nil }
44+ reducer
45+ |> entry ( start_metadata , apply_meta , module , function_name , arg_list )
46+ |> without_further_analysis ( )
4547 end
4648
4749 # remote function OtherModule.foo(:arg), OtherModule.foo() or OtherModule.foo
@@ -50,9 +52,7 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
5052 % Reducer { } = reducer
5153 )
5254 when is_atom ( fn_name ) do
53- entry = entry ( reducer , start_metadata , end_metadata , module , fn_name , args )
54-
55- { :ok , entry }
55+ entry ( reducer , start_metadata , end_metadata , module , fn_name , args )
5656 end
5757
5858 # local function capture &downcase/1
@@ -65,8 +65,9 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
6565 { module , _ , _ } =
6666 Engine.Analyzer . resolve_local_call ( reducer . analysis , position , fn_name , arity )
6767
68- entry = entry ( reducer , end_metadata , arity_meta , module , fn_name , arity )
69- { :ok , entry , nil }
68+ reducer
69+ |> entry ( end_metadata , arity_meta , module , fn_name , arity )
70+ |> without_further_analysis ( )
7071 end
7172
7273 # Function capture with arity: &OtherModule.foo/3
@@ -81,13 +82,13 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
8182 ] } ,
8283 % Reducer { } = reducer
8384 ) do
84- entry = entry ( reducer , start_metadata , end_metadata , module , function_name , arity )
85-
85+ reducer
86+ |> entry ( start_metadata , end_metadata , module , function_name , arity )
8687 # we return nil here to stop analysis from progressing down the syntax tree,
8788 # because if it did, the function head that deals with normal calls will pick
8889 # up the rest of the call and return a reference to MyModule.function/0, which
8990 # is incorrect
90- { :ok , entry , nil }
91+ |> without_further_analysis ( )
9192 end
9293
9394 def extract ( { :|> , pipe_meta , [ pipe_start , { fn_name , meta , args } ] } , % Reducer { } ) do
@@ -134,16 +135,17 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
134135 { module , _ , _ } =
135136 Engine.Analyzer . resolve_local_call ( reducer . analysis , position , fn_name , arity )
136137
137- entry = entry ( reducer , meta , meta , [ module ] , fn_name , args )
138-
139- { :ok , entry }
138+ entry ( reducer , meta , meta , [ module ] , fn_name , args )
140139 end
141140 end
142141
143142 def extract ( _ast , _reducer ) do
144143 :ignored
145144 end
146145
146+ defp without_further_analysis ( :ignored ) , do: :ignored
147+ defp without_further_analysis ( { :ok , entry } ) , do: { :ok , entry , nil }
148+
147149 defp entry (
148150 % Reducer { } = reducer ,
149151 start_metadata ,
@@ -156,64 +158,81 @@ defmodule Engine.Search.Indexer.Extractors.FunctionReference do
156158 block = Reducer . current_block ( reducer )
157159
158160 range =
159- get_reference_range ( reducer . analysis . document , start_metadata , end_metadata , function_name )
160-
161- case Engine.Analyzer . expand_alias ( module , reducer . analysis , range . start ) do
162- { :ok , module } ->
163- mfa = Subject . mfa ( module , function_name , arity )
161+ get_reference_range (
162+ reducer . analysis . document ,
163+ start_metadata ,
164+ end_metadata ,
165+ function_name
166+ )
164167
165- Entry . reference (
166- reducer . analysis . document . path ,
167- block ,
168- mfa ,
169- { :function , :usage } ,
170- range ,
171- Application . get_application ( module )
172- )
168+ case range do
169+ nil ->
170+ :ignored
173171
174172 _ ->
175- human_location = Reducer . human_location ( reducer )
176-
177- Logger . warning (
178- "Could not expand #{ inspect ( module ) } into an alias. Please report this. (at #{ human_location } )"
179- )
180-
181- nil
173+ case Engine.Analyzer . expand_alias ( module , reducer . analysis , range . start ) do
174+ { :ok , module } ->
175+ mfa = Subject . mfa ( module , function_name , arity )
176+
177+ { :ok ,
178+ Entry . reference (
179+ reducer . analysis . document . path ,
180+ block ,
181+ mfa ,
182+ { :function , :usage } ,
183+ range ,
184+ Application . get_application ( module )
185+ ) }
186+
187+ _ ->
188+ human_location = Reducer . human_location ( reducer )
189+
190+ Logger . warning (
191+ "Could not expand #{ inspect ( module ) } into an alias (at #{ human_location } ). Please open an issue!"
192+ )
193+
194+ :ignored
195+ end
182196 end
183197 end
184198
185199 defp get_reference_range ( document , start_metadata , end_metadata , function_name ) do
186- { start_line , start_column } = start_position ( start_metadata )
187- start_position = Position . new ( document , start_line , start_column )
188- has_parens? = not Keyword . get ( end_metadata , :no_parens , false )
189-
190- { end_line , end_column } =
191- case Metadata . position ( end_metadata , :closing ) do
192- { line , column } ->
193- if has_parens? do
194- { line , column + 1 }
195- else
196- { line , column }
197- end
198-
199- nil ->
200- { line , column } = Metadata . position ( end_metadata )
201-
202- if has_parens? do
203- { line , column + 1 }
204- else
205- name_length = function_name |> Atom . to_string ( ) |> String . length ( )
206- # without parens, the metadata points to the beginning of the call, so
207- # we need to add the length of the function name to be sure we have it
208- # all
209- { line , column + name_length }
210- end
211- end
200+ if valid_position_metadata? ( start_metadata ) and valid_position_metadata? ( end_metadata ) do
201+ { start_line , start_column } = start_position ( start_metadata )
202+ start_pos = Position . new ( document , start_line , start_column )
203+ has_parens? = not Keyword . get ( end_metadata , :no_parens , false )
204+
205+ { end_line , end_column } =
206+ case Metadata . position ( end_metadata , :closing ) do
207+ { line , column } when has_parens? -> { line , column + 1 }
208+ { line , column } -> { line , column }
209+ nil -> adjust_position_for_name ( end_metadata , function_name , has_parens? )
210+ end
211+
212+ end_pos = Position . new ( document , end_line , end_column )
213+ Range . new ( start_pos , end_pos )
214+ else
215+ nil
216+ end
217+ end
212218
213- end_position = Position . new ( document , end_line , end_column )
214- Range . new ( start_position , end_position )
219+ defp adjust_position_for_name ( metadata , function_name , has_parens? ) do
220+ { line , column } = Metadata . position ( metadata )
221+
222+ if has_parens? do
223+ { line , column + 1 }
224+ else
225+ name_length = function_name |> Atom . to_string ( ) |> String . length ( )
226+ { line , column + name_length }
227+ end
228+ end
229+
230+ defp valid_position_metadata? ( metadata ) when is_list ( metadata ) do
231+ Keyword . has_key? ( metadata , :line ) and Keyword . has_key? ( metadata , :column )
215232 end
216233
234+ defp valid_position_metadata? ( _ ) , do: false
235+
217236 defp start_position ( metadata ) do
218237 Metadata . position ( metadata )
219238 end
0 commit comments