-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathAnnotation.ml
99 lines (94 loc) · 3.95 KB
/
Annotation.ml
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
type attributePayload =
| BoolPayload of bool
| ConstructPayload of string
| FloatPayload of string
| IdentPayload of Longident.t
| IntPayload of string
| StringPayload of string
| TuplePayload of attributePayload list
| UnrecognizedPayload
let tagIsGenType s = s = "genType" || s = "gentype"
let tagIsGenTypeImport s = s = "genType.import" || s = "gentype.import"
let tagIsGenTypeOpaque s = s = "genType.opaque" || s = "gentype.opaque"
let tagIsOneOfTheGenTypeAnnotations s =
tagIsGenType s || tagIsGenTypeImport s || tagIsGenTypeOpaque s
let rec getAttributePayload checkText (attributes : Typedtree.attributes) =
let rec fromExpr (expr : Parsetree.expression) =
match expr with
| {pexp_desc = Pexp_constant (Pconst_string (s, _))} ->
Some (StringPayload s)
| {pexp_desc = Pexp_constant (Pconst_integer (n, _))} -> Some (IntPayload n)
| {pexp_desc = Pexp_constant (Pconst_float (s, _))} -> Some (FloatPayload s)
| {
pexp_desc = Pexp_construct ({txt = Lident (("true" | "false") as s)}, _);
_;
} ->
Some (BoolPayload (s = "true"))
| {pexp_desc = Pexp_construct ({txt = Longident.Lident "[]"}, None)} -> None
| {pexp_desc = Pexp_construct ({txt = Longident.Lident "::"}, Some e)} ->
fromExpr e
| {pexp_desc = Pexp_construct ({txt}, _); _} ->
Some (ConstructPayload (txt |> Longident.flatten |> String.concat "."))
| {pexp_desc = Pexp_tuple exprs | Pexp_array exprs} ->
let payloads =
exprs |> List.rev
|> List.fold_left
(fun payloads expr ->
match expr |> fromExpr with
| Some payload -> payload :: payloads
| None -> payloads)
[]
in
Some (TuplePayload payloads)
| {pexp_desc = Pexp_ident {txt}} -> Some (IdentPayload txt)
| _ -> None
in
match attributes with
| [] -> None
| ({Asttypes.txt}, payload) :: tl ->
if checkText txt then
match payload with
| PStr [] -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_eval (expr, _)} :: _) -> expr |> fromExpr
| PStr ({pstr_desc = Pstr_extension _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_value _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_primitive _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_type _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_typext _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_exception _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_module _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_recmodule _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_modtype _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_open _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_class _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_class_type _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_include _} :: _) -> Some UnrecognizedPayload
| PStr ({pstr_desc = Pstr_attribute _} :: _) -> Some UnrecognizedPayload
| PPat _ -> Some UnrecognizedPayload
| PSig _ -> Some UnrecognizedPayload
| PTyp _ -> Some UnrecognizedPayload
else getAttributePayload checkText tl
let hasAttribute checkText (attributes : Typedtree.attributes) =
getAttributePayload checkText attributes <> None
let isOcamlSuppressDeadWarning attributes =
match
attributes
|> getAttributePayload (fun x -> x = "ocaml.warning" || x = "warning")
with
| Some (StringPayload s) ->
let numeric =
match Str.search_forward (Str.regexp (Str.quote "-32")) s 0 with
| _ -> true
| exception Not_found -> false
in
let textual =
match
Str.search_forward
(Str.regexp (Str.quote "-unused-value-declaration"))
s 0
with
| _ -> true
| exception Not_found -> false
in
numeric || textual
| _ -> false