mt-lang 0.3.8 → 0.3.10

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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -2
  3. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
  4. data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
  5. data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
  6. data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
  7. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
  8. data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
  9. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
  10. data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
  11. data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
  12. data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
  13. data/lib/milk_tea/bindings/steamworks.rb +12 -16
  14. data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
  15. data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
  16. data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
  17. data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
  18. data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
  19. data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
  20. data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
  21. data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
  22. data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
  23. data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
  24. data/lib/milk_tea/core/ast.rb +103 -45
  25. data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
  26. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
  27. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
  28. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
  29. data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
  30. data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
  31. data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
  32. data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
  33. data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
  34. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
  35. data/lib/milk_tea/core/c_backend/statements.rb +528 -530
  36. data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
  37. data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
  38. data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
  39. data/lib/milk_tea/core/c_backend.rb +17 -9
  40. data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
  41. data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
  42. data/lib/milk_tea/core/compile_time.rb +32 -38
  43. data/lib/milk_tea/core/control_flow/builder.rb +3 -5
  44. data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
  45. data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
  46. data/lib/milk_tea/core/ir.rb +10 -10
  47. data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
  48. data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
  49. data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
  50. data/lib/milk_tea/core/lexer/indentation.rb +0 -2
  51. data/lib/milk_tea/core/lexer/numbers.rb +0 -2
  52. data/lib/milk_tea/core/lexer/recovery.rb +0 -2
  53. data/lib/milk_tea/core/lexer/strings.rb +0 -2
  54. data/lib/milk_tea/core/lexer/symbols.rb +0 -2
  55. data/lib/milk_tea/core/lexer/trivia.rb +0 -2
  56. data/lib/milk_tea/core/lexer.rb +0 -2
  57. data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
  58. data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
  59. data/lib/milk_tea/core/lowering/async/normalization.rb +0 -2
  60. data/lib/milk_tea/core/lowering/async.rb +627 -630
  61. data/lib/milk_tea/core/lowering/block.rb +413 -416
  62. data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
  63. data/lib/milk_tea/core/lowering/declarations.rb +180 -183
  64. data/lib/milk_tea/core/lowering/dyn.rb +48 -50
  65. data/lib/milk_tea/core/lowering/events.rb +983 -985
  66. data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
  67. data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
  68. data/lib/milk_tea/core/lowering/functions.rb +185 -188
  69. data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
  70. data/lib/milk_tea/core/lowering/proc.rb +363 -366
  71. data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
  72. data/lib/milk_tea/core/lowering/scans.rb +179 -181
  73. data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
  74. data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
  75. data/lib/milk_tea/core/lowering.rb +5 -7
  76. data/lib/milk_tea/core/module_binder.rb +0 -2
  77. data/lib/milk_tea/core/module_loader/errors.rb +4 -2
  78. data/lib/milk_tea/core/module_loader.rb +113 -20
  79. data/lib/milk_tea/core/module_path_resolver.rb +0 -2
  80. data/lib/milk_tea/core/module_roots.rb +6 -8
  81. data/lib/milk_tea/core/parser/attributes.rb +0 -2
  82. data/lib/milk_tea/core/parser/blocks.rb +0 -2
  83. data/lib/milk_tea/core/parser/declarations.rb +0 -2
  84. data/lib/milk_tea/core/parser/expressions.rb +31 -14
  85. data/lib/milk_tea/core/parser/recovery.rb +0 -2
  86. data/lib/milk_tea/core/parser/statements.rb +0 -2
  87. data/lib/milk_tea/core/parser/types.rb +8 -10
  88. data/lib/milk_tea/core/parser.rb +1 -3
  89. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
  90. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
  91. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
  92. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
  93. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
  94. data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
  95. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
  96. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
  97. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
  98. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +12 -15
  99. data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
  100. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
  101. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
  102. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
  103. data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
  104. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
  105. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
  106. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +102 -105
  107. data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
  108. data/lib/milk_tea/core/types/layout.rb +21 -22
  109. data/lib/milk_tea/core/types/predicates.rb +0 -2
  110. data/lib/milk_tea/core/types/registry.rb +16 -18
  111. data/lib/milk_tea/core/types/visitor.rb +0 -4
  112. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
  113. data/lib/milk_tea/dap/protocol.rb +1 -1
  114. data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
  115. data/lib/milk_tea/dap/server/debug_map.rb +0 -2
  116. data/lib/milk_tea/dap/server/handlers.rb +0 -2
  117. data/lib/milk_tea/dap/server/launch.rb +0 -2
  118. data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
  119. data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
  120. data/lib/milk_tea/dap/server/utilities.rb +0 -2
  121. data/lib/milk_tea/dap/server/wire.rb +0 -2
  122. data/lib/milk_tea/dap/server.rb +0 -2
  123. data/lib/milk_tea/lsp/diagnostics.rb +16 -16
  124. data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
  125. data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
  126. data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
  127. data/lib/milk_tea/lsp/server/completion.rb +873 -875
  128. data/lib/milk_tea/lsp/server/configuration.rb +129 -131
  129. data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
  130. data/lib/milk_tea/lsp/server/definition.rb +564 -565
  131. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
  132. data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
  133. data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
  134. data/lib/milk_tea/lsp/server/formatting.rb +478 -480
  135. data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
  136. data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
  137. data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
  138. data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
  139. data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
  140. data/lib/milk_tea/lsp/server/progress.rb +0 -2
  141. data/lib/milk_tea/lsp/server/references.rb +316 -318
  142. data/lib/milk_tea/lsp/server/rename.rb +445 -447
  143. data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
  144. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1318 -1320
  145. data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
  146. data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
  147. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
  148. data/lib/milk_tea/lsp/server/utilities.rb +397 -399
  149. data/lib/milk_tea/lsp/server.rb +0 -3
  150. data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
  151. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
  152. data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
  153. data/lib/milk_tea/packages/atomic_write.rb +4 -5
  154. data/lib/milk_tea/packages/dependency_solver.rb +15 -15
  155. data/lib/milk_tea/packages/lock.rb +4 -4
  156. data/lib/milk_tea/packages/manager_cli.rb +1 -1
  157. data/lib/milk_tea/packages/manifest.rb +3 -3
  158. data/lib/milk_tea/packages/registry_store.rb +4 -6
  159. data/lib/milk_tea/packages/services.rb +16 -16
  160. data/lib/milk_tea/packages/source_cache.rb +4 -6
  161. data/lib/milk_tea/packages/source_resolver.rb +44 -44
  162. data/lib/milk_tea/packages/version.rb +8 -8
  163. data/lib/milk_tea/tooling/build.rb +3 -7
  164. data/lib/milk_tea/tooling/build_cache.rb +0 -2
  165. data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
  166. data/lib/milk_tea/tooling/debug_map.rb +8 -10
  167. data/lib/milk_tea/tooling/docs_app.rb +0 -2
  168. data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
  169. data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
  170. data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
  171. data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
  172. data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
  173. data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
  174. data/lib/milk_tea/tooling/linter/rules.rb +87 -89
  175. data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
  176. data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
  177. data/lib/milk_tea/tooling/linter/visitors.rb +162 -50
  178. data/lib/milk_tea/tooling/linter.rb +0 -2
  179. data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
  180. data/lib/milk_tea/tooling/run.rb +0 -2
  181. data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
  182. data/std/cli.mt +13 -32
  183. data/std/color.mt +28 -28
  184. data/std/encoding.mt +4 -4
  185. data/std/graph.mt +1 -2
  186. data/std/hash.mt +14 -14
  187. data/std/http/server.mt +3 -3
  188. data/std/input.mt +1 -1
  189. data/std/json.mt +1 -1
  190. data/std/linear_algebra.mt +6 -6
  191. data/std/net/mux.mt +1 -1
  192. data/std/noise.mt +23 -23
  193. data/std/parse.mt +2 -2
  194. data/std/process.mt +3 -4
  195. data/std/sparse_set.mt +1 -1
  196. data/std/steering.mt +5 -5
  197. data/std/str.mt +1 -1
  198. data/std/tween.mt +4 -4
  199. data/std/utility.mt +3 -3
  200. metadata +2 -2
@@ -3,1439 +3,1437 @@
3
3
  module MilkTea
4
4
  class CBackend
5
5
  module TypeCollectors
6
- private
7
-
8
- def collect_checked_array_index_types(nullable_only: false)
9
- array_types = []
10
- emitted_functions.each do |function|
11
- collect_checked_array_index_types_from_statements(function.body, array_types, nullable_only:)
12
- end
13
- array_types.uniq
14
- end
15
-
16
- def collect_checked_span_index_types(nullable_only: false)
17
- span_types = []
18
- emitted_functions.each do |function|
19
- collect_checked_span_index_types_from_statements(function.body, span_types, nullable_only:)
20
- end
21
- span_types.uniq
22
- end
23
-
24
- def collect_checked_array_index_types_from_statements(statements, array_types, nullable_only: false)
25
- statements.each do |statement|
26
- case statement
27
- when IR::LocalDecl
28
- collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:)
29
- when IR::Assignment
30
- collect_checked_array_index_types_from_expression(statement.target, array_types, nullable_only:)
31
- collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:)
32
- when IR::BlockStmt
33
- collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
34
- when IR::WhileStmt
35
- collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
36
- collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
37
- when IR::ForStmt
38
- collect_checked_array_index_types_from_statements([statement.init], array_types, nullable_only:)
39
- collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
40
- collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
41
- collect_checked_array_index_types_from_statements([statement.post], array_types, nullable_only:)
42
- when IR::IfStmt
43
- collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
44
- collect_checked_array_index_types_from_statements(statement.then_body, array_types, nullable_only:)
45
- collect_checked_array_index_types_from_statements(statement.else_body, array_types, nullable_only:) if statement.else_body
46
- when IR::SwitchStmt
47
- collect_checked_array_index_types_from_expression(statement.expression, array_types, nullable_only:)
48
- statement.cases.each do |switch_case|
49
- collect_checked_array_index_types_from_statements(switch_case.body, array_types, nullable_only:)
50
- end
51
- when IR::StaticAssert
52
- collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
53
- collect_checked_array_index_types_from_expression(statement.message, array_types, nullable_only:)
54
- when IR::ReturnStmt
55
- collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:) if statement.value
56
- when IR::ExpressionStmt
57
- collect_checked_array_index_types_from_expression(statement.expression, array_types, nullable_only:)
58
- end
59
- end
6
+ def collect_checked_array_index_types(nullable_only: false)
7
+ array_types = []
8
+ emitted_functions.each do |function|
9
+ collect_checked_array_index_types_from_statements(function.body, array_types, nullable_only:)
10
+ end
11
+ array_types.uniq
12
+ end
13
+
14
+ def collect_checked_span_index_types(nullable_only: false)
15
+ span_types = []
16
+ emitted_functions.each do |function|
17
+ collect_checked_span_index_types_from_statements(function.body, span_types, nullable_only:)
18
+ end
19
+ span_types.uniq
20
+ end
21
+
22
+ def collect_checked_array_index_types_from_statements(statements, array_types, nullable_only: false)
23
+ statements.each do |statement|
24
+ case statement
25
+ when IR::LocalDecl
26
+ collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:)
27
+ when IR::Assignment
28
+ collect_checked_array_index_types_from_expression(statement.target, array_types, nullable_only:)
29
+ collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:)
30
+ when IR::BlockStmt
31
+ collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
32
+ when IR::WhileStmt
33
+ collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
34
+ collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
35
+ when IR::ForStmt
36
+ collect_checked_array_index_types_from_statements([statement.init], array_types, nullable_only:)
37
+ collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
38
+ collect_checked_array_index_types_from_statements(statement.body, array_types, nullable_only:)
39
+ collect_checked_array_index_types_from_statements([statement.post], array_types, nullable_only:)
40
+ when IR::IfStmt
41
+ collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
42
+ collect_checked_array_index_types_from_statements(statement.then_body, array_types, nullable_only:)
43
+ collect_checked_array_index_types_from_statements(statement.else_body, array_types, nullable_only:) if statement.else_body
44
+ when IR::SwitchStmt
45
+ collect_checked_array_index_types_from_expression(statement.expression, array_types, nullable_only:)
46
+ statement.cases.each do |switch_case|
47
+ collect_checked_array_index_types_from_statements(switch_case.body, array_types, nullable_only:)
48
+ end
49
+ when IR::StaticAssert
50
+ collect_checked_array_index_types_from_expression(statement.condition, array_types, nullable_only:)
51
+ collect_checked_array_index_types_from_expression(statement.message, array_types, nullable_only:)
52
+ when IR::ReturnStmt
53
+ collect_checked_array_index_types_from_expression(statement.value, array_types, nullable_only:) if statement.value
54
+ when IR::ExpressionStmt
55
+ collect_checked_array_index_types_from_expression(statement.expression, array_types, nullable_only:)
60
56
  end
61
-
62
- def collect_checked_array_index_types_from_expression(expression, array_types, nullable_only: false)
63
- case expression
64
- when IR::Member
65
- collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
66
- when IR::Index
67
- collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
68
- collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
69
- when IR::CheckedIndex
70
- array_types << expression.receiver_type unless nullable_only
71
- collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
72
- collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
73
- when IR::NullableIndex
74
- array_types << expression.receiver_type
75
- collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
76
- collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
77
- when IR::Call
78
- collect_checked_array_index_types_from_expression(expression.callee, array_types, nullable_only:) unless expression.callee.is_a?(String)
79
- expression.arguments.each { |argument| collect_checked_array_index_types_from_expression(argument, array_types, nullable_only:) }
80
- when IR::Unary
81
- collect_checked_array_index_types_from_expression(expression.operand, array_types, nullable_only:)
82
- when IR::Binary
83
- collect_checked_array_index_types_from_expression(expression.left, array_types, nullable_only:)
84
- collect_checked_array_index_types_from_expression(expression.right, array_types, nullable_only:)
85
- when IR::Conditional
86
- collect_checked_array_index_types_from_expression(expression.condition, array_types, nullable_only:)
87
- collect_checked_array_index_types_from_expression(expression.then_expression, array_types, nullable_only:)
88
- collect_checked_array_index_types_from_expression(expression.else_expression, array_types, nullable_only:)
89
- when IR::ReinterpretExpr
90
- collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
91
- when IR::AddressOf
92
- collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
93
- when IR::Cast
94
- collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
95
- when IR::AggregateLiteral
96
- expression.fields.each { |field| collect_checked_array_index_types_from_expression(field.value, array_types, nullable_only:) }
97
- when IR::ArrayLiteral
98
- expression.elements.each { |element| collect_checked_array_index_types_from_expression(element, array_types, nullable_only:) }
99
- when IR::VariantLiteral
100
- expression.fields.each { |field| collect_checked_array_index_types_from_expression(field.value, array_types, nullable_only:) }
101
- end
57
+ end
58
+ end
59
+
60
+ def collect_checked_array_index_types_from_expression(expression, array_types, nullable_only: false)
61
+ case expression
62
+ when IR::Member
63
+ collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
64
+ when IR::Index
65
+ collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
66
+ collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
67
+ when IR::CheckedIndex
68
+ array_types << expression.receiver_type unless nullable_only
69
+ collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
70
+ collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
71
+ when IR::NullableIndex
72
+ array_types << expression.receiver_type
73
+ collect_checked_array_index_types_from_expression(expression.receiver, array_types, nullable_only:)
74
+ collect_checked_array_index_types_from_expression(expression.index, array_types, nullable_only:)
75
+ when IR::Call
76
+ collect_checked_array_index_types_from_expression(expression.callee, array_types, nullable_only:) unless expression.callee.is_a?(String)
77
+ expression.arguments.each { |argument| collect_checked_array_index_types_from_expression(argument, array_types, nullable_only:) }
78
+ when IR::Unary
79
+ collect_checked_array_index_types_from_expression(expression.operand, array_types, nullable_only:)
80
+ when IR::Binary
81
+ collect_checked_array_index_types_from_expression(expression.left, array_types, nullable_only:)
82
+ collect_checked_array_index_types_from_expression(expression.right, array_types, nullable_only:)
83
+ when IR::Conditional
84
+ collect_checked_array_index_types_from_expression(expression.condition, array_types, nullable_only:)
85
+ collect_checked_array_index_types_from_expression(expression.then_expression, array_types, nullable_only:)
86
+ collect_checked_array_index_types_from_expression(expression.else_expression, array_types, nullable_only:)
87
+ when IR::ReinterpretExpr
88
+ collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
89
+ when IR::AddressOf
90
+ collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
91
+ when IR::Cast
92
+ collect_checked_array_index_types_from_expression(expression.expression, array_types, nullable_only:)
93
+ when IR::AggregateLiteral
94
+ expression.fields.each { |field| collect_checked_array_index_types_from_expression(field.value, array_types, nullable_only:) }
95
+ when IR::ArrayLiteral
96
+ expression.elements.each { |element| collect_checked_array_index_types_from_expression(element, array_types, nullable_only:) }
97
+ when IR::VariantLiteral
98
+ expression.fields.each { |field| collect_checked_array_index_types_from_expression(field.value, array_types, nullable_only:) }
99
+ end
100
+ end
101
+
102
+ def collect_checked_span_index_types_from_statements(statements, span_types, nullable_only: false)
103
+ statements.each do |statement|
104
+ case statement
105
+ when IR::LocalDecl
106
+ collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:)
107
+ when IR::Assignment
108
+ collect_checked_span_index_types_from_expression(statement.target, span_types, nullable_only:)
109
+ collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:)
110
+ when IR::BlockStmt
111
+ collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
112
+ when IR::WhileStmt
113
+ collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
114
+ collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
115
+ when IR::ForStmt
116
+ collect_checked_span_index_types_from_statements([statement.init], span_types, nullable_only:)
117
+ collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
118
+ collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
119
+ collect_checked_span_index_types_from_statements([statement.post], span_types, nullable_only:)
120
+ when IR::IfStmt
121
+ collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
122
+ collect_checked_span_index_types_from_statements(statement.then_body, span_types, nullable_only:)
123
+ collect_checked_span_index_types_from_statements(statement.else_body, span_types, nullable_only:) if statement.else_body
124
+ when IR::SwitchStmt
125
+ collect_checked_span_index_types_from_expression(statement.expression, span_types, nullable_only:)
126
+ statement.cases.each do |switch_case|
127
+ collect_checked_span_index_types_from_statements(switch_case.body, span_types, nullable_only:)
128
+ end
129
+ when IR::StaticAssert
130
+ collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
131
+ collect_checked_span_index_types_from_expression(statement.message, span_types, nullable_only:)
132
+ when IR::ReturnStmt
133
+ collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:) if statement.value
134
+ when IR::ExpressionStmt
135
+ collect_checked_span_index_types_from_expression(statement.expression, span_types, nullable_only:)
102
136
  end
