prism 2.0.0.rc1-x86_64-linux-gnu → 2.0.0-x86_64-linux-gnu

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -2
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/LICENSE.md +1 -1
  5. data/docs/serialization.md +20 -6
  6. data/ext/prism/api_node.c +81 -81
  7. data/ext/prism/extension.c +54 -69
  8. data/ext/prism/extension.h +1 -1
  9. data/include/prism/arena.h +8 -0
  10. data/include/prism/arena.hpp +42 -0
  11. data/include/prism/ast.h +11 -1
  12. data/include/prism/ast.hpp +641 -0
  13. data/include/prism/buffer.h +8 -0
  14. data/include/prism/buffer.hpp +55 -0
  15. data/include/prism/comments.h +17 -0
  16. data/include/prism/compiler/accel.h +3 -1
  17. data/include/prism/compiler/branch.h +26 -0
  18. data/include/prism/compiler/bswap.h +46 -0
  19. data/include/prism/compiler/cplusplus.hpp +16 -0
  20. data/include/prism/compiler/endianness.h +34 -0
  21. data/include/prism/compiler/exceptions.hpp +17 -0
  22. data/include/prism/compiler/format.h +2 -0
  23. data/include/prism/compiler/lifetimebound.hpp +25 -0
  24. data/include/prism/constant_pool.h +25 -0
  25. data/include/prism/diagnostic.h +18 -0
  26. data/include/prism/errors_format.h +8 -0
  27. data/include/prism/internal/buffer.h +3 -0
  28. data/include/prism/internal/node.h +8 -4
  29. data/include/prism/internal/parser.h +20 -0
  30. data/include/prism/internal/stringy.h +1 -6
  31. data/include/prism/internal/xxh3.h +16 -0
  32. data/include/prism/json.h +8 -0
  33. data/include/prism/line_offset_list.h +8 -0
  34. data/include/prism/magic_comments.h +18 -0
  35. data/include/prism/node.h +55 -10
  36. data/include/prism/node.hpp +272 -0
  37. data/include/prism/node_type.hpp +38 -0
  38. data/include/prism/options.h +10 -1
  39. data/include/prism/options.hpp +43 -0
  40. data/include/prism/parser.h +93 -64
  41. data/include/prism/parser.hpp +274 -0
  42. data/include/prism/prettyprint.h +8 -0
  43. data/include/prism/serialize.h +8 -0
  44. data/include/prism/source.h +8 -0
  45. data/include/prism/stream.h +8 -0
  46. data/include/prism/string_query.h +19 -0
  47. data/include/prism/stringy.h +16 -27
  48. data/include/prism/stringy.hpp +31 -0
  49. data/include/prism/version.h +9 -1
  50. data/include/prism.h +0 -8
  51. data/include/prism.hpp +24 -0
  52. data/lib/prism/3.3/prism.so +0 -0
  53. data/lib/prism/3.4/prism.so +0 -0
  54. data/lib/prism/4.0/prism.so +0 -0
  55. data/lib/prism/ffi.rb +6 -0
  56. data/lib/prism/node.rb +736 -0
  57. data/lib/prism/parse_result.rb +23 -8
  58. data/lib/prism/serialize.rb +2567 -3286
  59. data/lib/prism/string_query.rb +8 -0
  60. data/prism.gemspec +21 -4
  61. data/rbi/generated/prism/node.rbi +2430 -968
  62. data/rbi/generated/prism/parse_result.rbi +16 -4
  63. data/rbi/generated/prism/serialize.rbi +8 -4
  64. data/rbi/generated/prism/string_query.rbi +7 -0
  65. data/sig/generated/prism/node.rbs +2439 -967
  66. data/sig/generated/prism/parse_result.rbs +16 -4
  67. data/sig/generated/prism/serialize.rbs +9 -4
  68. data/sig/generated/prism/string_query.rbs +7 -0
  69. data/src/buffer.c +9 -0
  70. data/src/comments.c +2 -2
  71. data/src/diagnostic.c +8 -0
  72. data/src/node.c +216 -368
  73. data/src/options.c +7 -13
  74. data/src/parser.c +70 -48
  75. data/src/prism.c +581 -419
  76. data/src/regexp.c +0 -1
  77. data/src/serialize.c +2301 -1950
  78. data/src/source.c +8 -2
  79. data/src/string_query.c +14 -0
  80. data/src/stringy.c +3 -33
  81. data/src/xxh3.c +292 -0
  82. metadata +20 -3
