8
8
open Aast
9
9
open Hh_prelude
10
10
11
+ (* *
12
+ Lint on functions/methods that always return the same value. This
13
+ is usually a copy-paste error.
14
+
15
+ function some_prediate(Whatever $value): bool {
16
+ if ($value->foo()) {
17
+ return false;
18
+ }
19
+
20
+ if ($value->bar()) {
21
+ return false;
22
+ }
23
+
24
+ return false; // oops!
25
+ } *)
26
+
11
27
let is_expr_same ((_ , _ , expr1 ) : Tast. expr ) ((_ , _ , expr2 ) : Tast. expr ) : bool
12
28
=
13
29
match (expr1, expr2) with
@@ -26,6 +42,21 @@ let is_expr_same ((_, _, expr1) : Tast.expr) ((_, _, expr2) : Tast.expr) : bool
26
42
true
27
43
| _ -> false
28
44
45
+ (* Does this value look like a success exit code? We don't want to
46
+ lint on code like this:
47
+
48
+ function my_main(): int {
49
+ if (quick_check()) { return 0; }
50
+
51
+ normal_work();
52
+ return 0;
53
+ } *)
54
+ let is_success_ish ((_ , _ , e_ ) : Tast. expr ) : bool =
55
+ match e_ with
56
+ | Aast. Int "0" -> true
57
+ | Aast. Class_const (_ , (_ , "SUCCESS" )) -> true
58
+ | _ -> false
59
+
29
60
let rec are_return_expressions_same (ret_list : Tast.expr list ) : bool =
30
61
match ret_list with
31
62
| expr1 :: expr2 :: tail ->
@@ -61,25 +92,20 @@ let get_return_expr_visitor =
61
92
let get_return_exprs (stmts : Tast.stmt list ) : Tast.expr list =
62
93
get_return_expr_visitor#on_block () stmts
63
94
95
+ let check_block (block : Tast.block ) : unit =
96
+ let ret_list = get_return_exprs block in
97
+ match ret_list with
98
+ | expr1 :: _ :: _ when are_return_expressions_same ret_list ->
99
+ if not (is_success_ish expr1) then
100
+ List. iter ret_list ~f: (fun (_ , pos , _ ) ->
101
+ Lints_errors. branches_return_same_value pos)
102
+ | _ -> ()
103
+
64
104
let handler =
65
105
object
66
106
inherit Tast_visitor. handler_base
67
107
68
- method! at_fun_def _env f =
69
- let ret_list = get_return_exprs f.fd_fun.f_body.fb_ast in
70
- if List. length ret_list > 1 then (
71
- if are_return_expressions_same ret_list then
72
- List. iter ret_list ~f: (fun (_ , pos , _ ) ->
73
- Lints_errors. branches_return_same_value pos)
74
- ) else
75
- ()
76
-
77
- method! at_method_ _env m =
78
- let ret_list = get_return_exprs m.m_body.fb_ast in
79
- if List. length ret_list > 1 then (
80
- if are_return_expressions_same ret_list then
81
- List. iter ret_list ~f: (fun (_ , pos , _ ) ->
82
- Lints_errors. branches_return_same_value pos)
83
- ) else
84
- ()
108
+ method! at_fun_def _env f = check_block f.fd_fun.f_body.fb_ast
109
+
110
+ method! at_method_ _env m = check_block m.m_body.fb_ast
85
111
end
0 commit comments