103
-
104
- def collect_checked_span_index_types_from_statements(statements, span_types, nullable_only: false)
105
- statements.each do |statement|
106
- case statement
107
- when IR::LocalDecl
108
- collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:)
109
- when IR::Assignment
110
- collect_checked_span_index_types_from_expression(statement.target, span_types, nullable_only:)
111
- collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:)
112
- when IR::BlockStmt
113
- collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
114
- when IR::WhileStmt
115
- collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
116
- collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
117
- when IR::ForStmt
118
- collect_checked_span_index_types_from_statements([statement.init], span_types, nullable_only:)
119
- collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
120
- collect_checked_span_index_types_from_statements(statement.body, span_types, nullable_only:)
121
- collect_checked_span_index_types_from_statements([statement.post], span_types, nullable_only:)
122
- when IR::IfStmt
123
- collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
124
- collect_checked_span_index_types_from_statements(statement.then_body, span_types, nullable_only:)
125
- collect_checked_span_index_types_from_statements(statement.else_body, span_types, nullable_only:) if statement.else_body
126
- when IR::SwitchStmt
127
- collect_checked_span_index_types_from_expression(statement.expression, span_types, nullable_only:)
128
- statement.cases.each do |switch_case|
129
- collect_checked_span_index_types_from_statements(switch_case.body, span_types, nullable_only:)
130
- end
131
- when IR::StaticAssert
132
- collect_checked_span_index_types_from_expression(statement.condition, span_types, nullable_only:)
133
- collect_checked_span_index_types_from_expression(statement.message, span_types, nullable_only:)
134
- when IR::ReturnStmt
135
- collect_checked_span_index_types_from_expression(statement.value, span_types, nullable_only:) if statement.value
136
- when IR::ExpressionStmt
137
- collect_checked_span_index_types_from_expression(statement.expression, span_types, nullable_only:)
138
- end
139
- end
137
+ end
138
+ end
139
+
140
+ def collect_checked_span_index_types_from_expression(expression, span_types, nullable_only: false)
141
+ case expression
142
+ when IR::Member
143
+ collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
144
+ when IR::Index, IR::CheckedIndex, IR::NullableIndex
145
+ collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
146
+ collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
147
+ when IR::CheckedSpanIndex
148
+ span_types << expression.receiver_type unless nullable_only
149
+ collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
150
+ collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
151
+ when IR::NullableSpanIndex
152
+ span_types << expression.receiver_type
153
+ collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
154
+ collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
155
+ when IR::Call
156
+ collect_checked_span_index_types_from_expression(expression.callee, span_types, nullable_only:) unless expression.callee.is_a?(String)
157
+ expression.arguments.each { |argument| collect_checked_span_index_types_from_expression(argument, span_types, nullable_only:) }
158
+ when IR::Unary
159
+ collect_checked_span_index_types_from_expression(expression.operand, span_types, nullable_only:)
160
+ when IR::Binary
161
+ collect_checked_span_index_types_from_expression(expression.left, span_types, nullable_only:)
162
+ collect_checked_span_index_types_from_expression(expression.right, span_types, nullable_only:)
163
+ when IR::Conditional
164
+ collect_checked_span_index_types_from_expression(expression.condition, span_types, nullable_only:)
165
+ collect_checked_span_index_types_from_expression(expression.then_expression, span_types, nullable_only:)
166
+ collect_checked_span_index_types_from_expression(expression.else_expression, span_types, nullable_only:)
167
+ when IR::ReinterpretExpr
168
+ collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
169
+ when IR::AddressOf
170
+ collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
171
+ when IR::Cast
172
+ collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
173
+ when IR::AggregateLiteral
174
+ expression.fields.each { |field| collect_checked_span_index_types_from_expression(field.value, span_types, nullable_only:) }
175
+ when IR::ArrayLiteral
176
+ expression.elements.each { |element| collect_checked_span_index_types_from_expression(element, span_types, nullable_only:) }
177
+ when IR::VariantLiteral
178
+ expression.fields.each { |field| collect_checked_span_index_types_from_expression(field.value, span_types, nullable_only:) }
179
+ end
180
+ end
181
+
182
+ def collect_span_types
183
+ span_types = []
184
+ visited = {}
185
+
186
+ all_emitted_top_level_values.each do |value|
187
+ collect_span_type(value.type, span_types, visited)
188
+ end
189
+
190
+ @program.structs.each do |struct_decl|
191
+ struct_decl.fields.each do |field|
192
+ collect_span_type(field.type, span_types, visited)
140
193
  end
194
+ end
141
195
 
142
- def collect_checked_span_index_types_from_expression(expression, span_types, nullable_only: false)
143
- case expression
144
- when IR::Member
145
- collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
146
- when IR::Index, IR::CheckedIndex, IR::NullableIndex
147
- collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
148
- collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
149
- when IR::CheckedSpanIndex
150
- span_types << expression.receiver_type unless nullable_only
151
- collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
152
- collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
153
- when IR::NullableSpanIndex
154
- span_types << expression.receiver_type
155
- collect_checked_span_index_types_from_expression(expression.receiver, span_types, nullable_only:)
156
- collect_checked_span_index_types_from_expression(expression.index, span_types, nullable_only:)
157
- when IR::Call
158
- collect_checked_span_index_types_from_expression(expression.callee, span_types, nullable_only:) unless expression.callee.is_a?(String)
159
- expression.arguments.each { |argument| collect_checked_span_index_types_from_expression(argument, span_types, nullable_only:) }
160
- when IR::Unary
161
- collect_checked_span_index_types_from_expression(expression.operand, span_types, nullable_only:)
162
- when IR::Binary
163
- collect_checked_span_index_types_from_expression(expression.left, span_types, nullable_only:)
164
- collect_checked_span_index_types_from_expression(expression.right, span_types, nullable_only:)
165
- when IR::Conditional
166
- collect_checked_span_index_types_from_expression(expression.condition, span_types, nullable_only:)
167
- collect_checked_span_index_types_from_expression(expression.then_expression, span_types, nullable_only:)
168
- collect_checked_span_index_types_from_expression(expression.else_expression, span_types, nullable_only:)
169
- when IR::ReinterpretExpr
170
- collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
171
- when IR::AddressOf
172
- collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
173
- when IR::Cast
174
- collect_checked_span_index_types_from_expression(expression.expression, span_types, nullable_only:)
175
- when IR::AggregateLiteral
176
- expression.fields.each { |field| collect_checked_span_index_types_from_expression(field.value, span_types, nullable_only:) }
177
- when IR::ArrayLiteral
178
- expression.elements.each { |element| collect_checked_span_index_types_from_expression(element, span_types, nullable_only:) }
179
- when IR::VariantLiteral
180
- expression.fields.each { |field| collect_checked_span_index_types_from_expression(field.value, span_types, nullable_only:) }
181
- end
196
+ @program.unions.each do |union_decl|
197
+ union_decl.fields.each do |field|
198
+ collect_span_type(field.type, span_types, visited)
182
199
  end
200
+ end
183
201
 
184
- def collect_span_types
185
- span_types = []
186
- visited = {}
187
-
188
- all_emitted_top_level_values.each do |value|
189
- collect_span_type(value.type, span_types, visited)
190
- end
191
-
192
- @program.structs.each do |struct_decl|
193
- struct_decl.fields.each do |field|
194
- collect_span_type(field.type, span_types, visited)
195
- end
196
- end
197
-
198
- @program.unions.each do |union_decl|
199
- union_decl.fields.each do |field|
200
- collect_span_type(field.type, span_types, visited)
201
- end
202
- end
203
-
204
- each_variant_arm_field_type do |field_type|
205
- collect_span_type(field_type, span_types, visited)
206
- end
202
+ each_variant_arm_field_type do |field_type|
203
+ collect_span_type(field_type, span_types, visited)
204
+ end
207
205
 
208
- emitted_functions.each do |function|
209
- collect_span_type(function.return_type, span_types, visited)
210
- function.params.each do |param|
211
- collect_span_type(param.type, span_types, visited)
212
- end
213
- collect_span_types_from_statements(function.body, span_types, visited)
214
- end
215
-
216
- @program.static_asserts.each do |statement|
217
- collect_span_types_from_expression(statement.condition, span_types, visited)
218
- collect_span_types_from_expression(statement.message, span_types, visited)
219
- end
220
-
221
- span_types.uniq
206
+ emitted_functions.each do |function|
207
+ collect_span_type(function.return_type, span_types, visited)
208
+ function.params.each do |param|
209
+ collect_span_type(param.type, span_types, visited)
222
210
  end
211
+ collect_span_types_from_statements(function.body, span_types, visited)
212
+ end
223
213
 
224
- def collect_soa_types
225
- soa_types = []
226
- visited = {}
227
-
228
- emitted_functions.each do |function|
229
- collect_soa_type(function.return_type, soa_types, visited)
230
- function.params.each do |param|
231
- collect_soa_type(param.type, soa_types, visited)
232
- end
233
- collect_soa_from_statements(function.body, soa_types, visited)
234
- end
235
-
236
- @program.structs.each do |struct_decl|
237
- struct_decl.fields.each do |field|
238
- collect_soa_type(field.type, soa_types, visited)
239
- end
240
- end
214
+ @program.static_asserts.each do |statement|
215
+ collect_span_types_from_expression(statement.condition, span_types, visited)
216
+ collect_span_types_from_expression(statement.message, span_types, visited)
217
+ end
241
218
 
242
- soa_types.uniq
243
- end
244
-
245
- def collect_soa_from_statements(statements, soa_types, visited)
246
- statements.each do |stmt|
247
- case stmt
248
- when IR::LocalDecl
249
- collect_soa_type(stmt.type, soa_types, visited)
250
- when IR::BlockStmt
251
- collect_soa_from_statements(stmt.body, soa_types, visited)
252
- when IR::IfStmt
253
- collect_soa_from_statements(stmt.then_body || [], soa_types, visited)
254
- collect_soa_from_statements(stmt.else_body || [], soa_types, visited)
255
- when IR::WhileStmt
256
- collect_soa_from_statements(stmt.body || [], soa_types, visited)
257
- when IR::ForStmt
258
- collect_soa_from_statements(stmt.body || [], soa_types, visited)
259
- end
260
- end
261
- end
219
+ span_types.uniq
220
+ end
262
221
 
263
- def collect_soa_type(type, soa_types, visited)
264
- return unless type
265
- return if visited[type]
222
+ def collect_soa_types
223
+ soa_types = []
224
+ visited = {}
266
225
 
267
- if type.is_a?(Types::SoA)
268
- soa_types << type
269
- visited[type] = true
270
- end
226
+ emitted_functions.each do |function|
227
+ collect_soa_type(function.return_type, soa_types, visited)
228
+ function.params.each do |param|
229
+ collect_soa_type(param.type, soa_types, visited)
271
230
  end
231
+ collect_soa_from_statements(function.body, soa_types, visited)
232
+ end
272
233
 
273
- def collect_simd_types
274
- simd_types = []
275
- visited = {}
276
-
277
- emitted_functions.each do |function|
278
- collect_simd_type(function.return_type, simd_types, visited)
279
- function.params.each do |param|
280
- collect_simd_type(param.type, simd_types, visited)
281
- end
282
- collect_simd_from_statements(function.body, simd_types, visited)
283
- end
284
-
285
- @program.structs.each do |struct_decl|
286
- struct_decl.fields.each do |field|
287
- collect_simd_type(field.type, simd_types, visited)
288
- end
289
- end
290
-
291
- simd_types.uniq
292
- end
293
-
294
- def collect_simd_from_statements(statements, simd_types, visited)
295
- statements.each do |stmt|
296
- case stmt
297
- when IR::LocalDecl
298
- collect_simd_type(stmt.type, simd_types, visited)
299
- when IR::BlockStmt
300
- collect_simd_from_statements(stmt.body, simd_types, visited)
301
- when IR::IfStmt
302
- collect_simd_from_statements(stmt.then_body || [], simd_types, visited)
303
- collect_simd_from_statements(stmt.else_body || [], simd_types, visited)
304
- when IR::WhileStmt
305
- collect_simd_from_statements(stmt.body || [], simd_types, visited)
306
- when IR::ForStmt
307
- collect_simd_from_statements(stmt.body || [], simd_types, visited)
308
- end
309
- end
234
+ @program.structs.each do |struct_decl|
235
+ struct_decl.fields.each do |field|
236
+ collect_soa_type(field.type, soa_types, visited)
310
237
  end
311
-
312
- def collect_simd_type(type, simd_types, visited)
313
- return unless type
314
- return if visited[type]
315
-
316
- if type.is_a?(Types::Simd)
317
- simd_types << type
318
- visited[type] = true
319
- end
238
+ end
239
+
240
+ soa_types.uniq
241
+ end
242
+
243
+ def collect_soa_from_statements(statements, soa_types, visited)
244
+ statements.each do |stmt|
245
+ case stmt
246
+ when IR::LocalDecl
247
+ collect_soa_type(stmt.type, soa_types, visited)
248
+ when IR::BlockStmt
249
+ collect_soa_from_statements(stmt.body, soa_types, visited)
250
+ when IR::IfStmt
251
+ collect_soa_from_statements(stmt.then_body || [], soa_types, visited)
252
+ collect_soa_from_statements(stmt.else_body || [], soa_types, visited)
253
+ when IR::WhileStmt
254
+ collect_soa_from_statements(stmt.body || [], soa_types, visited)
255
+ when IR::ForStmt
256
+ collect_soa_from_statements(stmt.body || [], soa_types, visited)
320
257
  end
321
-
322
- def collect_generic_struct_decls
323
- collect_generic_struct_types.map do |type|
324
- fields = type.fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) }
325
- if type.respond_to?(:events)
326
- type.events.each_value do |event_type|
327
- fields << IR::Field.new(name: event_type.hidden_field_name, type: event_type)
328
- end
329
- end
330
- IR::StructDecl.new(
331
- name: type.to_s,
332
- linkage_name: named_type_c_name(type),
333
- fields:,
334
- packed: type.packed,
335
- alignment: type.alignment,
336
- )
337
- end
258
+ end
259
+ end
260
+
261
+ def collect_soa_type(type, soa_types, visited)
262
+ return unless type
263
+ return if visited[type]
264
+
265
+ if type.is_a?(Types::SoA)
266
+ soa_types << type
267
+ visited[type] = true
268
+ end
269
+ end
270
+
271
+ def collect_simd_types
272
+ simd_types = []
273
+ visited = {}
274
+
275
+ emitted_functions.each do |function|
276
+ collect_simd_type(function.return_type, simd_types, visited)
277
+ function.params.each do |param|
278
+ collect_simd_type(param.type, simd_types, visited)
338
279
  end