@@ -16,6 +16,10 @@
16
16
  #include "prism/magic_comments.h"
17
17
  #include "prism/options.h"
18
18
 
19
+ #ifdef __cplusplus
20
+ extern "C" {
21
+ #endif
22
+
19
23
  /**
20
24
  * The parser used to parse Ruby source.
21
25
  */
@@ -150,6 +154,24 @@ PRISM_EXPORTED_FUNCTION const pm_string_t * pm_parser_filepath(const pm_parser_t
150
154
  */
151
155
  PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);
152
156
 
157
+ /**
158
+ * Add a constant to the parser's constant pool, for naming a node that was not
159
+ * parsed from the source. If the constant is already in the pool, its existing
160
+ * id is returned. Otherwise the parser copies the bytes, so they only need to
161
+ * remain valid for the duration of the call.
162
+ *
163
+ * Adding a constant makes the pool larger, so a cache with one entry per
164
+ * constant built beforehand from pm_parser_constants_size and
165
+ * pm_parser_constant_at does not cover it. Build such caches after adding any
166
+ * constants.
167
+ *
168
+ * @param parser the parser whose constant pool we want to add to
169
+ * @param start a pointer to the start of the string to add
170
+ * @param length the length of the string to add
171
+ * @returns the id of the constant
172
+ */
173
+ PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);
174
+
153
175
  /**
154
176
  * Returns the frozen string literal value of the parser, as determined by the
155
177
  * frozen_string_literal magic comment or the option set on the parser.
@@ -177,6 +199,27 @@ PRISM_EXPORTED_FUNCTION const pm_line_offset_list_t * pm_parser_line_offsets(con
177
199
  */
178
200
  PRISM_EXPORTED_FUNCTION const pm_location_t * pm_parser_data_loc(const pm_parser_t *parser) PRISM_NONNULL(1);
179
201
 
202
+ /**
203
+ * Returns the checksum of the source code that was parsed. The data section
204
+ * after an __END__ marker is not code, so the hash covers the source only up to
205
+ * and including the newline that ends the __END__ line. The __END__ marker is
206
+ * only found by parsing, so this must be called after pm_parse.
207
+ *
208
+ * The hash is computed from the source on each call rather than during
209
+ * parsing, so that parses that never ask for it do not pay for it. This
210
+ * requires the source to still be alive, and callers that need the value more
211
+ * than once should keep it.
212
+ *
213
+ * The hash is currently the 64-bit variant of XXH3 with a seed of 0. It is not
214
+ * cryptographic, and the algorithm may change between versions of prism, so
215
+ * hashes should only be compared against other hashes computed by the same
216
+ * version of prism.
217
+ *
218
+ * @param parser the parser whose checksum we want to get
219
+ * @returns the checksum of the source code that was parsed
220
+ */
221
+ PRISM_EXPORTED_FUNCTION uint64_t pm_parser_checksum(const pm_parser_t *parser) PRISM_NONNULL(1);
222
+
180
223
  /**
181
224
  * Returns whether the given parser is continuable, meaning that it could become
182
225
  * valid if more input were appended, as opposed to being definitively invalid.
@@ -206,22 +249,19 @@ PRISM_EXPORTED_FUNCTION int pm_parser_lex_state(const pm_parser_t *parser) PRISM
206
249
  PRISM_EXPORTED_FUNCTION size_t pm_parser_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
207
250
 
208
251
  /**
209
- * A callback function that can be used to process comments found while parsing.
210
- */
211
- typedef void (*pm_comment_callback_t)(const pm_comment_t *comment, void *data);
212
-
213
- /**
214
- * Iterates over the comments associated with the given parser and calls the
215
- * given callback for each comment.
252
+ * Returns the first comment associated with the given parser. Iterate over the
253
+ * rest with pm_comment_next, as in:
254
+ *
255
+ * ```c
256
+ * for (const pm_comment_t *comment = pm_parser_comments_first(parser); comment != NULL; comment = pm_comment_next(comment)) {
257
+ * pm_location_t location = pm_comment_location(comment);
258
+ * }
259
+ * ```
216
260
  *
217
261
  * @param parser the parser whose comments we want to iterate over
218
- * @param callback the callback function to call for each comment. This function
219
- * will be passed a pointer to the comment and the data parameter passed to
220
- * this function.
221
- * @param data the data to pass to the callback function for each comment. This
222
- * can be NULL if no data needs to be passed to the callback function.
262
+ * @returns the first comment, or NULL if there are no comments
223
263
  */
