Introduce __ReturnsVoidToRx
[hiphop-php.git] / hphp / hack / src / typing / full_fidelity_typed_positioned_syntax.ml
bloba86ff9f29dde509f5e8198a847a5217dd6f551fc
1 (**
2 * Copyright (c) 2016, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 (** Typed and positioned syntax tree
12 * A positioned tree which may know information about the type of the node.
14 * Types come from the typed ast.
15 * type annotations are available on all:
16 * - expressions
17 * - class-id
18 * - instanceof
19 * - new
20 * - get
21 * - const
22 * TODO: Enable type annotations on:
23 * - tast hints (aka type annotations):
24 * - hint -> ty: Decl_hint.hint, Decl_env
25 * - parameters
26 * - return types
27 * - explicit type args on call
28 * - cast
29 * - is
30 * - as
31 * - tparam constraints
32 * - c_extends- uses
33 * - req-extends
34 * - req-implements
35 * - implements
36 * - class constant
37 * - property
38 * - type
39 * - constant
42 module SourceText = Full_fidelity_positioned_syntax.SourceText
43 module Token = Full_fidelity_positioned_token
44 module Trivia = Full_fidelity_positioned_trivia
45 module SyntaxKind = Full_fidelity_syntax_kind
46 module TokenKind = Full_fidelity_token_kind
47 module SyntaxWithToken = Full_fidelity_syntax.WithToken(Token)
51 Converts from full fidelity positions (which use a different indexing scheme
52 from typed ast positions) to json where:
53 - all indexes are 0 based
54 - start columns are inclusive
55 - end columns are exclusive
57 let pos_to_zero_indexed_json t =
58 let line_start, char_start, line_end, char_end = Pos.destruct_range t in
59 let fn = Pos.filename t in
60 Hh_json.JSON_Object [
61 "filename", Hh_json.JSON_String fn;
62 "start", Hh_json.JSON_Object [
63 "line", Hh_json.int_ (line_start - 1);
64 "column", Hh_json.int_ (char_start - 1)
66 "end", Hh_json.JSON_Object [
67 "line", Hh_json.int_ (line_end - 1);
68 "column", Hh_json.int_ char_end
72 module Value = struct
73 (* placeholder definitions *)
74 type absolute = Pos.absolute
75 let show_absolute _ = "<absolute>"
76 let pp_absolute _ _ = Printf.printf "%s\n" "<asbolute>"
78 type t = {
79 source_text: SourceText.t;
80 offset: int; (* Beginning of first trivia *)
81 leading_width: int;
82 width: int; (* Width of node, not counting trivia *)
83 trailing_width: int;
84 tys: Tast_type_collector.collected_type list;
85 position: absolute;
86 } [@@deriving show]
88 let position value =
89 SourceText.relative_pos
90 (SourceText.file_path value.source_text)
91 value.source_text value.offset
92 (value.offset + value.width)
94 let to_json value =
95 let open Hh_json in
96 JSON_Object
97 (["position", pos_to_zero_indexed_json value.position
98 ] @ match value.tys with
99 | [] -> []
100 | tys ->
101 let json_tys = Tast_type_collector.collected_types_to_json tys in
102 [("types", JSON_Array json_tys)])
105 module PositionedSyntaxValue = Full_fidelity_positioned_syntax.PositionedSyntaxValue
107 let positioned_value_to_typed
108 (position: Pos.absolute)
109 (types: Tast_type_collector.collected_type list)
110 (value: PositionedSyntaxValue.t): Value.t =
112 Value.source_text = PositionedSyntaxValue.source_text value;
113 offset = PositionedSyntaxValue.start_offset value;
114 leading_width = PositionedSyntaxValue.leading_width value;
115 width = PositionedSyntaxValue.width value;
116 trailing_width = PositionedSyntaxValue.trailing_width value;
117 tys = types;
118 position;
121 module TypedSyntax = SyntaxWithToken.WithSyntaxValue(Value)
123 module TypedValueBuilder = struct
124 let value_from_children _ _ _ _ =
125 assert false
127 let value_from_token _ =
128 assert false
130 let value_from_syntax _ =
131 assert false
134 include TypedSyntax
135 include TypedSyntax.WithValueBuilder(TypedValueBuilder)
138 let source_text node =
139 (value node).Value.source_text
141 let leading_width node =
142 (value node).Value.leading_width
144 let width node =
145 (value node).Value.width
147 let trailing_width node =
148 (value node).Value.trailing_width
150 let full_width node =
151 (leading_width node) + (width node) + (trailing_width node)
153 let leading_start_offset node =
154 (value node).Value.offset
156 let leading_end_offset node =
157 let w = (leading_width node) - 1 in
158 let w = if w < 0 then 0 else w in
159 (leading_start_offset node) + w
161 let start_offset node =
162 (leading_start_offset node) + (leading_width node)
164 let end_offset node =
165 let w = (width node) - 1 in
166 let w = if w < 0 then 0 else w in
167 (start_offset node) + w
169 let trailing_start_offset node =
170 (leading_start_offset node) + (leading_width node) + (width node)
172 let trailing_end_offset node =
173 let w = (full_width node) - 1 in
174 let w = if w < 0 then 0 else w in
175 (leading_start_offset node) + w
177 let leading_start_position node =
178 SourceText.offset_to_position (source_text node) (leading_start_offset node)
180 let leading_end_position node =
181 SourceText.offset_to_position (source_text node) (leading_end_offset node)
183 let start_position node =
184 SourceText.offset_to_position (source_text node) (start_offset node)
186 let end_position node =
187 SourceText.offset_to_position (source_text node) (end_offset node)
189 let trailing_start_position node =
190 SourceText.offset_to_position (source_text node) (trailing_start_offset node)
192 let trailing_end_position node =
193 SourceText.offset_to_position (source_text node) (trailing_end_offset node)
195 let leading_span node =
196 ((leading_start_position node), (leading_end_position node))
198 let span node =
199 ((start_position node), (end_position node))
201 let trailing_span node =
202 ((trailing_start_position node), (trailing_end_position node))
204 let full_span node =
205 ((leading_start_position node), (trailing_end_position node))
207 let full_text node =
208 SourceText.sub
209 (source_text node) (leading_start_offset node) (full_width node)
211 let leading_text node =
212 SourceText.sub
213 (source_text node)
214 (leading_start_offset node)
215 (leading_width node)
217 let trailing_text node =
218 SourceText.sub
219 (source_text node) ((end_offset node) + 1) (trailing_width node)
221 let text node =
222 SourceText.sub (source_text node) (start_offset node) (width node)
224 let extract_text node =
225 Some (text node)
227 (* Takes a node and an offset; produces the descent through the parse tree
228 to that position. *)
229 let parentage node position =
230 let rec aux nodes position acc =
231 match nodes with
232 | [] -> acc
233 | h :: t ->
234 let width = full_width h in
235 if position < width then
236 aux (children h) position (h :: acc)
237 else
238 aux t (position - width) acc in
239 aux [node] position []
241 let is_in_body node position =
242 let rec aux parents =
243 match parents with
244 | [] -> false
245 | h1 :: t1 ->
246 if is_compound_statement h1 then
247 match t1 with
248 | [] -> false
249 | h2 :: _ ->
250 is_methodish_declaration h2 || is_function_declaration h2 || aux t1
251 else
252 aux t1 in
253 let parents = parentage node position in
254 aux parents
256 let position (_file: Relative_path.t) (node: t) =
257 Some (Value.position node.value)
259 let offset node = Some (start_offset node)