ed-precompiled_prism 1.5.2

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 (154) hide show
  1. checksums.yaml +7 -0
  2. data/BSDmakefile +58 -0
  3. data/CHANGELOG.md +723 -0
  4. data/CODE_OF_CONDUCT.md +76 -0
  5. data/CONTRIBUTING.md +58 -0
  6. data/LICENSE.md +7 -0
  7. data/Makefile +110 -0
  8. data/README.md +143 -0
  9. data/config.yml +4714 -0
  10. data/docs/build_system.md +119 -0
  11. data/docs/configuration.md +68 -0
  12. data/docs/cruby_compilation.md +27 -0
  13. data/docs/design.md +53 -0
  14. data/docs/encoding.md +121 -0
  15. data/docs/fuzzing.md +88 -0
  16. data/docs/heredocs.md +36 -0
  17. data/docs/javascript.md +118 -0
  18. data/docs/local_variable_depth.md +229 -0
  19. data/docs/mapping.md +117 -0
  20. data/docs/parser_translation.md +24 -0
  21. data/docs/parsing_rules.md +22 -0
  22. data/docs/releasing.md +98 -0
  23. data/docs/relocation.md +34 -0
  24. data/docs/ripper_translation.md +72 -0
  25. data/docs/ruby_api.md +44 -0
  26. data/docs/ruby_parser_translation.md +19 -0
  27. data/docs/serialization.md +233 -0
  28. data/docs/testing.md +55 -0
  29. data/ext/prism/api_node.c +6941 -0
  30. data/ext/prism/api_pack.c +276 -0
  31. data/ext/prism/extconf.rb +127 -0
  32. data/ext/prism/extension.c +1419 -0
  33. data/ext/prism/extension.h +19 -0
  34. data/include/prism/ast.h +8220 -0
  35. data/include/prism/defines.h +260 -0
  36. data/include/prism/diagnostic.h +456 -0
  37. data/include/prism/encoding.h +283 -0
  38. data/include/prism/node.h +129 -0
  39. data/include/prism/options.h +482 -0
  40. data/include/prism/pack.h +163 -0
  41. data/include/prism/parser.h +933 -0
  42. data/include/prism/prettyprint.h +34 -0
  43. data/include/prism/regexp.h +43 -0
  44. data/include/prism/static_literals.h +121 -0
  45. data/include/prism/util/pm_buffer.h +236 -0
  46. data/include/prism/util/pm_char.h +204 -0
  47. data/include/prism/util/pm_constant_pool.h +218 -0
  48. data/include/prism/util/pm_integer.h +130 -0
  49. data/include/prism/util/pm_list.h +103 -0
  50. data/include/prism/util/pm_memchr.h +29 -0
  51. data/include/prism/util/pm_newline_list.h +113 -0
  52. data/include/prism/util/pm_string.h +200 -0
  53. data/include/prism/util/pm_strncasecmp.h +32 -0
  54. data/include/prism/util/pm_strpbrk.h +46 -0
  55. data/include/prism/version.h +29 -0
  56. data/include/prism.h +408 -0
  57. data/lib/prism/compiler.rb +801 -0
  58. data/lib/prism/desugar_compiler.rb +392 -0
  59. data/lib/prism/dispatcher.rb +2210 -0
  60. data/lib/prism/dot_visitor.rb +4762 -0
  61. data/lib/prism/dsl.rb +1003 -0
  62. data/lib/prism/ffi.rb +570 -0
  63. data/lib/prism/inspect_visitor.rb +2392 -0
  64. data/lib/prism/lex_compat.rb +928 -0
  65. data/lib/prism/mutation_compiler.rb +772 -0
  66. data/lib/prism/node.rb +18816 -0
  67. data/lib/prism/node_ext.rb +511 -0
  68. data/lib/prism/pack.rb +230 -0
  69. data/lib/prism/parse_result/comments.rb +188 -0
  70. data/lib/prism/parse_result/errors.rb +66 -0
  71. data/lib/prism/parse_result/newlines.rb +155 -0
  72. data/lib/prism/parse_result.rb +911 -0
  73. data/lib/prism/pattern.rb +269 -0
  74. data/lib/prism/polyfill/append_as_bytes.rb +15 -0
  75. data/lib/prism/polyfill/byteindex.rb +13 -0
  76. data/lib/prism/polyfill/scan_byte.rb +14 -0
  77. data/lib/prism/polyfill/unpack1.rb +14 -0
  78. data/lib/prism/polyfill/warn.rb +36 -0
  79. data/lib/prism/reflection.rb +416 -0
  80. data/lib/prism/relocation.rb +505 -0
  81. data/lib/prism/serialize.rb +2398 -0
  82. data/lib/prism/string_query.rb +31 -0
  83. data/lib/prism/translation/parser/builder.rb +62 -0
  84. data/lib/prism/translation/parser/compiler.rb +2234 -0
  85. data/lib/prism/translation/parser/lexer.rb +820 -0
  86. data/lib/prism/translation/parser.rb +374 -0
  87. data/lib/prism/translation/parser33.rb +13 -0
  88. data/lib/prism/translation/parser34.rb +13 -0
  89. data/lib/prism/translation/parser35.rb +13 -0
  90. data/lib/prism/translation/parser_current.rb +24 -0
  91. data/lib/prism/translation/ripper/sexp.rb +126 -0
  92. data/lib/prism/translation/ripper/shim.rb +5 -0
  93. data/lib/prism/translation/ripper.rb +3474 -0
  94. data/lib/prism/translation/ruby_parser.rb +1929 -0
  95. data/lib/prism/translation.rb +16 -0
  96. data/lib/prism/visitor.rb +813 -0
  97. data/lib/prism.rb +97 -0
  98. data/prism.gemspec +174 -0
  99. data/rbi/prism/compiler.rbi +12 -0
  100. data/rbi/prism/dsl.rbi +524 -0
  101. data/rbi/prism/inspect_visitor.rbi +12 -0
  102. data/rbi/prism/node.rbi +8734 -0
  103. data/rbi/prism/node_ext.rbi +107 -0
  104. data/rbi/prism/parse_result.rbi +404 -0
  105. data/rbi/prism/reflection.rbi +58 -0
  106. data/rbi/prism/string_query.rbi +12 -0
  107. data/rbi/prism/translation/parser.rbi +11 -0
  108. data/rbi/prism/translation/parser33.rbi +6 -0
  109. data/rbi/prism/translation/parser34.rbi +6 -0
  110. data/rbi/prism/translation/parser35.rbi +6 -0
  111. data/rbi/prism/translation/ripper.rbi +15 -0
  112. data/rbi/prism/visitor.rbi +473 -0
  113. data/rbi/prism.rbi +66 -0
  114. data/sig/prism/compiler.rbs +9 -0
  115. data/sig/prism/dispatcher.rbs +19 -0
  116. data/sig/prism/dot_visitor.rbs +6 -0
  117. data/sig/prism/dsl.rbs +351 -0
  118. data/sig/prism/inspect_visitor.rbs +22 -0
  119. data/sig/prism/lex_compat.rbs +10 -0
  120. data/sig/prism/mutation_compiler.rbs +159 -0
  121. data/sig/prism/node.rbs +4028 -0
  122. data/sig/prism/node_ext.rbs +149 -0
  123. data/sig/prism/pack.rbs +43 -0
  124. data/sig/prism/parse_result/comments.rbs +38 -0
  125. data/sig/prism/parse_result.rbs +196 -0
  126. data/sig/prism/pattern.rbs +13 -0
  127. data/sig/prism/reflection.rbs +50 -0
  128. data/sig/prism/relocation.rbs +185 -0
  129. data/sig/prism/serialize.rbs +8 -0
  130. data/sig/prism/string_query.rbs +11 -0
  131. data/sig/prism/visitor.rbs +169 -0
  132. data/sig/prism.rbs +254 -0
  133. data/src/diagnostic.c +850 -0
  134. data/src/encoding.c +5235 -0
  135. data/src/node.c +8676 -0
  136. data/src/options.c +328 -0
  137. data/src/pack.c +509 -0
  138. data/src/prettyprint.c +8941 -0
  139. data/src/prism.c +23361 -0
  140. data/src/regexp.c +790 -0
  141. data/src/serialize.c +2268 -0
  142. data/src/static_literals.c +617 -0
  143. data/src/token_type.c +703 -0
  144. data/src/util/pm_buffer.c +357 -0
  145. data/src/util/pm_char.c +318 -0
  146. data/src/util/pm_constant_pool.c +342 -0
  147. data/src/util/pm_integer.c +670 -0
  148. data/src/util/pm_list.c +49 -0
  149. data/src/util/pm_memchr.c +35 -0
  150. data/src/util/pm_newline_list.c +125 -0
  151. data/src/util/pm_string.c +381 -0
  152. data/src/util/pm_strncasecmp.c +36 -0
  153. data/src/util/pm_strpbrk.c +206 -0
  154. metadata +195 -0