224
- PRISM_EXPORTED_FUNCTION void pm_parser_comments_each(const pm_parser_t *parser, pm_comment_callback_t callback, void *data) PRISM_NONNULL(1);
264
+ PRISM_EXPORTED_FUNCTION const pm_comment_t * pm_parser_comments_first(const pm_parser_t *parser) PRISM_NONNULL(1);
225
265
 
226
266
  /**
227
267
  * Returns the number of comments owned by the given node. This is 0 if the
@@ -288,22 +328,13 @@ PRISM_EXPORTED_FUNCTION pm_comment_range_t pm_parser_comment_range(const pm_pars
288
328
  PRISM_EXPORTED_FUNCTION size_t pm_parser_magic_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
289
329
 
290
330
  /**
291
- * A callback function that can be used to process magic comments found while parsing.
292
- */
293
- typedef void (*pm_magic_comment_callback_t)(const pm_magic_comment_t *magic_comment, void *data);
294
-
295
- /**
296
- * Iterates over the magic comments associated with the given parser and calls the
297
- * given callback for each magic comment.
331
+ * Returns the first magic comment associated with the given parser. Iterate
332
+ * over the rest with pm_magic_comment_next.
298
333
  *
299
334
  * @param parser the parser whose magic comments we want to iterate over
300
- * @param callback the callback function to call for each magic comment. This
301
- * function will be passed a pointer to the magic comment and the data
302
- * parameter passed to this function.
303
- * @param data the data to pass to the callback function for each magic comment.
304
- * This can be NULL if no data needs to be passed to the callback function.
335
+ * @returns the first magic comment, or NULL if there are no magic comments
305
336
  */
306
- PRISM_EXPORTED_FUNCTION void pm_parser_magic_comments_each(const pm_parser_t *parser, pm_magic_comment_callback_t callback, void *data) PRISM_NONNULL(1);
337
+ PRISM_EXPORTED_FUNCTION const pm_magic_comment_t * pm_parser_magic_comments_first(const pm_parser_t *parser) PRISM_NONNULL(1);
307
338
 
