diff options
Diffstat (limited to 'perl_checker.src')
-rw-r--r-- | perl_checker.src/flags.ml | 1 | ||||
-rw-r--r-- | perl_checker.src/parser.mly | 8 | ||||
-rw-r--r-- | perl_checker.src/parser_helper.ml | 38 | ||||
-rw-r--r-- | perl_checker.src/parser_helper.mli | 6 |
4 files changed, 33 insertions, 20 deletions
diff --git a/perl_checker.src/flags.ml b/perl_checker.src/flags.ml index b2c40c2..5256831 100644 --- a/perl_checker.src/flags.ml +++ b/perl_checker.src/flags.ml @@ -2,4 +2,3 @@ open Common let verbose = ref false let quiet = ref false - diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly index 45c0db8..364ab5a 100644 --- a/perl_checker.src/parser.mly +++ b/perl_checker.src/parser.mly @@ -233,10 +233,10 @@ term: | term PATTERN_MATCH_NOT STRING {die_with_rawpos (sndsnd $3) "use a regexp, not a string"} -| term QUESTION_MARK term COLON term {sp_p($2); sp_p($3); sp_p($4); sp_p($5); check_ternary_paras $3 $5; to_Call_op_(P_ternary, "?:", [ prio_lo P_ternary $1 ; prio_lo_after P_ternary $3; prio_lo_after P_ternary $5]) (sp_pos_range $1 $5)} -| term QUESTION_MARK term COLON BRACKET expr BRACKET_END {sp_p($2); sp_p($3); check_ternary_para $3; sp_p($4); sp_p($5); sp_p($6); sp_p($7); check_ternary_para $1; to_Call_op_(P_ternary, "?:", [ prio_lo P_ternary $1 ; prio_lo_after P_ternary $3; Ref(I_hash, sndfst $6)]) (sp_pos_range $1 $7)} -| term QUESTION_MARK BRACKET expr BRACKET_END COLON term {sp_p($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sp_p($7); check_ternary_para $7; to_Call_op_(P_ternary, "?:", [ prio_lo P_ternary $1 ; Ref(I_hash, sndfst $4); prio_lo_after P_ternary $7]) (sp_pos_range $1 $7)} -| term QUESTION_MARK BRACKET expr BRACKET_END COLON BRACKET expr BRACKET_END {sp_p($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sp_p($7); sp_p($8); sp_p($9); to_Call_op_(P_ternary, "?:", [ prio_lo P_ternary $1 ; Ref(I_hash, sndfst $4); Ref(I_hash, sndfst $8)]) (sp_pos_range $1 $9)} +| term QUESTION_MARK term COLON term {sp_p($2); sp_p($3); sp_p($4); sp_p($5); to_Call_op_(P_ternary, "?:", check_ternary_paras(prio_lo P_ternary $1, prio_lo_after P_ternary $3, prio_lo_after P_ternary $5)) (sp_pos_range $1 $5)} +| term QUESTION_MARK term COLON BRACKET expr BRACKET_END {sp_p($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sp_p($7); to_Call_op_(P_ternary, "?:", check_ternary_paras(prio_lo P_ternary $1, prio_lo_after P_ternary $3, Ref(I_hash, sndfst $6))) (sp_pos_range $1 $7)} +| term QUESTION_MARK BRACKET expr BRACKET_END COLON term {sp_p($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sp_p($7); to_Call_op_(P_ternary, "?:", check_ternary_paras(prio_lo P_ternary $1, Ref(I_hash, sndfst $4), prio_lo_after P_ternary $7)) (sp_pos_range $1 $7)} +| term QUESTION_MARK BRACKET expr BRACKET_END COLON BRACKET expr BRACKET_END {sp_p($2); sp_p($3); sp_p($4); sp_p($5); sp_p($6); sp_p($7); sp_p($8); sp_p($9); to_Call_op_(P_ternary, "?:", check_ternary_paras(prio_lo P_ternary $1, Ref(I_hash, sndfst $4), Ref(I_hash, sndfst $8))) (sp_pos_range $1 $9)} /* Unary operators and terms */ diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml index 00b121d..a965dba 100644 --- a/perl_checker.src/parser_helper.ml +++ b/perl_checker.src/parser_helper.ml @@ -17,9 +17,6 @@ let is_var_dollar_ = function let is_var_number_match = function | Deref(I_scalar, Ident(None, s, _)) -> String.length s = 1 && s.[0] <> '0' && char_is_number s.[0] | _ -> false -let is_call = function - | Call _ -> true - | _ -> false let is_parenthesized = function | List[] @@ -282,14 +279,33 @@ let check_arrow_needed ((_, e), _) ter = | Deref_with _ -> warn (sndsnd ter) "the arrow \"->\" is unneeded" | _ -> () -let check_ternary_para ((_, e), _) = - match e with - | List [] -> warn_rule "you may use if_() here\n beware that the short-circuit semantic of ?: is not kept\n if you want to keep the short-circuit behaviour, replace () with @{[]} and there will be no warning anymore" - | _ -> () - -let check_ternary_paras ((_, e1), _ as ter1) ((_, e2), _ as ter2) = - if not (is_call e1) then check_ternary_para ter2; - if not (is_call e2) then check_ternary_para ter1 +let check_ternary_paras(cond, a, b) = + let rec dont_need_short_circuit_rec = function + | Num _ + | Raw_string _ + | String ([(_, List [])], _) + | Call_op("qw", _, _) + -> true + | Call(Deref(I_func, Ident(None, "N", _)), [ List(String _ :: l) ]) + | Call_op(".", l, _) + | Ref(I_hash, List l) + | List l -> List.for_all dont_need_short_circuit_rec l + | _ -> false + in + let rec dont_need_short_circuit = function + | Ref(_, Deref(_, Ident _)) + | Deref(_, Ident _) -> true + | Ref(I_hash, List l) + | List l -> List.for_all dont_need_short_circuit l + | e -> dont_need_short_circuit_rec e + in + let check_ternary_para = function + | List [] -> warn_rule "you may use if_() here\n beware that the short-circuit semantic of ?: is not kept\n if you want to keep the short-circuit behaviour, replace () with @{[]} and there will be no warning anymore" + | _ -> () + in + if dont_need_short_circuit a || is_same_fromparser cond a then check_ternary_para b; + if dont_need_short_circuit b || is_same_fromparser cond b then check_ternary_para a; + [ cond; a; b ] let check_unneeded_var_dollar_ ((_, e), (_, pos)) = if is_var_dollar_ e then warn pos "\"$_ =~ /regexp/\" can be written \"/regexp/\"" else diff --git a/perl_checker.src/parser_helper.mli b/perl_checker.src/parser_helper.mli index d3f5396..a5b0837 100644 --- a/perl_checker.src/parser_helper.mli +++ b/perl_checker.src/parser_helper.mli @@ -9,7 +9,6 @@ val var_dollar_ : Types.fromparser val var_STDOUT : Types.fromparser val is_var_dollar_ : Types.fromparser -> bool val is_var_number_match : Types.fromparser -> bool -val is_call : Types.fromparser -> bool val is_parenthesized : Types.fromparser -> bool val un_parenthesize : Types.fromparser -> Types.fromparser val un_parenthesize_full : Types.fromparser -> Types.fromparser @@ -62,10 +61,9 @@ val check_hash_subscript : ('a * Types.fromparser) * ('b * (int * int)) -> unit val check_arrow_needed : ('a * Types.fromparser) * 'b -> 'c * ('d * (int * int)) -> unit -val check_ternary_para : ('a * Types.fromparser) * ('b * (int * int)) -> unit val check_ternary_paras : - ('a * Types.fromparser) * ('b * (int * int)) -> - ('c * Types.fromparser) * ('d * (int * int)) -> unit + Types.fromparser * Types.fromparser * Types.fromparser -> + Types.fromparser list val check_unneeded_var_dollar_ : ('a * Types.fromparser) * ('b * (int * int)) -> unit val check_unneeded_var_dollar_not : |