herb 0.11.1 → 0.11.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 (247) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -2
  3. data/config.yml +6 -0
  4. data/ext/herb/extconf.rb +8 -31
  5. data/ext/herb/nodes.c +75 -75
  6. data/ext/herb/parser_options_helpers.c +26 -0
  7. data/lib/herb/analysis/partial_index.rb +1 -1
  8. data/lib/herb/analysis/partial_resolution.rb +27 -0
  9. data/lib/herb/ast/helpers.rb +1 -1
  10. data/lib/herb/configuration.rb +11 -1
  11. data/lib/herb/dev/classifier.rb +1 -1
  12. data/lib/herb/engine/compiler.rb +5 -8
  13. data/lib/herb/engine/slots/dynamics_compiler.rb +53 -14
  14. data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
  15. data/lib/herb/engine/slots/visitor.rb +32 -4
  16. data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
  17. data/lib/herb/parser_options.rb +6 -3
  18. data/lib/herb/project.rb +19 -8
  19. data/lib/herb/version.rb +1 -1
  20. data/lib/herb.rb +1 -1
  21. data/sig/herb/analysis/partial_resolution.rbs +8 -0
  22. data/sig/herb/configuration.rbs +3 -0
  23. data/sig/herb/engine/slots/dynamics_compiler.rbs +24 -7
  24. data/sig/herb/engine/slots/visitor.rbs +14 -0
  25. data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
  26. data/sig/herb/parser_options.rbs +6 -4
  27. data/sig/herb.rbs +2 -2
  28. data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
  29. data/src/analyze/action_view/generated_handlers.c +36 -36
  30. data/src/analyze/action_view/image_tag.c +7 -3
  31. data/src/analyze/action_view/javascript_include_tag.c +6 -3
  32. data/src/analyze/action_view/link_to.c +23 -23
  33. data/src/analyze/action_view/registry.c +7 -3
  34. data/src/analyze/action_view/tag_helper_node_builders.c +6 -13
  35. data/src/analyze/action_view/tag_helpers.c +139 -90
  36. data/src/analyze/action_view/turbo_frame_tag.c +5 -4
  37. data/src/analyze/analyze.c +35 -19
  38. data/src/analyze/analyze_helpers.c +161 -188
  39. data/src/analyze/analyzed_ruby.c +8 -7
  40. data/src/analyze/control_type.c +29 -22
  41. data/src/analyze/herb_directives.c +16 -20
  42. data/src/analyze/iteration_nodes.c +69 -24
  43. data/src/analyze/parse_errors.c +32 -22
  44. data/src/analyze/postfix_conditionals.c +23 -13
  45. data/src/analyze/prism_annotate.c +29 -28
  46. data/src/analyze/render_nodes.c +51 -41
  47. data/src/analyze/strict_locals.c +14 -15
  48. data/src/analyze/ternary_conditionals.c +14 -10
  49. data/src/herb.c +10 -8
  50. data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
  51. data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
  52. data/src/include/analyze/action_view/tag_helpers.h +1 -1
  53. data/src/include/analyze/analyze.h +3 -2
  54. data/src/include/analyze/analyzed_ruby.h +4 -2
  55. data/src/include/analyze/helpers.h +6 -6
  56. data/src/include/herb.h +3 -2
  57. data/src/include/parser/parser_options.h +5 -0
  58. data/src/include/prism/prism_context.h +12 -12
  59. data/src/include/prism/prism_helpers.h +30 -0
  60. data/src/include/prism_version.h +11 -0
  61. data/src/include/version.h +1 -1
  62. data/src/parser/parser_helpers.c +1 -2
  63. data/src/parser.c +6 -7
  64. data/src/parser_options_defaults.c +1 -0
  65. data/src/prism/prism_helpers.c +84 -50
  66. data/src/prism/ruby_parser.c +20 -20
  67. data/templates/ext/herb/nodes.c.erb +5 -5
  68. data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
  69. data/templates/java/nodes.c.erb +6 -6
  70. data/templates/java/parser_options_helpers.c.erb +41 -2
  71. data/templates/java/parser_options_helpers.h.erb +2 -1
  72. data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
  73. data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
  74. data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
  75. data/templates/lib/herb/parser_options.rb.erb +1 -1
  76. data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
  77. data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
  78. data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
  79. data/templates/src/include/parser/parser_options.h.erb +10 -0
  80. data/templates/src/include/prism_version.h.erb +17 -0
  81. data/templates/src/parser_options_defaults.c.erb +1 -1
  82. data/templates/template.rb +17 -2
  83. data/templates/wasm/nodes.cpp.erb +5 -5
  84. data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
  85. data/vendor/prism/Rakefile +76 -7
  86. data/vendor/prism/config.yml +174 -161
  87. data/vendor/prism/include/prism/arena.h +45 -0
  88. data/vendor/prism/include/prism/arena.hpp +42 -0
  89. data/vendor/prism/include/prism/ast.h +2738 -611
  90. data/vendor/prism/include/prism/ast.hpp +641 -0
  91. data/vendor/prism/include/prism/buffer.h +60 -0
  92. data/vendor/prism/include/prism/buffer.hpp +55 -0
  93. data/vendor/prism/include/prism/comments.h +72 -0
  94. data/vendor/prism/include/prism/compiler/accel.h +26 -0
  95. data/vendor/prism/include/prism/compiler/align.h +36 -0
  96. data/vendor/prism/include/prism/compiler/assume.h +25 -0
  97. data/vendor/prism/include/prism/compiler/branch.h +26 -0
  98. data/vendor/prism/include/prism/compiler/bswap.h +46 -0
  99. data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
  100. data/vendor/prism/include/prism/compiler/endianness.h +34 -0
  101. data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
  102. data/vendor/prism/include/prism/compiler/exported.h +24 -0
  103. data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
  104. data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
  105. data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
  106. data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
  107. data/vendor/prism/include/prism/compiler/format.h +27 -0
  108. data/vendor/prism/include/prism/compiler/inline.h +17 -0
  109. data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
  110. data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
  111. data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
  112. data/vendor/prism/include/prism/compiler/unused.h +18 -0
  113. data/vendor/prism/include/prism/constant_pool.h +106 -0
  114. data/vendor/prism/include/prism/diagnostic.h +55 -402
  115. data/vendor/prism/include/prism/errors_format.h +61 -0
  116. data/vendor/prism/include/prism/excludes.h +29 -0
  117. data/vendor/prism/include/prism/integer.h +41 -0
  118. data/vendor/prism/include/prism/internal/allocator.h +68 -0
  119. data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
  120. data/vendor/prism/include/prism/internal/arena.h +108 -0
  121. data/vendor/prism/include/prism/internal/bit.h +42 -0
  122. data/vendor/prism/include/prism/internal/buffer.h +94 -0
  123. data/vendor/prism/include/prism/internal/char.h +145 -0
  124. data/vendor/prism/include/prism/internal/comments.h +54 -0
  125. data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
  126. data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
  127. data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
  128. data/vendor/prism/include/prism/internal/integer.h +68 -0
  129. data/vendor/prism/include/prism/internal/isinf.h +16 -0
  130. data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
  131. data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  132. data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
  133. data/vendor/prism/include/prism/internal/memchr.h +15 -0
  134. data/vendor/prism/include/prism/internal/node.h +42 -0
  135. data/vendor/prism/include/prism/internal/options.h +232 -0
  136. data/vendor/prism/include/prism/internal/parser.h +1015 -0
  137. data/vendor/prism/include/prism/internal/regexp.h +26 -0
  138. data/vendor/prism/include/prism/internal/serialize.h +39 -0
  139. data/vendor/prism/include/prism/internal/source.h +72 -0
  140. data/vendor/prism/include/prism/internal/static_literals.h +60 -0
  141. data/vendor/prism/include/prism/internal/stringy.h +30 -0
  142. data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  143. data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  144. data/vendor/prism/include/prism/internal/tokens.h +11 -0
  145. data/vendor/prism/include/prism/internal/xxh3.h +16 -0
  146. data/vendor/prism/include/prism/json.h +40 -0
  147. data/vendor/prism/include/prism/line_offset_list.h +69 -0
  148. data/vendor/prism/include/prism/magic_comments.h +53 -0
  149. data/vendor/prism/include/prism/node.h +59 -49
  150. data/vendor/prism/include/prism/node.hpp +272 -0
  151. data/vendor/prism/include/prism/node_type.hpp +38 -0
  152. data/vendor/prism/include/prism/options.h +154 -279
  153. data/vendor/prism/include/prism/options.hpp +43 -0
  154. data/vendor/prism/include/prism/parser.h +367 -870
  155. data/vendor/prism/include/prism/parser.hpp +274 -0
  156. data/vendor/prism/include/prism/prettyprint.h +14 -9
  157. data/vendor/prism/include/prism/serialize.h +123 -0
  158. data/vendor/prism/include/prism/source.h +163 -0
  159. data/vendor/prism/include/prism/stream.h +36 -0
  160. data/vendor/prism/include/prism/string_query.h +82 -0
  161. data/vendor/prism/include/prism/stringy.h +61 -0
  162. data/vendor/prism/include/prism/stringy.hpp +31 -0
  163. data/vendor/prism/include/prism/version.h +20 -3
  164. data/vendor/prism/include/prism.h +35 -320
  165. data/vendor/prism/include/prism.hpp +24 -0
  166. data/vendor/prism/src/arena.c +122 -0
  167. data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
  168. data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
  169. data/vendor/prism/src/comments.c +455 -0
  170. data/vendor/prism/src/constant_pool.c +406 -0
  171. data/vendor/prism/src/diagnostic.c +120 -68
  172. data/vendor/prism/src/encoding.c +8 -3
  173. data/vendor/prism/src/errors_format.c +519 -0
  174. data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
  175. data/vendor/prism/src/json.c +5733 -0
  176. data/vendor/prism/src/line_offset_list.c +100 -0
  177. data/vendor/prism/src/list.c +24 -0
  178. data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
  179. data/vendor/prism/src/node.c +3465 -7787
  180. data/vendor/prism/src/options.c +161 -54
  181. data/vendor/prism/src/parser.c +371 -0
  182. data/vendor/prism/src/prettyprint.c +421 -354
  183. data/vendor/prism/src/prism.c +8522 -7280
  184. data/vendor/prism/src/regexp.c +960 -45
  185. data/vendor/prism/src/serialize.c +2434 -2048
  186. data/vendor/prism/src/source.c +524 -0
  187. data/vendor/prism/src/static_literals.c +303 -360
  188. data/vendor/prism/src/string_query.c +180 -0
  189. data/vendor/prism/src/stringy.c +61 -0
  190. data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  191. data/vendor/prism/src/strpbrk.c +447 -0
  192. data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
  193. data/vendor/prism/src/xxh3.c +292 -0
  194. data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
  195. data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
  196. data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
  197. data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
  198. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
  199. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
  200. data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
  201. data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
  202. data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
  203. data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
  204. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
  205. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
  206. data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
  207. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
  208. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
  209. data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
  210. data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
  211. data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
  212. data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
  213. data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
  214. data/vendor/prism/templates/src/json.c.erb +130 -0
  215. data/vendor/prism/templates/src/node.c.erb +79 -236
  216. data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
  217. data/vendor/prism/templates/src/serialize.c.erb +369 -183
  218. data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
  219. data/vendor/prism/templates/template.rb +193 -91
  220. metadata +100 -42
  221. data/vendor/prism/include/prism/defines.h +0 -260
  222. data/vendor/prism/include/prism/pack.h +0 -163
  223. data/vendor/prism/include/prism/regexp.h +0 -43
  224. data/vendor/prism/include/prism/static_literals.h +0 -121
  225. data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
  226. data/vendor/prism/include/prism/util/pm_char.h +0 -204
  227. data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
  228. data/vendor/prism/include/prism/util/pm_integer.h +0 -130
  229. data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
  230. data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
  231. data/vendor/prism/include/prism/util/pm_string.h +0 -200
  232. data/vendor/prism/src/pack.c +0 -509
  233. data/vendor/prism/src/util/pm_constant_pool.c +0 -342
  234. data/vendor/prism/src/util/pm_list.c +0 -49
  235. data/vendor/prism/src/util/pm_newline_list.c +0 -125
  236. data/vendor/prism/src/util/pm_string.c +0 -381
  237. data/vendor/prism/src/util/pm_strpbrk.c +0 -206
  238. data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
  239. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
  240. data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
  241. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
  242. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
  243. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
  244. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
  245. data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
  246. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
  247. data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