308
339
  /**
309
340
  * Returns the number of errors associated with the given parser.
@@ -322,36 +353,22 @@ PRISM_EXPORTED_FUNCTION size_t pm_parser_errors_size(const pm_parser_t *parser)
322
353
  PRISM_EXPORTED_FUNCTION size_t pm_parser_warnings_size(const pm_parser_t *parser) PRISM_NONNULL(1);
323
354
 
324
355
  /**
325
- * A callback function that can be used to process diagnostics found while
326
- * parsing.
327
- */
328
- typedef void (*pm_diagnostic_callback_t)(const pm_diagnostic_t *diagnostic, void *data);
329
-
330
- /**
331
- * Iterates over the errors associated with the given parser and calls the
332
- * given callback for each error.
356
+ * Returns the first error associated with the given parser. Iterate over the
357
+ * rest with pm_diagnostic_next.
333
358
  *
334
359
  * @param parser the parser whose errors we want to iterate over
335
- * @param callback the callback function to call for each error. This function
336
- * will be passed a pointer to the error and the data parameter passed to
337
- * this function.
338
- * @param data the data to pass to the callback function for each error. This
339
- * can be NULL if no data needs to be passed to the callback function.
360
+ * @returns the first error, or NULL if there are no errors
340
361
  */
341
- PRISM_EXPORTED_FUNCTION void pm_parser_errors_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) PRISM_NONNULL(1);
362
+ PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_errors_first(const pm_parser_t *parser) PRISM_NONNULL(1);
342
363
 
343
364
  /**
344
- * Iterates over the warnings associated with the given parser and calls the
345
- * given callback for each warning.
365
+ * Returns the first warning associated with the given parser. Iterate over the
366
+ * rest with pm_diagnostic_next.
346
367
  *
347
368
  * @param parser the parser whose warnings we want to iterate over
348
- * @param callback the callback function to call for each warning. This function
349
- * will be passed a pointer to the warning and the data parameter passed to
350
- * this function.
351
- * @param data the data to pass to the callback function for each warning. This
352
- * can be NULL if no data needs to be passed to the callback function.
369
+ * @returns the first warning, or NULL if there are no warnings
353
370
  */
354
- PRISM_EXPORTED_FUNCTION void pm_parser_warnings_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) PRISM_NONNULL(1);
371
+ PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_warnings_first(const pm_parser_t *parser) PRISM_NONNULL(1);
355
372
 
356
373
  /**
357
374
  * Returns the number of constants in the constant pool associated with the
@@ -365,30 +382,38 @@ PRISM_EXPORTED_FUNCTION void pm_parser_warnings_each(const pm_parser_t *parser,
365
382
  PRISM_EXPORTED_FUNCTION size_t pm_parser_constants_size(const pm_parser_t *parser) PRISM_NONNULL(1);
366
383
 
367
384
  /**
368
- * A callback function that can be used to process constants found while
369
- * parsing.
370
- */
371
- typedef void (*pm_constant_callback_t)(const pm_constant_t *constant, void *data);
372
-
373
- /**
374
- * Iterates over the constants in the constant pool associated with the given
375
- * parser and calls the given callback for each constant.
385
+ * Returns the constant at the given index in the constant pool associated with
386
+ * the given parser. Together with pm_constant_id_index, this lets a caller
387
+ * build a cache with one entry per constant and then find the entry for any
388
+ * constant id, as in:
389
+ *
390
+ * ```c
391
+ * size_t size = pm_parser_constants_size(parser);
392
+ * for (size_t index = 0; index < size; index++) {
393
+ * cache[index] = convert(pm_parser_constant_at(parser, index));
394
+ * }
395
+ *
396
+ * value = cache[pm_constant_id_index(constant_id)];
397
+ * ```
376
398
  *
377
- * @param parser the parser whose constants we want to iterate over
378
- * @param callback the callback function to call for each constant. This function
379
- * will be passed a pointer to the constant and the data parameter passed to
380
- * this function.
381
- * @param data the data to pass to the callback function for each constant. This
382
- * can be NULL if no data needs to be passed to the callback function.
399
+ * For any constant id, pm_parser_constant_at(parser,
400
+ * pm_constant_id_index(constant_id)) is pm_parser_constant(parser,
401
+ * constant_id).
402
+ *
403
+ * @param parser the parser whose constant pool we want to look up from
404
+ * @param index the index of the constant, which must be less than
405
+ * pm_parser_constants_size(parser)
406
+ * @returns a pointer to the constant at the given index
383
407
  */
