forked from rescript-lang/reanalyze
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAnnotation.re
111 lines (104 loc) · 3.79 KB
/
Annotation.re
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
type attributePayload =
| BoolPayload(bool)
| ConstructPayload(string)
| FloatPayload(string)
| IdentPayload(Longident.t)
| IntPayload(string)
| StringPayload(string)
| TuplePayload(list(attributePayload))
| 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) =>
switch (expr) {
| {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}, _), _} =>
Some(ConstructPayload(txt |> Longident.flatten |> String.concat(".")))
| {pexp_desc: Pexp_tuple(exprs)} =>
let payloads =
exprs
|> List.rev
|> List.fold_left(
(payloads, expr) =>
switch (expr |> fromExpr) {
| Some(payload) => [payload, ...payloads]
| None => payloads
},
[],
);
Some(TuplePayload(payloads));
| {pexp_desc: Pexp_ident({txt})} => Some(IdentPayload(txt))
| _ => None
};
switch (attributes) {
| [] => None
| [a, ...tl] =>
let (txt, payload) = a |> Compat.getPayload;
if (checkText(txt)) {
switch (payload) {
| 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 => {
switch (
attributes
|> getAttributePayload(x => x == "ocaml.warning" || x == "warning")
) {
| Some(StringPayload(s)) =>
switch (Str.search_forward(Str.regexp(Str.quote("-32")), s, 0)) {
| _ => true
| exception Not_found => false
}
| _ => false
};
};