@@ -0,0 +1,26 @@
1
+ #ifndef PRISM_INTERNAL_REGEXP_H
2
+ #define PRISM_INTERNAL_REGEXP_H
3
+
4
+ #include "prism/ast.h"
5
+ #include "prism/parser.h"
6
+
7
+ /*
8
+ * Callback invoked by pm_regexp_parse() for each named capture group found.
9
+ * The data pointer is whatever the caller passed in alongside the callback; the
10
+ * regexp parser passes it through without inspecting it.
11
+ */
12
+ typedef void (*pm_regexp_name_callback_t)(pm_parser_t *parser, const pm_string_t *name, void *data);
13
+
14
+ /*
15
+ * Parse a regular expression, validate its encoding, and optionally extract
16
+ * named capture groups. Returns the encoding flags to set on the node.
17
+ */
18
+ PRISM_EXPORTED_FUNCTION pm_node_flags_t pm_regexp_parse(pm_parser_t *parser, pm_regular_expression_node_t *node, pm_regexp_name_callback_t name_callback, void *name_data);
19
+
20
+ /*
21
+ * Parse an interpolated regular expression for named capture groups only.
22
+ * No encoding validation is performed.
23
+ */
24
+ void pm_regexp_parse_named_captures(pm_parser_t *parser, const uint8_t *source, size_t size, bool extended_mode, pm_regexp_name_callback_t name_callback, void *name_data);
25
+
26
+ #endif
@@ -0,0 +1,39 @@
1
+ #ifndef PRISM_INTERNAL_SERIALIZE_H
2
+ #define PRISM_INTERNAL_SERIALIZE_H
3
+
4
+ #include "prism/internal/encoding.h"
5
+ #include "prism/internal/list.h"
6
+
7
+ #include "prism/ast.h"
8
+ #include "prism/buffer.h"
9
+ #include "prism/excludes.h"
10
+ #include "prism/parser.h"
11
+
12
+ /* We optionally support serializing to a binary string. For systems that do not
13
+ * want or need this functionality, it can be turned off with the
14
+ * PRISM_EXCLUDE_SERIALIZATION define. */
15
+ #ifndef PRISM_EXCLUDE_SERIALIZATION
16
+
17
+ /*
18
+ * Serialize the given list of offsets to the given buffer.
19
+ */
20
+ void pm_serialize_line_offset_list(pm_line_offset_list_t *list, pm_buffer_t *buffer);
21
+
22
+ /*
23
+ * Serialize the given list of comments to the given buffer.
24
+ */
25
+ void pm_serialize_comment_list(pm_list_t *list, pm_buffer_t *buffer);
26
+
27
+ /*
28
+ * Serialize the name of the encoding to the buffer.
29
+ */
30
+ void pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer);
31
+
32
+ /*
33
+ * Serialize the encoding, metadata, nodes, and constant pool.
34
+ */
35
+ void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
36
+
37
+ #endif
38
+
39
+ #endif
@@ -0,0 +1,72 @@
1
+ #ifndef PRISM_INTERNAL_SOURCE_H
2
+ #define PRISM_INTERNAL_SOURCE_H
3
+
4
+ #include "prism/source.h"
5
+ #include "prism/buffer.h"
6
+
7
+ #include <stdbool.h>
8
+
9
+ /*
10
+ * The type of source, which determines cleanup behavior.
11
+ */
12
+ typedef enum {
13
+ /* Wraps existing constant memory, no cleanup. */
14
+ PM_SOURCE_CONSTANT,
15
+
16
+ /* Wraps existing shared memory (non-owning slice), no cleanup. */
17
+ PM_SOURCE_SHARED,
18
+
19
+ /* Owns a heap-allocated buffer, freed on cleanup. */
20
+ PM_SOURCE_OWNED,
21
+
22
+ /* Memory-mapped file, unmapped on cleanup. */
23
+ PM_SOURCE_MAPPED,
24
+
25
+ /* Stream source backed by a pm_buffer_t. */
26
+ PM_SOURCE_STREAM
27
+ } pm_source_type_t;
28
+
29
+ /*
30
+ * The internal representation of a source.
31
+ */
32
+ struct pm_source_t {
33
+ /* A pointer to the start of the source data. */
34
+ const uint8_t *source;
35
+
36
+ /* The length of the source data in bytes. */
37
+ size_t length;
38
+
39
+ /* The type of the source. */
40
+ pm_source_type_t type;
41
+
42
+ /* Stream-specific data, only used for PM_SOURCE_STREAM sources. */
43
+ struct {
44
+ /* The buffer that holds the accumulated stream data. */
45
+ pm_buffer_t *buffer;
46
+
47
+ /* The stream object to read from. */
48
+ void *stream;
49
+
50
+ /* The function to use to read from the stream. */
51
+ pm_source_stream_fgets_t *fgets;
52
+
53
+ /* The function to use to check if the stream is at EOF. */
54
+ pm_source_stream_feof_t *feof;
55
+
56
+ /* Whether the stream has reached EOF. */
57
+ bool eof;
58
+ } stream;
59
+ };
60
+
61
+ /*
62
+ * Read from a stream into the source's internal buffer. This is used by
63
+ * pm_parse_stream to incrementally read the source.
64
+ */
65
+ bool pm_source_stream_read(pm_source_t *source);
66
+
67
+ /*
68
+ * Returns whether the stream source has reached EOF.
69
+ */
70
+ bool pm_source_stream_eof(const pm_source_t *source);
71
+
72
+ #endif
@@ -0,0 +1,60 @@
1
+ #ifndef PRISM_INTERNAL_STATIC_LITERALS_H
2
+ #define PRISM_INTERNAL_STATIC_LITERALS_H
3
+
4
+ #include "prism/ast.h"
5
+ #include "prism/buffer.h"
6
+ #include "prism/parser.h"
7
+
8
+ /*
9
+ * Certain sets of nodes (hash keys and when clauses) check for duplicate nodes
10
+ * to alert the user of potential issues. To do this, we keep a set of the nodes
11
+ * that have been seen so far, and compare whenever we find a new node.
12
+ */
13
+ typedef struct {
14
+ /* The node stored in this slot, or NULL if the slot is empty. */
15
+ pm_node_t *node;
16
+
17
+ /* The hash of the node, kept so that it is never recomputed. */
18
+ uint64_t hash;
19
+ } pm_static_literals_entry_t;
20
+
21
+ /*
22
+ * The number of nodes a set holds directly before it moves them into a hash
23
+ * table. Most sets are this small, so they are searched linearly without
24
+ * hashing their nodes or allocating any memory.
25
+ */
26
+ #define PM_STATIC_LITERALS_INLINE_CAPACITY 4
27
+
28
+ typedef struct {
29
+ /*
30
+ * The nodes in the set while it has no hash table. Once the set outgrows
31
+ * this array, its nodes move into the hash table and this is unused.
32
+ */
33
+ pm_node_t *nodes[PM_STATIC_LITERALS_INLINE_CAPACITY];
34
+
35
+ /* The array of entries in the hash table, or NULL if there is none. */
36
+ pm_static_literals_entry_t *entries;
37
+
38
+ /* The number of nodes in the set. */
39
+ uint32_t size;
40
+
41
+ /* The number of entries allocated in the hash table, or 0 if there is none. */
42
+ uint32_t capacity;
43
+ } pm_static_literals_t;
44
+
45
+ /*
46
+ * Add a node to the set of static literals.
47
+ */
48
+ pm_node_t * pm_static_literals_add(const pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node, bool replace);
49
+
50
+ /*
51
+ * Free the internal memory associated with the given static literals set.
52
+ */
53
+ void pm_static_literals_free(pm_static_literals_t *literals);
54
+
55
+ /*
56
+ * Create a string-based representation of the given static literal.
57
+ */
58
+ void pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node);
59
+
60
+ #endif
@@ -0,0 +1,30 @@
1
+ #ifndef PRISM_INTERNAL_STRINGY_H
2
+ #define PRISM_INTERNAL_STRINGY_H
3
+
4
+ #include "prism/stringy.h"
5
+
6
+ /*
7
+ * Backing storage for an empty string.
8
+ */
9
+ static const uint8_t empty_source[] = "";
10
+
11
+ /*
12
+ * Defines an empty string. This is useful for initializing a string that will
13
+ * be filled in later.
14
+ */
15
+ #define PM_STRING_EMPTY ((pm_string_t) { .source = empty_source, .length = 0 })
16
+
17
+ /*
18
+ * Initialize a shared string that is based on initial input.
19
+ */
20
+ void pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end);
21
+
22
+ /*
23
+ * Compare the underlying lengths and bytes of two strings. Returns 0 if the
24
+ * strings are equal, a negative number if the left string is less than the
25
+ * right string, and a positive number if the left string is greater than the
26
+ * right string.
27
+ */
28
+ int pm_string_compare(const pm_string_t *left, const pm_string_t *right);
29
+
30
+ #endif
@@ -1,18 +1,10 @@
1
- /**
2
- * @file pm_strncasecmp.h
3
- *
4
- * A custom strncasecmp implementation.
5
- */
6
- #ifndef PRISM_STRNCASECMP_H
7
- #define PRISM_STRNCASECMP_H
1
+ #ifndef PRISM_INTERNAL_STRNCASECMP_H
2
+ #define PRISM_INTERNAL_STRNCASECMP_H
8
3
 