384
- PRISM_EXPORTED_FUNCTION void pm_parser_constants_each(const pm_parser_t *parser, pm_constant_callback_t callback, void *data) PRISM_NONNULL(1);
408
+ PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant_at(const pm_parser_t *parser, size_t index) PRISM_NONNULL(1);
385
409
 
386
410
  /**
387
411
  * Returns a pointer to the constant at the given id in the constant pool
388
412
  * associated with the given parser.
389
413
  *
390
414
  * @param parser the parser whose constant pool we want to look up from
391
- * @param constant_id the id of the constant to look up (1-based)
415
+ * @param constant_id the id of the constant to look up. Optional constant
416
+ * fields on nodes hold 0 when they are absent, which is not a valid id.
392
417
  * @returns a pointer to the constant at the given id
393
418
  */
394
419
  PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant(const pm_parser_t *parser, pm_constant_id_t constant_id) PRISM_NONNULL(1);
@@ -401,4 +426,8 @@ PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant(const pm_parser
401
426
  */
402
427
  PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser) PRISM_NONNULL(1);
403
428
 
429
+ #ifdef __cplusplus
430
+ }
431
+ #endif
432
+
404
433
  #endif
@@ -0,0 +1,274 @@
1
+ /**
2
+ * @file parser.hpp
3
+ *
4
+ * Ownership of parsers from C++, and lookups through a parser into the source,
5
+ * the constant pool, comments, and diagnostics.
6
+ */
7
+ #ifndef PRISM_PARSER_HPP
8
+ #define PRISM_PARSER_HPP
9
+
10
+ #include "prism/compiler/cplusplus.hpp"
11
+ #include "prism/compiler/lifetimebound.hpp"
12
+
13
+ #include "prism/arena.h"
14
+ #include "prism/constant_pool.h"
15
+ #include "prism/line_offset_list.h"
16
+ #include "prism/parser.h"
17
+
18
+ #include <cassert>
19
+ #include <cstddef>
20
+ #include <cstdint>
21
+ #include <iterator>
22
+ #include <memory>
23
+ #include <string_view>
24
+
25
+ namespace prism {
26
+
27
+ /** Frees a parser with pm_parser_free. */
28
+ struct parser_deleter {
29
+ /**
30
+ * Free the given parser.
31
+ *
32
+ * @param parser The parser to free.
33
+ */
34
+ void operator()(pm_parser_t *parser) const noexcept { pm_parser_free(parser); }
35
+ };
36
+
37
+ /** An owned parser. */
38
+ using unique_parser = std::unique_ptr<pm_parser_t, parser_deleter>;
39
+
40
+ /**
41
+ * Allocate a new parser over the given source. The source, the arena, and the
42
+ * options (which may be null) are not copied, so all three must outlive the
43
+ * parser. Allocation failure aborts, so this never throws.
44
+ *
45
+ * @param arena The arena to use for allocations.
46
+ * @param source The source code to parse.
47
+ * @param options The parse options, or null for defaults.
48
+ * @return A unique_parser owning the newly allocated parser.
49
+ */
50
+ [[nodiscard]] inline unique_parser
51
+ make_parser(pm_arena_t *arena PRISM_LIFETIMEBOUND, std::string_view source PRISM_LIFETIMEBOUND, const pm_options_t *options PRISM_LIFETIMEBOUND = nullptr) noexcept {
52
+ return unique_parser(pm_parser_new(arena, reinterpret_cast<const std::uint8_t *>(source.data()), source.size(), options));
53
+ }
54
+
55
+ /**
56
+ * The name of the constant with the given id, which must not be zero. Fields
57
+ * holding an optional constant use zero for none, so check those first.
58
+ *
59
+ * @param parser The parser containing the constant.
60
+ * @param constant_id The id of the constant.
61
+ * @return The value of the constant.
62
+ */
63
+ [[nodiscard]] inline std::string_view
64
+ constant(const pm_parser_t *parser PRISM_LIFETIMEBOUND, pm_constant_id_t constant_id) noexcept {
65
+ assert(constant_id != 0);
66
+ const pm_constant_t *entry = pm_parser_constant(parser, constant_id);
67
+ return std::string_view(reinterpret_cast<const char *>(pm_constant_start(entry)), pm_constant_length(entry));
68
+ }
69
+
70
+ /**
71
+ * The bytes of source that the given location covers.
72
+ *
73
+ * @param parser The parser containing the source.
74
+ * @param location The location in the source.
75
+ * @return The bytes of source covered by the location.
76
+ */
77
+ [[nodiscard]] inline std::string_view
78
+ slice(const pm_parser_t *parser PRISM_LIFETIMEBOUND, pm_location_t location) noexcept {
79
+ return std::string_view(reinterpret_cast<const char *>(pm_parser_start(parser) + location.start), location.length);
80
+ }
81
+
82
+ /**
83
+ * The line and column of the given byte offset into the source. Lines start at
84
+ * the parser's start line, and columns are byte offsets from the line start.
85
+ *
86
+ * @param parser The parser containing the source.
87
+ * @param offset The byte offset into the source.
88
+ * @return The line and column of the byte offset.
89
+ */
90
+ [[nodiscard]] inline pm_line_column_t
91
+ line_column(const pm_parser_t *parser, std::uint32_t offset) noexcept {
92
+ return pm_line_offset_list_line_column(pm_parser_line_offsets(parser), offset, pm_parser_start_line(parser));
93
+ }
94
+
95
+ namespace detail {
96
+
97
+ /**
98
+ * The diagnostics, comments, or magic comments found while parsing, usable in a
99
+ * range-based for loop and with the standard algorithms. Each element is a
100
+ * pointer to the C struct, which the C accessors read, and Next is the C
101
+ * function that returns the item after a given one. It refers to the parser
102
+ * rather than copying from it, so the parser must outlive it. It is used
103
+ * through diagnostic_range, comment_range, and magic_comment_range.
104
+ */
105
+ template <typename T, const T *(*Next)(const T *)> class next_range {
106
+ public:
107
+ /** Steps through the items one after another. */
108
+ class iterator {
109
+ public:
110
+ /** The iterator category, for the standard algorithms. */
111
+ using iterator_category = std::forward_iterator_tag;
112
+
113
+ /** The type of each element. */
114
+ using value_type = const T *;
115
+
116
+ /** The type of the distance between two iterators. */
117
+ using difference_type = std::ptrdiff_t;
118
+
119
+ /** The type of a pointer to an element. */
120
+ using pointer = const value_type *;
121
+
122
+ /** The type of a reference to an element. */
123
+ using reference = const value_type &;
124
+
125
+ /** Create the iterator that marks the end of the items. */
126
+ iterator() noexcept = default;
127
+
128
+ /**
129
+ * Create an iterator at the given item.
130
+ *
131
+ * @param current The current item.
132
+ */
133
+ explicit iterator(const T *current) noexcept : current_(current) {}
134
+
135
+ /**
136
+ * The item at this position, which must not be the end.
137
+ *
138
+ * @return The current item.
139
+ */
140
+ reference operator*() const noexcept { return current_; }
141
+
142
+ /**
143
+ * Advance to the next item.
144
+ *
145
+ * @return The iterator after advancing.
146
+ */
147
+ iterator &
148
+ operator++() noexcept {
149
+ assert(current_ != nullptr);
150
+ current_ = Next(current_);
151
+ return *this;
152
+ }
153
+
154
+ /**
155
+ * Advance to the next item, returning the iterator from before.
156
+ *
157
+ * @return The iterator from before advancing.
158
+ */
159
+ iterator
160
+ operator++(int) noexcept {
161
+ iterator previous = *this;
162
+ ++*this;
163
+ return previous;
164
+ }
165
+
166
+ /** Whether the two iterators are at the same item. */
167
+ friend bool operator==(iterator left, iterator right) noexcept { return left.current_ == right.current_; }
168
+
169
+ /** Whether the two iterators are at different items. */
170
+ friend bool operator!=(iterator left, iterator right) noexcept { return left.current_ != right.current_; }
171
+
172
+ private:
173
+ const T *current_ = nullptr;
174
+ };
175
+
176
+ /**
177
+ * Create a range of the given number of items starting at first.
178
+ *
179
+ * @param first The first item.
180
+ * @param size The number of items.
181
+ */
182
+ next_range(const T *first, std::size_t size) noexcept : first_(first), size_(size) {}
183
+
184
+ /**
185
+ * An iterator at the first item.
186
+ *
187
+ * @return An iterator at the first item.
188
+ */
189
+ iterator begin() const noexcept { return iterator(first_); }
190
+
191
+ /**
192
+ * An iterator past the last item.
193
+ *
194
+ * @return An iterator past the last item.
195
+ */
196
+ iterator end() const noexcept { return iterator(); }
197
+
198
+ /**
199
+ * The number of items.
200
+ *
201
+ * @return The number of items.
202
+ */
203
+ std::size_t size() const noexcept { return size_; }
204
+
205
+ /**
206
+ * Whether there are no items.
207
+ *
208
+ * @return Whether there are no items.
209
+ */
210
+ [[nodiscard]] bool empty() const noexcept { return size_ == 0; }
211
+
212
+ private:
213
+ const T *first_;
214
+ std::size_t size_;
215
+ };
216
+
217
+ }
218
+
219
+ /** The errors or warnings found while parsing. */
220
+ using diagnostic_range = detail::next_range<pm_diagnostic_t, pm_diagnostic_next>;
221
+
222
+ /** The comments found while parsing. */
223
+ using comment_range = detail::next_range<pm_comment_t, pm_comment_next>;
224
+
225
+ /** The magic comments found while parsing. */
226
+ using magic_comment_range = detail::next_range<pm_magic_comment_t, pm_magic_comment_next>;
227
+
228
+ /**
229
+ * The errors found while parsing.
230
+ *
231
+ * @param parser The parser containing the source.
232
+ * @return The range of errors found while parsing.
233
+ */
234
+ [[nodiscard]] inline diagnostic_range
235
+ errors(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
236
+ return diagnostic_range(pm_parser_errors_first(parser), pm_parser_errors_size(parser));
237
+ }
238
+
239
+ /**
240
+ * The warnings found while parsing.
241
+ *
242
+ * @param parser The parser containing the source.
243
+ * @return The range of warnings found while parsing.
244
+ */
245
+ [[nodiscard]] inline diagnostic_range
246
+ warnings(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
247
+ return diagnostic_range(pm_parser_warnings_first(parser), pm_parser_warnings_size(parser));
248
+ }
249
+
250
+ /**
251
+ * The comments found while parsing, in source order.
252
+ *
253
+ * @param parser The parser containing the source.
254
+ * @return The range of comments found while parsing.
255
+ */
256
+ [[nodiscard]] inline comment_range
257
+ comments(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
258
+ return comment_range(pm_parser_comments_first(parser), pm_parser_comments_size(parser));
259
+ }
260
+
261
+ /**
262
+ * The magic comments found while parsing.
263
+ *
264
+ * @param parser The parser containing the source.
265
+ * @return The range of magic comments found while parsing.
266
+ */
267
+ [[nodiscard]] inline magic_comment_range
268
+ magic_comments(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
269
+ return magic_comment_range(pm_parser_magic_comments_first(parser), pm_parser_magic_comments_size(parser));
270
+ }
271
+
272
+ }
273
+
274
+ #endif
@@ -17,6 +17,10 @@
17
17
  #include "prism/buffer.h"