@@ -0,0 +1,505 @@
1
+ # frozen_string_literal: true
2
+ # :markup: markdown
3
+
4
+ module Prism
5
+ # Prism parses deterministically for the same input. This provides a nice
6
+ # property that is exposed through the #node_id API on nodes. Effectively this
7
+ # means that for the same input, these values will remain consistent every
8
+ # time the source is parsed. This means we can reparse the source same with a
9
+ # #node_id value and find the exact same node again.
10
+ #
11
+ # The Relocation module provides an API around this property. It allows you to
12
+ # "save" nodes and locations using a minimal amount of memory (just the
13
+ # node_id and a field identifier) and then reify them later.
14
+ module Relocation
15
+ # An entry in a repository that will lazily reify its values when they are
16
+ # first accessed.
17
+ class Entry
18
+ # Raised if a value that could potentially be on an entry is missing
19
+ # because it was either not configured on the repository or it has not yet
20
+ # been fetched.
21
+ class MissingValueError < StandardError
22
+ end
23
+
24
+ # Initialize a new entry with the given repository.
25
+ def initialize(repository)
26
+ @repository = repository
27
+ @values = nil
28
+ end
29
+
30
+ # Fetch the filepath of the value.
31
+ def filepath
32
+ fetch_value(:filepath)
33
+ end
34
+
35
+ # Fetch the start line of the value.
36
+ def start_line
37
+ fetch_value(:start_line)
38
+ end
39
+
40
+ # Fetch the end line of the value.
41
+ def end_line
42
+ fetch_value(:end_line)
43
+ end
44
+
45
+ # Fetch the start byte offset of the value.
46
+ def start_offset
47
+ fetch_value(:start_offset)
48
+ end
49
+
50
+ # Fetch the end byte offset of the value.
51
+ def end_offset
52
+ fetch_value(:end_offset)
53
+ end
54
+
55
+ # Fetch the start character offset of the value.
56
+ def start_character_offset
57
+ fetch_value(:start_character_offset)
58
+ end
59
+
60
+ # Fetch the end character offset of the value.
61
+ def end_character_offset
62
+ fetch_value(:end_character_offset)
63
+ end
64
+
65
+ # Fetch the start code units offset of the value, for the encoding that
66
+ # was configured on the repository.
67
+ def start_code_units_offset
68
+ fetch_value(:start_code_units_offset)
69
+ end
70
+
71
+ # Fetch the end code units offset of the value, for the encoding that was
72
+ # configured on the repository.
73
+ def end_code_units_offset
74
+ fetch_value(:end_code_units_offset)
75
+ end
76
+
77
+ # Fetch the start byte column of the value.
78
+ def start_column
79
+ fetch_value(:start_column)
80
+ end
81
+
82
+ # Fetch the end byte column of the value.
83
+ def end_column
84
+ fetch_value(:end_column)
85
+ end
86
+
87
+ # Fetch the start character column of the value.
88
+ def start_character_column
89
+ fetch_value(:start_character_column)
90
+ end
91
+
92
+ # Fetch the end character column of the value.
93
+ def end_character_column
94
+ fetch_value(:end_character_column)
95
+ end
96
+
97
+ # Fetch the start code units column of the value, for the encoding that
98
+ # was configured on the repository.
99
+ def start_code_units_column
100
+ fetch_value(:start_code_units_column)
101
+ end
102
+
103
+ # Fetch the end code units column of the value, for the encoding that was
104
+ # configured on the repository.
105
+ def end_code_units_column
106
+ fetch_value(:end_code_units_column)
107
+ end
108
+
109
+ # Fetch the leading comments of the value.
110
+ def leading_comments
111
+ fetch_value(:leading_comments)
112
+ end
113
+
114
+ # Fetch the trailing comments of the value.
115
+ def trailing_comments
116
+ fetch_value(:trailing_comments)
117
+ end
118
+
119
+ # Fetch the leading and trailing comments of the value.
120
+ def comments
121
+ leading_comments.concat(trailing_comments)
122
+ end
123
+
124
+ # Reify the values on this entry with the given values. This is an
125
+ # internal-only API that is called from the repository when it is time to
126
+ # reify the values.
127
+ def reify!(values) # :nodoc:
128
+ @repository = nil
129
+ @values = values
130
+ end
131
+
132
+ private
133
+
134
+ # Fetch a value from the entry, raising an error if it is missing.
135
+ def fetch_value(name)
136
+ values.fetch(name) do
137
+ raise MissingValueError, "No value for #{name}, make sure the " \
138
+ "repository has been properly configured"
139
+ end
140
+ end
141
+
142
+ # Return the values from the repository, reifying them if necessary.
143
+ def values
144
+ @values || (@repository.reify!; @values)
145
+ end
146
+ end
147
+
148
+ # Represents the source of a repository that will be reparsed.
149
+ class Source
150
+ # The value that will need to be reparsed.
151
+ attr_reader :value
152
+
153
+ # Initialize the source with the given value.
154
+ def initialize(value)
155
+ @value = value
156
+ end
157
+
158
+ # Reparse the value and return the parse result.
159
+ def result
160
+ raise NotImplementedError, "Subclasses must implement #result"
161
+ end
162
+
163
+ # Create a code units cache for the given encoding.
164
+ def code_units_cache(encoding)
165
+ result.code_units_cache(encoding)
166
+ end
167
+ end
168
+
169
+ # A source that is represented by a file path.
170
+ class SourceFilepath < Source
171
+ # Reparse the file and return the parse result.
172
+ def result
173
+ Prism.parse_file(value)
174
+ end
175
+ end
176
+
177
+ # A source that is represented by a string.
178
+ class SourceString < Source
179
+ # Reparse the string and return the parse result.
180
+ def result
181
+ Prism.parse(value)
182
+ end
183
+ end
184
+
185
+ # A field that represents the file path.
186
+ class FilepathField
187
+ # The file path that this field represents.
188
+ attr_reader :value
189
+
190
+ # Initialize a new field with the given file path.
191
+ def initialize(value)
192
+ @value = value
193
+ end
194
+
195
+ # Fetch the file path.
196
+ def fields(_value)
197
+ { filepath: value }
198
+ end
199
+ end
200
+
201
+ # A field representing the start and end lines.
202
+ class LinesField
203
+ # Fetches the start and end line of a value.
204
+ def fields(value)
205
+ { start_line: value.start_line, end_line: value.end_line }
206
+ end
207
+ end
208
+
209
+ # A field representing the start and end byte offsets.
210
+ class OffsetsField
211
+ # Fetches the start and end byte offset of a value.
212
+ def fields(value)
213
+ { start_offset: value.start_offset, end_offset: value.end_offset }
214
+ end
215
+ end
216
+
217
+ # A field representing the start and end character offsets.
218
+ class CharacterOffsetsField
219
+ # Fetches the start and end character offset of a value.
220
+ def fields(value)
221
+ {
222
+ start_character_offset: value.start_character_offset,
223
+ end_character_offset: value.end_character_offset
224
+ }
225
+ end
226
+ end
227
+
228
+ # A field representing the start and end code unit offsets.
229
+ class CodeUnitOffsetsField
230
+ # A pointer to the repository object that is used for lazily creating a
231
+ # code units cache.
232
+ attr_reader :repository
233
+
234
+ # The associated encoding for the code units.
235
+ attr_reader :encoding
236
+
237
+ # Initialize a new field with the associated repository and encoding.
238
+ def initialize(repository, encoding)
239
+ @repository = repository
240
+ @encoding = encoding
241
+ @cache = nil
242
+ end
243
+
244
+ # Fetches the start and end code units offset of a value for a particular
245
+ # encoding.
246
+ def fields(value)
247
+ {
248
+ start_code_units_offset: value.cached_start_code_units_offset(cache),
249
+ end_code_units_offset: value.cached_end_code_units_offset(cache)
250
+ }
251
+ end
252
+
253
+ private
254
+
255
+ # Lazily create a code units cache for the associated encoding.
256
+ def cache
257
+ @cache ||= repository.code_units_cache(encoding)
258
+ end
259
+ end
260
+
261
+ # A field representing the start and end byte columns.
262
+ class ColumnsField
263
+ # Fetches the start and end byte column of a value.
264
+ def fields(value)
265
+ { start_column: value.start_column, end_column: value.end_column }
266
+ end
267
+ end
268
+
269
+ # A field representing the start and end character columns.
270
+ class CharacterColumnsField
271
+ # Fetches the start and end character column of a value.
272
+ def fields(value)
273
+ {
274
+ start_character_column: value.start_character_column,
275
+ end_character_column: value.end_character_column
276
+ }
277
+ end
278
+ end
279
+
280
+ # A field representing the start and end code unit columns for a specific
281
+ # encoding.
282
+ class CodeUnitColumnsField
283
+ # The repository object that is used for lazily creating a code units
284
+ # cache.
285
+ attr_reader :repository
286
+
287
+ # The associated encoding for the code units.
288
+ attr_reader :encoding
289
+
290
+ # Initialize a new field with the associated repository and encoding.
291
+ def initialize(repository, encoding)
292
+ @repository = repository
293
+ @encoding = encoding
294
+ @cache = nil
295
+ end
296
+
297
+ # Fetches the start and end code units column of a value for a particular
298
+ # encoding.
299
+ def fields(value)
300
+ {
301
+ start_code_units_column: value.cached_start_code_units_column(cache),
302
+ end_code_units_column: value.cached_end_code_units_column(cache)
303
+ }
304
+ end
305
+
306
+ private
307
+
308
+ # Lazily create a code units cache for the associated encoding.
309
+ def cache
310
+ @cache ||= repository.code_units_cache(encoding)
311
+ end
312
+ end
313
+
314
+ # An abstract field used as the parent class of the two comments fields.
315
+ class CommentsField
316
+ # An object that represents a slice of a comment.
317
+ class Comment
318
+ # The slice of the comment.
319
+ attr_reader :slice
320
+
321
+ # Initialize a new comment with the given slice.
322
+ def initialize(slice)
323
+ @slice = slice
324
+ end
325
+ end
326
+
327
+ private
328
+
329
+ # Create comment objects from the given values.
330
+ def comments(values)
331
+ values.map { |value| Comment.new(value.slice) }
332
+ end
333
+ end
334
+
335
+ # A field representing the leading comments.
336
+ class LeadingCommentsField < CommentsField
337
+ # Fetches the leading comments of a value.
338
+ def fields(value)
339
+ { leading_comments: comments(value.leading_comments) }
340
+ end
341
+ end
342
+
343
+ # A field representing the trailing comments.
344
+ class TrailingCommentsField < CommentsField
345
+ # Fetches the trailing comments of a value.
346
+ def fields(value)
347
+ { trailing_comments: comments(value.trailing_comments) }
348
+ end
349
+ end
350
+
351
+ # A repository is a configured collection of fields and a set of entries
352
+ # that knows how to reparse a source and reify the values.
353
+ class Repository
354
+ # Raised when multiple fields of the same type are configured on the same
355
+ # repository.
356
+ class ConfigurationError < StandardError
357
+ end
358
+
359
+ # The source associated with this repository. This will be either a
360
+ # SourceFilepath (the most common use case) or a SourceString.
361
+ attr_reader :source
362
+
363
+ # The fields that have been configured on this repository.
364
+ attr_reader :fields
365
+
366
+ # The entries that have been saved on this repository.
367
+ attr_reader :entries
368
+
369
+ # Initialize a new repository with the given source.
370
+ def initialize(source)
371
+ @source = source
372
+ @fields = {}
373
+ @entries = Hash.new { |hash, node_id| hash[node_id] = {} }
374
+ end
375
+
376
+ # Create a code units cache for the given encoding from the source.
377
+ def code_units_cache(encoding)
378
+ source.code_units_cache(encoding)
379
+ end
380
+
381
+ # Configure the filepath field for this repository and return self.
382
+ def filepath
383
+ raise ConfigurationError, "Can only specify filepath for a filepath source" unless source.is_a?(SourceFilepath)
384
+ field(:filepath, FilepathField.new(source.value))
385
+ end
386
+
387
+ # Configure the lines field for this repository and return self.
388
+ def lines
389
+ field(:lines, LinesField.new)
390
+ end
391
+
392
+ # Configure the offsets field for this repository and return self.
393
+ def offsets
394
+ field(:offsets, OffsetsField.new)
395
+ end
396
+
397
+ # Configure the character offsets field for this repository and return
398
+ # self.
399
+ def character_offsets
400
+ field(:character_offsets, CharacterOffsetsField.new)
401
+ end
402
+
403
+ # Configure the code unit offsets field for this repository for a specific
404
+ # encoding and return self.
405
+ def code_unit_offsets(encoding)
406
+ field(:code_unit_offsets, CodeUnitOffsetsField.new(self, encoding))
407
+ end
408
+
409
+ # Configure the columns field for this repository and return self.
410
+ def columns
411
+ field(:columns, ColumnsField.new)
412
+ end
413
+
414
+ # Configure the character columns field for this repository and return
415
+ # self.
416
+ def character_columns
417
+ field(:character_columns, CharacterColumnsField.new)
418
+ end
419
+
420
+ # Configure the code unit columns field for this repository for a specific
421
+ # encoding and return self.
422
+ def code_unit_columns(encoding)
423
+ field(:code_unit_columns, CodeUnitColumnsField.new(self, encoding))
424
+ end
425
+
426
+ # Configure the leading comments field for this repository and return
427
+ # self.
428
+ def leading_comments
429
+ field(:leading_comments, LeadingCommentsField.new)
430
+ end
431
+
432
+ # Configure the trailing comments field for this repository and return
433
+ # self.
434
+ def trailing_comments
435
+ field(:trailing_comments, TrailingCommentsField.new)
436
+ end
437
+
438
+ # Configure both the leading and trailing comment fields for this
439
+ # repository and return self.
440
+ def comments
441
+ leading_comments.trailing_comments
442
+ end
443
+
444
+ # This method is called from nodes and locations when they want to enter
445
+ # themselves into the repository. It it internal-only and meant to be
446
+ # called from the #save* APIs.
447
+ def enter(node_id, field_name) # :nodoc:
448
+ entry = Entry.new(self)
449
+ @entries[node_id][field_name] = entry
450
+ entry
451
+ end
452
+
453
+ # This method is called from the entries in the repository when they need
454
+ # to reify their values. It is internal-only and meant to be called from
455
+ # the various value APIs.
456
+ def reify! # :nodoc:
457
+ result = source.result
458
+
459
+ # Attach the comments if they have been requested as part of the
460
+ # configuration of this repository.
461
+ if fields.key?(:leading_comments) || fields.key?(:trailing_comments)
462
+ result.attach_comments!
463
+ end
464
+
465
+ queue = [result.value] #: Array[Prism::node]
466
+ while (node = queue.shift)
467
+ @entries[node.node_id].each do |field_name, entry|
468
+ value = node.public_send(field_name)
469
+ values = {} #: Hash[Symbol, untyped]
470
+
471
+ fields.each_value do |field|
472
+ values.merge!(field.fields(value))
473
+ end
474
+
475
+ entry.reify!(values)
476
+ end
477
+
478
+ queue.concat(node.compact_child_nodes)
479
+ end
480
+
481
+ @entries.clear
482
+ end
483
+
484
+ private
485
+
486
+ # Append the given field to the repository and return the repository so
487
+ # that these calls can be chained.
488
+ def field(name, value)
489
+ raise ConfigurationError, "Cannot specify multiple #{name} fields" if @fields.key?(name)
490
+ @fields[name] = value
491
+ self
492
+ end
493
+ end
494
+
495
+ # Create a new repository for the given filepath.
496
+ def self.filepath(value)
497
+ Repository.new(SourceFilepath.new(value))
498
+ end
499
+
500
+ # Create a new repository for the given string.
501
+ def self.string(value)
502
+ Repository.new(SourceString.new(value))
503
+ end
504
+ end
505
+ end