prism 1.9.0 → 2.0.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +88 -0
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/LICENSE.md +1 -1
  5. data/Makefile +41 -12
  6. data/README.md +35 -97
  7. data/config.yml +174 -161
  8. data/docs/build_system.md +2 -2
  9. data/docs/configuration.md +5 -4
  10. data/docs/encoding.md +2 -2
  11. data/docs/fuzzing.md +4 -11
  12. data/docs/javascript.md +19 -4
  13. data/docs/mapping.md +1 -1
  14. data/docs/releasing.md +77 -5
  15. data/docs/relocation.md +2 -4
  16. data/docs/serialization.md +22 -24
  17. data/docs/testing.md +46 -29
  18. data/ext/prism/api_node.c +1461 -1401
  19. data/ext/prism/extconf.rb +3 -4
  20. data/ext/prism/extension.c +796 -422
  21. data/ext/prism/extension.h +3 -3
  22. data/include/prism/arena.h +37 -0
  23. data/include/prism/ast.h +2727 -610
  24. data/include/prism/buffer.h +52 -0
  25. data/include/prism/comments.h +55 -0
  26. data/include/prism/compiler/accel.h +26 -0
  27. data/include/prism/compiler/align.h +36 -0
  28. data/include/prism/compiler/assume.h +25 -0
  29. data/include/prism/compiler/bswap.h +46 -0
  30. data/include/prism/compiler/endianness.h +34 -0
  31. data/include/prism/compiler/exported.h +24 -0
  32. data/include/prism/compiler/fallthrough.h +22 -0
  33. data/include/prism/compiler/filesystem.h +32 -0
  34. data/include/prism/compiler/flex_array.h +19 -0
  35. data/include/prism/compiler/force_inline.h +21 -0
  36. data/include/prism/compiler/format.h +25 -0
  37. data/include/prism/compiler/inline.h +17 -0
  38. data/include/prism/compiler/nodiscard.h +22 -0
  39. data/include/prism/compiler/nonnull.h +18 -0
  40. data/include/prism/compiler/unused.h +18 -0
  41. data/include/prism/constant_pool.h +81 -0
  42. data/include/prism/diagnostic.h +38 -403
  43. data/include/prism/errors_format.h +53 -0
  44. data/include/prism/excludes.h +29 -0
  45. data/include/prism/integer.h +41 -0
  46. data/include/prism/internal/allocator.h +68 -0
  47. data/include/prism/internal/allocator_debug.h +88 -0
  48. data/include/prism/internal/arena.h +108 -0
  49. data/include/prism/internal/bit.h +42 -0
  50. data/include/prism/internal/buffer.h +94 -0
  51. data/include/prism/internal/char.h +145 -0
  52. data/include/prism/internal/comments.h +53 -0
  53. data/include/prism/internal/constant_pool.h +152 -0
  54. data/include/prism/internal/diagnostic.h +389 -0
  55. data/include/prism/{encoding.h → internal/encoding.h} +27 -68
  56. data/include/prism/internal/integer.h +68 -0
  57. data/include/prism/internal/isinf.h +16 -0
  58. data/include/prism/internal/line_offset_list.h +34 -0
  59. data/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  60. data/include/prism/internal/magic_comments.h +23 -0
  61. data/include/prism/internal/memchr.h +15 -0
  62. data/include/prism/internal/node.h +38 -0
  63. data/include/prism/internal/options.h +232 -0
  64. data/include/prism/internal/parser.h +1004 -0
  65. data/include/prism/internal/regexp.h +26 -0
  66. data/include/prism/internal/serialize.h +39 -0
  67. data/include/prism/internal/source.h +72 -0
  68. data/include/prism/{static_literals.h → internal/static_literals.h} +26 -47
  69. data/include/prism/internal/stringy.h +35 -0
  70. data/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  71. data/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  72. data/include/prism/internal/tokens.h +11 -0
  73. data/include/prism/internal/xxh3.h +16 -0
  74. data/include/prism/json.h +32 -0
  75. data/include/prism/line_offset_list.h +61 -0
  76. data/include/prism/magic_comments.h +35 -0
  77. data/include/prism/node.h +18 -53
  78. data/include/prism/options.h +146 -280
  79. data/include/prism/parser.h +356 -867
  80. data/include/prism/prettyprint.h +6 -9
  81. data/include/prism/serialize.h +115 -0
  82. data/include/prism/source.h +155 -0
  83. data/include/prism/stream.h +28 -0
  84. data/include/prism/string_query.h +74 -0
  85. data/include/prism/stringy.h +72 -0
  86. data/include/prism/version.h +12 -3
  87. data/include/prism.h +43 -320
  88. data/lib/prism/compiler.rb +319 -305
  89. data/lib/prism/desugar_compiler.rb +105 -34
  90. data/lib/prism/dispatcher.rb +646 -473
  91. data/lib/prism/dot_visitor.rb +592 -511
  92. data/lib/prism/dsl.rb +391 -25
  93. data/lib/prism/ffi.rb +258 -90
  94. data/lib/prism/inspect_visitor.rb +357 -325
  95. data/lib/prism/lex_compat.rb +254 -212
  96. data/lib/prism/mutation_compiler.rb +313 -305
  97. data/lib/prism/node.rb +20966 -6992
  98. data/lib/prism/node_ext.rb +180 -187
  99. data/lib/prism/node_find.rb +215 -0
  100. data/lib/prism/parse_result/errors.rb +7 -1
  101. data/lib/prism/parse_result/newlines.rb +276 -8
  102. data/lib/prism/parse_result.rb +468 -139
  103. data/lib/prism/pattern.rb +65 -20
  104. data/lib/prism/reflection.rb +23 -12
  105. data/lib/prism/relocation.rb +149 -87
  106. data/lib/prism/serialize.rb +3460 -539
  107. data/lib/prism/string_query.rb +24 -1
  108. data/lib/prism/translation/parser/builder.rb +10 -2
  109. data/lib/prism/translation/parser/compiler.rb +44 -52
  110. data/lib/prism/translation/parser/lexer.rb +41 -92
  111. data/lib/prism/translation/parser.rb +1 -1
  112. data/lib/prism/translation/parser_current.rb +1 -1
  113. data/lib/prism/translation/ripper/lexer.rb +8 -10
  114. data/lib/prism/translation/ripper/sexp.rb +2 -10
  115. data/lib/prism/translation/ripper/shim.rb +2 -0
  116. data/lib/prism/translation/ripper.rb +967 -209
  117. data/lib/prism/translation/ruby_parser.rb +73 -316
  118. data/lib/prism/translation.rb +2 -0
  119. data/lib/prism/visitor.rb +632 -5
  120. data/lib/prism.rb +79 -9
  121. data/prism.gemspec +128 -62
  122. data/rbi/generated/prism/compiler.rbi +489 -0
  123. data/rbi/generated/prism/desugar_compiler.rbi +306 -0
  124. data/rbi/generated/prism/dispatcher.rbi +1138 -0
  125. data/rbi/generated/prism/dot_visitor.rbi +618 -0
  126. data/rbi/generated/prism/dsl.rbi +751 -0
  127. data/rbi/generated/prism/inspect_visitor.rbi +503 -0
  128. data/rbi/generated/prism/lex_compat.rbi +162 -0
  129. data/rbi/generated/prism/mutation_compiler.rbi +464 -0
  130. data/rbi/generated/prism/node.rbi +14407 -0
  131. data/rbi/generated/prism/node_ext.rbi +259 -0
  132. data/rbi/generated/prism/node_find.rbi +79 -0
  133. data/rbi/generated/prism/parse_result/errors.rbi +21 -0
  134. data/rbi/generated/prism/parse_result/newlines.rbi +208 -0
  135. data/rbi/generated/prism/parse_result.rbi +776 -0
  136. data/rbi/generated/prism/pattern.rbi +134 -0
  137. data/rbi/generated/prism/reflection.rbi +89 -0
  138. data/rbi/generated/prism/relocation.rbi +329 -0
  139. data/rbi/generated/prism/serialize.rbi +184 -0
  140. data/rbi/generated/prism/string_query.rbi +43 -0
  141. data/rbi/generated/prism/translation.rbi +7 -0
  142. data/rbi/generated/prism/visitor.rbi +650 -0
  143. data/rbi/generated/prism.rbi +86 -0
  144. data/rbi/prism/translation/parser_versions.rbi +5 -0
  145. data/rbi/rubyvm/node_find.rbi +14 -0
  146. data/sig/generated/prism/compiler.rbs +492 -0
  147. data/sig/generated/prism/desugar_compiler.rbs +305 -0
  148. data/sig/generated/prism/dispatcher.rbs +1292 -0
  149. data/sig/generated/prism/dot_visitor.rbs +635 -0
  150. data/sig/generated/prism/dsl.rbs +928 -0
  151. data/sig/generated/prism/inspect_visitor.rbs +509 -0
  152. data/sig/generated/prism/lex_compat.rbs +166 -0
  153. data/sig/{prism → generated/prism}/mutation_compiler.rbs +309 -4
  154. data/sig/generated/prism/node.rbs +20896 -0
  155. data/sig/generated/prism/node_ext.rbs +290 -0
  156. data/sig/generated/prism/node_find.rbs +90 -0
  157. data/sig/generated/prism/parse_result/errors.rbs +22 -0
  158. data/sig/generated/prism/parse_result/newlines.rbs +223 -0
  159. data/sig/generated/prism/parse_result.rbs +871 -0
  160. data/sig/generated/prism/pattern.rbs +156 -0
  161. data/sig/generated/prism/reflection.rbs +101 -0
  162. data/sig/generated/prism/relocation.rbs +428 -0
  163. data/sig/generated/prism/serialize.rbs +198 -0
  164. data/sig/generated/prism/string_query.rbs +43 -0
  165. data/sig/generated/prism/translation.rbs +8 -0
  166. data/sig/generated/prism/visitor.rbs +1111 -0
  167. data/sig/generated/prism.rbs +84 -0
  168. data/sig/manifest.yaml +2 -0
  169. data/src/arena.c +117 -0
  170. data/src/{util/pm_buffer.c → buffer.c} +53 -21
  171. data/src/{util/pm_char.c → char.c} +28 -57
  172. data/src/comments.c +454 -0
  173. data/src/constant_pool.c +406 -0
  174. data/src/diagnostic.c +97 -65
  175. data/src/encoding.c +8 -3
  176. data/src/errors_format.c +519 -0
  177. data/src/{util/pm_integer.c → integer.c} +33 -22
  178. data/src/json.c +5733 -0
  179. data/src/line_offset_list.c +100 -0
  180. data/src/list.c +24 -0
  181. data/src/{util/pm_memchr.c → memchr.c} +8 -6
  182. data/src/node.c +3504 -7674
  183. data/src/options.c +162 -49
  184. data/src/parser.c +367 -0
  185. data/src/prettyprint.c +421 -354
  186. data/src/prism.c +8402 -7161
  187. data/src/regexp.c +961 -45
  188. data/src/serialize.c +460 -424
  189. data/src/source.c +518 -0
  190. data/src/static_literals.c +111 -43
  191. data/src/string_query.c +180 -0
  192. data/src/stringy.c +91 -0
  193. data/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  194. data/src/strpbrk.c +447 -0
  195. data/src/{token_type.c → tokens.c} +39 -18
  196. data/src/xxh3.c +292 -0
  197. metadata +128 -63
  198. data/ext/prism/api_pack.c +0 -276
  199. data/include/prism/defines.h +0 -260
  200. data/include/prism/pack.h +0 -163
  201. data/include/prism/regexp.h +0 -43
  202. data/include/prism/util/pm_buffer.h +0 -236
  203. data/include/prism/util/pm_char.h +0 -204
  204. data/include/prism/util/pm_constant_pool.h +0 -218
  205. data/include/prism/util/pm_integer.h +0 -130
  206. data/include/prism/util/pm_memchr.h +0 -29
  207. data/include/prism/util/pm_newline_list.h +0 -113
  208. data/include/prism/util/pm_string.h +0 -200
  209. data/lib/prism/pack.rb +0 -230
  210. data/lib/prism/parse_result/comments.rb +0 -188
  211. data/rbi/prism/compiler.rbi +0 -12
  212. data/rbi/prism/dsl.rbi +0 -524
  213. data/rbi/prism/inspect_visitor.rbi +0 -12
  214. data/rbi/prism/node.rbi +0 -8750
  215. data/rbi/prism/node_ext.rbi +0 -107
  216. data/rbi/prism/parse_result.rbi +0 -404
  217. data/rbi/prism/reflection.rbi +0 -58
  218. data/rbi/prism/string_query.rbi +0 -12
  219. data/rbi/prism/visitor.rbi +0 -473
  220. data/rbi/prism.rbi +0 -63
  221. data/sig/prism/compiler.rbs +0 -9
  222. data/sig/prism/dispatcher.rbs +0 -19
  223. data/sig/prism/dot_visitor.rbs +0 -6
  224. data/sig/prism/dsl.rbs +0 -351
  225. data/sig/prism/inspect_visitor.rbs +0 -22
  226. data/sig/prism/lex_compat.rbs +0 -10
  227. data/sig/prism/node.rbs +0 -4042
  228. data/sig/prism/node_ext.rbs +0 -149
  229. data/sig/prism/pack.rbs +0 -43
  230. data/sig/prism/parse_result/comments.rbs +0 -38
  231. data/sig/prism/parse_result.rbs +0 -197
  232. data/sig/prism/pattern.rbs +0 -13
  233. data/sig/prism/reflection.rbs +0 -50
  234. data/sig/prism/relocation.rbs +0 -185
  235. data/sig/prism/serialize.rbs +0 -8
  236. data/sig/prism/string_query.rbs +0 -11
  237. data/sig/prism/visitor.rbs +0 -169
  238. data/sig/prism.rbs +0 -272
  239. data/src/pack.c +0 -509
  240. data/src/util/pm_constant_pool.c +0 -342
  241. data/src/util/pm_list.c +0 -49
  242. data/src/util/pm_newline_list.c +0 -125
  243. data/src/util/pm_string.c +0 -381
  244. data/src/util/pm_strpbrk.c +0 -206