280
+ collect_simd_from_statements(function.body, simd_types, visited)
281
+ end
339
282
 
340
- def collect_task_decls
341
- collect_task_types.map do |type|
342
- IR::StructDecl.new(
343
- name: type.to_s,
344
- linkage_name: task_type_name(type),
345
- fields: type.fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
346
- packed: false,
347
- alignment: nil,
348
- )
349
- end
283
+ @program.structs.each do |struct_decl|
284
+ struct_decl.fields.each do |field|
285
+ collect_simd_type(field.type, simd_types, visited)
350
286
  end
351
-
352
- def collect_proc_decls
353
- collect_proc_types.map do |type|
354
- IR::StructDecl.new(
355
- name: type.to_s,
356
- linkage_name: proc_type_name(type),
357
- fields: proc_field_types(type).map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
358
- packed: false,
359
- alignment: nil,
360
- )
361
- end
287
+ end
288
+
289
+ simd_types.uniq
290
+ end
291
+
292
+ def collect_simd_from_statements(statements, simd_types, visited)
293
+ statements.each do |stmt|
294
+ case stmt
295
+ when IR::LocalDecl
296
+ collect_simd_type(stmt.type, simd_types, visited)
297
+ when IR::BlockStmt
298
+ collect_simd_from_statements(stmt.body, simd_types, visited)
299
+ when IR::IfStmt
300
+ collect_simd_from_statements(stmt.then_body || [], simd_types, visited)
301
+ collect_simd_from_statements(stmt.else_body || [], simd_types, visited)
302
+ when IR::WhileStmt
303
+ collect_simd_from_statements(stmt.body || [], simd_types, visited)
304
+ when IR::ForStmt
305
+ collect_simd_from_statements(stmt.body || [], simd_types, visited)
362
306
  end
363
-
364
- def proc_field_types(type)
365
- void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
366
-
367
- {
368
- "env" => void_ptr,
369
- "invoke" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)] + type.params, return_type: type.return_type),
370
- "release" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)], return_type: Types::Registry.primitive("void")),
371
- "retain" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)], return_type: Types::Registry.primitive("void")),
372
- }
373
- end
374
-
375
- def collect_str_buffer_decls
376
- collect_str_buffer_types.map do |type|
377
- IR::StructDecl.new(
378
- name: type.to_s,
379
- linkage_name: str_buffer_type_name(type),
380
- fields: [
381
- IR::Field.new(name: "data", type: Types::Registry.generic_instance("array", [Types::Registry.primitive("char"), Types::LiteralTypeArg.new(str_buffer_storage_capacity(type))])),
382
- IR::Field.new(name: "len", type: Types::Registry.primitive("ptr_uint")),
383
- IR::Field.new(name: "dirty", type: Types::Registry.primitive("bool")),
384
- ],
385
- packed: false,
386
- alignment: nil,
387
- )
307
+ end
308
+ end
309
+
310
+ def collect_simd_type(type, simd_types, visited)
311
+ return unless type
312
+ return if visited[type]
313
+
314
+ if type.is_a?(Types::Simd)
315
+ simd_types << type
316
+ visited[type] = true
317
+ end
318
+ end
319
+
320
+ def collect_generic_struct_decls
321
+ collect_generic_struct_types.map do |type|
322
+ fields = type.fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) }
323
+ if type.respond_to?(:events)
324
+ type.events.each_value do |event_type|
325
+ fields << IR::Field.new(name: event_type.hidden_field_name, type: event_type)
388
326
  end
389
327
  end
390
-
391
- def collect_generic_variant_decls
392
- collect_generic_variant_types.map do |type|
393
- outer_c = named_type_c_name(type)
394
- arms = type.arm_names.map do |arm_name|
395
- fields = type.arm(arm_name)
396
- IR::VariantArm.new(
397
- name: arm_name,
398
- linkage_name: "#{outer_c}_#{arm_name}",
399
- fields: fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
400
- )
401
- end
402
- IR::VariantDecl.new(name: type.to_s, linkage_name: outer_c, arms:)
403
- end
328
+ IR::StructDecl.new(
329
+ name: type.to_s,
330
+ linkage_name: named_type_c_name(type),
331
+ fields:,
332
+ packed: type.packed,
333
+ alignment: type.alignment,
334
+ )
335
+ end
336
+ end
337
+
338
+ def collect_task_decls
339
+ collect_task_types.map do |type|
340
+ IR::StructDecl.new(
341
+ name: type.to_s,
342
+ linkage_name: task_type_name(type),
343
+ fields: type.fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
344
+ packed: false,
345
+ alignment: nil,
346
+ )
347
+ end
348
+ end
349
+
350
+ def collect_proc_decls
351
+ collect_proc_types.map do |type|
352
+ IR::StructDecl.new(
353
+ name: type.to_s,
354
+ linkage_name: proc_type_name(type),
355
+ fields: proc_field_types(type).map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
356
+ packed: false,
357
+ alignment: nil,
358
+ )
359
+ end
360
+ end
361
+
362
+ def proc_field_types(type)
363
+ void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
364
+
365
+ {
366
+ "env" => void_ptr,
367
+ "invoke" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)] + type.params, return_type: type.return_type),
368
+ "release" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)], return_type: Types::Registry.primitive("void")),
369
+ "retain" => Types::Registry.function(nil, params: [Types::Registry.parameter("env", void_ptr)], return_type: Types::Registry.primitive("void")),
370
+ }
371
+ end
372
+
373
+ def collect_str_buffer_decls
374
+ collect_str_buffer_types.map do |type|
375
+ IR::StructDecl.new(
376
+ name: type.to_s,
377
+ linkage_name: str_buffer_type_name(type),
378
+ fields: [
379
+ IR::Field.new(name: "data", type: Types::Registry.generic_instance("array", [Types::Registry.primitive("char"), Types::LiteralTypeArg.new(str_buffer_storage_capacity(type))])),
380
+ IR::Field.new(name: "len", type: Types::Registry.primitive("ptr_uint")),
381
+ IR::Field.new(name: "dirty", type: Types::Registry.primitive("bool")),
382
+ ],
383
+ packed: false,
384
+ alignment: nil,
385
+ )
386
+ end
387
+ end
388
+
389
+ def collect_generic_variant_decls
390
+ collect_generic_variant_types.map do |type|
391
+ outer_c = named_type_c_name(type)
392
+ arms = type.arm_names.map do |arm_name|
393
+ fields = type.arm(arm_name)
394
+ IR::VariantArm.new(
395
+ name: arm_name,
396
+ linkage_name: "#{outer_c}_#{arm_name}",
397
+ fields: fields.map { |field_name, field_type| IR::Field.new(name: field_name, type: field_type) },
398
+ )
404
399
  end
400
+ IR::VariantDecl.new(name: type.to_s, linkage_name: outer_c, arms:)
401
+ end
402
+ end
405
403
 
406
- def collect_task_types
407
- task_types = []
408
- visited = {}
409
-
410
- all_emitted_top_level_values.each do |value|
411
- collect_task_type(value.type, task_types, visited)
412
- end
413
-
414
- @program.structs.each do |struct_decl|
415
- struct_decl.fields.each do |field|
416
- collect_task_type(field.type, task_types, visited)
417
- end
418
- end
419
-
420
- @program.unions.each do |union_decl|
421
- union_decl.fields.each do |field|
422
- collect_task_type(field.type, task_types, visited)
423
- end
424
- end
425
-
426
- each_variant_arm_field_type do |field_type|
427
- collect_task_type(field_type, task_types, visited)
428
- end
404
+ def collect_task_types
405
+ task_types = []
406
+ visited = {}
429
407
 
430
- emitted_functions.each do |function|
431
- collect_task_type(function.return_type, task_types, visited)
432
- function.params.each do |param|
433
- collect_task_type(param.type, task_types, visited)
434
- end
435
- collect_task_types_from_statements(function.body, task_types, visited)
436
- end
437
-
438
- @program.static_asserts.each do |statement|
439
- collect_task_types_from_expression(statement.condition, task_types, visited)
440
- collect_task_types_from_expression(statement.message, task_types, visited)
441
- end
408
+ all_emitted_top_level_values.each do |value|
409
+ collect_task_type(value.type, task_types, visited)
410
+ end
442
411
 
443
- task_types
412
+ @program.structs.each do |struct_decl|
413
+ struct_decl.fields.each do |field|
414
+ collect_task_type(field.type, task_types, visited)
444
415
  end
416
+ end
445
417
 
446
- def collect_proc_types
447
- proc_types = []
448
- visited = {}
418
+ @program.unions.each do |union_decl|
419
+ union_decl.fields.each do |field|
420
+ collect_task_type(field.type, task_types, visited)
421
+ end
422
+ end
449
423
 
450
- all_emitted_top_level_values.each do |value|
451
- collect_proc_type(value.type, proc_types, visited)
452
- end
424
+ each_variant_arm_field_type do |field_type|
425
+ collect_task_type(field_type, task_types, visited)
426
+ end
453
427
 
454
- @program.structs.each do |struct_decl|
455
- struct_decl.fields.each do |field|
456
- collect_proc_type(field.type, proc_types, visited)
457
- end
458
- end
428
+ emitted_functions.each do |function|
429
+ collect_task_type(function.return_type, task_types, visited)
430
+ function.params.each do |param|
431
+ collect_task_type(param.type, task_types, visited)
432
+ end
433
+ collect_task_types_from_statements(function.body, task_types, visited)
434
+ end
459
435
 
460
- @program.unions.each do |union_decl|
461
- union_decl.fields.each do |field|
462
- collect_proc_type(field.type, proc_types, visited)
463
- end
464
- end
436
+ @program.static_asserts.each do |statement|
437
+ collect_task_types_from_expression(statement.condition, task_types, visited)
438
+ collect_task_types_from_expression(statement.message, task_types, visited)
439
+ end
465
440
 
466
- each_variant_arm_field_type do |field_type|
467
- collect_proc_type(field_type, proc_types, visited)
468
- end
441
+ task_types
442
+ end
469
443
 
470
- emitted_functions.each do |function|
471
- collect_proc_type(function.return_type, proc_types, visited)
472
- function.params.each do |param|
473
- collect_proc_type(param.type, proc_types, visited)
474
- end
475
- collect_proc_types_from_statements(function.body, proc_types, visited)
476
- end
444
+ def collect_proc_types
445
+ proc_types = []
446
+ visited = {}
477
447
 
478
- @program.static_asserts.each do |statement|
479
- collect_proc_types_from_expression(statement.condition, proc_types, visited)
480
- collect_proc_types_from_expression(statement.message, proc_types, visited)
481
- end
448
+ all_emitted_top_level_values.each do |value|
449
+ collect_proc_type(value.type, proc_types, visited)
450
+ end
482
451
 
