diff options
| -rw-r--r-- | perl_checker.src/parser.mly | 8 | ||||
| -rw-r--r-- | perl_checker.src/parser_helper.ml | 28 | ||||
| -rw-r--r-- | perl_checker.src/parser_helper.mli | 11 | 
3 files changed, 40 insertions, 7 deletions
| diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly index 4d73fca..5b78351 100644 --- a/perl_checker.src/parser.mly +++ b/perl_checker.src/parser.mly @@ -349,8 +349,8 @@ diamond:  subscripted: /* Some kind of subscripted expression */  | variable PKG_SCOPE bracket_subscript {sp_0($2); sp_0($3); Call(Too_complex, [fst $3]), sp_pos_range $1 $3} /* $foo::{something} */ -| scalar bracket_subscript             {sp_0($2); to_Deref_with(I_hash , I_scalar, from_scalar $1, fst                $2), sp_pos_range $1 $2} /* $foo{bar} */ -| scalar arrayref                      {sp_0($2); to_Deref_with(I_array, I_scalar, from_scalar $1, only_one_array_ref $2), sp_pos_range $1 $2} /* $array[$element] */ +| scalar bracket_subscript             {sp_0($2); check_scalar_subscripted $1; to_Deref_with(I_hash , I_scalar, from_scalar $1, fst                $2), sp_pos_range $1 $2} /* $foo{bar} */ +| scalar arrayref                      {sp_0($2); check_scalar_subscripted $1; to_Deref_with(I_array, I_scalar, from_scalar $1, only_one_array_ref $2), sp_pos_range $1 $2} /* $array[$element] */  | term ARROW bracket_subscript         {sp_0($2); sp_0($3); check_arrow_needed $1 $2; to_Deref_with(I_hash , I_scalar, sndfst $1, fst                $3), sp_pos_range $1 $3} /* somehref->{bar} */  | term ARROW arrayref                  {sp_0($2); sp_0($3); check_arrow_needed $1 $2; to_Deref_with(I_array, I_scalar, sndfst $1, only_one_array_ref $3), sp_pos_range $1 $3} /* somearef->[$element] */  | term ARROW parenthesized             {sp_0($2); sp_0($3); to_Deref_with(I_func , I_scalar, sndfst $1, List(sndfst $3)), sp_pos_range $1 $3} /* $subref->(@args) */ @@ -360,8 +360,8 @@ subscripted: /* Some kind of subscripted expression */  restricted_subscripted: /* Some kind of subscripted expression */  | variable PKG_SCOPE bracket_subscript {sp_0($2); sp_0($3); Call(Too_complex, [fst $3]), sp_pos_range $1 $3} /* $foo::{something} */ -| scalar bracket_subscript             {sp_0($2); to_Deref_with(I_hash , I_scalar, from_scalar $1, fst                $2), sp_pos_range $1 $2} /* $foo{bar} */ -| scalar arrayref                      {sp_0($2); to_Deref_with(I_array, I_scalar, from_scalar $1, only_one_array_ref $2), sp_pos_range $1 $2} /* $array[$element] */ +| scalar bracket_subscript             {sp_0($2); check_scalar_subscripted $1; to_Deref_with(I_hash , I_scalar, from_scalar $1, fst                $2), sp_pos_range $1 $2} /* $foo{bar} */ +| scalar arrayref                      {sp_0($2); check_scalar_subscripted $1; to_Deref_with(I_array, I_scalar, from_scalar $1, only_one_array_ref $2), sp_pos_range $1 $2} /* $array[$element] */  | restricted_subscripted bracket_subscript        {sp_0($2); to_Deref_with(I_hash , I_scalar, fst $1, fst                $2), sp_pos_range $1 $2} /* $foo->[bar]{baz} */  | restricted_subscripted arrayref                 {sp_0($2); to_Deref_with(I_array, I_scalar, fst $1, only_one_array_ref $2), sp_pos_range $1 $2} /* $foo->[$bar][$baz] */  | restricted_subscripted parenthesized            {sp_0($2); to_Deref_with(I_func , I_scalar, fst $1, List(sndfst $2)), sp_pos_range $1 $2} /* $foo->{bar}(@args) */ diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml index 832ad76..f16ca14 100644 --- a/perl_checker.src/parser_helper.ml +++ b/perl_checker.src/parser_helper.ml @@ -58,6 +58,19 @@ let rec un_parenthesize_full = function    | List[e] -> un_parenthesize_full e    | e -> e +let is_always_true = function +  | Num(n, _) -> float_of_string n <> 0. +  | Raw_string(s, _) -> s <> "" +  | String(l, _) -> l <> [] +  | Ref _ -> true +  | _ -> false + +let is_always_false = function +  | Num(n, _) -> float_of_string n = 0. +  | Raw_string(s, _) -> s = "" +  | String(l, _) -> l = [] +  | _ -> false +  let not_complex e =    if is_parenthesized e then true else    let rec not_complex_ op = function @@ -296,7 +309,7 @@ let check_parenthesized_first_argexpr_with_Ident ident ((prio, e), _ as ex) =        (match e with        | [e] when is_parenthesized e -> ()        | _ -> warn_rule "use parentheses around argument (otherwise it might cause syntax errors if the package is \"require\"d and not \"use\"d") -  | Ident(None, word, _) when List.mem word ["ref"] -> +  | Ident(None, word, _) when List.mem word ["ref" ; "readlink"] ->        if prio <> P_tok then warn_rule "use parentheses around argument"    | _ -> ());    check_parenthesized_first_argexpr (string_of_Ident ident) ex @@ -318,6 +331,11 @@ let check_arrow_needed ((_, e), _) ter =    | Deref_with _ -> warn (sndsnd ter) "the arrow \"->\" is unneeded"    | _ -> () +let check_scalar_subscripted (e, _) = +  match e with +  | Deref(I_scalar, Deref _) -> warn_rule "for complex dereferencing, use \"->\"" +  | _ -> () +  let check_ternary_paras(cond, a, b) =    let rec dont_need_short_circuit_rec = function      | Num _ @@ -432,6 +450,9 @@ let deref_raw context e =    | Raw_string(s, pos) ->         let fq, ident = split_name_or_fq_name s in        Ident(fq, ident, pos) +  | Deref(I_scalar, (Ident _ as ident)) -> +      warn_rule (sprintf "%s{$%s} can be written %s$%s" (context2s context) (string_of_Ident ident) (context2s context) (string_of_Ident ident)); +      e    | _ -> e    in Deref(context, e) @@ -508,6 +529,11 @@ let cook_call_op(op, para, pos) =    | "=", [ Deref(I_star, (Ident _ as f1)); (Anonymous_sub _ as sub) ] ->        sub_declaration (f1, "") [ sub ] +  | "||", e :: _ when is_always_true  e -> warn_rule "<constant> || ... is the same as <constant>"; call +  | "&&", e :: _ when is_always_false e -> warn_rule "<constant> && ... is the same as <constant>"; call +  | "||", e :: _ when is_always_false e -> warn_rule "<constant> || ... is the same as ..."; call +  | "&&", e :: _ when is_always_true  e -> warn_rule "<constant> && ... is the same as ..."; call +    | _ ->         call diff --git a/perl_checker.src/parser_helper.mli b/perl_checker.src/parser_helper.mli index cbb04e6..adb7a05 100644 --- a/perl_checker.src/parser_helper.mli +++ b/perl_checker.src/parser_helper.mli @@ -10,15 +10,20 @@ val var_STDOUT : Types.fromparser  val split_name_or_fq_name : string -> string option * string  val is_var_dollar_ : Types.fromparser -> bool  val is_var_number_match : Types.fromparser -> bool +val non_scalar_context : Types.context -> bool +val is_scalar_context : Types.context -> bool +val is_not_a_scalar : Types.fromparser -> bool +val is_a_scalar : Types.fromparser -> bool  val is_parenthesized : Types.fromparser -> bool  val un_parenthesize : Types.fromparser -> Types.fromparser  val un_parenthesize_full : Types.fromparser -> Types.fromparser +val is_always_true : Types.fromparser -> bool +val is_always_false : Types.fromparser -> bool  val not_complex : Types.fromparser -> bool  val not_simple : Types.fromparser -> bool  val string_of_Ident : Types.fromparser -> string  val context2s : Types.context -> string  val variable2s : Types.context * string -> string -val non_scalar_context : Types.context -> bool  val is_same_fromparser : Types.fromparser -> Types.fromparser -> bool  val from_scalar : Types.fromparser * 'a -> Types.fromparser  val from_array : Types.fromparser * 'a -> Types.fromparser @@ -66,6 +71,7 @@ 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_scalar_subscripted : Types.fromparser * 'a -> unit  val check_ternary_paras :    Types.fromparser * Types.fromparser * Types.fromparser ->    Types.fromparser list @@ -94,7 +100,6 @@ val only_one_array_ref :  val only_one_in_List :    ('a * Types.fromparser) * ('b * (int * int)) -> Types.fromparser  val is_only_one_in_List : Types.fromparser list -> bool -val is_not_a_scalar : Types.fromparser -> bool  val maybe_to_Raw_string : Types.fromparser -> Types.fromparser  val to_List : Types.fromparser list -> Types.fromparser  val deref_arraylen : Types.fromparser -> Types.fromparser @@ -134,6 +139,8 @@ val to_Call_op_ :    'b * (int * int) -> ('a * Types.fromparser) * ('b * (int * int))  val followed_by_comma :    ('a * Types.fromparser list) * 'b -> bool * 'c -> Types.fromparser list +val pot_strings : (string, string list) Hashtbl.t +val pot_strings_and_file : (string, string) Hashtbl.t  val po_comments : string list ref  val po_comment : string * 'a -> unit  val check_format_a_la_printf : string -> int -> unit | 
