2 * Copyright (c) 2016, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
14 * A positioned token stores the original source text,
15 * the offset of the leading trivia, the width of the leading trivia,
16 * node proper, and trailing trivia. From all this information we can
17 * rapidly compute the absolute position of any portion of the node,
22 module MinimalToken
= Full_fidelity_minimal_token
23 module Trivia
= Full_fidelity_positioned_trivia
24 module SourceText
= Full_fidelity_source_text
25 module TokenKind
= Full_fidelity_token_kind
29 source_text
: SourceText.t
;
30 offset
: int; (* Beginning of first trivia *)
32 width
: int; (* Width of actual token, not counting trivia *)
34 leading
: Trivia.t list
;
35 trailing
: Trivia.t list
38 let make kind source_text offset width leading trailing
=
39 let folder sum trivia
=
40 sum
+ (Trivia.width trivia
) in
41 let leading_width = List.fold_left
folder 0 leading
in
42 let trailing_width = List.fold_left
folder 0 trailing
in
43 { kind
; source_text
; offset
; leading_width; width
; trailing_width;
49 let with_kind token
kind =
52 let source_text token
=
55 let leading_width token
=
61 let trailing_width token
=
64 let full_width token
=
65 (leading_width token
) + (width token
) + (trailing_width token
)
70 let with_leading leading token
=
71 { token
with leading }
76 let with_trailing trailing token
=
77 { token
with trailing }
79 let has_trivia_kind token
kind =
80 List.exists
(fun t
-> Trivia.kind t
= kind) token
.leading ||
81 List.exists
(fun t
-> Trivia.kind t
= kind) token
.trailing
83 let leading_start_offset token
=
86 let leading_end_offset token
=
87 let w = (leading_width token
) - 1 in
88 let w = if w < 0 then 0 else w in
89 (leading_start_offset token
) + w
91 let start_offset token
=
92 (leading_start_offset token
) + (leading_width token
)
94 let end_offset token
=
95 let w = (width token
) - 1 in
96 let w = if w < 0 then 0 else w in
97 (start_offset token
) + w
99 let trailing_start_offset token
=
100 (leading_start_offset token
) + (leading_width token
) + (width token
)
102 let trailing_end_offset token
=
103 let w = (full_width token
) - 1 in
104 let w = if w < 0 then 0 else w in
105 (leading_start_offset token
) + w
107 let leading_start_position token
=
108 SourceText.offset_to_position
(source_text token
) (leading_start_offset token
)
110 let leading_end_position token
=
111 SourceText.offset_to_position
(source_text token
) (leading_end_offset token
)
113 let start_position token
=
114 SourceText.offset_to_position
(source_text token
) (start_offset token
)
116 let end_position token
=
117 SourceText.offset_to_position
(source_text token
) (end_offset token
)
119 let trailing_start_position token
=
120 SourceText.offset_to_position
121 (source_text token
) (trailing_start_offset token
)
123 let trailing_end_position token
=
124 SourceText.offset_to_position
(source_text token
) (trailing_end_offset token
)
126 let leading_span token
=
127 ((leading_start_position token
), (leading_end_position token
))
130 ((start_position token
), (end_position token
))
132 let trailing_span token
=
133 ((trailing_start_position token
), (trailing_end_position token
))
135 let full_span token
=
136 ((leading_start_position token
), (trailing_end_position token
))
138 let full_text token
=
140 (source_text token
) (leading_start_offset token
) (full_width token
)
142 let leading_text token
=
144 (source_text token
) (leading_start_offset token
) (leading_width token
)
146 let trailing_text token
=
148 (source_text token
) ((end_offset token
) + 1) (trailing_width token
)
151 SourceText.sub
(source_text token
) (start_offset token
) (width token
)
153 let from_minimal source_text minimal_token offset
=
154 let kind = MinimalToken.kind minimal_token
in
155 let leading_width = MinimalToken.leading_width minimal_token
in
156 let width = MinimalToken.width minimal_token
in
157 let leading = Trivia.from_minimal_list
source_text
158 (MinimalToken.leading minimal_token
) offset
in
159 let trailing = Trivia.from_minimal_list
source_text
160 (MinimalToken.trailing minimal_token
) (offset
+ leading_width + width) in
161 make kind source_text offset
width leading trailing
165 let (line_number
, _
) = start_position token
in
167 ("kind", JSON_String
(TokenKind.to_string token
.kind));
168 ("text", JSON_String
(text token
));
169 ("offset", int_ token
.offset
);
170 ("leading_width", int_ token
.leading_width);
171 ("width", int_ token
.width);
172 ("trailing_width", int_ token
.trailing_width);
173 ("leading", JSON_Array
(List.map
Trivia.to_json token
.leading));
174 ("trailing", JSON_Array
(List.map
Trivia.to_json token
.trailing));
175 ("line_number", int_ line_number
);