9
- #include "prism/defines.h"
10
-
11
- #include <ctype.h>
12
4
  #include <stddef.h>
13
5
  #include <stdint.h>
14
6
 
15
- /**
7
+ /*
16
8
  * Compare two strings, ignoring case, up to the given length. Returns 0 if the
17
9
  * strings are equal, a negative number if string1 is less than string2, or a
18
10
  * positive number if string1 is greater than string2.
@@ -20,12 +12,6 @@
20
12
  * Note that this is effectively our own implementation of strncasecmp, but it's
21
13
  * not available on all of the platforms we want to support so we're rolling it
22
14
  * here.
23
- *
24
- * @param string1 The first string to compare.
25
- * @param string2 The second string to compare
26
- * @param length The maximum number of characters to compare.
27
- * @return 0 if the strings are equal, a negative number if string1 is less than
28
- * string2, or a positive number if string1 is greater than string2.
29
15
  */
30
16
  int pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length);
31
17
 
@@ -1,19 +1,15 @@
1
- /**
2
- * @file pm_strpbrk.h
3
- *
4
- * A custom strpbrk implementation.
5
- */
6
- #ifndef PRISM_STRPBRK_H
7
- #define PRISM_STRPBRK_H
1
+ #ifndef PRISM_INTERNAL_STRPBRK_H
2
+ #define PRISM_INTERNAL_STRPBRK_H
8
3
 
