@@ -5,8 +5,8 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheck do
55 explanations: [
66 # TODO: improve checkdoc
77 check: """
8- Checking if the size of the enum is `0` can be very expensive, since you are
9- determining the exact count of elements.
8+ Checking if the size of the enum is `0` (or not `0`) can be very expensive,
9+ since you are determining the exact count of elements.
1010
1111 Checking if an enum is empty should be done by using
1212
@@ -17,7 +17,7 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheck do
1717 list == []
1818
1919
20- For Enum.count/2: Checking if an enum doesn't contain specific elements should
20+ For ` Enum.count/2` : Checking if an enum doesn't contain specific elements should
2121 be done by using
2222
2323 not Enum.any?(enum, condition)
@@ -28,9 +28,9 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheck do
2828 @ doc false
2929 @ impl true
3030 def run ( % SourceFile { } = source_file , params ) do
31- issue_meta = IssueMeta . for ( source_file , params )
32-
33- Credo.Code . prewalk ( source_file , & traverse ( & 1 , & 2 , issue_meta ) )
31+ ctx = Context . build ( source_file , params , __MODULE__ )
32+ result = Credo.Code . prewalk ( source_file , & walk / 2 , ctx )
33+ result . issues
3434 end
3535
3636 @ enum_count_pattern quote do: {
@@ -43,74 +43,44 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheck do
4343 { @ enum_count_pattern , "Enum.count" } ,
4444 { @ length_pattern , "length" }
4545 ]
46- @ eq_operators [ :== , :!= , :=== , :!== , :> , :< ]
47-
48- # Comparisons against 0
49- for { pattern , trigger } <- @ comparisons ,
50- operator <- @ eq_operators do
51- defp traverse (
52- { unquote ( operator ) , _meta , [ unquote ( pattern ) , 0 ] } = ast ,
53- issues ,
54- issue_meta
55- ) do
56- { ast , issues_for_call ( unquote ( trigger ) , issues , issue_meta , ast ) }
57- end
46+ @ operators [ :== , :!= , :=== , :!== , :> , :< ]
5847
59- defp traverse (
60- { unquote ( operator ) , _meta , [ 0 , unquote ( pattern ) ] } = ast ,
61- issues ,
62- issue_meta
63- ) do
64- { ast , issues_for_call ( unquote ( trigger ) , issues , issue_meta , ast ) }
48+ for { pattern , trigger } <- @ comparisons do
49+ # Comparisons against 0
50+ defp walk ( { op , meta , [ unquote ( pattern ) , 0 ] } = ast , ctx ) when op in @ operators do
51+ { ast , put_issue ( ctx , issue_for ( ctx , meta , unquote ( trigger ) , suggest ( ast ) ) ) }
6552 end
66- end
6753
68- # Comparisons against 1
69- for { pattern , trigger } <- @ comparisons do
70- defp traverse (
71- { :>= , _meta , [ unquote ( pattern ) , 1 ] } = ast ,
72- issues ,
73- issue_meta
74- ) do
75- { ast , issues_for_call ( unquote ( trigger ) , issues , issue_meta , ast ) }
54+ defp walk ( { op , meta , [ 0 , unquote ( pattern ) ] } = ast , ctx ) when op in @ operators do
55+ { ast , put_issue ( ctx , issue_for ( ctx , meta , unquote ( trigger ) , suggest ( ast ) ) ) }
7656 end
7757
78- defp traverse (
79- { :<= , _meta , [ 1 , unquote ( pattern ) ] } = ast ,
80- issues ,
81- issue_meta
82- ) do
83- { ast , issues_for_call ( unquote ( trigger ) , issues , issue_meta , ast ) }
58+ # Comparisons against 1
59+ defp walk ( { :>= , meta , [ unquote ( pattern ) , 1 ] } = ast , ctx ) do
60+ { ast , put_issue ( ctx , issue_for ( ctx , meta , unquote ( trigger ) , suggest ( ast ) ) ) }
8461 end
85- end
8662
87- defp traverse ( ast , issues , _issue_meta ) do
88- { ast , issues }
63+ defp walk ( { :<= , meta , [ 1 , unquote ( pattern ) ] } = ast , ctx ) do
64+ { ast , put_issue ( ctx , issue_for ( ctx , meta , unquote ( trigger ) , suggest ( ast ) ) ) }
65+ end
8966 end
9067
91- defp issues_for_call ( trigger , issues , issue_meta , ast ) do
92- meta = get_meta ( ast )
93- [ issue_for ( issue_meta , meta , trigger , suggest ( ast ) ) | issues ]
68+ defp walk ( ast , ctx ) do
69+ { ast , ctx }
9470 end
9571
9672 defp suggest ( { _op , _ , [ _ , { _pattern , _ , args } ] } ) , do: suggest_for_arity ( Enum . count ( args ) )
9773 defp suggest ( { _op , _ , [ { _pattern , _ , args } , _ ] } ) , do: suggest_for_arity ( Enum . count ( args ) )
9874
99- defp get_meta ( { _op , _ , [ _ , { { :. , _ , [ { :__aliases__ , meta , _ } , _ ] } , _ , _ } ] } ) , do: meta
100- defp get_meta ( { _op , _ , [ _ , { _ , meta , _ } ] } ) , do: meta
101- defp get_meta ( { _op , _ , [ { { :. , _ , [ { :__aliases__ , meta , _ } , _ ] } , _ , _ } , _ ] } ) , do: meta
102- defp get_meta ( { _op , _ , [ { _ , meta , _ } , _ ] } ) , do: meta
103-
10475 defp suggest_for_arity ( 2 ) , do: "`not Enum.any?/2`"
105- defp suggest_for_arity ( 1 ) , do: "`Enum.empty?/1` or `list == []` "
76+ defp suggest_for_arity ( 1 ) , do: "`Enum.empty?/1`"
10677
107- defp issue_for ( issue_meta , meta , trigger , suggestion ) do
78+ defp issue_for ( ctx , meta , trigger , suggestion ) do
10879 format_issue (
109- issue_meta ,
110- message: "#{ trigger } is expensive, prefer #{ suggestion } ." ,
80+ ctx ,
81+ message: "Using ` #{ trigger } /1` is expensive, prefer #{ suggestion } ." ,
11182 trigger: trigger ,
112- line_no: meta [ :line ] ,
113- column: meta [ :column ]
83+ line_no: meta [ :line ]
11484 )
11585 end
11686end
0 commit comments