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
@@ -1,12 +1,12 @@
1
- #include <string.h>
2
-
3
1
  #include "prism/ast.h"
4
2
 
3
+ #include <assert.h>
4
+
5
5
  /**
6
6
  * Returns a string representation of the given token type.
7
7
  */
8
- PRISM_EXPORTED_FUNCTION const char *
9
- pm_token_type_name(pm_token_type_t token_type) {
8
+ const char *
9
+ pm_token_type(pm_token_type_t token_type) {
10
10
  switch (token_type) {
11
11
  <%- tokens.each do |token| -%>
12
12
  case PM_TOKEN_<%= token.name %>:
@@ -27,14 +27,10 @@ pm_token_type_name(pm_token_type_t token_type) {
27
27
  * Returns the human name of the given token type.
28
28
  */
29
29
  const char *
30
- pm_token_type_human(pm_token_type_t token_type) {
30
+ pm_token_str(pm_token_type_t token_type) {
31
31
  switch (token_type) {
32
32
  case PM_TOKEN_EOF:
33
33
  return "end-of-input";
34
- case PM_TOKEN_MISSING:
35
- return "missing token";
36
- case PM_TOKEN_NOT_PROVIDED:
37
- return "not provided token";
38
34
  case PM_TOKEN_AMPERSAND:
39
35
  return "'&'";
40
36
  case PM_TOKEN_AMPERSAND_AMPERSAND:
@@ -57,6 +53,10 @@ pm_token_type_human(pm_token_type_t token_type) {
57
53
  return "'!~'";
58
54
  case PM_TOKEN_BRACE_LEFT:
59
55
  return "'{'";
56
+ case PM_TOKEN_BRACE_LEFT_ARGUMENT:
57
+ return "'{'";
58
+ case PM_TOKEN_BRACE_LEFT_HASH:
59
+ return "'{'";
60
60
  case PM_TOKEN_BRACE_RIGHT:
61
61
  return "'}'";
62
62
  case PM_TOKEN_BRACKET_LEFT:
@@ -171,6 +171,10 @@ pm_token_type_human(pm_token_type_t token_type) {
171
171
  return "'defined?'";
172
172
  case PM_TOKEN_KEYWORD_DO:
173
173
  return "'do'";
174
+ case PM_TOKEN_KEYWORD_DO_BLOCK:
175
+ return "'do'";
176
+ case PM_TOKEN_KEYWORD_DO_LAMBDA:
177
+ return "'do'";
174
178
  case PM_TOKEN_KEYWORD_DO_LOOP:
175
179
  return "'do'";
176
180
  case PM_TOKEN_KEYWORD_ELSE:
@@ -271,10 +275,14 @@ pm_token_type_human(pm_token_type_t token_type) {
271
275
  return "'->'";
272
276
  case PM_TOKEN_NEWLINE:
273
277
  return "newline";
278
+ case PM_TOKEN_NEWLINE_TERMINATOR:
279
+ return "newline";
274
280
  case PM_TOKEN_NUMBERED_REFERENCE:
275
281
  return "numbered reference";
276
282
  case PM_TOKEN_PARENTHESIS_LEFT:
277
283
  return "'('";
284
+ case PM_TOKEN_PARENTHESIS_LEFT_GROUPING:
285
+ return "'('";
278
286
  case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES:
279
287
  return "'('";
280
288
  case PM_TOKEN_PARENTHESIS_RIGHT:
@@ -354,7 +362,10 @@ pm_token_type_human(pm_token_type_t token_type) {
354
362
  case PM_TOKEN_USTAR_STAR:
355
363
  return "**";
356
364
  case PM_TOKEN_WORDS_SEP:
365
+ case PM_TOKEN_WORDS_SEP_IMPLICIT:
357
366
  return "string separator";
367
+ case PM_TOKEN_XSTRING_BEGIN:
368
+ return "backtick string literal";
358
369
  case PM_TOKEN___END__:
359
370
  return "'__END__'";
360
371
  case PM_TOKEN_MAXIMUM:
@@ -362,8 +373,8 @@ pm_token_type_human(pm_token_type_t token_type) {
362
373
  return "";
363
374
  }
364
375
 
365
- // Provide a default, because some compilers can't determine that the above
366
- // switch is exhaustive.
376
+ /* Provide a default, because some compilers cannot determine that the above
377
+ * switch is exhaustive. */
367
378
  assert(false && "unreachable");
368
379
  return "";
369
380
  }
@@ -6,17 +6,22 @@ require "fileutils"
6
6
  require "yaml"
7
7
 
8
8
  module Prism
9
- module Template
9
+ module Template # :nodoc: all
10
10
  SERIALIZE_ONLY_SEMANTICS_FIELDS = ENV.fetch("PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS", false)
11
- REMOVE_ON_ERROR_TYPES = SERIALIZE_ONLY_SEMANTICS_FIELDS
12
11
  CHECK_FIELD_KIND = ENV.fetch("CHECK_FIELD_KIND", false)
13
12
 
14
- JAVA_BACKEND = ENV["PRISM_JAVA_BACKEND"] || "truffleruby"
15
- JAVA_STRING_TYPE = JAVA_BACKEND == "jruby" ? "org.jruby.RubySymbol" : "String"
13
+ JAVA_BACKEND = ENV["PRISM_JAVA_BACKEND"] || "default"
14
+ JAVA_IDENTIFIER_TYPE = JAVA_BACKEND == "truffleruby" ? "String" : "byte[]"
16
15
  INCLUDE_NODE_ID = !SERIALIZE_ONLY_SEMANTICS_FIELDS || JAVA_BACKEND == "jruby"
17
16
 
18
17
  COMMON_FLAGS_COUNT = 2
19
18
 
19
+ # The byte that precedes the child subtrees of a node with a lazy field in
20
+ # the serialized output (see NodeType#lazy_field). Node types are serialized
21
+ # as 1 through the number of node types and 0 marks an absent optional node,
22
+ # so this must be greater than the number of node types.
23
+ LAZY_MARKER = 0xFF
24
+
20
25
  class Error
21
26
  attr_reader :name
22
27
 
@@ -49,6 +54,14 @@ module Prism
49
54
  end
50
55
  end
51
56
 
57
+ # This module contains methods for escaping characters in Doxygen comments.
58
+ module Doxygen
59
+ # Similar to /verbatim ... /endverbatim but doesn't wrap the result in a code block.
60
+ def self.verbatim(value)
61
+ value.gsub(/[*%!`#<>_+@-]/, '\\\\\0')
62
+ end
63
+ end
64
+
52
65
  # A comment attached to a field or node.
53
66
  class ConfigComment
54
67
  attr_reader :value
@@ -61,6 +74,41 @@ module Prism
61
74
  value.each_line { |line| yield line.prepend(" ").rstrip }
62
75
  end
63
76
 
77
+ def each_rdoc_line(&block)
78
+ code_block = false
79
+ code = +""
80
+ value.each_line do |line|
81
+ # Wrap code in explicit language fences so there is syntax highlighting
82
+ if line.start_with?(" ") && !code_block
83
+ code_block = true
84
+ yield " ```rb"
85
+ elsif !line.strip.empty? && !line.start_with?(" ") && code_block
86
+ code_block = false
87
+ rdoc_close_codeblock(code, &block)
88
+ code = +""
89
+ end
90
+
91
+ if code_block
92
+ line = line.delete_prefix(" ")
93
+ code << line
94
+ end
95
+ yield line.prepend(" ").rstrip
96
+ end
97
+
98
+ # Close trailing blocks
99
+ rdoc_close_codeblock(code, &block) if code_block
100
+ end
101
+
102
+ def rdoc_close_codeblock(code, &block)
103
+ yield " ```"
104
+ return if code.strip.empty?
105
+
106
+ code.gsub!(/^[\s^]*$/, "") # clear marker lines
107
+ encoded = [code].pack("m0").tr("+/", "-_").delete("=") # base64 urlsafe
108
+ yield ""
109
+ yield " [Explore code sample](https://ruby.github.io/prism/playground.html##{encoded})"
110
+ end
111
+
64
112
  def each_java_line(&block)
65
113
  ConfigComment.new(JavaDoc.escape(value)).each_line(&block)
66
114
  end
@@ -81,6 +129,10 @@ module Prism
81
129
  ConfigComment.new(comment).each_line(&block) if comment
82
130
  end
83
131
 
132
+ def each_comment_rdoc_line(&block)
133
+ ConfigComment.new(comment).each_rdoc_line(&block) if comment
134
+ end
135
+
84
136
  def each_comment_java_line(&block)
85
137
  ConfigComment.new(comment).each_java_line(&block) if comment
86
138
  end
@@ -97,6 +149,11 @@ module Prism
97
149
  # Some node fields can be specialized if they point to a specific kind of
98
150
  # node and not just a generic node.
99
151
  class NodeKindField < Field
152
+ # The C type to use for this field as a function parameter.
153
+ def c_param
154
+ "struct #{c_type} *#{name}"
155
+ end
156
+
100
157
  def initialize(kind:, **options)
101
158
  @kind = kind
102
159
  super(**options)
@@ -142,27 +199,27 @@ module Prism
142
199
  if specific_kind
143
200
  specific_kind
144
201
  elsif union_kind
145
- union_kind.join(" | ")
202
+ "(#{union_kind.join(" | ")})"
146
203
  else
147
204
  "Prism::node"
148
205
  end
149
206
  end
150
207
 
151
- def rbi_class
208
+ def call_seq_type
152
209
  if specific_kind
153
- "Prism::#{specific_kind}"
210
+ specific_kind
154
211
  elsif union_kind
155
- "T.any(#{union_kind.map { |kind| "Prism::#{kind}" }.join(", ")})"
212
+ union_kind.join(" | ")
156
213
  else
157
- "Prism::Node"
214
+ "Node"
158
215
  end
159
216
  end
160
217
 
161
218
  def check_field_kind
162
219
  if union_kind
163
- "[#{union_kind.join(', ')}].include?(#{name}.class)"
220
+ "[#{union_kind.join(', ')}, ErrorRecoveryNode].include?(#{name}.class)"
164
221
  else
165
- "#{name}.is_a?(#{ruby_type})"
222
+ "#{name}.is_a?(#{ruby_type}) || #{name}.is_a?(ErrorRecoveryNode)"
166
223
  end
167
224
  end
168
225
  end
@@ -174,27 +231,27 @@ module Prism
174
231
  if specific_kind
175
232
  "#{specific_kind}?"
176
233
  elsif union_kind
177
- [*union_kind, "nil"].join(" | ")
234
+ "(#{union_kind.join(" | ")})?"
178
235
  else
179
236
  "Prism::node?"
180
237
  end
181
238
  end
182
239
 
183
- def rbi_class
240
+ def call_seq_type
184
241
  if specific_kind
185
- "T.nilable(Prism::#{specific_kind})"
242
+ "#{specific_kind} | nil"
186
243
  elsif union_kind
187
- "T.nilable(T.any(#{union_kind.map { |kind| "Prism::#{kind}" }.join(", ")}))"
244
+ [*union_kind, "nil"].join(" | ")
188
245
  else
189
- "T.nilable(Prism::Node)"
246
+ "Node | nil"
190
247
  end
191
248
  end
192
249
 
193
250
  def check_field_kind
194
251
  if union_kind
195
- "[#{union_kind.join(', ')}, NilClass].include?(#{name}.class)"
252
+ "[#{union_kind.join(', ')}, ErrorRecoveryNode, NilClass].include?(#{name}.class)"
196
253
  else
197
- "#{name}.nil? || #{name}.is_a?(#{ruby_type})"
254
+ "#{name}.nil? || #{name}.is_a?(#{ruby_type}) || #{name}.is_a?(ErrorRecoveryNode)"
198
255
  end
199
256
  end
200
257
  end
@@ -202,23 +259,31 @@ module Prism
202
259
  # This represents a field on a node that is a list of nodes. We pass them as
203
260
  # references and store them directly on the struct.
204
261
  class NodeListField < NodeKindField
205
- def rbs_class
262
+ def c_param
263
+ "pm_node_list_t #{name}"
264
+ end
265
+
266
+ def element_rbs_class
206
267
  if specific_kind
207
- "Array[#{specific_kind}]"
268
+ "#{specific_kind}"
208
269
  elsif union_kind
209
- "Array[#{union_kind.join(" | ")}]"
270
+ "#{union_kind.join(" | ")}"
210
271
  else
211
- "Array[Prism::node]"
272
+ "Prism::node"
212
273
  end
213
274
  end
214
275
 
215
- def rbi_class
276
+ def rbs_class
277
+ "Array[#{element_rbs_class}]"
278
+ end
279
+
280
+ def call_seq_type
216
281
  if specific_kind
217
- "T::Array[Prism::#{specific_kind}]"
282
+ "Array[#{specific_kind}]"
218
283
  elsif union_kind
219
- "T::Array[T.any(#{union_kind.map { |kind| "Prism::#{kind}" }.join(", ")})]"
284
+ "Array[#{union_kind.join(" | ")}]"
220
285
  else
221
- "T::Array[Prism::Node]"
286
+ "Array[Node]"
222
287
  end
223
288
  end
224
289
 
@@ -228,9 +293,9 @@ module Prism
228
293
 
229
294
  def check_field_kind
230
295
  if union_kind
231
- "#{name}.all? { |n| [#{union_kind.join(', ')}].include?(n.class) }"
296
+ "#{name}.all? { |n| [#{union_kind.join(', ')}, ErrorRecoveryNode].include?(n.class) }"
232
297
  else
233
- "#{name}.all? { |n| n.is_a?(#{ruby_type}) }"
298
+ "#{name}.all? { |n| n.is_a?(#{ruby_type}) || n.is_a?(ErrorRecoveryNode) }"
234
299
  end
235
300
  end
236
301
  end
@@ -238,58 +303,74 @@ module Prism
238
303
  # This represents a field on a node that is the ID of a string interned
239
304
  # through the parser's constant pool.
240
305
  class ConstantField < Field
306
+ def c_param
307
+ "pm_constant_id_t #{name}"
308
+ end
309
+
241
310
  def rbs_class
242
311
  "Symbol"
243
312
  end
244
313
 
245
- def rbi_class
314
+ def call_seq_type
246
315
  "Symbol"
247
316
  end
248
317
 
249
318
  def java_type
250
- JAVA_STRING_TYPE
319
+ JAVA_IDENTIFIER_TYPE
251
320
  end
252
321
  end
253
322
 
254
323
  # This represents a field on a node that is the ID of a string interned
255
324
  # through the parser's constant pool and can be optionally null.
256
325
  class OptionalConstantField < Field
326
+ def c_param
327
+ "pm_constant_id_t #{name}"
328
+ end
329
+
257
330
  def rbs_class
258
331
  "Symbol?"
259
332
  end
260
333
 
261
- def rbi_class
262
- "T.nilable(Symbol)"
334
+ def call_seq_type
335
+ "Symbol | nil"
263
336
  end
264
337
 
265
338
  def java_type
266
- JAVA_STRING_TYPE
339
+ JAVA_IDENTIFIER_TYPE
267
340
  end
268
341
  end
269
342
 
270
343
  # This represents a field on a node that is a list of IDs that are associated
271
344
  # with strings interned through the parser's constant pool.
272
345
  class ConstantListField < Field
346
+ def c_param
347
+ "pm_constant_id_list_t #{name}"
348
+ end
349
+
273
350
  def rbs_class
274
351
  "Array[Symbol]"
275
352
  end
276
353
 
277
- def rbi_class
278
- "T::Array[Symbol]"
354
+ def call_seq_type
355
+ "Array[Symbol]"
279
356
  end
280
357
 
281
358
  def java_type
282
- "#{JAVA_STRING_TYPE}[]"
359
+ "#{JAVA_IDENTIFIER_TYPE}[]"
283
360
  end
284
361
  end
285
362
 
286
363
  # This represents a field on a node that is a string.
287
364
  class StringField < Field
365
+ def c_param
366
+ "pm_string_t #{name}"
367
+ end
368
+
288
369
  def rbs_class
289
370
  "String"
290
371
  end
291
372
 
292
- def rbi_class
373
+ def call_seq_type
293
374
  "String"
294
375
  end
295
376
 
@@ -300,6 +381,10 @@ module Prism
300
381
 
301
382
  # This represents a field on a node that is a location.
302
383
  class LocationField < Field
384
+ def c_param
385
+ "pm_location_t #{name}"
386
+ end
387
+
303
388
  def semantic_field?
304
389
  false
305
390
  end
@@ -308,8 +393,8 @@ module Prism
308
393
  "Location"
309
394
  end
310
395
 
311
- def rbi_class
312
- "Prism::Location"
396
+ def call_seq_type
397
+ "Location"
313
398
  end
314
399
 
315
400
  def java_type
@@ -319,6 +404,10 @@ module Prism
319
404
 
320
405
  # This represents a field on a node that is a location that is optional.
321
406
  class OptionalLocationField < Field
407
+ def c_param
408
+ "pm_location_t #{name}"
409
+ end
410
+
322
411
  def semantic_field?
323
412
  false
324
413
  end
@@ -327,8 +416,8 @@ module Prism
327
416
  "Location?"
328
417
  end
329
418
 
330
- def rbi_class
331
- "T.nilable(Prism::Location)"
419
+ def call_seq_type
420
+ "Location | nil"
332
421
  end
333
422
 
334
423
  def java_type
@@ -338,11 +427,15 @@ module Prism
338
427
 
339
428
  # This represents an integer field.
340
429
  class UInt8Field < Field
430
+ def c_param
431
+ "uint8_t #{name}"
432
+ end
433
+
341
434
  def rbs_class
342
435
  "Integer"
343
436
  end
344
437
 
345
- def rbi_class
438
+ def call_seq_type
346
439
  "Integer"
347
440
  end
348
441
 
@@ -353,11 +446,15 @@ module Prism
353
446
 
354
447
  # This represents an integer field.
355
448
  class UInt32Field < Field
449
+ def c_param
450
+ "uint32_t #{name}"
451
+ end
452
+
356
453
  def rbs_class
357
454
  "Integer"
358
455
  end
359
456
 
360
- def rbi_class
457
+ def call_seq_type
361
458
  "Integer"
362
459
  end
363
460
 
@@ -369,11 +466,15 @@ module Prism
369
466
  # This represents an arbitrarily-sized integer. When it gets to Ruby it will
370
467
  # be an Integer.
371
468
  class IntegerField < Field
469
+ def c_param
470
+ "pm_integer_t #{name}"
471
+ end
472
+
372
473
  def rbs_class
373
474
  "Integer"
374
475
  end
375
476
 
376
- def rbi_class
477
+ def call_seq_type
377
478
  "Integer"
378
479
  end
379
480
 
@@ -385,11 +486,15 @@ module Prism
385
486
  # This represents a double-precision floating point number. When it gets to
386
487
  # Ruby it will be a Float.
387
488
  class DoubleField < Field
489
+ def c_param
490
+ "double #{name}"
491
+ end
492
+
388
493
  def rbs_class
389
494
  "Float"
390
495
  end
391
496
 
392
- def rbi_class
497
+ def call_seq_type
393
498
  "Float"
394
499
  end
395
500
 
@@ -432,9 +537,6 @@ module Prism
432
537
  when "pattern expression"
433
538
  # the list of all possible types is too long with 37+ different classes
434
539
  "Node"
435
- when Hash
436
- kind = kind.fetch("on error")
437
- REMOVE_ON_ERROR_TYPES ? nil : kind
438
540
  else
439
541
  kind
440
542
  end
@@ -462,6 +564,10 @@ module Prism
462
564
  ConfigComment.new(comment).each_line(&block)
463
565
  end
464
566
 
567
+ def each_comment_rdoc_line(&block)
568
+ ConfigComment.new(comment).each_rdoc_line(&block)
569
+ end
570
+
465
571
  def each_comment_java_line(&block)
466
572
  ConfigComment.new(comment).each_java_line(&block)
467
573
  end
@@ -470,10 +576,19 @@ module Prism
470
576
  @semantic_fields ||= @fields.select(&:semantic_field?)
471
577
  end
472
578
 
473
- # Should emit serialized length of node so implementations can skip
474
- # the node to enable lazy parsing.
475
- def needs_serialized_length?
476
- name == "DefNode"
579
+ # The fields that hold child nodes. In the serialized output, their
580
+ # subtrees are written in field order ahead of this node's own record.
581
+ def child_fields
582
+ @child_fields ||= fields.grep(NodeKindField)
583
+ end
584
+
585
+ # The field whose subtree loaders can skip and deserialize on demand. In
586
+ # the serialized output, the node's child subtrees are preceded by
587
+ # LAZY_MARKER and two uint32 values: the byte length of the subtrees
588
+ # before this field's subtree, and the byte length of this field's
589
+ # subtree.
590
+ def lazy_field
591
+ fields.find { |field| field.name == "body" } if name == "DefNode"
477
592
  end
478
593
 
479
594
  private
@@ -547,8 +662,7 @@ module Prism
547
662
  extension = File.extname(filepath.gsub(".erb", ""))
548
663
 
549
664
  heading =
550
- case extension
551
- when ".rb"
665
+ if extension == ".rb"
552
666
  <<~HEADING
553
667
  # frozen_string_literal: true
554
668
  # :markup: markdown
@@ -561,29 +675,9 @@ module Prism
561
675
  ++
562
676
  =end
563
677
 
564
- HEADING
565
- when ".rbs"
566
- <<~HEADING
567
- # This file is generated by the templates/template.rb script and should not be
568
- # modified manually. See #{filepath}
569
- # if you are looking to modify the template
570
-
571
- HEADING
572
- when ".rbi"
573
- <<~HEADING
574
- # typed: strict
575
-
576
- =begin
577
- This file is generated by the templates/template.rb script and should not be
578
- modified manually. See #{filepath}
579
- if you are looking to modify the template
580
- =end
581
-
582
678
  HEADING
583
679
  else
584
680
  <<~HEADING
585
- /* :markup: markdown */
586
-
587
681
  /*----------------------------------------------------------------------------*/
588
682
  /* This file is generated by the templates/template.rb script and should not */
589
683
  /* be modified manually. See */
@@ -607,8 +701,14 @@ module Prism
607
701
  end
608
702
  end
609
703
 
610
- FileUtils.mkdir_p(File.dirname(write_to))
611
- File.write(write_to, contents)
704
+ begin
705
+ FileUtils.mkdir_p(File.dirname(write_to))
706
+ File.write(write_to, contents)
707
+ rescue SystemCallError # EACCES, EPERM, EROFS, etc.
708
+ # Fall back to the current directory
709
+ FileUtils.mkdir_p(File.dirname(name))
710
+ File.write(name, contents)
711
+ end
612
712
  end
613
713
 
614
714
  private
@@ -630,10 +730,19 @@ module Prism
630
730
  config = YAML.load_file(File.expand_path("../config.yml", __dir__))
631
731
  flags = config.fetch("flags").to_h { |flags| [flags["name"], Flags.new(flags)] }
632
732
 
733
+ nodes = config.fetch("nodes").map { |node| NodeType.new(node, flags) }.sort_by(&:name)
734
+ raise "Too many node types to reserve LAZY_MARKER" if nodes.length >= LAZY_MARKER
735
+
736
+ nodes.each do |node|
737
+ if (field = node.lazy_field) && !field.is_a?(OptionalNodeField)
738
+ raise "Lazy field #{node.name}##{field.name} must be an optional node field"
739
+ end
740
+ end
741
+
633
742
  {
634
743
  errors: config.fetch("errors").map { |name| Error.new(name) },
635
744
  warnings: config.fetch("warnings").map { |name| Warning.new(name) },
636
- nodes: config.fetch("nodes").map { |node| NodeType.new(node, flags) }.sort_by(&:name),
745
+ nodes: nodes,
637
746
  tokens: config.fetch("tokens").map { |token| Token.new(token) },
638
747
  flags: flags.values
639
748
  }
@@ -644,13 +753,14 @@ module Prism
644
753
  TEMPLATES = [
645
754
  "ext/prism/api_node.c",
646
755
  "include/prism/ast.h",
647
- "include/prism/diagnostic.h",
756
+ "include/prism/ast.hpp",
757
+ "include/prism/internal/diagnostic.h",
648
758
  "javascript/src/deserialize.js",
649
759
  "javascript/src/nodes.js",
650
760
  "javascript/src/visitor.js",
651
- "java/org/prism/Loader.java",
652
- "java/org/prism/Nodes.java",
653
- "java/org/prism/AbstractNodeVisitor.java",
761
+ "java/api/src/main/java-templates/org/ruby_lang/prism/Loader.java",
762
+ "java/api/src/main/java-templates/org/ruby_lang/prism/Nodes.java",
763
+ "java/api/src/main/java-templates/org/ruby_lang/prism/AbstractNodeVisitor.java",
654
764
  "lib/prism/compiler.rb",
655
765
  "lib/prism/dispatcher.rb",
656
766
  "lib/prism/dot_visitor.rb",
@@ -662,19 +772,11 @@ module Prism
662
772
  "lib/prism/serialize.rb",
663
773
  "lib/prism/visitor.rb",
664
774
  "src/diagnostic.c",
775
+ "src/json.c",
665
776
  "src/node.c",
666
777
  "src/prettyprint.c",
667
778
  "src/serialize.c",
668
- "src/token_type.c",
669
- "rbi/prism/dsl.rbi",
670
- "rbi/prism/node.rbi",
671
- "rbi/prism/visitor.rbi",
672
- "sig/prism.rbs",
673
- "sig/prism/dsl.rbs",
674
- "sig/prism/mutation_compiler.rbs",
675
- "sig/prism/node.rbs",
676
- "sig/prism/visitor.rbs",
677
- "sig/prism/_private/dot_visitor.rbs"
779
+ "src/tokens.c"
678
780
  ]
679
781
  end
680
782
  end