@@ -0,0 +1,776 @@
1
+ # typed: true
2
+
3
+ module Prism
4
+ # This represents a source of Ruby code that has been parsed. It is used in
5
+ # conjunction with locations to allow them to resolve line numbers and source
6
+ # ranges.
7
+ class Source
8
+ # Create a new source object with the given source code. This method should
9
+ # be used instead of `new` and it will return either a `Source` or a
10
+ # specialized and more performant `ASCIISource` if no multibyte characters
11
+ # are present in the source code.
12
+ #
13
+ # Note that if you are calling this method manually, you will need to supply
14
+ # the start_line and offsets parameters. start_line is the line number that
15
+ # the source starts on, which is typically 1 but can be different if this
16
+ # source is a subset of a larger source or if this is an eval. offsets is an
17
+ # array of byte offsets for the start of each line in the source code, which
18
+ # can be calculated by iterating through the source code and recording the
19
+ # byte offset whenever a newline character is encountered. The first
20
+ # element is always 0 to mark the first line.
21
+ #
22
+ # The comments, comment_attachments, and comment_ranges parameters are the
23
+ # lists described by the attributes of the same names. They are passed in
24
+ # empty when the source is created by the parser and filled in afterward,
25
+ # because the comments themselves refer to the source.
26
+ #
27
+ # The checksum parameter is the value described by the attribute of the same
28
+ # name. It is nil when the source is not created by the parser.
29
+ sig { params(source: String, start_line: Integer, offsets: T::Array[Integer], comments: T::Array[Comment], comment_attachments: T::Array[Comment], comment_ranges: T::Array[::T.nilable(Integer)], checksum: ::T.nilable(Integer)).returns(Source) }
30
+ def self.for(source, start_line, offsets, comments = T.unsafe(nil), comment_attachments = T.unsafe(nil), comment_ranges = T.unsafe(nil), checksum = T.unsafe(nil)); end
31
+
32
+ # The source code that this source object represents.
33
+ sig { returns(String) }
34
+ attr_reader :source
35
+
36
+ # The line number where this source starts.
37
+ sig { returns(Integer) }
38
+ attr_reader :start_line
39
+
40
+ # The checksum of the source code which can be used to quickly determine if
41
+ # the source has changed.
42
+ sig { returns(::T.nilable(Integer)) }
43
+ attr_reader :checksum
44
+
45
+ # The list of comments that were encountered during parsing. When the source
46
+ # is parsed with the attach_comments option, these are sorted by start
47
+ # offset.
48
+ sig { returns(T::Array[Comment]) }
49
+ attr_reader :comments
50
+
51
+ # The comments attached to nodes, grouped by node in order of node id. This
52
+ # is empty unless the source was parsed with the attach_comments option.
53
+ sig { returns(T::Array[Comment]) }
54
+ attr_reader :comment_attachments
55
+
56
+ # Indices into comment_attachments, indexed by node id. For each node that
57
+ # owns comments, the index at which its comments begin is stored at its node
58
+ # id and the index at which they end is stored at the following node id. The
59
+ # other entries are nil. This is empty unless the source was parsed with the
60
+ # attach_comments option.
61
+ sig { returns(T::Array[::T.nilable(Integer)]) }
62
+ attr_reader :comment_ranges
63
+
64
+ # The list of newline byte offsets in the source code. When initialized from
65
+ # the C extension, this may be a packed binary string of uint32_t values
66
+ # that is lazily unpacked on first access.
67
+ sig { returns(T::Array[Integer]) }
68
+ def offsets; end
69
+
70
+ # Create a new source object with the given source code. The offsets
71
+ # parameter can be either an Array of Integer byte offsets or a packed
72
+ # binary string of uint32_t values (from the C extension).
73
+ sig { params(source: String, start_line: Integer, offsets: ::T.any(T::Array[Integer], String), comments: T::Array[Comment], comment_attachments: T::Array[Comment], comment_ranges: T::Array[::T.nilable(Integer)], checksum: ::T.nilable(Integer)).void }
74
+ def initialize(source, start_line, offsets, comments = T.unsafe(nil), comment_attachments = T.unsafe(nil), comment_ranges = T.unsafe(nil), checksum = T.unsafe(nil)); end
75
+
76
+ # Replace the value of start_line with the given value.
77
+ sig { params(start_line: Integer).void }
78
+ def replace_start_line(start_line); end
79
+
80
+ # Replace the value of checksum with the given value.
81
+ sig { params(checksum: Integer).void }
82
+ def replace_checksum(checksum); end
83
+
84
+ # Replace the value of offsets with the given value.
85
+ sig { params(offsets: T::Array[Integer]).void }
86
+ def replace_offsets(offsets); end
87
+
88
+ # The comments attached to the node with the given id, ordered by start
89
+ # offset. Comments are only attached when the source is parsed with the
90
+ # attach_comments option.
91
+ sig { params(node_id: Integer).returns(T::Array[Comment]) }
92
+ def comments_for(node_id); end
93
+
94
+ # Returns the encoding of the source code, which is set by parameters to the
95
+ # parser or by the encoding magic comment.
96
+ sig { returns(Encoding) }
97
+ def encoding; end
98
+
99
+ # Returns the lines of the source code as an array of strings.
100
+ sig { returns(T::Array[String]) }
101
+ def lines; end
102
+
103
+ # Perform a byteslice on the source code using the given byte offset and
104
+ # byte length.
105
+ sig { params(byte_offset: Integer, length: Integer).returns(String) }
106
+ def slice(byte_offset, length); end
107
+
108
+ # Converts the line number and column in bytes to a byte offset.
109
+ sig { params(line: Integer, column: Integer).returns(Integer) }
110
+ def byte_offset(line, column); end
111
+
112
+ # Binary search through the offsets to find the line number for the given
113
+ # byte offset.
114
+ sig { params(byte_offset: Integer).returns(Integer) }
115
+ def line(byte_offset); end
116
+
117
+ # Return the byte offset of the start of the line corresponding to the given
118
+ # byte offset.
119
+ sig { params(byte_offset: Integer).returns(Integer) }
120
+ def line_start(byte_offset); end
121
+
122
+ # Returns the byte offset of the end of the line corresponding to the given
123
+ # byte offset.
124
+ sig { params(byte_offset: Integer).returns(Integer) }
125
+ def line_end(byte_offset); end
126
+
127
+ # Return the column in bytes for the given byte offset.
128
+ sig { params(byte_offset: Integer).returns(Integer) }
129
+ def column(byte_offset); end
130
+
131
+ # Return the character offset for the given byte offset.
132
+ sig { params(byte_offset: Integer).returns(Integer) }
133
+ def character_offset(byte_offset); end
134
+
135
+ # Return the column in characters for the given byte offset.
136
+ sig { params(byte_offset: Integer).returns(Integer) }
137
+ def character_column(byte_offset); end
138
+
139
+ # Returns the offset from the start of the file for the given byte offset
140
+ # counting in code units for the given encoding.
141
+ #
142
+ # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the
143
+ # concept of code units that differs from the number of characters in other
144
+ # encodings, it is not captured here.
145
+ #
146
+ # We purposefully replace invalid and undefined characters with replacement
147
+ # characters in this conversion. This happens for two reasons. First, it's
148
+ # possible that the given byte offset will not occur on a character
149
+ # boundary. Second, it's possible that the source code will contain a
150
+ # character that has no equivalent in the given encoding.
151
+ sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) }
152
+ def code_units_offset(byte_offset, encoding); end
153
+
154
+ # Generate a cache that targets a specific encoding for calculating code
155
+ # unit offsets.
156
+ sig { params(encoding: Encoding).returns(CodeUnitsCache) }
157
+ def code_units_cache(encoding); end
158
+
159
+ # Returns the column in code units for the given encoding for the
160
+ # given byte offset.
161
+ sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) }
162
+ def code_units_column(byte_offset, encoding); end
163
+
164
+ # Freeze this object and the objects it contains.
165
+ sig { void }
166
+ def deep_freeze; end
167
+
168
+ # Binary search through the offsets to find the index for the given
169
+ # byte offset.
170
+ sig { params(byte_offset: Integer).returns(Integer) }
171
+ def find_line(byte_offset); end
172
+ end
173
+
174
+ # A cache that can be used to quickly compute code unit offsets from byte
175
+ # offsets. It purposefully provides only a single #[] method to access the
176
+ # cache in order to minimize surface area.
177
+ #
178
+ # Note that there are some known issues here that may or may not be addressed
179
+ # in the future:
180
+ #
181
+ # * The first is that there are issues when the cache computes values that are
182
+ # not on character boundaries. This can result in subsequent computations
183
+ # being off by one or more code units.
184
+ # * The second is that this cache is currently unbounded. In theory we could
185
+ # introduce some kind of LRU cache to limit the number of entries, but this
186
+ # has not yet been implemented.
187
+ class CodeUnitsCache
188
+ # Counter used for UTF-8, where one code unit equals one byte.
189
+ class UTF8Counter
190
+ sig { params(byte_offset: Integer, byte_length: Integer).returns(Integer) }
191
+ def count(byte_offset, byte_length); end
192
+ end
193
+
194
+ class UTF16Counter
195
+ sig { params(source: String, encoding: Encoding).void }
196
+ def initialize(source, encoding); end
197
+
198
+ sig { params(byte_offset: Integer, byte_length: Integer).returns(Integer) }
199
+ def count(byte_offset, byte_length); end
200
+ end
201
+
202
+ # Counter used for UTF-32, where one code unit equals one code point and
203
+ # matches String#length. Also used as a best-effort fallback for any other
204
+ # encoding that does not have a dedicated counter.
205
+ class UTF32Counter
206
+ sig { params(source: String, encoding: Encoding).void }
207
+ def initialize(source, encoding); end
208
+
209
+ sig { params(byte_offset: Integer, byte_length: Integer).returns(Integer) }
210
+ def count(byte_offset, byte_length); end
211
+ end
212
+
213
+ # Initialize a new cache with the given source and encoding.
214
+ sig { params(source: String, encoding: Encoding).void }
215
+ def initialize(source, encoding); end
216
+
217
+ # Retrieve the code units offset from the given byte offset.
218
+ sig { params(byte_offset: Integer).returns(Integer) }
219
+ def [](byte_offset); end
220
+ end
221
+
222
+ # Specialized version of Prism::Source for source code that includes ASCII
223
+ # characters only. This class is used to apply performance optimizations that
224
+ # cannot be applied to sources that include multibyte characters.
225
+ #
226
+ # In the extremely rare case that a source includes multi-byte characters but
227
+ # is marked as binary because of a magic encoding comment and it cannot be
228
+ # eagerly converted to UTF-8, this class will be used as well. This is because
229
+ # at that point we will treat everything as single-byte characters.
230
+ class ASCIISource < Source
231
+ # Return the character offset for the given byte offset.
232
+ sig { params(byte_offset: Integer).returns(Integer) }
233
+ def character_offset(byte_offset); end
234
+
235
+ # Return the column in characters for the given byte offset.
236
+ sig { params(byte_offset: Integer).returns(Integer) }
237
+ def character_column(byte_offset); end
238
+
239
+ # Returns the offset from the start of the file for the given byte offset
240
+ # counting in code units for the given encoding.
241
+ #
242
+ # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the
243
+ # concept of code units that differs from the number of characters in other
244
+ # encodings, it is not captured here.
245
+ sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) }
246
+ def code_units_offset(byte_offset, encoding); end
247
+
248
+ # Returns a cache that is the identity function in order to maintain the
249
+ # same interface. We can do this because code units are always equivalent to
250
+ # byte offsets for ASCII-only sources.
251
+ sig { params(encoding: Encoding).returns(::T.untyped) }
252
+ def code_units_cache(encoding); end
253
+
254
+ # Specialized version of `code_units_column` that does not depend on
255
+ # `code_units_offset`, which is a more expensive operation. This is
256
+ # essentially the same as `Prism::Source#column`.
257
+ sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) }
258
+ def code_units_column(byte_offset, encoding); end
259
+ end
260
+
261
+ # This represents a location in the source.
262
+ class Location
263
+ # A Source object that is used to determine more information from the given
264
+ # offset and length.
265
+ sig { returns(Source) }
266
+ attr_reader :source
267
+
268
+ # The byte offset from the beginning of the source where this location
269
+ # starts.
270
+ sig { returns(Integer) }
271
+ attr_reader :start_offset
272
+
273
+ # The length of this location in bytes.
274
+ sig { returns(Integer) }
275
+ attr_reader :length
276
+
277
+ # Create a new location object with the given source, start byte offset, and
278
+ # byte length.
279
+ sig { params(source: Source, start_offset: Integer, length: Integer).void }
280
+ def initialize(source, start_offset, length); end
281
+
282
+ # Create a new location object with the given options.
283
+ sig { params(source: Source, start_offset: Integer, length: Integer).returns(Location) }
284
+ def copy(source: T.unsafe(nil), start_offset: T.unsafe(nil), length: T.unsafe(nil)); end
285
+
286
+ # Returns a new location that is the result of chopping off the last byte.
287
+ sig { returns(Location) }
288
+ def chop; end
289
+
290
+ # Returns a string representation of this location.
291
+ sig { returns(String) }
292
+ def inspect; end
293
+
294
+ # Returns all of the lines of the source code associated with this location.
295
+ sig { returns(T::Array[String]) }
296
+ def source_lines; end
297
+
298
+ # The source code that this location represents.
299
+ sig { returns(String) }
300
+ def slice; end
301
+
302
+ # The source code that this location represents starting from the beginning
303
+ # of the line that this location starts on to the end of the line that this
304
+ # location ends on.
305
+ sig { returns(String) }
306
+ def slice_lines; end
307
+
308
+ # The character offset from the beginning of the source where this location
309
+ # starts.
310
+ sig { returns(Integer) }
311
+ def start_character_offset; end
312
+
313
+ # The offset from the start of the file in code units of the given encoding.
314
+ sig { params(encoding: Encoding).returns(Integer) }
315
+ def start_code_units_offset(encoding); end
316
+
317
+ # The start offset from the start of the file in code units using the given
318
+ # cache to fetch or calculate the value.
319
+ sig { params(cache: ::T.untyped).returns(Integer) }
320
+ def cached_start_code_units_offset(cache); end
321
+
322
+ # The byte offset from the beginning of the source where this location ends.
323
+ sig { returns(Integer) }
324
+ def end_offset; end
325
+
326
+ # The character offset from the beginning of the source where this location
327
+ # ends.
328
+ sig { returns(Integer) }
329
+ def end_character_offset; end
330
+
331
+ # The offset from the start of the file in code units of the given encoding.
332
+ sig { params(encoding: Encoding).returns(Integer) }
333
+ def end_code_units_offset(encoding); end
334
+
335
+ # The end offset from the start of the file in code units using the given
336
+ # cache to fetch or calculate the value.
337
+ sig { params(cache: ::T.untyped).returns(Integer) }
338
+ def cached_end_code_units_offset(cache); end
339
+
340
+ # The line number where this location starts.
341
+ sig { returns(Integer) }
342
+ def start_line; end
343
+
344
+ # The content of the line where this location starts before this location.
345
+ sig { returns(String) }
346
+ def start_line_slice; end
347
+
348
+ # The line number where this location ends.
349
+ sig { returns(Integer) }
350
+ def end_line; end
351
+
352
+ # The column in bytes where this location starts from the start of
353
+ # the line.
354
+ sig { returns(Integer) }
355
+ def start_column; end
356
+
357
+ # The column in characters where this location ends from the start of
358
+ # the line.
359
+ sig { returns(Integer) }
360
+ def start_character_column; end
361
+
362
+ # The column in code units of the given encoding where this location
363
+ # starts from the start of the line.
364
+ sig { params(encoding: Encoding).returns(Integer) }
365
+ def start_code_units_column(encoding = T.unsafe(nil)); end
366
+
367
+ # The start column in code units using the given cache to fetch or calculate
368
+ # the value.
369
+ sig { params(cache: ::T.untyped).returns(Integer) }
370
+ def cached_start_code_units_column(cache); end
371
+
372
+ # The column in bytes where this location ends from the start of the
373
+ # line.
374
+ sig { returns(Integer) }
375
+ def end_column; end
376
+
377
+ # The column in characters where this location ends from the start of
378
+ # the line.
379
+ sig { returns(Integer) }
380
+ def end_character_column; end
381
+
382
+ # The column in code units of the given encoding where this location
383
+ # ends from the start of the line.
384
+ sig { params(encoding: Encoding).returns(Integer) }
385
+ def end_code_units_column(encoding = T.unsafe(nil)); end
386
+
387
+ # The end column in code units using the given cache to fetch or calculate
388
+ # the value.
389
+ sig { params(cache: ::T.untyped).returns(Integer) }
390
+ def cached_end_code_units_column(cache); end
391
+
392
+ # Implement the hash pattern matching interface for Location.
393
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
394
+ def deconstruct_keys(keys); end
395
+
396
+ # Implement the pretty print interface for Location.
397
+ sig { params(q: PP).void }
398
+ def pretty_print(q); end
399
+
400
+ # Returns true if the given other location is equal to this location.
401
+ sig { params(other: ::T.untyped).returns(T::Boolean) }
402
+ def ==(other); end
403
+
404
+ # Returns a new location that stretches from this location to the given
405
+ # other location. Raises an error if this location is not before the other
406
+ # location or if they don't share the same source.
407
+ sig { params(other: Location).returns(Location) }
408
+ def join(other); end
409
+
410
+ # Join this location with the first occurrence of the string in the source
411
+ # that occurs after this location on the same line, and return the new
412
+ # location. This will raise an error if the string does not exist.
413
+ sig { params(string: String).returns(Location) }
414
+ def adjoin(string); end
415
+ end
416
+
417
+ # This represents a comment that was encountered during parsing. It is the
418
+ # base class for all comment types.
419
+ class Comment
420
+ # The Location of this comment in the source.
421
+ sig { returns(Location) }
422
+ attr_reader :location
423
+
424
+ # Create a new comment object with the given location.
425
+ sig { params(location: Location).void }
426
+ def initialize(location); end
427
+
428
+ # Implement the hash pattern matching interface for Comment.
429
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
430
+ def deconstruct_keys(keys); end
431
+
432
+ # Returns the content of the comment by slicing it from the source code.
433
+ sig { returns(String) }
434
+ def slice; end
435
+
436
+ # Returns true if this comment happens on the same line as other code and
437
+ # false if the comment is by itself. This can only be true for inline
438
+ # comments and should be false for block comments.
439
+ sig { returns(T::Boolean) }
440
+ def trailing?; end
441
+ end
442
+
443
+ # InlineComment objects are the most common. They correspond to comments in
444
+ # the source file like this one that start with #.
445
+ class InlineComment < Comment
446
+ # Returns true if this comment happens on the same line as other code and
447
+ # false if the comment is by itself.
448
+ sig { returns(T::Boolean) }
449
+ def trailing?; end
450
+
451
+ # Returns a string representation of this comment.
452
+ sig { returns(String) }
453
+ def inspect; end
454
+ end
455
+
456
+ # EmbDocComment objects correspond to comments that are surrounded by =begin
457
+ # and =end.
458
+ class EmbDocComment < Comment
459
+ # Returns false. This can only be true for inline comments.
460
+ sig { returns(T::Boolean) }
461
+ def trailing?; end
462
+
463
+ # Returns a string representation of this comment.
464
+ sig { returns(String) }
465
+ def inspect; end
466
+ end
467
+
468
+ # This represents a magic comment that was encountered during parsing.
469
+ class MagicComment
470
+ # A Location object representing the location of the key in the source.
471
+ sig { returns(Location) }
472
+ attr_reader :key_loc
473
+
474
+ # A Location object representing the location of the value in the source.
475
+ sig { returns(Location) }
476
+ attr_reader :value_loc
477
+
478
+ # Create a new magic comment object with the given key and value locations.
479
+ sig { params(key_loc: Location, value_loc: Location).void }
480
+ def initialize(key_loc, value_loc); end
481
+
482
+ # Returns the key of the magic comment by slicing it from the source code.
483
+ sig { returns(String) }
484
+ def key; end
485
+
486
+ # Returns the value of the magic comment by slicing it from the source code.
487
+ sig { returns(String) }
488
+ def value; end
489
+
490
+ # Implement the hash pattern matching interface for MagicComment.
491
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
492
+ def deconstruct_keys(keys); end
493
+
494
+ # Returns a string representation of this magic comment.
495
+ sig { returns(String) }
496
+ def inspect; end
497
+ end
498
+
499
+ # This represents an error that was encountered during parsing.
500
+ class ParseError
501
+ # The type of error. This is an _internal_ symbol that is used for
502
+ # communicating with translation layers. It is not meant to be public API.
503
+ sig { returns(Symbol) }
504
+ attr_reader :type
505
+
506
+ # The message associated with this error.
507
+ sig { returns(String) }
508
+ attr_reader :message
509
+
510
+ # A Location object representing the location of this error in the source.
511
+ sig { returns(Location) }
512
+ attr_reader :location
513
+
514
+ # The level of this error.
515
+ sig { returns(Symbol) }
516
+ attr_reader :level
517
+
518
+ # Create a new error object with the given message and location.
519
+ sig { params(type: Symbol, message: String, location: Location, level: Symbol).void }
520
+ def initialize(type, message, location, level); end
521
+
522
+ # Implement the hash pattern matching interface for ParseError.
523
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
524
+ def deconstruct_keys(keys); end
525
+
526
+ # Returns a string representation of this error.
527
+ sig { returns(String) }
528
+ def inspect; end
529
+ end
530
+
531
+ # This represents a warning that was encountered during parsing.
532
+ class ParseWarning
533
+ # The type of warning. This is an _internal_ symbol that is used for
534
+ # communicating with translation layers. It is not meant to be public API.
535
+ sig { returns(Symbol) }
536
+ attr_reader :type
537
+
538
+ # The message associated with this warning.
539
+ sig { returns(String) }
540
+ attr_reader :message
541
+
542
+ # A Location object representing the location of this warning in the source.
543
+ sig { returns(Location) }
544
+ attr_reader :location
545
+
546
+ # The level of this warning.
547
+ sig { returns(Symbol) }
548
+ attr_reader :level
549
+
550
+ # Create a new warning object with the given message and location.
551
+ sig { params(type: Symbol, message: String, location: Location, level: Symbol).void }
552
+ def initialize(type, message, location, level); end
553
+
554
+ # Implement the hash pattern matching interface for ParseWarning.
555
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
556
+ def deconstruct_keys(keys); end
557
+
558
+ # Returns a string representation of this warning.
559
+ sig { returns(String) }
560
+ def inspect; end
561
+ end
562
+
563
+ # This represents the result of a call to Prism.parse or Prism.parse_file.
564
+ # It contains the requested structure, any comments that were encounters,
565
+ # and any errors that were encountered.
566
+ class Result
567
+ # The list of magic comments that were encountered during parsing.
568
+ sig { returns(T::Array[MagicComment]) }
569
+ attr_reader :magic_comments
570
+
571
+ # An optional location that represents the location of the __END__ marker
572
+ # and the rest of the content of the file. This content is loaded into the
573
+ # DATA constant when the file being parsed is the main file being executed.
574
+ sig { returns(::T.nilable(Location)) }
575
+ attr_reader :data_loc
576
+
577
+ # The list of errors that were generated during parsing.
578
+ sig { returns(T::Array[ParseError]) }
579
+ attr_reader :errors
580
+
581
+ # The list of warnings that were generated during parsing.
582
+ sig { returns(T::Array[ParseWarning]) }
583
+ attr_reader :warnings
584
+
585
+ # A Source instance that represents the source code that was parsed.
586
+ sig { returns(Source) }
587
+ attr_reader :source
588
+
589
+ # Create a new result object with the given values.
590
+ sig { params(magic_comments: T::Array[MagicComment], data_loc: ::T.nilable(Location), errors: T::Array[ParseError], warnings: T::Array[ParseWarning], continuable: T::Boolean, source: Source).void }
591
+ def initialize(magic_comments, data_loc, errors, warnings, continuable, source); end
592
+
593
+ # The list of comments that were encountered during parsing.
594
+ sig { returns(T::Array[Comment]) }
595
+ def comments; end
596
+
597
+ # Implement the hash pattern matching interface for Result.
598
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
599
+ def deconstruct_keys(keys); end
600
+
601
+ # Returns the encoding of the source code that was parsed.
602
+ sig { returns(Encoding) }
603
+ def encoding; end
604
+
605
+ # Returns true if there were no errors during parsing and false if there
606
+ # were.
607
+ sig { returns(T::Boolean) }
608
+ def success?; end
609
+
610
+ # Returns true if there were errors during parsing and false if there were
611
+ # not.
612
+ sig { returns(T::Boolean) }
613
+ def failure?; end
614
+
615
+ # Returns true if the parsed source is an incomplete expression that could
616
+ # become valid with additional input. This is useful for REPL contexts (such
617
+ # as IRB) where the user may be entering a multi-line expression one line at
618
+ # a time and the implementation needs to determine whether to wait for more
619
+ # input or to evaluate what has been entered so far.
620
+ #
621
+ # Concretely, this returns true when every error present is caused by the
622
+ # parser reaching the end of the input before a construct was closed (e.g.
623
+ # an unclosed string, array, block, or keyword), and returns false when any
624
+ # error is caused by a token that makes the input structurally invalid
625
+ # regardless of what might follow (e.g. a stray `end`, `]`, or `)` with no
626
+ # matching opener).
627
+ #
628
+ # Examples:
629
+ #
630
+ # Prism.parse("1 + [").continuable? #=> true (unclosed array)
631
+ # Prism.parse("1 + ]").continuable? #=> false (stray ])
632
+ # Prism.parse("tap do").continuable? #=> true (unclosed block)
633
+ # Prism.parse("end.tap do").continuable? #=> false (stray end)
634
+ sig { returns(T::Boolean) }
635
+ def continuable?; end
636
+
637
+ # Create a code units cache for the given encoding.
638
+ sig { params(encoding: Encoding).returns(::T.untyped) }
639
+ def code_units_cache(encoding); end
640
+ end
641
+
642
+ # This is a result specific to the `parse` and `parse_file` methods.
643
+ class ParseResult < Result
644
+ # The syntax tree that was parsed from the source code.
645
+ sig { returns(ProgramNode) }
646
+ attr_reader :value
647
+
648
+ # Create a new parse result object with the given values.
649
+ sig { params(value: ProgramNode, magic_comments: T::Array[MagicComment], data_loc: ::T.nilable(Location), errors: T::Array[ParseError], warnings: T::Array[ParseWarning], continuable: T::Boolean, source: Source).void }
650
+ def initialize(value, magic_comments, data_loc, errors, warnings, continuable, source); end
651
+
652
+ # Implement the hash pattern matching interface for ParseResult.
653
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
654
+ def deconstruct_keys(keys); end
655
+
656
+ # Walk the tree and mark nodes that are on a new line, loosely emulating
657
+ # the behavior of CRuby's `:line` tracepoint event.
658
+ sig { void }
659
+ def mark_newlines!; end
660
+
661
+ # Returns a string representation of the syntax tree with the errors
662
+ # displayed inline.
663
+ sig { returns(String) }
664
+ def errors_format; end
665
+ end
666
+
667
+ # This is a result specific to the `lex` and `lex_file` methods.
668
+ class LexResult < Result
669
+ # The list of tokens that were parsed from the source code.
670
+ sig { returns(T::Array[Token]) }
671
+ attr_reader :value
672
+
673
+ # Create a new lex result object with the given values.
674
+ sig { params(value: T::Array[Token], magic_comments: T::Array[MagicComment], data_loc: ::T.nilable(Location), errors: T::Array[ParseError], warnings: T::Array[ParseWarning], continuable: T::Boolean, source: Source).void }
675
+ def initialize(value, magic_comments, data_loc, errors, warnings, continuable, source); end
676
+
677
+ # Implement the hash pattern matching interface for LexResult.
678
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
679
+ def deconstruct_keys(keys); end
680
+ end
681
+
682
+ # This is a result specific to the `parse_lex` and `parse_lex_file` methods.
683
+ class ParseLexResult < Result
684
+ # A tuple of the syntax tree and the list of tokens that were parsed from
685
+ # the source code.
686
+ sig { returns([ProgramNode, T::Array[Token]]) }
687
+ attr_reader :value
688
+
689
+ # Create a new parse lex result object with the given values.
690
+ sig { params(value: [ProgramNode, T::Array[Token]], magic_comments: T::Array[MagicComment], data_loc: ::T.nilable(Location), errors: T::Array[ParseError], warnings: T::Array[ParseWarning], continuable: T::Boolean, source: Source).void }
691
+ def initialize(value, magic_comments, data_loc, errors, warnings, continuable, source); end
692
+
693
+ # Implement the hash pattern matching interface for ParseLexResult.
694
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
695
+ def deconstruct_keys(keys); end
696
+ end
697
+
698
+ # This represents a token from the Ruby source.
699
+ class Token
700
+ # The Source object that represents the source this token came from.
701
+ sig { returns(Source) }
702
+ attr_reader :source
703
+
704
+ # The type of token that this token is.
705
+ sig { returns(Symbol) }
706
+ attr_reader :type
707
+
708
+ # A byteslice of the source that this token represents.
709
+ sig { returns(String) }
710
+ attr_reader :value
711
+
712
+ # Create a new token object with the given type, value, and location.
713
+ sig { params(source: Source, type: Symbol, value: String, location: ::T.any(Location, Integer), state: Integer).void }
714
+ def initialize(source, type, value, location, state); end
715
+
716
+ # Implement the hash pattern matching interface for Token.
717
+ sig { params(keys: ::T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, ::T.untyped]) }
718
+ def deconstruct_keys(keys); end
719
+
720
+ # A Location object representing the location of this token in the source.
721
+ sig { returns(Location) }
722
+ def location; end
723
+
724
+ # Implement the pretty print interface for Token.
725
+ sig { params(q: PP).void }
726
+ def pretty_print(q); end
727
+
728
+ # Returns true if the given other token is equal to this token.
729
+ sig { params(other: ::T.untyped).returns(T::Boolean) }
730
+ def ==(other); end
731
+
732
+ # Returns a string representation of this token.
733
+ sig { returns(String) }
734
+ def inspect; end
735
+
736
+ # Freeze this object and the objects it contains.
737
+ sig { void }
738
+ def deep_freeze; end
739
+
740
+ # For internal use only.
741
+ sig { returns(Integer) }
742
+ def _ripper_state; end
743
+
744
+ sig { params(index: Integer).returns(Token) }
745
+ def [](index); end
746
+
747
+ sig { returns(Token) }
748
+ def first; end
749
+ end
750
+
751
+ # This object is passed to the various Prism.* methods that accept the
752
+ # `scopes` option as an element of the list. It defines both the local
753
+ # variables visible at that scope as well as the forwarding parameters
754
+ # available at that scope.
755
+ class Scope
756
+ # The list of local variables that are defined in this scope. This should be
757
+ # defined as an array of symbols.
758
+ sig { returns(T::Array[Symbol]) }
759
+ attr_reader :locals
760
+
761
+ # The list of local variables that are forwarded to the next scope. This
762
+ # should by defined as an array of symbols containing the specific values of
763
+ sig { returns(T::Array[Symbol]) }
764
+ attr_reader :forwarding
765
+
766
+ # Create a new scope object with the given locals and forwarding.
767
+ sig { params(locals: T::Array[Symbol], forwarding: T::Array[Symbol]).void }
768
+ def initialize(locals, forwarding); end
769
+ end
770
+
771
+ # Create a new scope with the given locals and forwarding options that is
772
+ # suitable for passing into one of the Prism.* methods that accepts the
773
+ # `scopes` option.
774
+ sig { params(locals: T::Array[Symbol], forwarding: T::Array[Symbol]).returns(Scope) }
775
+ def self.scope(locals: T.unsafe(nil), forwarding: T.unsafe(nil)); end
776
+ end