18
18
  #include "prism/parser.h"
19
19
 
20
+ #ifdef __cplusplus
21
+ extern "C" {
22
+ #endif
23
+
20
24
  /**
21
25
  * Pretty-prints the AST represented by the given node to the given buffer.
22
26
  *
@@ -26,6 +30,10 @@
26
30
  */
27
31
  PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) PRISM_NONNULL(1, 2, 3);
28
32
 
33
+ #ifdef __cplusplus
34
+ }
35
+ #endif
36
+
29
37
  #endif
30
38
 
31
39
  #endif
@@ -22,6 +22,10 @@
22
22
  #include "prism/source.h"
23
23
  #include "prism/stream.h"
24
24
 
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
25
29
  /**
26
30
  * Serialize the AST represented by the given node to the given buffer.
27
31
  *
@@ -110,6 +114,10 @@ PRISM_EXPORTED_FUNCTION bool pm_serialize_parse_success_p(const uint8_t *source,
110
114
  */
111
115
  PRISM_EXPORTED_FUNCTION int8_t pm_serialize_parse_errors_format(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data, pm_errors_format_type_t format_type) PRISM_NONNULL(1, 2);
112
116
 
117
+ #ifdef __cplusplus
118
+ }
119
+ #endif
120
+
113
121
  #endif