483
- proc_types
484
- end
485
-
486
- def each_ir_statement_for_type_collection(statements, type_collector_method:, expression_walker_method:, accumulator:, visited:)
487
- statements.each do |stmt|
488
- case stmt
489
- when IR::LocalDecl
490
- send(type_collector_method, stmt.type, accumulator, visited)
491
- send(expression_walker_method, stmt.value, accumulator, visited) if stmt.value
492
- when IR::Assignment
493
- send(expression_walker_method, stmt.target, accumulator, visited)
494
- send(expression_walker_method, stmt.value, accumulator, visited)
495
- when IR::BlockStmt
496
- each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
497
- when IR::WhileStmt
498
- send(expression_walker_method, stmt.condition, accumulator, visited)
499
- each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
500
- when IR::ForStmt
501
- each_ir_statement_for_type_collection([stmt.init], type_collector_method:, expression_walker_method:, accumulator:, visited:)
502
- send(expression_walker_method, stmt.condition, accumulator, visited)
503
- each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
504
- each_ir_statement_for_type_collection([stmt.post], type_collector_method:, expression_walker_method:, accumulator:, visited:)
505
- when IR::IfStmt
506
- send(expression_walker_method, stmt.condition, accumulator, visited)
507
- each_ir_statement_for_type_collection(stmt.then_body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
508
- each_ir_statement_for_type_collection(stmt.else_body, type_collector_method:, expression_walker_method:, accumulator:, visited:) if stmt.else_body
509
- when IR::SwitchStmt
510
- send(expression_walker_method, stmt.expression, accumulator, visited)
511
- stmt.cases.each do |switch_case|
512
- each_ir_statement_for_type_collection(switch_case.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
513
- end
514
- when IR::StaticAssert
515
- send(expression_walker_method, stmt.condition, accumulator, visited)
516
- send(expression_walker_method, stmt.message, accumulator, visited)
517
- when IR::ReturnStmt
518
- send(expression_walker_method, stmt.value, accumulator, visited) if stmt.value
519
- when IR::ExpressionStmt
520
- send(expression_walker_method, stmt.expression, accumulator, visited)
521
- end
522
- end
452
+ @program.structs.each do |struct_decl|
453
+ struct_decl.fields.each do |field|
454
+ collect_proc_type(field.type, proc_types, visited)
523
455
  end
456
+ end
524
457
 
525
- def collect_proc_types_from_statements(statements, proc_types, visited)
526
- each_ir_statement_for_type_collection(statements,
527
- type_collector_method: :collect_proc_type,
528
- expression_walker_method: :collect_proc_types_from_expression,
529
- accumulator: proc_types, visited:)
530
- end
531
-
532
- def collect_proc_types_from_expression(expression, proc_types, visited)
533
- case expression
534
- when IR::Member
535
- collect_proc_types_from_expression(expression.receiver, proc_types, visited)
536
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
537
- collect_proc_types_from_expression(expression.receiver, proc_types, visited)
538
- collect_proc_types_from_expression(expression.index, proc_types, visited)
539
- when IR::Call
540
- collect_proc_type(expression.type, proc_types, visited)
541
- collect_proc_types_from_expression(expression.callee, proc_types, visited) unless expression.callee.is_a?(String)
542
- expression.arguments.each { |argument| collect_proc_types_from_expression(argument, proc_types, visited) }
543
- when IR::Unary
544
- collect_proc_types_from_expression(expression.operand, proc_types, visited)
545
- when IR::Binary
546
- collect_proc_types_from_expression(expression.left, proc_types, visited)
547
- collect_proc_types_from_expression(expression.right, proc_types, visited)
548
- when IR::Conditional
549
- collect_proc_types_from_expression(expression.condition, proc_types, visited)
550
- collect_proc_types_from_expression(expression.then_expression, proc_types, visited)
551
- collect_proc_types_from_expression(expression.else_expression, proc_types, visited)
552
- when IR::ReinterpretExpr
553
- collect_proc_type(expression.target_type, proc_types, visited)
554
- collect_proc_type(expression.source_type, proc_types, visited)
555
- collect_proc_types_from_expression(expression.expression, proc_types, visited)
556
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
557
- collect_proc_type(expression.target_type, proc_types, visited)
558
- when IR::AddressOf, IR::Cast
559
- collect_proc_types_from_expression(expression.expression, proc_types, visited)
560
- when IR::AggregateLiteral
561
- collect_proc_type(expression.type, proc_types, visited)
562
- expression.fields.each { |field| collect_proc_types_from_expression(field.value, proc_types, visited) }
563
- when IR::ArrayLiteral
564
- expression.elements.each { |element| collect_proc_types_from_expression(element, proc_types, visited) }
565
- when IR::VariantLiteral
566
- collect_proc_type(expression.type, proc_types, visited)
567
- expression.fields.each { |field| collect_proc_types_from_expression(field.value, proc_types, visited) }
568
- end
458
+ @program.unions.each do |union_decl|
459
+ union_decl.fields.each do |field|
460
+ collect_proc_type(field.type, proc_types, visited)
569
461
  end
462
+ end
570
463
 
571
- def collect_proc_type(type, proc_types, visited)
572
- return unless type
573
- return if visited[type]
574
-
575
- visited[type] = true
464
+ each_variant_arm_field_type do |field_type|
465
+ collect_proc_type(field_type, proc_types, visited)
466
+ end
576
467
 
577
- case type
578
- when Types::Nullable
579
- collect_proc_type(type.base, proc_types, visited)
580
- when Types::Task
581
- collect_proc_type(type.result_type, proc_types, visited)
582
- when Types::Proc
583
- proc_types << type
584
- type.params.each do |param|
585
- collect_proc_type(param.type, proc_types, visited)
586
- end
587
- collect_proc_type(type.return_type, proc_types, visited)
588
- when Types::Span
589
- collect_proc_type(type.element_type, proc_types, visited)
590
- when Types::StructInstance
591
- type.arguments.each do |argument|
592
- collect_proc_type(argument, proc_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
593
- end
594
- type.fields.each_value do |field_type|
595
- collect_proc_type(field_type, proc_types, visited)
596
- end
597
- when Types::GenericInstance
598
- type.arguments.each do |argument|
599
- collect_proc_type(argument, proc_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
600
- end
601
- when Types::Function
602
- type.params.each do |param|
603
- collect_proc_type(param.type, proc_types, visited)
604
- end
605
- collect_proc_type(type.return_type, proc_types, visited)
606
- when Types::Struct, Types::Union
607
- type.fields.each_value do |field_type|
608
- collect_proc_type(field_type, proc_types, visited)
609
- end
610
- when Types::Variant
611
- type.arm_names.each do |arm_name|
612
- type.arm(arm_name).each_value do |field_type|
613
- collect_proc_type(field_type, proc_types, visited)
614
- end
615
- end
468
+ emitted_functions.each do |function|
469
+ collect_proc_type(function.return_type, proc_types, visited)
470
+ function.params.each do |param|
471
+ collect_proc_type(param.type, proc_types, visited)
472
+ end
473
+ collect_proc_types_from_statements(function.body, proc_types, visited)
474
+ end
475
+
476
+ @program.static_asserts.each do |statement|
477
+ collect_proc_types_from_expression(statement.condition, proc_types, visited)
478
+ collect_proc_types_from_expression(statement.message, proc_types, visited)
479
+ end
480
+
481
+ proc_types
482
+ end
483
+
484
+ def each_ir_statement_for_type_collection(statements, type_collector_method:, expression_walker_method:, accumulator:, visited:)
485
+ statements.each do |stmt|
486
+ case stmt
487
+ when IR::LocalDecl
488
+ send(type_collector_method, stmt.type, accumulator, visited)
489
+ send(expression_walker_method, stmt.value, accumulator, visited) if stmt.value
490
+ when IR::Assignment
491
+ send(expression_walker_method, stmt.target, accumulator, visited)
492
+ send(expression_walker_method, stmt.value, accumulator, visited)
493
+ when IR::BlockStmt
494
+ each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
495
+ when IR::WhileStmt
496
+ send(expression_walker_method, stmt.condition, accumulator, visited)
497
+ each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
498
+ when IR::ForStmt
499
+ each_ir_statement_for_type_collection([stmt.init], type_collector_method:, expression_walker_method:, accumulator:, visited:)
500
+ send(expression_walker_method, stmt.condition, accumulator, visited)
501
+ each_ir_statement_for_type_collection(stmt.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
502
+ each_ir_statement_for_type_collection([stmt.post], type_collector_method:, expression_walker_method:, accumulator:, visited:)
503
+ when IR::IfStmt
504
+ send(expression_walker_method, stmt.condition, accumulator, visited)
505
+ each_ir_statement_for_type_collection(stmt.then_body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
506
+ each_ir_statement_for_type_collection(stmt.else_body, type_collector_method:, expression_walker_method:, accumulator:, visited:) if stmt.else_body
507
+ when IR::SwitchStmt
508
+ send(expression_walker_method, stmt.expression, accumulator, visited)
509
+ stmt.cases.each do |switch_case|
510
+ each_ir_statement_for_type_collection(switch_case.body, type_collector_method:, expression_walker_method:, accumulator:, visited:)
511
+ end
512
+ when IR::StaticAssert
513
+ send(expression_walker_method, stmt.condition, accumulator, visited)
514
+ send(expression_walker_method, stmt.message, accumulator, visited)
515
+ when IR::ReturnStmt
516
+ send(expression_walker_method, stmt.value, accumulator, visited) if stmt.value
517
+ when IR::ExpressionStmt
518
+ send(expression_walker_method, stmt.expression, accumulator, visited)
519
+ end
520
+ end
521
+ end
522
+
523
+ def collect_proc_types_from_statements(statements, proc_types, visited)
524
+ each_ir_statement_for_type_collection(statements,
525
+ type_collector_method: :collect_proc_type,
526
+ expression_walker_method: :collect_proc_types_from_expression,
527
+ accumulator: proc_types, visited:)
528
+ end
529
+
530
+ def collect_proc_types_from_expression(expression, proc_types, visited)
531
+ case expression
532
+ when IR::Member
533
+ collect_proc_types_from_expression(expression.receiver, proc_types, visited)
534
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
535
+ collect_proc_types_from_expression(expression.receiver, proc_types, visited)
536
+ collect_proc_types_from_expression(expression.index, proc_types, visited)
537
+ when IR::Call
538
+ collect_proc_type(expression.type, proc_types, visited)
539
+ collect_proc_types_from_expression(expression.callee, proc_types, visited) unless expression.callee.is_a?(String)
540
+ expression.arguments.each { |argument| collect_proc_types_from_expression(argument, proc_types, visited) }
541
+ when IR::Unary
542
+ collect_proc_types_from_expression(expression.operand, proc_types, visited)
543
+ when IR::Binary
544
+ collect_proc_types_from_expression(expression.left, proc_types, visited)
545
+ collect_proc_types_from_expression(expression.right, proc_types, visited)
546
+ when IR::Conditional
547
+ collect_proc_types_from_expression(expression.condition, proc_types, visited)
548
+ collect_proc_types_from_expression(expression.then_expression, proc_types, visited)
549
+ collect_proc_types_from_expression(expression.else_expression, proc_types, visited)
550
+ when IR::ReinterpretExpr
551
+ collect_proc_type(expression.target_type, proc_types, visited)
552
+ collect_proc_type(expression.source_type, proc_types, visited)
553
+ collect_proc_types_from_expression(expression.expression, proc_types, visited)
554
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
555
+ collect_proc_type(expression.target_type, proc_types, visited)
556
+ when IR::AddressOf, IR::Cast
557
+ collect_proc_types_from_expression(expression.expression, proc_types, visited)
558
+ when IR::AggregateLiteral
559
+ collect_proc_type(expression.type, proc_types, visited)
560
+ expression.fields.each { |field| collect_proc_types_from_expression(field.value, proc_types, visited) }
561
+ when IR::ArrayLiteral
562
+ expression.elements.each { |element| collect_proc_types_from_expression(element, proc_types, visited) }
563
+ when IR::VariantLiteral
564
+ collect_proc_type(expression.type, proc_types, visited)
565
+ expression.fields.each { |field| collect_proc_types_from_expression(field.value, proc_types, visited) }
566
+ end
567
+ end
568
+
569
+ def collect_proc_type(type, proc_types, visited)
570
+ return unless type
571
+ return if visited[type]
572
+
573
+ visited[type] = true
574
+
575
+ case type
576
+ when Types::Nullable
577
+ collect_proc_type(type.base, proc_types, visited)
578
+ when Types::Task
579
+ collect_proc_type(type.result_type, proc_types, visited)
580
+ when Types::Proc
581
+ proc_types << type
582
+ type.params.each do |param|
583
+ collect_proc_type(param.type, proc_types, visited)
584
+ end
585
+ collect_proc_type(type.return_type, proc_types, visited)
586
+ when Types::Span
587
+ collect_proc_type(type.element_type, proc_types, visited)
588
+ when Types::StructInstance
589
+ type.arguments.each do |argument|
590
+ collect_proc_type(argument, proc_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
591
+ end
592
+ type.fields.each_value do |field_type|
593
+ collect_proc_type(field_type, proc_types, visited)
594
+ end
595
+ when Types::GenericInstance
596
+ type.arguments.each do |argument|
597
+ collect_proc_type(argument, proc_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
598
+ end
599
+ when Types::Function
600
+ type.params.each do |param|
601
+ collect_proc_type(param.type, proc_types, visited)
602
+ end
603
+ collect_proc_type(type.return_type, proc_types, visited)
604
+ when Types::Struct, Types::Union
605
+ type.fields.each_value do |field_type|
606
+ collect_proc_type(field_type, proc_types, visited)
607
+ end
608
+ when Types::Variant
609
+ type.arm_names.each do |arm_name|
610
+ type.arm(arm_name).each_value do |field_type|
611
+ collect_proc_type(field_type, proc_types, visited)
616
612
  end
617
613
  end
618
-
619
- def collect_task_types_from_statements(statements, task_types, visited)
620
- each_ir_statement_for_type_collection(statements,
621
- type_collector_method: :collect_task_type,
622
- expression_walker_method: :collect_task_types_from_expression,
623
- accumulator: task_types, visited:)
624
- end
625
-
626
- def collect_task_types_from_expression(expression, task_types, visited)
627
- case expression
628
- when IR::Member
629
- collect_task_types_from_expression(expression.receiver, task_types, visited)
630
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
631
- collect_task_types_from_expression(expression.receiver, task_types, visited)
632
- collect_task_types_from_expression(expression.index, task_types, visited)
633
- when IR::Call
634
- collect_task_type(expression.type, task_types, visited)
635
- collect_task_types_from_expression(expression.callee, task_types, visited) unless expression.callee.is_a?(String)
636
- expression.arguments.each { |argument| collect_task_types_from_expression(argument, task_types, visited) }
637
- when IR::Unary
638
- collect_task_types_from_expression(expression.operand, task_types, visited)
639
- when IR::Binary
640
- collect_task_types_from_expression(expression.left, task_types, visited)
641
- collect_task_types_from_expression(expression.right, task_types, visited)
642
- when IR::Conditional
643
- collect_task_types_from_expression(expression.condition, task_types, visited)
644
- collect_task_types_from_expression(expression.then_expression, task_types, visited)
645
- collect_task_types_from_expression(expression.else_expression, task_types, visited)
646
- when IR::ReinterpretExpr
647
- collect_task_type(expression.target_type, task_types, visited)
648
- collect_task_type(expression.source_type, task_types, visited)
649
- collect_task_types_from_expression(expression.expression, task_types, visited)
650
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
651
- collect_task_type(expression.target_type, task_types, visited)
652
- when IR::AddressOf, IR::Cast
653
- collect_task_types_from_expression(expression.expression, task_types, visited)
654
- when IR::AggregateLiteral
655
- collect_task_type(expression.type, task_types, visited)
656
- expression.fields.each { |field| collect_task_types_from_expression(field.value, task_types, visited) }
657
- when IR::ArrayLiteral
658
- expression.elements.each { |element| collect_task_types_from_expression(element, task_types, visited) }
659
- when IR::VariantLiteral
660
- collect_task_type(expression.type, task_types, visited)
661
- expression.fields.each { |field| collect_task_types_from_expression(field.value, task_types, visited) }
614
+ end
615
+ end
616
+
617
+ def collect_task_types_from_statements(statements, task_types, visited)
618
+ each_ir_statement_for_type_collection(statements,
619
+ type_collector_method: :collect_task_type,
620
+ expression_walker_method: :collect_task_types_from_expression,
621
+ accumulator: task_types, visited:)
622
+ end
623
+
624
+ def collect_task_types_from_expression(expression, task_types, visited)
625
+ case expression
626
+ when IR::Member
627
+ collect_task_types_from_expression(expression.receiver, task_types, visited)
628
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
629
+ collect_task_types_from_expression(expression.receiver, task_types, visited)
630
+ collect_task_types_from_expression(expression.index, task_types, visited)
631
+ when IR::Call
632
+ collect_task_type(expression.type, task_types, visited)
633
+ collect_task_types_from_expression(expression.callee, task_types, visited) unless expression.callee.is_a?(String)
634
+ expression.arguments.each { |argument| collect_task_types_from_expression(argument, task_types, visited) }
635
+ when IR::Unary
636
+ collect_task_types_from_expression(expression.operand, task_types, visited)
637
+ when IR::Binary
638
+ collect_task_types_from_expression(expression.left, task_types, visited)
639
+ collect_task_types_from_expression(expression.right, task_types, visited)
640
+ when IR::Conditional
641
+ collect_task_types_from_expression(expression.condition, task_types, visited)
642
+ collect_task_types_from_expression(expression.then_expression, task_types, visited)
643
+ collect_task_types_from_expression(expression.else_expression, task_types, visited)
644
+ when IR::ReinterpretExpr
645
+ collect_task_type(expression.target_type, task_types, visited)
646
+ collect_task_type(expression.source_type, task_types, visited)
647
+ collect_task_types_from_expression(expression.expression, task_types, visited)
648
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
649
+ collect_task_type(expression.target_type, task_types, visited)
650
+ when IR::AddressOf, IR::Cast
651
+ collect_task_types_from_expression(expression.expression, task_types, visited)
652
+ when IR::AggregateLiteral
653
+ collect_task_type(expression.type, task_types, visited)
654
+ expression.fields.each { |field| collect_task_types_from_expression(field.value, task_types, visited) }
655
+ when IR::ArrayLiteral
656
+ expression.elements.each { |element| collect_task_types_from_expression(element, task_types, visited) }
657
+ when IR::VariantLiteral
658
+ collect_task_type(expression.type, task_types, visited)
659
+ expression.fields.each { |field| collect_task_types_from_expression(field.value, task_types, visited) }
660
+ end
661
+ end
662
+
663
+ def collect_task_type(type, task_types, visited)
664
+ return unless type
665
+ return if visited[type]
666
+
667
+ visited[type] = true
668
+
669
+ case type
670
+ when Types::Nullable
671
+ collect_task_type(type.base, task_types, visited)
672
+ when Types::Task
673
+ task_types << type
674
+ collect_task_type(type.result_type, task_types, visited)
675
+ when Types::Span
676
+ collect_task_type(type.element_type, task_types, visited)
677
+ when Types::StructInstance
678
+ type.arguments.each do |argument|
679
+ collect_task_type(argument, task_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
680
+ end
681
+ type.fields.each_value do |field_type|
682
+ collect_task_type(field_type, task_types, visited)
683
+ end
684
+ when Types::GenericInstance
685
+ type.arguments.each do |argument|
686
+ collect_task_type(argument, task_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
687
+ end
688
+ when Types::Function
689
+ type.params.each do |param|
690
+ collect_task_type(param.type, task_types, visited)
691
+ end
692
+ collect_task_type(type.return_type, task_types, visited)
693
+ when Types::Struct, Types::Union
694
+ type.fields.each_value do |field_type|
695
+ collect_task_type(field_type, task_types, visited)
696
+ end
697
+ when Types::Variant
698
+ type.arm_names.each do |arm_name|
699
+ type.arm(arm_name).each_value do |field_type|
700
+ collect_task_type(field_type, task_types, visited)
662
701
  end
663
702
  end
703
+ end
704
+ end
664
705
 
665
- def collect_task_type(type, task_types, visited)
666
- return unless type
667
- return if visited[type]
706
+ def collect_generic_variant_types
707
+ generic_variant_types = []
708
+ visited = {}
668
709
 
669
- visited[type] = true
710
+ all_emitted_top_level_values.each do |value|
711
+ collect_generic_variant_type(value.type, generic_variant_types, visited)
712
+ end
670
713
 
671
- case type
672
- when Types::Nullable
673
- collect_task_type(type.base, task_types, visited)
674
- when Types::Task
675
- task_types << type
676
- collect_task_type(type.result_type, task_types, visited)
677
- when Types::Span
678
- collect_task_type(type.element_type, task_types, visited)
679
- when Types::StructInstance
680
- type.arguments.each do |argument|
681
- collect_task_type(argument, task_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
682
- end
683
- type.fields.each_value do |field_type|
684
- collect_task_type(field_type, task_types, visited)
685
- end
686
- when Types::GenericInstance
687
- type.arguments.each do |argument|
688
- collect_task_type(argument, task_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
689
- end
690
- when Types::Function
691
- type.params.each do |param|
692
- collect_task_type(param.type, task_types, visited)
693
- end
694
- collect_task_type(type.return_type, task_types, visited)
695
- when Types::Struct, Types::Union
696
- type.fields.each_value do |field_type|
697
- collect_task_type(field_type, task_types, visited)
698
- end
699
- when Types::Variant
700
- type.arm_names.each do |arm_name|
701
- type.arm(arm_name).each_value do |field_type|
702
- collect_task_type(field_type, task_types, visited)
703
- end
704
- end
705
- end
714
+ @program.structs.each do |struct_decl|
715
+ struct_decl.fields.each do |field|
716
+ collect_generic_variant_type(field.type, generic_variant_types, visited)
706
717
  end
718
+ end
707
719
 
708
- def collect_generic_variant_types
709
- generic_variant_types = []
710
- visited = {}
711
-
712
- all_emitted_top_level_values.each do |value|
713
- collect_generic_variant_type(value.type, generic_variant_types, visited)
714
- end
720
+ @program.unions.each do |union_decl|
721
+ union_decl.fields.each do |field|
722
+ collect_generic_variant_type(field.type, generic_variant_types, visited)
723
+ end
724
+ end
715
725
 
716
- @program.structs.each do |struct_decl|
717
- struct_decl.fields.each do |field|
718
- collect_generic_variant_type(field.type, generic_variant_types, visited)
719
- end
720
- end
726
+ each_variant_arm_field_type do |field_type|
727
+ collect_generic_variant_type(field_type, generic_variant_types, visited)
728
+ end
721
729
 
722
- @program.unions.each do |union_decl|
723
- union_decl.fields.each do |field|
724
- collect_generic_variant_type(field.type, generic_variant_types, visited)
725
- end
726
- end
727
-
728
- each_variant_arm_field_type do |field_type|
730
+ emitted_functions.each do |function|
731
+ collect_generic_variant_type(function.return_type, generic_variant_types, visited)
732
+ function.params.each do |param|
733
+ collect_generic_variant_type(param.type, generic_variant_types, visited)
734
+ end
735
+ collect_generic_variant_types_from_statements(function.body, generic_variant_types, visited)
736
+ end
737
+
738
+ @program.static_asserts.each do |statement|
739
+ collect_generic_variant_types_from_expression(statement.condition, generic_variant_types, visited)
740
+ collect_generic_variant_types_from_expression(statement.message, generic_variant_types, visited)
741
+ end
742
+
743
+ generic_variant_types
744
+ end
745
+
746
+ def collect_generic_variant_types_from_statements(statements, generic_variant_types, visited)
747
+ each_ir_statement_for_type_collection(statements,
748
+ type_collector_method: :collect_generic_variant_type,
749
+ expression_walker_method: :collect_generic_variant_types_from_expression,
750
+ accumulator: generic_variant_types, visited:)
751
+ end
752
+
753
+ def collect_generic_variant_types_from_expression(expression, generic_variant_types, visited)
754
+ case expression
755
+ when IR::Member
756
+ collect_generic_variant_types_from_expression(expression.receiver, generic_variant_types, visited)
757
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
758
+ collect_generic_variant_types_from_expression(expression.receiver, generic_variant_types, visited)
759
+ collect_generic_variant_types_from_expression(expression.index, generic_variant_types, visited)
760
+ when IR::Call
761
+ collect_generic_variant_type(expression.type, generic_variant_types, visited)
762
+ collect_generic_variant_types_from_expression(expression.callee, generic_variant_types, visited) unless expression.callee.is_a?(String)
763
+ expression.arguments.each { |argument| collect_generic_variant_types_from_expression(argument, generic_variant_types, visited) }
764
+ when IR::Unary
765
+ collect_generic_variant_types_from_expression(expression.operand, generic_variant_types, visited)
766
+ when IR::Binary
767
+ collect_generic_variant_types_from_expression(expression.left, generic_variant_types, visited)
768
+ collect_generic_variant_types_from_expression(expression.right, generic_variant_types, visited)
769
+ when IR::Conditional
770
+ collect_generic_variant_types_from_expression(expression.condition, generic_variant_types, visited)
771
+ collect_generic_variant_types_from_expression(expression.then_expression, generic_variant_types, visited)
772
+ collect_generic_variant_types_from_expression(expression.else_expression, generic_variant_types, visited)
773
+ when IR::ReinterpretExpr
774
+ collect_generic_variant_type(expression.target_type, generic_variant_types, visited)
775
+ collect_generic_variant_type(expression.source_type, generic_variant_types, visited)
776
+ collect_generic_variant_types_from_expression(expression.expression, generic_variant_types, visited)
777
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
778
+ collect_generic_variant_type(expression.target_type, generic_variant_types, visited)
779
+ when IR::AddressOf, IR::Cast
780
+ collect_generic_variant_types_from_expression(expression.expression, generic_variant_types, visited)
781
+ when IR::AggregateLiteral
782
+ collect_generic_variant_type(expression.type, generic_variant_types, visited)
783
+ expression.fields.each { |field| collect_generic_variant_types_from_expression(field.value, generic_variant_types, visited) }
784
+ when IR::ArrayLiteral
785
+ expression.elements.each { |element| collect_generic_variant_types_from_expression(element, generic_variant_types, visited) }
786
+ when IR::VariantLiteral
787
+ collect_generic_variant_type(expression.type, generic_variant_types, visited)
788
+ expression.fields.each { |field| collect_generic_variant_types_from_expression(field.value, generic_variant_types, visited) }
789
+ end
790
+ end
791
+
792
+ def collect_generic_variant_type(type, generic_variant_types, visited)
793
+ return unless type
794
+ return if visited[type]
795
+
796
+ visited[type] = true
797
+
798
+ case type
799
+ when Types::Nullable
800
+ collect_generic_variant_type(type.base, generic_variant_types, visited)
801
+ when Types::Task
802
+ collect_generic_variant_type(type.result_type, generic_variant_types, visited)
803
+ when Types::Span
804
+ collect_generic_variant_type(type.element_type, generic_variant_types, visited)
805
+ when Types::VariantInstance
806
+ type.arguments.each do |argument|
807
+ collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
808
+ end
809
+ type.arm_names.each do |arm_name|
810
+ type.arm(arm_name).each_value do |field_type|
729
811
  collect_generic_variant_type(field_type, generic_variant_types, visited)
730
812
  end
731
-
732
- emitted_functions.each do |function|
733
- collect_generic_variant_type(function.return_type, generic_variant_types, visited)
734
- function.params.each do |param|
735
- collect_generic_variant_type(param.type, generic_variant_types, visited)
736
- end
737
- collect_generic_variant_types_from_statements(function.body, generic_variant_types, visited)
738
- end
739
-
740
- @program.static_asserts.each do |statement|
741
- collect_generic_variant_types_from_expression(statement.condition, generic_variant_types, visited)
742
- collect_generic_variant_types_from_expression(statement.message, generic_variant_types, visited)
743
- end
744
-
745
- generic_variant_types
746
- end
747
-
748
- def collect_generic_variant_types_from_statements(statements, generic_variant_types, visited)
749
- each_ir_statement_for_type_collection(statements,
750
- type_collector_method: :collect_generic_variant_type,
751
- expression_walker_method: :collect_generic_variant_types_from_expression,
752
- accumulator: generic_variant_types, visited:)
753
- end
754
-
755
- def collect_generic_variant_types_from_expression(expression, generic_variant_types, visited)
756
- case expression
757
- when IR::Member
758
- collect_generic_variant_types_from_expression(expression.receiver, generic_variant_types, visited)
759
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
760
- collect_generic_variant_types_from_expression(expression.receiver, generic_variant_types, visited)
761
- collect_generic_variant_types_from_expression(expression.index, generic_variant_types, visited)
762
- when IR::Call
763
- collect_generic_variant_type(expression.type, generic_variant_types, visited)
764
- collect_generic_variant_types_from_expression(expression.callee, generic_variant_types, visited) unless expression.callee.is_a?(String)
765
- expression.arguments.each { |argument| collect_generic_variant_types_from_expression(argument, generic_variant_types, visited) }
766
- when IR::Unary
767
- collect_generic_variant_types_from_expression(expression.operand, generic_variant_types, visited)
768
- when IR::Binary
769
- collect_generic_variant_types_from_expression(expression.left, generic_variant_types, visited)
770
- collect_generic_variant_types_from_expression(expression.right, generic_variant_types, visited)
771
- when IR::Conditional
772
- collect_generic_variant_types_from_expression(expression.condition, generic_variant_types, visited)
773
- collect_generic_variant_types_from_expression(expression.then_expression, generic_variant_types, visited)
774
- collect_generic_variant_types_from_expression(expression.else_expression, generic_variant_types, visited)
775
- when IR::ReinterpretExpr
776
- collect_generic_variant_type(expression.target_type, generic_variant_types, visited)
777
- collect_generic_variant_type(expression.source_type, generic_variant_types, visited)
778
- collect_generic_variant_types_from_expression(expression.expression, generic_variant_types, visited)
779
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
780
- collect_generic_variant_type(expression.target_type, generic_variant_types, visited)
781
- when IR::AddressOf, IR::Cast
782
- collect_generic_variant_types_from_expression(expression.expression, generic_variant_types, visited)
783
- when IR::AggregateLiteral
784
- collect_generic_variant_type(expression.type, generic_variant_types, visited)
785
- expression.fields.each { |field| collect_generic_variant_types_from_expression(field.value, generic_variant_types, visited) }
786
- when IR::ArrayLiteral
787
- expression.elements.each { |element| collect_generic_variant_types_from_expression(element, generic_variant_types, visited) }
788
- when IR::VariantLiteral
789
- collect_generic_variant_type(expression.type, generic_variant_types, visited)
790
- expression.fields.each { |field| collect_generic_variant_types_from_expression(field.value, generic_variant_types, visited) }
813
+ end
814
+ generic_variant_types << type
815
+ when Types::StructInstance
816
+ type.arguments.each do |argument|
817
+ collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
818
+ end
819
+ type.fields.each_value do |field_type|
820
+ collect_generic_variant_type(field_type, generic_variant_types, visited)
821
+ end
822
+ when Types::GenericInstance
823
+ type.arguments.each do |argument|
824
+ collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
825
+ end
826
+ when Types::Function, Types::Proc
827
+ type.params.each do |param|
828
+ collect_generic_variant_type(param.type, generic_variant_types, visited)
829
+ end
830
+ collect_generic_variant_type(type.return_type, generic_variant_types, visited)
831
+ when Types::Struct, Types::Union
832
+ type.fields.each_value do |field_type|
833
+ collect_generic_variant_type(field_type, generic_variant_types, visited)
834
+ end
835
+ when Types::Variant
836
+ type.arm_names.each do |arm_name|
837
+ type.arm(arm_name).each_value do |field_type|
838
+ collect_generic_variant_type(field_type, generic_variant_types, visited)
791
839
  end
792
840
  end
841
+ end
842
+ end
793
843
 
794
- def collect_generic_variant_type(type, generic_variant_types, visited)
795
- return unless type
796
- return if visited[type]
844
+ def collect_generic_struct_types
845
+ generic_struct_types = []
846
+ visited = {}
797
847
 
798
- visited[type] = true
848
+ all_emitted_top_level_values.each do |value|
849
+ collect_generic_struct_type(value.type, generic_struct_types, visited)
850
+ end
799
851
 
800
- case type
801
- when Types::Nullable
802
- collect_generic_variant_type(type.base, generic_variant_types, visited)
803
- when Types::Task
804
- collect_generic_variant_type(type.result_type, generic_variant_types, visited)
805
- when Types::Span
806
- collect_generic_variant_type(type.element_type, generic_variant_types, visited)
807
- when Types::VariantInstance
808
- type.arguments.each do |argument|
809
- collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
810
- end
811
- type.arm_names.each do |arm_name|
812
- type.arm(arm_name).each_value do |field_type|
813
- collect_generic_variant_type(field_type, generic_variant_types, visited)
814
- end
815
- end
816
- generic_variant_types << type
817
- when Types::StructInstance
818
- type.arguments.each do |argument|
819
- collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
820
- end
821
- type.fields.each_value do |field_type|
822
- collect_generic_variant_type(field_type, generic_variant_types, visited)
823
- end
824
- when Types::GenericInstance
825
- type.arguments.each do |argument|
826
- collect_generic_variant_type(argument, generic_variant_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
827
- end
828
- when Types::Function, Types::Proc
829
- type.params.each do |param|
830
- collect_generic_variant_type(param.type, generic_variant_types, visited)
831
- end
832
- collect_generic_variant_type(type.return_type, generic_variant_types, visited)
833
- when Types::Struct, Types::Union
834
- type.fields.each_value do |field_type|
835
- collect_generic_variant_type(field_type, generic_variant_types, visited)
836
- end
837
- when Types::Variant
838
- type.arm_names.each do |arm_name|
839
- type.arm(arm_name).each_value do |field_type|
840
- collect_generic_variant_type(field_type, generic_variant_types, visited)
841
- end
842
- end
843
- end
852
+ @program.structs.each do |struct_decl|
853
+ struct_decl.fields.each do |field|
854
+ collect_generic_struct_type(field.type, generic_struct_types, visited)
844
855
  end
856
+ end
845
857
 
846
- def collect_generic_struct_types
847
- generic_struct_types = []
848
- visited = {}
858
+ @program.unions.each do |union_decl|
859
+ union_decl.fields.each do |field|
860
+ collect_generic_struct_type(field.type, generic_struct_types, visited)
861
+ end
862
+ end
849
863
 
850
- all_emitted_top_level_values.each do |value|
851
- collect_generic_struct_type(value.type, generic_struct_types, visited)
852
- end
864
+ each_variant_arm_field_type do |field_type|
865
+ collect_generic_struct_type(field_type, generic_struct_types, visited)
866
+ end
853
867
 
854
- @program.structs.each do |struct_decl|
855
- struct_decl.fields.each do |field|
856
- collect_generic_struct_type(field.type, generic_struct_types, visited)
857
- end
858
- end
868
+ emitted_functions.each do |function|
869
+ collect_generic_struct_type(function.return_type, generic_struct_types, visited)
870
+ function.params.each do |param|
871
+ collect_generic_struct_type(param.type, generic_struct_types, visited)
872
+ end
873
+ collect_generic_struct_types_from_statements(function.body, generic_struct_types, visited)
874
+ end
859
875
 
860
- @program.unions.each do |union_decl|
861
- union_decl.fields.each do |field|
862
- collect_generic_struct_type(field.type, generic_struct_types, visited)
863
- end
864
- end
876
+ @program.static_asserts.each do |statement|
877
+ collect_generic_struct_types_from_expression(statement.condition, generic_struct_types, visited)
878
+ collect_generic_struct_types_from_expression(statement.message, generic_struct_types, visited)
879
+ end
865
880
 
866
- each_variant_arm_field_type do |field_type|
867
- collect_generic_struct_type(field_type, generic_struct_types, visited)
868
- end
881
+ generic_struct_types
882
+ end
869
883
 
870
- emitted_functions.each do |function|
871
- collect_generic_struct_type(function.return_type, generic_struct_types, visited)
872
- function.params.each do |param|
873
- collect_generic_struct_type(param.type, generic_struct_types, visited)
874
- end
875
- collect_generic_struct_types_from_statements(function.body, generic_struct_types, visited)
876
- end
884
+ def collect_str_buffer_types
885
+ str_buffer_types = []
886
+ visited = {}
877
887
 
878
- @program.static_asserts.each do |statement|
879
- collect_generic_struct_types_from_expression(statement.condition, generic_struct_types, visited)
880
- collect_generic_struct_types_from_expression(statement.message, generic_struct_types, visited)
881
- end
888
+ all_emitted_top_level_values.each do |value|
889
+ collect_str_buffer_type(value.type, str_buffer_types, visited)
890
+ end
882
891
 
883
- generic_struct_types
892
+ @program.structs.each do |struct_decl|
893
+ struct_decl.fields.each do |field|
894
+ collect_str_buffer_type(field.type, str_buffer_types, visited)
884
895
  end
896
+ end
885
897
 
886
- def collect_str_buffer_types
887
- str_buffer_types = []
888
- visited = {}
889
-
890
- all_emitted_top_level_values.each do |value|
891
- collect_str_buffer_type(value.type, str_buffer_types, visited)
892
- end
893
-
894
- @program.structs.each do |struct_decl|
895
- struct_decl.fields.each do |field|
896
- collect_str_buffer_type(field.type, str_buffer_types, visited)
897
- end
898
- end
898
+ @program.unions.each do |union_decl|
899
+ union_decl.fields.each do |field|
900
+ collect_str_buffer_type(field.type, str_buffer_types, visited)
901
+ end
902
+ end
899
903
 
900
- @program.unions.each do |union_decl|
901
- union_decl.fields.each do |field|
902
- collect_str_buffer_type(field.type, str_buffer_types, visited)
903
- end
904
- end
904
+ each_variant_arm_field_type do |field_type|
905
+ collect_str_buffer_type(field_type, str_buffer_types, visited)
906
+ end
905
907
 
906
- each_variant_arm_field_type do |field_type|
908
+ emitted_functions.each do |function|
909
+ collect_str_buffer_type(function.return_type, str_buffer_types, visited)
910
+ function.params.each do |param|
911
+ collect_str_buffer_type(param.type, str_buffer_types, visited)
912
+ end
913
+ collect_str_buffer_types_from_statements(function.body, str_buffer_types, visited)
914
+ end
915
+
916
+ @program.static_asserts.each do |statement|
917
+ collect_str_buffer_types_from_expression(statement.condition, str_buffer_types, visited)
918
+ collect_str_buffer_types_from_expression(statement.message, str_buffer_types, visited)
919
+ end
920
+
921
+ str_buffer_types
922
+ end
923
+
924
+ def collect_str_buffer_types_from_statements(statements, str_buffer_types, visited)
925
+ each_ir_statement_for_type_collection(statements,
926
+ type_collector_method: :collect_str_buffer_type,
927
+ expression_walker_method: :collect_str_buffer_types_from_expression,
928
+ accumulator: str_buffer_types, visited:)
929
+ end
930
+
931
+ def collect_str_buffer_types_from_expression(expression, str_buffer_types, visited)
932
+ case expression
933
+ when IR::Member
934
+ collect_str_buffer_types_from_expression(expression.receiver, str_buffer_types, visited)
935
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
936
+ collect_str_buffer_types_from_expression(expression.receiver, str_buffer_types, visited)
937
+ collect_str_buffer_types_from_expression(expression.index, str_buffer_types, visited)
938
+ when IR::Call
939
+ collect_str_buffer_type(expression.type, str_buffer_types, visited)
940
+ collect_str_buffer_types_from_expression(expression.callee, str_buffer_types, visited) unless expression.callee.is_a?(String)
941
+ expression.arguments.each { |argument| collect_str_buffer_types_from_expression(argument, str_buffer_types, visited) }
942
+ when IR::Unary
943
+ collect_str_buffer_types_from_expression(expression.operand, str_buffer_types, visited)
944
+ when IR::Binary
945
+ collect_str_buffer_types_from_expression(expression.left, str_buffer_types, visited)
946
+ collect_str_buffer_types_from_expression(expression.right, str_buffer_types, visited)
947
+ when IR::Conditional
948
+ collect_str_buffer_types_from_expression(expression.condition, str_buffer_types, visited)
949
+ collect_str_buffer_types_from_expression(expression.then_expression, str_buffer_types, visited)
950
+ collect_str_buffer_types_from_expression(expression.else_expression, str_buffer_types, visited)
951
+ when IR::ReinterpretExpr
952
+ collect_str_buffer_type(expression.target_type, str_buffer_types, visited)
953
+ collect_str_buffer_type(expression.source_type, str_buffer_types, visited)
954
+ collect_str_buffer_types_from_expression(expression.expression, str_buffer_types, visited)
955
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
956
+ collect_str_buffer_type(expression.target_type, str_buffer_types, visited)
957
+ when IR::AddressOf, IR::Cast
958
+ collect_str_buffer_types_from_expression(expression.expression, str_buffer_types, visited)
959
+ when IR::AggregateLiteral
960
+ collect_str_buffer_type(expression.type, str_buffer_types, visited)
961
+ expression.fields.each { |field| collect_str_buffer_types_from_expression(field.value, str_buffer_types, visited) }
962
+ when IR::ArrayLiteral
963
+ expression.elements.each { |element| collect_str_buffer_types_from_expression(element, str_buffer_types, visited) }
964
+ when IR::VariantLiteral
965
+ collect_str_buffer_type(expression.type, str_buffer_types, visited)
966
+ expression.fields.each { |field| collect_str_buffer_types_from_expression(field.value, str_buffer_types, visited) }
967
+ end
968
+ end
969
+
970
+ def collect_str_buffer_type(type, str_buffer_types, visited)
971
+ return unless type
972
+ return if visited[type]
973
+
974
+ visited[type] = true
975
+
976
+ case type
977
+ when Types::Nullable
978
+ collect_str_buffer_type(type.base, str_buffer_types, visited)
979
+ when Types::Span
980
+ collect_str_buffer_type(type.element_type, str_buffer_types, visited)
981
+ when Types::StructInstance
982
+ type.arguments.each do |argument|
983
+ collect_str_buffer_type(argument, str_buffer_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
984
+ end
985
+ type.fields.each_value do |field_type|
986
+ collect_str_buffer_type(field_type, str_buffer_types, visited)
987
+ end
988
+ when Types::GenericInstance
989
+ str_buffer_types << type if str_buffer_type?(type)
990
+ type.arguments.each do |argument|
991
+ collect_str_buffer_type(argument, str_buffer_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
992
+ end
993
+ when Types::Function
994
+ type.params.each do |param|
995
+ collect_str_buffer_type(param.type, str_buffer_types, visited)
996
+ end
997
+ collect_str_buffer_type(type.return_type, str_buffer_types, visited)
998
+ when Types::Struct, Types::Union
999
+ type.fields.each_value do |field_type|
1000
+ collect_str_buffer_type(field_type, str_buffer_types, visited)
1001
+ end
1002
+ when Types::Variant
1003
+ type.arm_names.each do |arm_name|
1004
+ type.arm(arm_name).each_value do |field_type|
907
1005
  collect_str_buffer_type(field_type, str_buffer_types, visited)
908
1006
  end
909
-
910
- emitted_functions.each do |function|
911
- collect_str_buffer_type(function.return_type, str_buffer_types, visited)
912
- function.params.each do |param|
913
- collect_str_buffer_type(param.type, str_buffer_types, visited)
914
- end
915
- collect_str_buffer_types_from_statements(function.body, str_buffer_types, visited)
916
- end
917
-
918
- @program.static_asserts.each do |statement|
919
- collect_str_buffer_types_from_expression(statement.condition, str_buffer_types, visited)
920
- collect_str_buffer_types_from_expression(statement.message, str_buffer_types, visited)
921
- end
922
-
923
- str_buffer_types
924
- end
925
-
926
- def collect_str_buffer_types_from_statements(statements, str_buffer_types, visited)
927
- each_ir_statement_for_type_collection(statements,
928
- type_collector_method: :collect_str_buffer_type,
929
- expression_walker_method: :collect_str_buffer_types_from_expression,
930
- accumulator: str_buffer_types, visited:)
931
- end
932
-
933
- def collect_str_buffer_types_from_expression(expression, str_buffer_types, visited)
934
- case expression
935
- when IR::Member
936
- collect_str_buffer_types_from_expression(expression.receiver, str_buffer_types, visited)
937
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
938
- collect_str_buffer_types_from_expression(expression.receiver, str_buffer_types, visited)
939
- collect_str_buffer_types_from_expression(expression.index, str_buffer_types, visited)
940
- when IR::Call
941
- collect_str_buffer_type(expression.type, str_buffer_types, visited)
942
- collect_str_buffer_types_from_expression(expression.callee, str_buffer_types, visited) unless expression.callee.is_a?(String)
943
- expression.arguments.each { |argument| collect_str_buffer_types_from_expression(argument, str_buffer_types, visited) }
944
- when IR::Unary
945
- collect_str_buffer_types_from_expression(expression.operand, str_buffer_types, visited)
946
- when IR::Binary
947
- collect_str_buffer_types_from_expression(expression.left, str_buffer_types, visited)
948
- collect_str_buffer_types_from_expression(expression.right, str_buffer_types, visited)
949
- when IR::Conditional
950
- collect_str_buffer_types_from_expression(expression.condition, str_buffer_types, visited)
951
- collect_str_buffer_types_from_expression(expression.then_expression, str_buffer_types, visited)
952
- collect_str_buffer_types_from_expression(expression.else_expression, str_buffer_types, visited)
953
- when IR::ReinterpretExpr
954
- collect_str_buffer_type(expression.target_type, str_buffer_types, visited)
955
- collect_str_buffer_type(expression.source_type, str_buffer_types, visited)
956
- collect_str_buffer_types_from_expression(expression.expression, str_buffer_types, visited)
957
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
958
- collect_str_buffer_type(expression.target_type, str_buffer_types, visited)
959
- when IR::AddressOf, IR::Cast
960
- collect_str_buffer_types_from_expression(expression.expression, str_buffer_types, visited)
961
- when IR::AggregateLiteral
962
- collect_str_buffer_type(expression.type, str_buffer_types, visited)
963
- expression.fields.each { |field| collect_str_buffer_types_from_expression(field.value, str_buffer_types, visited) }
964
- when IR::ArrayLiteral
965
- expression.elements.each { |element| collect_str_buffer_types_from_expression(element, str_buffer_types, visited) }
966
- when IR::VariantLiteral
967
- collect_str_buffer_type(expression.type, str_buffer_types, visited)
968
- expression.fields.each { |field| collect_str_buffer_types_from_expression(field.value, str_buffer_types, visited) }
969
- end
970
1007
  end
971
-
972
- def collect_str_buffer_type(type, str_buffer_types, visited)
973
- return unless type
974
- return if visited[type]
975
-
976
- visited[type] = true
977
-
978
- case type
979
- when Types::Nullable
980
- collect_str_buffer_type(type.base, str_buffer_types, visited)
981
- when Types::Span
982
- collect_str_buffer_type(type.element_type, str_buffer_types, visited)
983
- when Types::StructInstance
984
- type.arguments.each do |argument|
985
- collect_str_buffer_type(argument, str_buffer_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
986
- end
987
- type.fields.each_value do |field_type|
988
- collect_str_buffer_type(field_type, str_buffer_types, visited)
989
- end
990
- when Types::GenericInstance
991
- str_buffer_types << type if str_buffer_type?(type)
992
- type.arguments.each do |argument|
993
- collect_str_buffer_type(argument, str_buffer_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
994
- end
995
- when Types::Function
996
- type.params.each do |param|
997
- collect_str_buffer_type(param.type, str_buffer_types, visited)
998
- end
999
- collect_str_buffer_type(type.return_type, str_buffer_types, visited)
1000
- when Types::Struct, Types::Union
1001
- type.fields.each_value do |field_type|
1002
- collect_str_buffer_type(field_type, str_buffer_types, visited)
1003
- end
1004
- when Types::Variant
1005
- type.arm_names.each do |arm_name|
1006
- type.arm(arm_name).each_value do |field_type|
1007
- collect_str_buffer_type(field_type, str_buffer_types, visited)
1008
- end
1009
- end
1010
- end
1008
+ end
1009
+ end
1010
+
1011
+ def collect_generic_struct_types_from_statements(statements, generic_struct_types, visited)
1012
+ each_ir_statement_for_type_collection(statements,
1013
+ type_collector_method: :collect_generic_struct_type,
1014
+ expression_walker_method: :collect_generic_struct_types_from_expression,
1015
+ accumulator: generic_struct_types, visited:)
1016
+ end
1017
+
1018
+ def collect_generic_struct_types_from_expression(expression, generic_struct_types, visited)
1019
+ case expression
1020
+ when IR::Member
1021
+ collect_generic_struct_types_from_expression(expression.receiver, generic_struct_types, visited)
1022
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1023
+ collect_generic_struct_types_from_expression(expression.receiver, generic_struct_types, visited)
1024
+ collect_generic_struct_types_from_expression(expression.index, generic_struct_types, visited)
1025
+ when IR::Call
1026
+ collect_generic_struct_type(expression.type, generic_struct_types, visited)
1027
+ collect_generic_struct_types_from_expression(expression.callee, generic_struct_types, visited) unless expression.callee.is_a?(String)
1028
+ expression.arguments.each { |argument| collect_generic_struct_types_from_expression(argument, generic_struct_types, visited) }
1029
+ when IR::Unary
1030
+ collect_generic_struct_types_from_expression(expression.operand, generic_struct_types, visited)
1031
+ when IR::Binary
1032
+ collect_generic_struct_types_from_expression(expression.left, generic_struct_types, visited)
1033
+ collect_generic_struct_types_from_expression(expression.right, generic_struct_types, visited)
1034
+ when IR::Conditional
1035
+ collect_generic_struct_types_from_expression(expression.condition, generic_struct_types, visited)
1036
+ collect_generic_struct_types_from_expression(expression.then_expression, generic_struct_types, visited)
1037
+ collect_generic_struct_types_from_expression(expression.else_expression, generic_struct_types, visited)
1038
+ when IR::ReinterpretExpr
1039
+ collect_generic_struct_type(expression.target_type, generic_struct_types, visited)
1040
+ collect_generic_struct_type(expression.source_type, generic_struct_types, visited)
1041
+ collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1042
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
1043
+ collect_generic_struct_type(expression.target_type, generic_struct_types, visited)
1044
+ when IR::AddressOf
1045
+ collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1046
+ when IR::Cast
1047
+ collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1048
+ when IR::AggregateLiteral
1049
+ collect_generic_struct_type(expression.type, generic_struct_types, visited)
1050
+ expression.fields.each { |field| collect_generic_struct_types_from_expression(field.value, generic_struct_types, visited) }
1051
+ when IR::ArrayLiteral
1052
+ expression.elements.each { |element| collect_generic_struct_types_from_expression(element, generic_struct_types, visited) }
1053
+ when IR::VariantLiteral
1054
+ collect_generic_struct_type(expression.type, generic_struct_types, visited)
1055
+ expression.fields.each { |field| collect_generic_struct_types_from_expression(field.value, generic_struct_types, visited) }
1056
+ end
1057
+ end
1058
+
1059
+ def collect_generic_struct_type(type, generic_struct_types, visited)
1060
+ return unless type
1061
+ return if visited[type]
1062
+
1063
+ visited[type] = true
1064
+
1065
+ case type
1066
+ when Types::Nullable
1067
+ collect_generic_struct_type(type.base, generic_struct_types, visited)
1068
+ when Types::Span
1069
+ collect_generic_struct_type(type.element_type, generic_struct_types, visited)
1070
+ when Types::StructInstance
1071
+ generic_struct_types << type
1072
+ type.arguments.each do |argument|
1073
+ collect_generic_struct_type(argument, generic_struct_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1011
1074
  end
1012
-
1013
- def collect_generic_struct_types_from_statements(statements, generic_struct_types, visited)
1014
- each_ir_statement_for_type_collection(statements,
1015
- type_collector_method: :collect_generic_struct_type,
1016
- expression_walker_method: :collect_generic_struct_types_from_expression,
1017
- accumulator: generic_struct_types, visited:)
1018
- end
1019
-
1020
- def collect_generic_struct_types_from_expression(expression, generic_struct_types, visited)
1021
- case expression
1022
- when IR::Member
1023
- collect_generic_struct_types_from_expression(expression.receiver, generic_struct_types, visited)
1024
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1025
- collect_generic_struct_types_from_expression(expression.receiver, generic_struct_types, visited)
1026
- collect_generic_struct_types_from_expression(expression.index, generic_struct_types, visited)
1027
- when IR::Call
1028
- collect_generic_struct_type(expression.type, generic_struct_types, visited)
1029
- collect_generic_struct_types_from_expression(expression.callee, generic_struct_types, visited) unless expression.callee.is_a?(String)
1030
- expression.arguments.each { |argument| collect_generic_struct_types_from_expression(argument, generic_struct_types, visited) }
1031
- when IR::Unary
1032
- collect_generic_struct_types_from_expression(expression.operand, generic_struct_types, visited)
1033
- when IR::Binary
1034
- collect_generic_struct_types_from_expression(expression.left, generic_struct_types, visited)
1035
- collect_generic_struct_types_from_expression(expression.right, generic_struct_types, visited)
1036
- when IR::Conditional
1037
- collect_generic_struct_types_from_expression(expression.condition, generic_struct_types, visited)
1038
- collect_generic_struct_types_from_expression(expression.then_expression, generic_struct_types, visited)
1039
- collect_generic_struct_types_from_expression(expression.else_expression, generic_struct_types, visited)
1040
- when IR::ReinterpretExpr
1041
- collect_generic_struct_type(expression.target_type, generic_struct_types, visited)
1042
- collect_generic_struct_type(expression.source_type, generic_struct_types, visited)
1043
- collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1044
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
1045
- collect_generic_struct_type(expression.target_type, generic_struct_types, visited)
1046
- when IR::AddressOf
1047
- collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1048
- when IR::Cast
1049
- collect_generic_struct_types_from_expression(expression.expression, generic_struct_types, visited)
1050
- when IR::AggregateLiteral
1051
- collect_generic_struct_type(expression.type, generic_struct_types, visited)
1052
- expression.fields.each { |field| collect_generic_struct_types_from_expression(field.value, generic_struct_types, visited) }
1053
- when IR::ArrayLiteral
1054
- expression.elements.each { |element| collect_generic_struct_types_from_expression(element, generic_struct_types, visited) }
1055
- when IR::VariantLiteral
1056
- collect_generic_struct_type(expression.type, generic_struct_types, visited)
1057
- expression.fields.each { |field| collect_generic_struct_types_from_expression(field.value, generic_struct_types, visited) }
1058
- end
1075
+ type.fields.each_value do |field_type|
1076
+ collect_generic_struct_type(field_type, generic_struct_types, visited)
1059
1077
  end
1060
-
1061
- def collect_generic_struct_type(type, generic_struct_types, visited)
1062
- return unless type
1063
- return if visited[type]
1064
-
1065
- visited[type] = true
1066
-
1067
- case type
1068
- when Types::Nullable
1069
- collect_generic_struct_type(type.base, generic_struct_types, visited)
1070
- when Types::Span
1071
- collect_generic_struct_type(type.element_type, generic_struct_types, visited)
1072
- when Types::StructInstance
1073
- generic_struct_types << type
1074
- type.arguments.each do |argument|
1075
- collect_generic_struct_type(argument, generic_struct_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1076
- end
1077
- type.fields.each_value do |field_type|
1078
- collect_generic_struct_type(field_type, generic_struct_types, visited)
1079
- end
1080
- when Types::GenericInstance
1081
- type.arguments.each do |argument|
1082
- collect_generic_struct_type(argument, generic_struct_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1083
- end
1084
- when Types::Function
1085
- type.params.each do |param|
1086
- collect_generic_struct_type(param.type, generic_struct_types, visited)
1087
- end
1088
- collect_generic_struct_type(type.return_type, generic_struct_types, visited)
1089
- when Types::Struct, Types::Union
1090
- type.fields.each_value do |field_type|
1091
- collect_generic_struct_type(field_type, generic_struct_types, visited)
1092
- end
1093
- when Types::Variant
1094
- type.arm_names.each do |arm_name|
1095
- type.arm(arm_name).each_value do |field_type|
1096
- collect_generic_struct_type(field_type, generic_struct_types, visited)
1097
- end
1098
- end
1099
- end
1078
+ when Types::GenericInstance
1079
+ type.arguments.each do |argument|
1080
+ collect_generic_struct_type(argument, generic_struct_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1100
1081
  end
1101
-
1102
- def collect_span_types_from_statements(statements, span_types, visited)
1103
- each_ir_statement_for_type_collection(statements,
1104
- type_collector_method: :collect_span_type,
1105
- expression_walker_method: :collect_span_types_from_expression,
1106
- accumulator: span_types, visited:)
1107
- end
1108
-
1109
- def collect_span_types_from_expression(expression, span_types, visited)
1110
- case expression
1111
- when IR::Member
1112
- collect_span_types_from_expression(expression.receiver, span_types, visited)
1113
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1114
- collect_span_types_from_expression(expression.receiver, span_types, visited)
1115
- collect_span_types_from_expression(expression.index, span_types, visited)
1116
- when IR::Call
1117
- collect_span_type(expression.type, span_types, visited)
1118
- collect_span_types_from_expression(expression.callee, span_types, visited) unless expression.callee.is_a?(String)
1119
- expression.arguments.each { |argument| collect_span_types_from_expression(argument, span_types, visited) }
1120
- when IR::Unary
1121
- collect_span_types_from_expression(expression.operand, span_types, visited)
1122
- when IR::Binary
1123
- collect_span_types_from_expression(expression.left, span_types, visited)
1124
- collect_span_types_from_expression(expression.right, span_types, visited)
1125
- when IR::Conditional
1126
- collect_span_types_from_expression(expression.condition, span_types, visited)
1127
- collect_span_types_from_expression(expression.then_expression, span_types, visited)
1128
- collect_span_types_from_expression(expression.else_expression, span_types, visited)
1129
- when IR::ReinterpretExpr
1130
- collect_span_type(expression.target_type, span_types, visited)
1131
- collect_span_type(expression.source_type, span_types, visited)
1132
- collect_span_types_from_expression(expression.expression, span_types, visited)
1133
- when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
1134
- collect_span_type(expression.target_type, span_types, visited)
1135
- when IR::AddressOf
1136
- collect_span_types_from_expression(expression.expression, span_types, visited)
1137
- when IR::Cast
1138
- collect_span_types_from_expression(expression.expression, span_types, visited)
1139
- when IR::AggregateLiteral
1140
- collect_span_type(expression.type, span_types, visited)
1141
- expression.fields.each { |field| collect_span_types_from_expression(field.value, span_types, visited) }
1142
- when IR::ArrayLiteral
1143
- expression.elements.each { |element| collect_span_types_from_expression(element, span_types, visited) }
1144
- when IR::VariantLiteral
1145
- collect_span_type(expression.type, span_types, visited)
1146
- expression.fields.each { |field| collect_span_types_from_expression(field.value, span_types, visited) }
1147
- end
1082
+ when Types::Function
1083
+ type.params.each do |param|
1084
+ collect_generic_struct_type(param.type, generic_struct_types, visited)
1148
1085
  end
1149
-
1150
- def collect_span_type(type, span_types, visited)
1151
- return unless type
1152
- return if visited[type]
1153
-
1154
- visited[type] = true
1155
-
1156
- case type
1157
- when Types::Nullable
1158
- collect_span_type(type.base, span_types, visited)
1159
- when Types::Span
1160
- span_types << type
1161
- collect_span_type(type.element_type, span_types, visited)
1162
- when Types::GenericInstance
1163
- type.arguments.each do |argument|
1164
- collect_span_type(argument, span_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1165
- end
1166
- when Types::Function
1167
- type.params.each do |param|
1168
- collect_span_type(param.type, span_types, visited)
1169
- end
1170
- collect_span_type(type.return_type, span_types, visited)
1171
- when Types::Struct, Types::Union
1172
- type.fields.each_value do |field_type|
1173
- collect_span_type(field_type, span_types, visited)
1174
- end
1175
- when Types::Variant
1176
- type.arm_names.each do |arm_name|
1177
- type.arm(arm_name).each_value do |field_type|
1178
- collect_span_type(field_type, span_types, visited)
1179
- end
1180
- end
1181
- end
1086
+ collect_generic_struct_type(type.return_type, generic_struct_types, visited)
1087
+ when Types::Struct, Types::Union
1088
+ type.fields.each_value do |field_type|
1089
+ collect_generic_struct_type(field_type, generic_struct_types, visited)
1182
1090
  end
1183
-
1184
- def collect_dyn_decls
1185
- void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
1186
- collect_dyn_types.map do |type|
1187
- IR::StructDecl.new(
1188
- name: type.to_s,
1189
- linkage_name: dyn_type_name(type),
1190
- fields: [
1191
- IR::Field.new(name: "data", type: void_ptr),
1192
- IR::Field.new(name: "vtable", type: void_ptr),
1193
- ],
1194
- packed: false,
1195
- alignment: nil,
1196
- )
1091
+ when Types::Variant
1092
+ type.arm_names.each do |arm_name|
1093
+ type.arm(arm_name).each_value do |field_type|
1094
+ collect_generic_struct_type(field_type, generic_struct_types, visited)
1197
1095
  end
1198
1096
  end
1199
-
1200
- def collect_dyn_types
1201
- dyn_types = []
1202
- seen = []
1203
-
1204
- collect_type = lambda do |type|
1205
- return unless type
1206
- case type
1207
- when Types::Dyn
1208
- name = type.interface_binding.name
1209
- unless seen.include?(name)
1210
- seen << name
1211
- dyn_types << type
1212
- end
1213
- when Types::Nullable
1214
- collect_type.call(type.base)
1215
- when Types::GenericInstance
1216
- type.arguments.each { |arg| collect_type.call(arg) unless arg.is_a?(Types::LiteralTypeArg) }
1217
- when Types::Span
1218
- collect_type.call(type.element_type)
1219
- when Types::Task
1220
- collect_type.call(type.result_type)
1221
- when Types::Function
1222
- type.params.each { |p| collect_type.call(p.type) }
1223
- collect_type.call(type.return_type)
1224
- when Types::Proc
1225
- type.params.each { |p| collect_type.call(p.type) }
1226
- collect_type.call(type.return_type)
1227
- when Types::StructInstance
1228
- type.arguments.each { |arg| collect_type.call(arg) }
1229
- when Types::VariantInstance
1230
- type.arguments.each { |arg| collect_type.call(arg) }
1231
- end
1232
- end
1233
-
1234
- collect_in_stmt = lambda do |stmt|
1235
- case stmt
1236
- when IR::LocalDecl
1237
- collect_type.call(stmt.type)
1238
- when IR::BlockStmt
1239
- stmt.body.each { |s| collect_in_stmt.call(s) }
1240
- when IR::IfStmt
1241
- stmt.then_body.each { |s| collect_in_stmt.call(s) }
1242
- stmt.else_body&.each { |s| collect_in_stmt.call(s) }
1243
- when IR::WhileStmt
1244
- stmt.body.each { |s| collect_in_stmt.call(s) }
1245
- when IR::ForStmt
1246
- stmt.body.each { |s| collect_in_stmt.call(s) }
1247
- when IR::SwitchStmt
1248
- stmt.cases.each { |c| c.body.each { |s| collect_in_stmt.call(s) } }
1249
- end
1250
- end
1251
-
1252
- if @program
1253
- @program.constants.each { |c| collect_type.call(c.type) }
1254
- @program.globals.each { |g| collect_type.call(g.type) }
1255
- @program.structs.each { |s| s.fields.each { |f| collect_type.call(f.type) } }
1256
- @program.unions.each { |u| u.fields.each { |f| collect_type.call(f.type) } }
1257
- @program.functions.each do |f|
1258
- collect_type.call(f.return_type)
1259
- f.params.each { |p| collect_type.call(p.type) }
1260
- body = f.body
1261
- if body.is_a?(IR::BlockStmt)
1262
- body.body.each { |s| collect_in_stmt.call(s) }
1263
- elsif body.is_a?(Array)
1264
- body.each { |s| collect_in_stmt.call(s) }
1265
- end
1266
- end
1267
- end
1268
-
1269
- dyn_types
1270
- end
1271
-
1272
- def collect_nullable_opt_decls
1273
- collect_nullable_opt_types.map do |type|
1274
- IR::StructDecl.new(
1275
- name: type.to_s,
1276
- linkage_name: nullable_opt_type_name(type),
1277
- fields: [
1278
- IR::Field.new(name: "has_value", type: Types::Registry.primitive("bool")),
1279
- IR::Field.new(name: "value", type: type.base),
1280
- ],
1281
- packed: false,
1282
- alignment: nil,
1283
- )
1284
- end
1097
+ end
1098
+ end
1099
+
1100
+ def collect_span_types_from_statements(statements, span_types, visited)
1101
+ each_ir_statement_for_type_collection(statements,
1102
+ type_collector_method: :collect_span_type,
1103
+ expression_walker_method: :collect_span_types_from_expression,
1104
+ accumulator: span_types, visited:)
1105
+ end
1106
+
1107
+ def collect_span_types_from_expression(expression, span_types, visited)
1108
+ case expression
1109
+ when IR::Member
1110
+ collect_span_types_from_expression(expression.receiver, span_types, visited)
1111
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1112
+ collect_span_types_from_expression(expression.receiver, span_types, visited)
1113
+ collect_span_types_from_expression(expression.index, span_types, visited)
1114
+ when IR::Call
1115
+ collect_span_type(expression.type, span_types, visited)
1116
+ collect_span_types_from_expression(expression.callee, span_types, visited) unless expression.callee.is_a?(String)
1117
+ expression.arguments.each { |argument| collect_span_types_from_expression(argument, span_types, visited) }
1118
+ when IR::Unary
1119
+ collect_span_types_from_expression(expression.operand, span_types, visited)
1120
+ when IR::Binary
1121
+ collect_span_types_from_expression(expression.left, span_types, visited)
1122
+ collect_span_types_from_expression(expression.right, span_types, visited)
1123
+ when IR::Conditional
1124
+ collect_span_types_from_expression(expression.condition, span_types, visited)
1125
+ collect_span_types_from_expression(expression.then_expression, span_types, visited)
1126
+ collect_span_types_from_expression(expression.else_expression, span_types, visited)
1127
+ when IR::ReinterpretExpr
1128
+ collect_span_type(expression.target_type, span_types, visited)
1129
+ collect_span_type(expression.source_type, span_types, visited)
1130
+ collect_span_types_from_expression(expression.expression, span_types, visited)
1131
+ when IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr
1132
+ collect_span_type(expression.target_type, span_types, visited)
1133
+ when IR::AddressOf
1134
+ collect_span_types_from_expression(expression.expression, span_types, visited)
1135
+ when IR::Cast
1136
+ collect_span_types_from_expression(expression.expression, span_types, visited)
1137
+ when IR::AggregateLiteral
1138
+ collect_span_type(expression.type, span_types, visited)
1139
+ expression.fields.each { |field| collect_span_types_from_expression(field.value, span_types, visited) }
1140
+ when IR::ArrayLiteral
1141
+ expression.elements.each { |element| collect_span_types_from_expression(element, span_types, visited) }
1142
+ when IR::VariantLiteral
1143
+ collect_span_type(expression.type, span_types, visited)
1144
+ expression.fields.each { |field| collect_span_types_from_expression(field.value, span_types, visited) }
1145
+ end
1146
+ end
1147
+
1148
+ def collect_span_type(type, span_types, visited)
1149
+ return unless type
1150
+ return if visited[type]
1151
+
1152
+ visited[type] = true
1153
+
1154
+ case type
1155
+ when Types::Nullable
1156
+ collect_span_type(type.base, span_types, visited)
1157
+ when Types::Span
1158
+ span_types << type
1159
+ collect_span_type(type.element_type, span_types, visited)
1160
+ when Types::GenericInstance
1161
+ type.arguments.each do |argument|
1162
+ collect_span_type(argument, span_types, visited) unless argument.is_a?(Types::LiteralTypeArg)
1285
1163
  end
1286
-
1287
- def collect_nullable_opt_types
1288
- opt_types = []
1289
- seen = {}
1290
-
1291
- collect_type = lambda do |type|
1292
- return unless type
1293
-
1294
- case type
1295
- when Types::Nullable
1296
- unless c_backend_pointer_like_type?(type.base)
1297
- name = nullable_opt_type_name(type)
1298
- unless seen[name]
1299
- seen[name] = true
1300
- opt_types << type
1301
- end
1302
- end
1303
- collect_type.call(type.base)
1304
- when Types::GenericInstance
1305
- type.arguments.each { |arg| collect_type.call(arg) unless arg.is_a?(Types::LiteralTypeArg) }
1306
- when Types::Span
1307
- collect_type.call(type.element_type)
1308
- when Types::Task
1309
- collect_type.call(type.result_type)
1310
- when Types::Function, Types::Proc
1311
- type.params.each { |p| collect_type.call(p.type) }
1312
- collect_type.call(type.return_type)
1313
- when Types::StructInstance, Types::VariantInstance
1314
- type.arguments.each { |arg| collect_type.call(arg) }
1315
- end
1316
- end
1317
-
1318
- collect_in_stmt = lambda do |stmt|
1319
- case stmt
1320
- when IR::LocalDecl
1321
- collect_type.call(stmt.type)
1322
- when IR::BlockStmt
1323
- stmt.body.each { |s| collect_in_stmt.call(s) }
1324
- when IR::IfStmt
1325
- stmt.then_body.each { |s| collect_in_stmt.call(s) }
1326
- stmt.else_body&.each { |s| collect_in_stmt.call(s) }
1327
- when IR::WhileStmt
1328
- stmt.body.each { |s| collect_in_stmt.call(s) }
1329
- when IR::ForStmt
1330
- stmt.body.each { |s| collect_in_stmt.call(s) }
1331
- when IR::SwitchStmt
1332
- stmt.cases.each { |c| c.body.each { |s| collect_in_stmt.call(s) } }
1333
- end
1334
- end
1335
-
1336
- emitted_aggregate_structs.each { |decl| decl.fields.each { |f| collect_type.call(f.type) } }
1337
- emitted_aggregate_unions.each { |decl| decl.fields.each { |f| collect_type.call(f.type) } }
1338
- emitted_aggregate_variants.each do |decl|
1339
- decl.arms.each { |arm| arm.fields.each { |f| collect_type.call(f.type) } }
1340
- end
1341
- emitted_constants.each { |c| collect_type.call(c.type) }
1342
- emitted_globals.each { |g| collect_type.call(g.type) }
1343
- emitted_functions.each do |f|
1344
- collect_type.call(f.return_type)
1345
- f.params.each { |p| collect_type.call(p.type) }
1346
- f.body.each { |s| collect_in_stmt.call(s) }
1347
- end
1348
-
1349
- opt_types
1164
+ when Types::Function
1165
+ type.params.each do |param|
1166
+ collect_span_type(param.type, span_types, visited)
1350
1167
  end
1351
-
1352
- def collect_str_literals
1353
- literals = {}
1354
- emitted_functions.each do |func|
1355
- collect_str_literals_from_statements(func.body, literals)
1356
- end
1357
- emitted_globals.each do |global|
1358
- collect_str_literals_from_expression(global.value, literals)
1359
- end
1360
- emitted_constants.each do |constant|
1361
- collect_str_literals_from_expression(constant.value, literals)
1362
- end
1363
- literals.keys.sort_by { |k| [k.bytesize, k] }
1364
- end
1365
-
1366
- def collect_str_literals_from_statements(statements, literals)
1367
- statements.each do |stmt|
1368
- case stmt
1369
- when IR::LocalDecl
1370
- collect_str_literals_from_expression(stmt.value, literals) if stmt.value
1371
- when IR::Assignment
1372
- collect_str_literals_from_expression(stmt.target, literals)
1373
- collect_str_literals_from_expression(stmt.value, literals)
1374
- when IR::BlockStmt
1375
- collect_str_literals_from_statements(stmt.body, literals)
1376
- when IR::WhileStmt
1377
- collect_str_literals_from_expression(stmt.condition, literals)
1378
- collect_str_literals_from_statements(stmt.body, literals)
1379
- when IR::ForStmt
1380
- collect_str_literals_from_statements([stmt.init], literals)
1381
- collect_str_literals_from_expression(stmt.condition, literals)
1382
- collect_str_literals_from_statements(stmt.body, literals)
1383
- collect_str_literals_from_statements([stmt.post], literals)
1384
- when IR::IfStmt
1385
- collect_str_literals_from_expression(stmt.condition, literals)
1386
- collect_str_literals_from_statements(stmt.then_body, literals)
1387
- collect_str_literals_from_statements(stmt.else_body, literals) if stmt.else_body
1388
- when IR::SwitchStmt
1389
- collect_str_literals_from_expression(stmt.expression, literals)
1390
- stmt.cases.each { |c| collect_str_literals_from_statements(c.body, literals) }
1391
- when IR::ReturnStmt
1392
- collect_str_literals_from_expression(stmt.value, literals) if stmt.value
1393
- when IR::ExpressionStmt
1394
- collect_str_literals_from_expression(stmt.expression, literals)
1395
- when IR::StaticAssert
1396
- collect_str_literals_from_expression(stmt.condition, literals)
1397
- collect_str_literals_from_expression(stmt.message, literals)
1398
- end
1168
+ collect_span_type(type.return_type, span_types, visited)
1169
+ when Types::Struct, Types::Union
1170
+ type.fields.each_value do |field_type|
1171
+ collect_span_type(field_type, span_types, visited)
1172
+ end
1173
+ when Types::Variant
1174
+ type.arm_names.each do |arm_name|
1175
+ type.arm(arm_name).each_value do |field_type|
1176
+ collect_span_type(field_type, span_types, visited)
1399
1177
  end
1400
1178
  end
1401
-
1402
- def collect_str_literals_from_expression(expr, literals)
1403
- return unless expr
1404
-
1405
- case expr
1406
- when IR::StringLiteral
1407
- literals[expr.value] = true if expr.type.is_a?(Types::StringView)
1408
- when IR::Member
1409
- collect_str_literals_from_expression(expr.receiver, literals)
1410
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1411
- collect_str_literals_from_expression(expr.receiver, literals)
1412
- collect_str_literals_from_expression(expr.index, literals)
1413
- when IR::Call
1414
- collect_str_literals_from_expression(expr.callee, literals) unless expr.callee.is_a?(String)
1415
- expr.arguments.each { |arg| collect_str_literals_from_expression(arg, literals) }
1416
- when IR::Unary
1417
- collect_str_literals_from_expression(expr.operand, literals)
1418
- when IR::Binary
1419
- collect_str_literals_from_expression(expr.left, literals)
1420
- collect_str_literals_from_expression(expr.right, literals)
1421
- when IR::Conditional
1422
- collect_str_literals_from_expression(expr.condition, literals)
1423
- collect_str_literals_from_expression(expr.then_expression, literals)
1424
- collect_str_literals_from_expression(expr.else_expression, literals)
1425
- when IR::ReinterpretExpr
1426
- collect_str_literals_from_expression(expr.expression, literals)
1427
- when IR::AddressOf
1428
- collect_str_literals_from_expression(expr.expression, literals)
1429
- when IR::Cast
1430
- collect_str_literals_from_expression(expr.expression, literals)
1431
- when IR::AggregateLiteral
1432
- expr.fields.each { |f| collect_str_literals_from_expression(f.value, literals) }
1433
- when IR::ArrayLiteral
1434
- expr.elements.each { |e| collect_str_literals_from_expression(e, literals) }
1435
- when IR::VariantLiteral
1436
- expr.fields.each { |f| collect_str_literals_from_expression(f.value, literals) }
1179
+ end
1180
+ end
1181
+
1182
+ def collect_dyn_decls
1183
+ void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
1184
+ collect_dyn_types.map do |type|
1185
+ IR::StructDecl.new(
1186
+ name: type.to_s,
1187
+ linkage_name: dyn_type_name(type),
1188
+ fields: [
1189
+ IR::Field.new(name: "data", type: void_ptr),
1190
+ IR::Field.new(name: "vtable", type: void_ptr),
1191
+ ],
1192
+ packed: false,
1193
+ alignment: nil,
1194
+ )
1195
+ end
1196
+ end
1197
+
1198
+ def collect_dyn_types
1199
+ dyn_types = []
1200
+ seen = []
1201
+
1202
+ collect_type = lambda do |type|
1203
+ return unless type
1204
+ case type
1205
+ when Types::Dyn
1206
+ name = type.interface_binding.name
1207
+ unless seen.include?(name)
1208
+ seen << name
1209
+ dyn_types << type
1210
+ end
1211
+ when Types::Nullable
1212
+ collect_type.call(type.base)
1213
+ when Types::GenericInstance
1214
+ type.arguments.each { |arg| collect_type.call(arg) unless arg.is_a?(Types::LiteralTypeArg) }
1215
+ when Types::Span
1216
+ collect_type.call(type.element_type)
1217
+ when Types::Task
1218
+ collect_type.call(type.result_type)
1219
+ when Types::Function
1220
+ type.params.each { |p| collect_type.call(p.type) }
1221
+ collect_type.call(type.return_type)
1222
+ when Types::Proc
1223
+ type.params.each { |p| collect_type.call(p.type) }
1224
+ collect_type.call(type.return_type)
1225
+ when Types::StructInstance
1226
+ type.arguments.each { |arg| collect_type.call(arg) }
1227
+ when Types::VariantInstance
1228
+ type.arguments.each { |arg| collect_type.call(arg) }
1229
+ end
1230
+ end
1231
+
1232
+ collect_in_stmt = lambda do |stmt|
1233
+ case stmt
1234
+ when IR::LocalDecl
1235
+ collect_type.call(stmt.type)
1236
+ when IR::BlockStmt
1237
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1238
+ when IR::IfStmt
1239
+ stmt.then_body.each { |s| collect_in_stmt.call(s) }
1240
+ stmt.else_body&.each { |s| collect_in_stmt.call(s) }
1241
+ when IR::WhileStmt
1242
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1243
+ when IR::ForStmt
1244
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1245
+ when IR::SwitchStmt
1246
+ stmt.cases.each { |c| c.body.each { |s| collect_in_stmt.call(s) } }
1247
+ end
1248
+ end
1249
+
1250
+ if @program
1251
+ @program.constants.each { |c| collect_type.call(c.type) }
1252
+ @program.globals.each { |g| collect_type.call(g.type) }
1253
+ @program.structs.each { |s| s.fields.each { |f| collect_type.call(f.type) } }
1254
+ @program.unions.each { |u| u.fields.each { |f| collect_type.call(f.type) } }
1255
+ @program.functions.each do |f|
1256
+ collect_type.call(f.return_type)
1257
+ f.params.each { |p| collect_type.call(p.type) }
1258
+ body = f.body
1259
+ if body.is_a?(IR::BlockStmt)
1260
+ body.body.each { |s| collect_in_stmt.call(s) }
1261
+ elsif body.is_a?(Array)
1262
+ body.each { |s| collect_in_stmt.call(s) }
1437
1263
  end
1438
1264
  end
1265
+ end
1266
+
1267
+ dyn_types
1268
+ end
1269
+
1270
+ def collect_nullable_opt_decls
1271
+ collect_nullable_opt_types.map do |type|
1272
+ IR::StructDecl.new(
1273
+ name: type.to_s,
1274
+ linkage_name: nullable_opt_type_name(type),
1275
+ fields: [
1276
+ IR::Field.new(name: "has_value", type: Types::Registry.primitive("bool")),
1277
+ IR::Field.new(name: "value", type: type.base),
1278
+ ],
1279
+ packed: false,
1280
+ alignment: nil,
1281
+ )
1282
+ end
1283
+ end
1284
+
1285
+ def collect_nullable_opt_types
1286
+ opt_types = []
1287
+ seen = {}
1288
+
1289
+ collect_type = lambda do |type|
1290
+ return unless type
1291
+
1292
+ case type
1293
+ when Types::Nullable
1294
+ unless c_backend_pointer_like_type?(type.base)
1295
+ name = nullable_opt_type_name(type)
1296
+ unless seen[name]
1297
+ seen[name] = true
1298
+ opt_types << type
1299
+ end
1300
+ end
1301
+ collect_type.call(type.base)
1302
+ when Types::GenericInstance
1303
+ type.arguments.each { |arg| collect_type.call(arg) unless arg.is_a?(Types::LiteralTypeArg) }
1304
+ when Types::Span
1305
+ collect_type.call(type.element_type)
1306
+ when Types::Task
1307
+ collect_type.call(type.result_type)
1308
+ when Types::Function, Types::Proc
1309
+ type.params.each { |p| collect_type.call(p.type) }
1310
+ collect_type.call(type.return_type)
1311
+ when Types::StructInstance, Types::VariantInstance
1312
+ type.arguments.each { |arg| collect_type.call(arg) }
1313
+ end
1314
+ end
1315
+
1316
+ collect_in_stmt = lambda do |stmt|
1317
+ case stmt
1318
+ when IR::LocalDecl
1319
+ collect_type.call(stmt.type)
1320
+ when IR::BlockStmt
1321
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1322
+ when IR::IfStmt
1323
+ stmt.then_body.each { |s| collect_in_stmt.call(s) }
1324
+ stmt.else_body&.each { |s| collect_in_stmt.call(s) }
1325
+ when IR::WhileStmt
1326
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1327
+ when IR::ForStmt
1328
+ stmt.body.each { |s| collect_in_stmt.call(s) }
1329
+ when IR::SwitchStmt
1330
+ stmt.cases.each { |c| c.body.each { |s| collect_in_stmt.call(s) } }
1331
+ end
1332
+ end
1333
+
1334
+ emitted_aggregate_structs.each { |decl| decl.fields.each { |f| collect_type.call(f.type) } }
1335
+ emitted_aggregate_unions.each { |decl| decl.fields.each { |f| collect_type.call(f.type) } }
1336
+ emitted_aggregate_variants.each do |decl|
1337
+ decl.arms.each { |arm| arm.fields.each { |f| collect_type.call(f.type) } }
1338
+ end
1339
+ emitted_constants.each { |c| collect_type.call(c.type) }
1340
+ emitted_globals.each { |g| collect_type.call(g.type) }
1341
+ emitted_functions.each do |f|
1342
+ collect_type.call(f.return_type)
1343
+ f.params.each { |p| collect_type.call(p.type) }
1344
+ f.body.each { |s| collect_in_stmt.call(s) }
1345
+ end
1346
+
1347
+ opt_types
1348
+ end
1349
+
1350
+ def collect_str_literals
1351
+ literals = {}
1352
+ emitted_functions.each do |func|
1353
+ collect_str_literals_from_statements(func.body, literals)
1354
+ end
1355
+ emitted_globals.each do |global|
1356
+ collect_str_literals_from_expression(global.value, literals)
1357
+ end
1358
+ emitted_constants.each do |constant|
1359
+ collect_str_literals_from_expression(constant.value, literals)
1360
+ end
1361
+ literals.keys.sort_by { |k| [k.bytesize, k] }
1362
+ end
1363
+
1364
+ def collect_str_literals_from_statements(statements, literals)
1365
+ statements.each do |stmt|
1366
+ case stmt
1367
+ when IR::LocalDecl
1368
+ collect_str_literals_from_expression(stmt.value, literals) if stmt.value
1369
+ when IR::Assignment
1370
+ collect_str_literals_from_expression(stmt.target, literals)
1371
+ collect_str_literals_from_expression(stmt.value, literals)
1372
+ when IR::BlockStmt
1373
+ collect_str_literals_from_statements(stmt.body, literals)
1374
+ when IR::WhileStmt
1375
+ collect_str_literals_from_expression(stmt.condition, literals)
1376
+ collect_str_literals_from_statements(stmt.body, literals)
1377
+ when IR::ForStmt
1378
+ collect_str_literals_from_statements([stmt.init], literals)
1379
+ collect_str_literals_from_expression(stmt.condition, literals)
1380
+ collect_str_literals_from_statements(stmt.body, literals)
1381
+ collect_str_literals_from_statements([stmt.post], literals)
1382
+ when IR::IfStmt
1383
+ collect_str_literals_from_expression(stmt.condition, literals)
1384
+ collect_str_literals_from_statements(stmt.then_body, literals)
1385
+ collect_str_literals_from_statements(stmt.else_body, literals) if stmt.else_body
1386
+ when IR::SwitchStmt
1387
+ collect_str_literals_from_expression(stmt.expression, literals)
1388
+ stmt.cases.each { |c| collect_str_literals_from_statements(c.body, literals) }
1389
+ when IR::ReturnStmt
1390
+ collect_str_literals_from_expression(stmt.value, literals) if stmt.value
1391
+ when IR::ExpressionStmt
1392
+ collect_str_literals_from_expression(stmt.expression, literals)
1393
+ when IR::StaticAssert
1394
+ collect_str_literals_from_expression(stmt.condition, literals)
1395
+ collect_str_literals_from_expression(stmt.message, literals)
1396
+ end
1397
+ end
1398
+ end
1399
+
1400
+ def collect_str_literals_from_expression(expr, literals)
1401
+ return unless expr
1402
+
1403
+ case expr
1404
+ when IR::StringLiteral
1405
+ literals[expr.value] = true if expr.type.is_a?(Types::StringView)
1406
+ when IR::Member
1407
+ collect_str_literals_from_expression(expr.receiver, literals)
1408
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
1409
+ collect_str_literals_from_expression(expr.receiver, literals)
1410
+ collect_str_literals_from_expression(expr.index, literals)
1411
+ when IR::Call
1412
+ collect_str_literals_from_expression(expr.callee, literals) unless expr.callee.is_a?(String)
1413
+ expr.arguments.each { |arg| collect_str_literals_from_expression(arg, literals) }
1414
+ when IR::Unary
1415
+ collect_str_literals_from_expression(expr.operand, literals)
1416
+ when IR::Binary
1417
+ collect_str_literals_from_expression(expr.left, literals)
1418
+ collect_str_literals_from_expression(expr.right, literals)
1419
+ when IR::Conditional
1420
+ collect_str_literals_from_expression(expr.condition, literals)
1421
+ collect_str_literals_from_expression(expr.then_expression, literals)
1422
+ collect_str_literals_from_expression(expr.else_expression, literals)
1423
+ when IR::ReinterpretExpr
1424
+ collect_str_literals_from_expression(expr.expression, literals)
1425
+ when IR::AddressOf
1426
+ collect_str_literals_from_expression(expr.expression, literals)
1427
+ when IR::Cast
1428
+ collect_str_literals_from_expression(expr.expression, literals)
1429
+ when IR::AggregateLiteral
1430
+ expr.fields.each { |f| collect_str_literals_from_expression(f.value, literals) }
1431
+ when IR::ArrayLiteral
1432
+ expr.elements.each { |e| collect_str_literals_from_expression(e, literals) }
1433
+ when IR::VariantLiteral
1434
+ expr.fields.each { |f| collect_str_literals_from_expression(f.value, literals) }
1435
+ end
1436
+ end
1439
1437
  end
1440
1438
  end
1441
1439
  end