9
- #include "prism/defines.h"
10
- #include "prism/diagnostic.h"
11
4
  #include "prism/parser.h"
12
5
 
6
+ /* The maximum number of bytes in a strpbrk charset. */
7
+ #define PM_STRPBRK_CACHE_SIZE 16
8
+
13
9
  #include <stddef.h>
14
- #include <string.h>
10
+ #include <stdint.h>
15
11
 
16
- /**
12
+ /*
17
13
  * Here we have rolled our own version of strpbrk. The standard library strpbrk
18
14
  * has undefined behavior when the source string is not null-terminated. We want
19
15
  * to support strings that are not null-terminated because pm_parse does not
@@ -31,15 +27,6 @@
31
27
  * characters that are trailing bytes of multi-byte characters. For example, in
32
28
  * Shift-JIS, the backslash character can be a trailing byte. In that case we
33
29
  * need to take a slower path and iterate one multi-byte character at a time.
34
- *
35
- * @param parser The parser.
36
- * @param source The source to search.
37
- * @param charset The charset to search for.
38
- * @param length The maximum number of bytes to search.
39
- * @param validate Whether to validate that the source string is valid in the
40
- * current encoding of the parser.
41
- * @return A pointer to the first character in the source string that is in the
42
- * charset, or NULL if no such character exists.
43
30
  */