114
122
 
115
123
  #endif
@@ -15,6 +15,10 @@
15
15
  #include <stddef.h>
16
16
  #include <stdint.h>
17
17
 
18
+ #ifdef __cplusplus
19
+ extern "C" {
20
+ #endif
21
+
18
22
  /**
19
23
  * An opaque type representing source code being parsed.
20
24
  */
@@ -152,4 +156,8 @@ PRISM_EXPORTED_FUNCTION size_t pm_source_length(const pm_source_t *source) PRISM
152
156
  */
153
157
  PRISM_EXPORTED_FUNCTION const uint8_t * pm_source_source(const pm_source_t *source) PRISM_NONNULL(1);
154
158
 
159
+ #ifdef __cplusplus
160
+ }
161
+ #endif
162
+
155
163
  #endif
@@ -14,6 +14,10 @@
14
14
  #include "prism/parser.h"
15
15
  #include "prism/source.h"
16
16
 
17
+ #ifdef __cplusplus
18
+ extern "C" {
19
+ #endif
20
+
17
21
  /**
18
22
  * Parse a stream of Ruby source and return the tree.
19
23
  *
@@ -25,4 +29,8 @@
25
29
  */
26
30
  PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse_stream(pm_parser_t **parser, pm_arena_t *arena, pm_source_t *source, const pm_options_t *options) PRISM_NONNULL(1, 2, 3);
27
31
 
32
+ #ifdef __cplusplus
33
+ }
34
+ #endif
35
+
28
36
  #endif
@@ -13,6 +13,10 @@
13
13
  #include <stddef.h>
14
14
  #include <stdint.h>
15
15
 
16
+ #ifdef __cplusplus
17
+ extern "C" {
18
+ #endif
19
+
16
20
  /**
17
21
  * Represents the results of a slice query.
18
22
  */
@@ -60,4 +64,19 @@ PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_constant(const uint8_t
60
64
  */
61
65
  PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name) PRISM_NONNULL(1, 3);
62
66
 
67
+ /**
68
+ * Check that the slice is a keyword.
69
+ *
70
+ * @param source The source to check.
71
+ * @param length The length of the source.
72
+ * @param encoding_name The name of the encoding of the source.
73
+ * @returns PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
74
+ * the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
75
+ */
76
+ PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_keyword(const uint8_t *source, size_t length, const char *encoding_name) PRISM_NONNULL(1, 3);
77
+
78
+ #ifdef __cplusplus
79
+ }
80
+ #endif
81
+
63
82
  #endif