Source file reason_toolchain_ocaml.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
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
open Ppxlib
let () =
let seen = Hashtbl.create 7 in
let mapper =
object
inherit Ast_traverse.map as super
method! attribute attr =
match attr with
| { attr_name = { Location.txt = "ocaml.doc" | "ocaml.text"; _ }
; attr_payload =
PStr
[ { pstr_desc =
Pstr_eval
( { pexp_desc =
Pexp_constant (Pconst_string (_text, _loc, None))
; _
}
, _ )
; pstr_loc = loc
}
]
; _
} as attribute ->
Hashtbl.add seen loc ();
super#attribute attribute
| attribute -> super#attribute attribute
end
in
let filter (_text, loc) = not (Hashtbl.mem seen loc) in
mapper, filter
module Lexer_impl = struct
type t = Lexing.lexbuf
let init ?insert_completion_ident:_ lexbuf =
Lexer.init ();
lexbuf
let token = Lexer.token
let = ref []
let filter =
filtered_comments := List.filter filter (Lexer.comments ())
let _lexbuf _docstrings = !filtered_comments
end
module OCaml_parser = Ocaml_common.Parser
type token = OCaml_parser.token
type invalid_docstrings = unit
let parse_and_filter_doc_comments iter fn lexbuf =
let it, filter = doc_comments_filter () in
let result = fn lexbuf in
ignore (iter it result);
Lexer_impl.filter_comments filter;
result, ()
let implementation lexbuf =
parse_and_filter_doc_comments
(fun it stru -> it#structure stru)
(fun lexbuf ->
Reason_toolchain_conf.From_current.copy_structure
(OCaml_parser.implementation Lexer.token lexbuf))
lexbuf
let core_type lexbuf =
parse_and_filter_doc_comments
(fun it ty -> it#core_type ty)
(fun lexbuf ->
Reason_toolchain_conf.From_current.copy_core_type
(OCaml_parser.parse_core_type Lexer.token lexbuf))
lexbuf
let interface lexbuf =
parse_and_filter_doc_comments
(fun it sig_ -> it#signature sig_)
(fun lexbuf ->
Reason_toolchain_conf.From_current.copy_signature
(OCaml_parser.interface Lexer.token lexbuf))
lexbuf
let filter_toplevel_phrase it = function
| Parsetree.Ptop_def str -> ignore (it#structure str)
| Parsetree.Ptop_dir _ -> ()
let toplevel_phrase lexbuf =
parse_and_filter_doc_comments
filter_toplevel_phrase
(fun lexbuf ->
Reason_toolchain_conf.From_current.copy_toplevel_phrase
(OCaml_parser.toplevel_phrase Lexer.token lexbuf))
lexbuf
let use_file lexbuf =
parse_and_filter_doc_comments
(fun it result -> List.map (filter_toplevel_phrase it) result)
(fun lexbuf ->
List.map
Reason_toolchain_conf.From_current.copy_toplevel_phrase
(OCaml_parser.use_file Lexer.token lexbuf))
lexbuf
let rec skip_phrase lexbuf =
try
match Lexer.token lexbuf with
| OCaml_parser.SEMISEMI | OCaml_parser.EOF -> ()
| _ -> skip_phrase lexbuf
with
| Lexer.Error (Lexer.Unterminated_comment _, _)
| Lexer.Error (Lexer.Unterminated_string, _)
| Lexer.Error (Lexer.Unterminated_string_in_comment _, _)
| Lexer.Error (Lexer.Illegal_character _, _) ->
skip_phrase lexbuf
let maybe_skip_phrase lexbuf =
if
Parsing.is_current_lookahead OCaml_parser.SEMISEMI
|| Parsing.is_current_lookahead OCaml_parser.EOF
then ()
else skip_phrase lexbuf
module Location = Ocaml_common.Location
let safeguard_parsing lexbuf fn =
try fn () with
| Lexer.Error (Lexer.Illegal_character _, _) as err
when !Location.input_name = "//toplevel//" ->
skip_phrase lexbuf;
raise err
| Syntaxerr.Error _ as err when !Location.input_name = "//toplevel//" ->
maybe_skip_phrase lexbuf;
raise err
| Parsing.Parse_error | Syntaxerr.Escape_error ->
let loc = Location.curr lexbuf in
if !Location.input_name = "//toplevel//" then maybe_skip_phrase lexbuf;
raise (Syntaxerr.Error (Syntaxerr.Other loc))
let (signature, _) formatter =
Ocaml_common.Pprintast.signature
formatter
(Reason_toolchain_conf.To_current.copy_signature signature)
let (structure, _) formatter =
let structure =
structure
|> Reason_syntax_util.(apply_mapper_to_structure backport_letopt_mapper)
|> Reason_syntax_util.(
apply_mapper_to_structure remove_stylistic_attrs_mapper)
in
Ocaml_common.Pprintast.structure
formatter
(Reason_toolchain_conf.To_current.copy_structure structure)
module Lexer = Lexer_impl