44
31
  const uint8_t * pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length, bool validate);
45
32
 
@@ -0,0 +1,11 @@
1
+ #ifndef PRISM_INTERNAL_TOKENS_H
2
+ #define PRISM_INTERNAL_TOKENS_H
3
+
4
+ #include "prism/ast.h"
5
+
6
+ /*
7
+ * Returns the human name of the given token type.
8
+ */
9
+ const char * pm_token_str(pm_token_type_t token_type);
10
+
11
+ #endif
@@ -0,0 +1,16 @@
1
+ #ifndef PRISM_INTERNAL_XXH3_H
2
+ #define PRISM_INTERNAL_XXH3_H
3
+
4
+ #include <stddef.h>
5
+ #include <stdint.h>
6
+
7
+ /**
8
+ * Computes the XXH3 digest of the given input.
9
+ *
10
+ * @param input The input data to hash.
11
+ * @param length The length of the input data.
12
+ * @return The 64-bit XXH3 hash of the input data.
13
+ */
14
+ uint64_t pm_xxh3(const uint8_t *input, size_t length);
15
+
16
+ #endif
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @file json.h
3
+ */
4
+ #ifndef PRISM_JSON_H
5
+ #define PRISM_JSON_H
6
+
7
+ #include "prism/excludes.h"
8
+
9
+ /* We optionally support dumping to JSON. For systems that don't want or need
10
+ * this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
11
+ */
12
+ #ifndef PRISM_EXCLUDE_JSON
13
+
14
+ #include "prism/compiler/exported.h"
15
+ #include "prism/compiler/nonnull.h"
16
+
17
+ #include "prism/ast.h"
18
+ #include "prism/buffer.h"
19
+ #include "prism/parser.h"
20
+
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
25
+ /**
26
+ * Dump JSON to the given buffer.
27
+ *
28
+ * @param buffer The buffer to serialize to.
29
+ * @param parser The parser that parsed the node.
30
+ * @param node The node to serialize.
31
+ */
32
+ PRISM_EXPORTED_FUNCTION void pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node) PRISM_NONNULL(1, 2, 3);
33
+
34
+ #ifdef __cplusplus
35
+ }
36
+ #endif
37
+
38
+ #endif
39
+
40
+ #endif
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @file line_offset_list.h
3
+ *
4
+ * A list of byte offsets of newlines in a string.
5
+ *
6
+ * When compiling the syntax tree, it's necessary to know the line and column
7
+ * of many nodes. This is necessary to support things like error messages,
8
+ * tracepoints, etc.
9
+ *
10
+ * It's possible that we could store the start line, start column, end line, and
11
+ * end column on every node in addition to the offsets that we already store,
12
+ * but that would be quite a lot of memory overhead.
13
+ */
14
+ #ifndef PRISM_LINE_OFFSET_LIST_H
15
+ #define PRISM_LINE_OFFSET_LIST_H
16
+
17
+ #include "prism/compiler/exported.h"
18
+ #include "prism/compiler/nonnull.h"
19
+
20
+ #include <stddef.h>
21
+ #include <stdint.h>
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ /**
28
+ * A list of offsets of the start of lines in a string. The offsets are assumed
29
+ * to be sorted/inserted in ascending order.
30
+ */
31
+ typedef struct {
32
+ /** The number of offsets in the list. */
33
+ size_t size;
34
+
35
+ /** The capacity of the list that has been allocated. */
36
+ size_t capacity;
37
+
38
+ /** The list of offsets. */
39
+ uint32_t *offsets;
40
+ } pm_line_offset_list_t;
41
+
42
+ /**
43
+ * A line and column in a string.
44
+ */
45
+ typedef struct {
46
+ /** The line number. */
47
+ int32_t line;
48
+
49
+ /** The column in bytes. */
50
+ uint32_t column;
51
+ } pm_line_column_t;
52
+
53
+ /**
54
+ * Returns the line and column of the given offset. If the offset is not in the
55
+ * list, the line and column of the closest offset less than the given offset
56
+ * are returned.
57
+ *
58
+ * @param list The list to search.
59
+ * @param cursor The offset to search for.
60
+ * @param start_line The line to start counting from.
61
+ * @returns The line and column of the given offset.
62
+ */
63
+ PRISM_EXPORTED_FUNCTION pm_line_column_t pm_line_offset_list_line_column(const pm_line_offset_list_t *list, uint32_t cursor, int32_t start_line) PRISM_NONNULL(1);
64
+
65
+ #ifdef __cplusplus
66
+ }
67
+ #endif
68
+
69
+ #endif
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file magic_comments.h
3
+ *
4
+ * Types and functions related to magic comments found during parsing.
5
+ */
6
+ #ifndef PRISM_MAGIC_COMMENTS_H
7
+ #define PRISM_MAGIC_COMMENTS_H
8
+
9
+ #include "prism/compiler/exported.h"
10
+ #include "prism/compiler/nonnull.h"
11
+
12
+ #include "prism/ast.h"
13
+
14
+ #include <stddef.h>
15
+
16
+ #ifdef __cplusplus
17
+ extern "C" {
18
+ #endif
19
+
20
+ /** An opaque pointer to a magic comment found while parsing. */
21
+ typedef struct pm_magic_comment_t pm_magic_comment_t;
22
+
23
+ /**
24
+ * Returns the location of the key associated with the given magic comment.
25
+ *
26
+ * @param magic_comment the magic comment whose key location we want to get
27
+ * @returns the location of the key associated with the given magic comment
28
+ */
29
+ PRISM_EXPORTED_FUNCTION pm_location_t pm_magic_comment_key(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1);
30
+
31
+ /**
32
+ * Returns the location of the value associated with the given magic comment.
33
+ *
34
+ * @param magic_comment the magic comment whose value location we want to get
35
+ * @returns the location of the value associated with the given magic comment
36
+ */
37
+ PRISM_EXPORTED_FUNCTION pm_location_t pm_magic_comment_value(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1);
38
+
39
+ /**
40
+ * Returns the magic comment that follows the given magic comment among the
41
+ * magic comments associated with the parser that found it.
42
+ *
43
+ * @param magic_comment the magic comment whose successor we want to get
44
+ * @returns the next magic comment, or NULL if the given magic comment is the
45
+ * last one
46
+ */
47
+ PRISM_EXPORTED_FUNCTION const pm_magic_comment_t * pm_magic_comment_next(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1);
48
+
49
+ #ifdef __cplusplus
50
+ }
51
+ #endif
52
+
53
+ #endif
@@ -6,9 +6,14 @@
6
6
  #ifndef PRISM_NODE_H
