forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathres_driver.ml
161 lines (149 loc) · 4.87 KB
/
res_driver.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
module IO = Res_io
type ('ast, 'diagnostics) parseResult = {
filename: string; [@live]
source: string;
parsetree: 'ast;
diagnostics: 'diagnostics;
invalid: bool;
comments: Res_comment.t list;
}
type 'diagnostics parsingEngine = {
parseImplementation:
forPrinter:bool ->
filename:string ->
(Parsetree.structure, 'diagnostics) parseResult;
parseInterface:
forPrinter:bool ->
filename:string ->
(Parsetree.signature, 'diagnostics) parseResult;
stringOfDiagnostics: source:string -> filename:string -> 'diagnostics -> unit;
}
type printEngine = {
printImplementation:
width:int ->
filename:string ->
comments:Res_comment.t list ->
Parsetree.structure ->
unit;
printInterface:
width:int ->
filename:string ->
comments:Res_comment.t list ->
Parsetree.signature ->
unit;
}
let setup ~filename ~forPrinter () =
let src = IO.readFile ~filename in
let mode = if forPrinter then Res_parser.Default else ParseForTypeChecker in
Res_parser.make ~mode src filename
let setupFromSource ~displayFilename ~source ~forPrinter () =
let mode = if forPrinter then Res_parser.Default else ParseForTypeChecker in
Res_parser.make ~mode source displayFilename
let parsingEngine =
{
parseImplementation =
(fun ~forPrinter ~filename ->
let engine = setup ~filename ~forPrinter () in
let structure = Res_core.parseImplementation engine in
let invalid, diagnostics =
match engine.diagnostics with
| [] as diagnostics -> (false, diagnostics)
| _ as diagnostics -> (true, diagnostics)
in
{
filename = engine.scanner.filename;
source = engine.scanner.src;
parsetree = structure;
diagnostics;
invalid;
comments = List.rev engine.comments;
});
parseInterface =
(fun ~forPrinter ~filename ->
let engine = setup ~filename ~forPrinter () in
let signature = Res_core.parseSpecification engine in
let invalid, diagnostics =
match engine.diagnostics with
| [] as diagnostics -> (false, diagnostics)
| _ as diagnostics -> (true, diagnostics)
in
{
filename = engine.scanner.filename;
source = engine.scanner.src;
parsetree = signature;
diagnostics;
invalid;
comments = List.rev engine.comments;
});
stringOfDiagnostics =
(fun ~source ~filename:_ diagnostics ->
Res_diagnostics.printReport diagnostics source);
}
let parseImplementationFromSource ~forPrinter ~displayFilename ~source =
let engine = setupFromSource ~displayFilename ~source ~forPrinter () in
let structure = Res_core.parseImplementation engine in
let invalid, diagnostics =
match engine.diagnostics with
| [] as diagnostics -> (false, diagnostics)
| _ as diagnostics -> (true, diagnostics)
in
{
filename = engine.scanner.filename;
source = engine.scanner.src;
parsetree = structure;
diagnostics;
invalid;
comments = List.rev engine.comments;
}
let parseInterfaceFromSource ~forPrinter ~displayFilename ~source =
let engine = setupFromSource ~displayFilename ~source ~forPrinter () in
let signature = Res_core.parseSpecification engine in
let invalid, diagnostics =
match engine.diagnostics with
| [] as diagnostics -> (false, diagnostics)
| _ as diagnostics -> (true, diagnostics)
in
{
filename = engine.scanner.filename;
source = engine.scanner.src;
parsetree = signature;
diagnostics;
invalid;
comments = List.rev engine.comments;
}
let printEngine =
{
printImplementation =
(fun ~width ~filename:_ ~comments structure ->
print_string
(Res_printer.printImplementation ~width structure ~comments));
printInterface =
(fun ~width ~filename:_ ~comments signature ->
print_string (Res_printer.printInterface ~width signature ~comments));
}
let parse_implementation ?(ignoreParseErrors = false) sourcefile =
Location.input_name := sourcefile;
let parseResult =
parsingEngine.parseImplementation ~forPrinter:false ~filename:sourcefile
in
if parseResult.invalid then (
Res_diagnostics.printReport parseResult.diagnostics parseResult.source;
if not ignoreParseErrors then exit 1);
parseResult.parsetree
[@@raises exit]
let parse_interface ?(ignoreParseErrors = false) sourcefile =
Location.input_name := sourcefile;
let parseResult =
parsingEngine.parseInterface ~forPrinter:false ~filename:sourcefile
in
if parseResult.invalid then (
Res_diagnostics.printReport parseResult.diagnostics parseResult.source;
if not ignoreParseErrors then exit 1);
parseResult.parsetree
[@@raises exit]
(* suppress unused optional arg *)
let _ =
fun s ->
( parse_implementation ~ignoreParseErrors:false s,
parse_interface ~ignoreParseErrors:false s )
[@@raises exit]