aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChimrod <>2023-11-06 15:07:28 +0100
committerChimrod <>2023-11-06 15:09:06 +0100
commit5acc63c0653b363d3d6dc9217e0a29d7e44cbcaa (patch)
tree1bd8b5349b6c63081ea92686f03c7c101001deec
parent1128450d0b52c09e78d64df5737b8a034b3e230c (diff)
In the string expression simplification, only report the strings converted into strings
-rw-r--r--lib/syntax/nested_strings.ml51
-rw-r--r--lib/syntax/type_of.ml3
-rw-r--r--lib/syntax/type_of.mli10
-rw-r--r--readme.md4
-rw-r--r--test/nested_string.ml33
5 files changed, 72 insertions, 29 deletions
diff --git a/lib/syntax/nested_strings.ml b/lib/syntax/nested_strings.ml
index 16ec4ac..c7b0b83 100644
--- a/lib/syntax/nested_strings.ml
+++ b/lib/syntax/nested_strings.ml
@@ -5,10 +5,11 @@ let description = "Check for unnecessary use of expression encoded in string"
let active = ref true
module Expression : S.Expression with type t' = Report.t list = struct
- type t = Report.t list
- type t' = t
+ type t = Report.t list * Type_of.Expression.t
+ type t' = Report.t list
- let v : t -> t' = Fun.id
+ let get_type t = Type_of.Expression.v t |> Type_of.get_type
+ let v : t -> t' = Stdlib.fst
(** Identify the expressions reprented as string. That’s here that the report
are added.
@@ -16,28 +17,48 @@ module Expression : S.Expression with type t' = Report.t list = struct
All the rest of the module only push thoses warning to the top level. *)
let literal : S.pos -> t T.literal list -> t =
fun pos content ->
+ let type_of =
+ List.map content ~f:(function
+ | T.Text _ as text -> text
+ | T.Expression expr -> T.Expression (List.map ~f:snd expr))
+ |> Type_of.Expression.literal pos
+ in
+
match content with
- | [ T.Expression expr; T.Text "" ] ->
- ignore expr;
- let msg = Report.debug pos "This expression can be simplified" in
- [ msg ]
- | _ -> []
+ | [ T.Expression [ (_, t') ]; T.Text "" ] -> (
+ match get_type t' with
+ | Type_of.Helper.Integer -> ([], type_of)
+ | _ ->
+ let msg = Report.debug pos "This expression can be simplified" in
+ ([ msg ], type_of))
+ | _ -> ([], type_of)
let ident : (S.pos, t) S.variable -> t =
fun { pos; name : string; index : t option } ->
- ignore pos;
- ignore name;
- match index with None -> [] | Some v -> v
+ match index with
+ | None ->
+ let type_ = Type_of.Expression.ident { pos; name; index = None } in
+ ([], type_)
+ | Some (v, t') ->
+ let type_ = Type_of.Expression.ident { pos; name; index = Some t' } in
+ (v, type_)
- let integer : S.pos -> string -> t = fun _ _ -> []
+ let integer : S.pos -> string -> t =
+ fun pos t -> ([], Type_of.Expression.integer pos t)
let function_ : S.pos -> T.function_ -> t list -> t =
- fun _ _ expressions -> List.concat expressions
+ fun pos f expressions ->
+ let r, t = List.split expressions in
+
+ let type_of = Type_of.Expression.function_ pos f t in
+ (List.concat r, type_of)
- let uoperator : S.pos -> T.uoperator -> t -> t = fun _ _ expr1 -> expr1
+ let uoperator : S.pos -> T.uoperator -> t -> t =
+ fun pos op (r, expr1) -> (r, Type_of.Expression.uoperator pos op expr1)
let boperator : S.pos -> T.boperator -> t -> t -> t =
- fun _ _ expr1 expr2 -> expr1 @ expr2
+ fun pos op (r1, expr1) (r2, expr2) ->
+ (r1 @ r2, Type_of.Expression.boperator pos op expr1 expr2)
end
module Instruction :
diff --git a/lib/syntax/type_of.ml b/lib/syntax/type_of.ml
index 223633c..15d6fe8 100644
--- a/lib/syntax/type_of.ml
+++ b/lib/syntax/type_of.ml
@@ -483,3 +483,6 @@ module Location = struct
in
report
end
+
+let get_type : Expression.t' -> Helper.type_of =
+ fun t' -> match (fst t').result with Raw r -> r | Variable r -> r
diff --git a/lib/syntax/type_of.mli b/lib/syntax/type_of.mli
index 551f9ac..a009c48 100644
--- a/lib/syntax/type_of.mli
+++ b/lib/syntax/type_of.mli
@@ -1,3 +1,11 @@
+module Helper : sig
+ type type_of =
+ | Integer (** A numeric value *)
+ | Bool (** A boolean, not a real type *)
+ | String (** String value *)
+ | NumericString
+end
+
include S.Analyzer
(** The module [type_of] populate the report with differents inconsistency
errors in the types.
@@ -5,3 +13,5 @@ include S.Analyzer
- Assigning a [string] value in an [integer] variable
- Comparing a [string] with an [integer]
- Giving the wrong type in the argument for a function and so one. *)
+
+val get_type : Expression.t' -> Helper.type_of
diff --git a/readme.md b/readme.md
index d18b371..e6efa88 100644
--- a/readme.md
+++ b/readme.md
@@ -77,4 +77,6 @@ instructions are given, which can lead to dead end in the code.
The application will report text strings containing only one expression with a
`debug` message.
-For example `"<<$variable>>"` can be written directly: `$variable>`.
+For example `"<<$variable>>"` can be written directly: `$variable>`. This test
+will not report this usage when an integer converted into a string this way.
+
diff --git a/test/nested_string.ml b/test/nested_string.ml
index b121667..3338fa3 100644
--- a/test/nested_string.ml
+++ b/test/nested_string.ml
@@ -5,23 +5,30 @@ let _position = (Lexing.dummy_pos, Lexing.dummy_pos)
let _test_instruction : string -> Qsp_syntax.Report.t list -> unit =
Check._test_instruction
-let nothing () = _test_instruction {|
-"value = <<$variable>>"
- |} []
+let report =
+ [
+ {
+ Qsp_syntax.Report.level = Debug;
+ Qsp_syntax.Report.loc = _position;
+ Qsp_syntax.Report.message = "This expression can be simplified";
+ };
+ ]
-let simple_expression () =
- _test_instruction {|"<<$variable>>"|}
- [
- {
- level = Debug;
- loc = _position;
- message = "This expression can be simplified";
- };
- ]
+let nothing () = _test_instruction {|"value = <<$variable>>"|} []
+let string () = _test_instruction {|"<<'ABC'>>"|} report
+let string_variable () = _test_instruction {|"<<$variable>>"|} report
+
+(** It’s OK to use this system to convert a numeric value into a string *)
+let integer () = _test_instruction {|"<<123>>"|} []
+
+let integer_variable () = _test_instruction {|"<<variable>>"|} []
let test =
( "Nested_strings checker",
[
Alcotest.test_case "Ok" `Quick nothing;
- Alcotest.test_case "Simple expression" `Quick simple_expression;
+ Alcotest.test_case "String variable" `Quick string_variable;
+ Alcotest.test_case "Integer" `Quick integer;
+ Alcotest.test_case "String" `Quick string;
+ Alcotest.test_case "Integer variable" `Quick integer_variable;
] )