7
7
  #define PRISM_NODE_H
8
8
 
9
- #include "prism/defines.h"
10
- #include "prism/parser.h"
11
- #include "prism/util/pm_buffer.h"
9
+ #include "prism/compiler/exported.h"
10
+ #include "prism/compiler/nonnull.h"
11
+
12
+ #include "prism/ast.h"
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
12
17
 
13
18
  /**
14
19
  * Loop through each node in the node list, writing each node to the given
@@ -18,93 +23,90 @@
18
23
  for (size_t index = 0; index < (list)->size && ((node) = (list)->nodes[index]); index++)
19
24
 
20
25
  /**
21
- * Append a new node onto the end of the node list.
26
+ * Append a node to the end of a node list. If the list is full, its storage is
27
+ * grown by allocating from the given arena, so the arena must live as long as
28
+ * the list does. For a list in a parsed tree, that is the arena that was passed
29
+ * to pm_parser_new.
22
30
  *
31
+ * @param arena The arena to allocate the list's storage from.
23
32
  * @param list The list to append to.
24
33
  * @param node The node to append.
25
34
  */
26
- void pm_node_list_append(pm_node_list_t *list, pm_node_t *node);
35
+ PRISM_EXPORTED_FUNCTION void pm_node_list_append(pm_arena_t *arena, pm_node_list_t *list, pm_node_t *node) PRISM_NONNULL(1, 2, 3);
27
36
 
