1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
open StdLabels
let identifier = "escaped_string"
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_of.Expression.t
type t' = Report.t list
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.
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 [ (_, 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 } ->
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 pos t -> ([], Type_of.Expression.integer pos t)
let function_ : S.pos -> T.function_ -> t list -> t =
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 pos op (r, expr1) -> (r, Type_of.Expression.uoperator pos op expr1)
let boperator : S.pos -> T.boperator -> t -> t -> t =
fun pos op (r1, expr1) (r2, expr2) ->
(r1 @ r2, Type_of.Expression.boperator pos op expr1 expr2)
end
module Instruction :
S.Instruction with type t' = Report.t list and type expression = Expression.t' =
struct
type t = Report.t list
(** Internal type used in the evaluation *)
type t' = t
let v : t -> t' = Fun.id
type expression = Expression.t'
let call : S.pos -> T.keywords -> expression list -> t =
fun pos k exprs ->
ignore pos;
ignore k;
List.concat exprs
let location : S.pos -> string -> t = fun _ _ -> []
let comment : S.pos -> t = fun _ -> []
let expression : expression -> t = Fun.id
let act : S.pos -> label:expression -> t list -> t =
fun pos ~label instructions ->
ignore pos;
List.concat (label :: instructions)
let fold_clause : (expression, t) S.clause -> t =
fun (_pos1, expression, ts) -> List.concat (expression :: ts)
let if_ :
S.pos ->
(expression, t) S.clause ->
elifs:(expression, t) S.clause list ->
else_:(S.pos * t list) option ->
t =
fun pos clause ~elifs ~else_ ->
ignore pos;
let init =
match else_ with
| None -> fold_clause clause
| Some (_, ts) -> List.rev_append (fold_clause clause) (List.concat ts)
in
List.fold_left elifs ~init ~f:(fun t clause ->
List.rev_append (fold_clause clause) t)
let assign :
S.pos ->
(S.pos, expression) S.variable ->
T.assignation_operator ->
expression ->
t =
fun pos variable op expression ->
ignore pos;
ignore op;
match variable.index with
| None -> expression
| Some v -> List.rev_append v expression
end
module Location = struct
type t = Report.t list
type instruction = Instruction.t'
let v = Fun.id
let location : S.pos -> instruction list -> t =
fun pos intructions ->
ignore pos;
List.concat intructions
end
|