@@ -12,10 +12,11 @@ defmodule ElixirAnalyzer.ExerciseTest.CommonChecks.PrivateHelperFunctions do
1212 def run ( _ast , nil ) , do: [ ]
1313
1414 def run ( code_ast , exemploid_ast ) do
15- { _ , code_definitions } = Macro . prewalk ( code_ast , [ ] , & traverse / 2 )
16- { _ , exemploid_definitions } = Macro . prewalk ( exemploid_ast , [ ] , & traverse / 2 )
15+ { _ , code_hidden } = Macro . prewalk ( code_ast , [ ] , & find_hidden / 2 )
16+ { _ , code_def } = Macro . prewalk ( code_ast , [ ] , & traverse / 2 )
17+ { _ , exemploid_def } = Macro . prewalk ( exemploid_ast , [ ] , & traverse / 2 )
1718
18- case Enum . reverse ( find_public_helpers ( code_definitions , exemploid_definitions ) ) do
19+ case find_public_helpers ( code_def , code_hidden , exemploid_def ) |> Enum . reverse ( ) do
1920 [ ] ->
2021 [ ]
2122
@@ -35,23 +36,55 @@ defmodule ElixirAnalyzer.ExerciseTest.CommonChecks.PrivateHelperFunctions do
3536 end
3637 end
3738
38- defp traverse ( { op , _meta , [ { :when , _ , [ { name , _ , args } | _ ] } | _ ] } = ast , names )
39+ defp find_hidden ( { _ , _ , args } = ast , names ) when is_list ( args ) do
40+ { ast , do_find_hidden ( args , names ) }
41+ end
42+
43+ defp find_hidden ( ast , names ) , do: { ast , names }
44+
45+ defp do_find_hidden ( [ doc , function | rest ] , names ) do
46+ hidden? =
47+ match? ( { :@ , _ , [ { :doc , _ , [ false ] } ] } , doc ) or match? ( { :@ , _ , [ { :impl , _ , [ true ] } ] } , doc )
48+
49+ def? = function_def? ( function )
50+
51+ if hidden? and def? do
52+ names = [ get_function_data ( function ) | names ]
53+ do_find_hidden ( rest , names )
54+ else
55+ do_find_hidden ( [ function | rest ] , names )
56+ end
57+ end
58+
59+ defp do_find_hidden ( _ , names ) , do: names
60+
61+ defp function_def? ( { _op , _ , [ { :when , _ , [ { _name , _ , _args } | _ ] } | _ ] } ) , do: true
62+ defp function_def? ( { _op , _ , [ { _name , _ , _args } | _ ] } ) , do: true
63+ defp function_def? ( _node ) , do: false
64+
65+ defp get_function_data ( { op , _ , [ { :when , _ , [ { name , _ , args } | _ ] } | _ ] } ) do
66+ { op , name , if ( is_atom ( args ) , do: 0 , else: length ( args ) ) }
67+ end
68+
69+ defp get_function_data ( { op , _ , [ { name , _ , args } | _ ] } ) do
70+ { op , name , if ( is_atom ( args ) , do: 0 , else: length ( args ) ) }
71+ end
72+
73+ defp traverse ( { op , _ , [ { :when , _ , [ { name , _ , args } | _ ] } | _ ] } = ast , names )
3974 when op in @ public_ops do
4075 definition = { op , name , if ( is_atom ( args ) , do: 0 , else: length ( args ) ) }
4176 { ast , [ definition | names ] }
4277 end
4378
44- defp traverse ( { op , _meta , [ { name , _ , args } | _ ] } = ast , names ) when op in @ public_ops do
79+ defp traverse ( { op , _ , [ { name , _ , args } | _ ] } = ast , names ) when op in @ public_ops do
4580 definition = { op , name , if ( is_atom ( args ) , do: 0 , else: length ( args ) ) }
4681 { ast , [ definition | names ] }
4782 end
4883
49- defp traverse ( ast , names ) do
50- { ast , names }
51- end
84+ defp traverse ( ast , names ) , do: { ast , names }
5285
53- defp find_public_helpers ( code_definitions , exemploid_definitions ) do
54- ( Enum . uniq ( code_definitions ) -- exemploid_definitions )
86+ defp find_public_helpers ( code_def , code_hidden , exemploid_def ) do
87+ ( ( Enum . uniq ( code_def ) -- exemploid_def ) -- code_hidden )
5588 |> Enum . map ( & print_definition / 1 )
5689 end
5790
0 commit comments