28
37
  /**
29
- * Prepend a new node onto the beginning of the node list.
38
+ * Returns a string representation of the given node type.
30
39
  *
31
- * @param list The list to prepend to.
32
- * @param node The node to prepend.
40
+ * @param node_type The node type to convert to a string.
41
+ * @returns A string representation of the given node type.
33
42
  */
34
- void pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node);
43
+ PRISM_EXPORTED_FUNCTION const char * pm_node_type(pm_node_type_t node_type);
35
44
 
36
45
  /**
37
- * Concatenate the given node list onto the end of the other node list.
38
- *
39
- * @param list The list to concatenate onto.
40
- * @param other The list to concatenate.
46
+ * The value returned by a visitor callback, which determines where the walk
47
+ * goes next.
41
48
  */
42
- void pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other);
49
+ typedef enum {
50
+ /** Continue the walk without visiting this node's children. */
51
+ PM_VISIT_SKIP,
43
52
 
44
- /**
45
- * Free the internal memory associated with the given node list.
46
- *
47
- * @param list The list to free.
48
- */
49
- void pm_node_list_free(pm_node_list_t *list);
53
+ /** Continue the walk by visiting this node's children. */
54
+ PM_VISIT_DESCEND,
50
55
 
51
- /**
52
- * Deallocate a node and all of its children.
53
- *
54
- * @param parser The parser that owns the node.
55
- * @param node The node to deallocate.
56
- */
57
- PRISM_EXPORTED_FUNCTION void pm_node_destroy(pm_parser_t *parser, struct pm_node *node);
56
+ /** End the walk without visiting any more nodes. */
57
+ PM_VISIT_STOP
58
+ } pm_visit_result_t;
58
59
 
59
60
  /**
60
- * Returns a string representation of the given node type.
61
- *
62
- * @param node_type The node type to convert to a string.
63
- * @return A string representation of the given node type.
61
+ * A callback that is called for each node visited by pm_visit_node and
62
+ * pm_visit_child_nodes. The data parameter is the opaque pointer that was
63
+ * passed to the function that started the walk.
64
64
  */
65
- PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_type);
65
+ typedef pm_visit_result_t (*pm_visit_callback_t)(const pm_node_t *node, void *data);
66
66
 
67
67
  /**
68
68
  * Visit each of the nodes in this subtree using the given visitor callback. The
69
- * callback function will be called for each node in the subtree. If it returns
70
- * false, then that node's children will not be visited. If it returns true,
71
- * then the children will be visited. The data parameter is treated as an opaque
72
- * pointer and is passed to the visitor callback for consumers to use as they
73
- * see fit.
69
+ * callback function will be called for each node in the subtree, and its
70
+ * return value determines whether the walk visits that node's children, skips
71
+ * them, or stops entirely. The data parameter is treated as an opaque pointer
72
+ * and is passed to the visitor callback for consumers to use as they see fit.
74
73
  *
75
74
  * As an example:
76
75
  *
77
76
  * ```c
78
77
  * #include "prism.h"
79
78
  *
80
- * bool visit(const pm_node_t *node, void *data) {
79
+ * pm_visit_result_t visit(const pm_node_t *node, void *data) {
81
80
  * size_t *indent = (size_t *) data;
82
81
  * for (size_t i = 0; i < *indent * 2; i++) putc(' ', stdout);
83
- * printf("%s\n", pm_node_type_to_str(node->type));
82
+ * printf("%s\n", pm_node_type(node->type));
84
83
  *
85
84
  * size_t next_indent = *indent + 1;
86
85
  * size_t *next_data = &next_indent;
87
86
  * pm_visit_child_nodes(node, visit, next_data);
88
87
  *
89
- * return false;
88
+ * return PM_VISIT_SKIP;
90
89
  * }
91
90
  *
92
91
  * int main(void) {
93
92
  * const char *source = "1 + 2; 3 + 4";
94
93
  * size_t size = strlen(source);
95
94
  *
96
- * pm_parser_t parser;
97
- * pm_options_t options = { 0 };
98
- * pm_parser_init(&parser, (const uint8_t *) source, size, &options);
95
+ * pm_arena_t *arena = pm_arena_new();
96
+ * pm_options_t *options = pm_options_new();
97
+ *
98
+ * pm_parser_t *parser = pm_parser_new(arena, (const uint8_t *) source, size, options);
99
99
  *
100
100
  * size_t indent = 0;
101
- * pm_node_t *node = pm_parse(&parser);
101
+ * pm_node_t *node = pm_parse(parser);
102
102
  *
103
103
  * size_t *data = &indent;
104
104
  * pm_visit_node(node, visit, data);
105
105
  *
106
- * pm_node_destroy(&parser, node);
107
- * pm_parser_free(&parser);
106
+ * pm_parser_free(parser);
107
+ * pm_options_free(options);
108
+ * pm_arena_free(arena);
109
+ *
108
110
  * return EXIT_SUCCESS;
109
111
  * }
110
112
  * ```
@@ -112,18 +114,26 @@ PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_typ
112
114
  * @param node The root node to start visiting from.
113
115
  * @param visitor The callback to call for each node in the subtree.
114
116
  * @param data An opaque pointer that is passed to the visitor callback.
117
+ * @returns false if the visitor stopped the walk by returning PM_VISIT_STOP,
118
+ * true otherwise.
115
119
  */
116
- PRISM_EXPORTED_FUNCTION void pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);
120
+ PRISM_EXPORTED_FUNCTION bool pm_visit_node(const pm_node_t *node, pm_visit_callback_t visitor, void *data) PRISM_NONNULL(1);
117
121
 
118
122
  /**
119
123
  * Visit the children of the given node with the given callback. This is the
120
124
  * default behavior for walking the tree that is called from pm_visit_node if
121
- * the callback returns true.
125
+ * the callback returns PM_VISIT_DESCEND.
122
126
  *
123
127
  * @param node The node to visit the children of.
124
128
  * @param visitor The callback to call for each child node.
125
129
  * @param data An opaque pointer that is passed to the visitor callback.
130
+ * @returns false if the visitor stopped the walk by returning PM_VISIT_STOP,
131
+ * true otherwise.
126
132
  */
127
- PRISM_EXPORTED_FUNCTION void pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);
133
+ PRISM_EXPORTED_FUNCTION bool pm_visit_child_nodes(const pm_node_t *node, pm_visit_callback_t visitor, void *data) PRISM_NONNULL(1);
134
+
135
+ #ifdef __cplusplus
136
+ }
137
+ #endif
128
138
 
129
139
  #endif