mt-lang 0.2.0

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 (258) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/AUTHORS +3 -0
  4. data/Gemfile +19 -0
  5. data/Gemfile.lock +82 -0
  6. data/LICENSE +21 -0
  7. data/README.md +1208 -0
  8. data/Rakefile +332 -0
  9. data/bin/mtc +8 -0
  10. data/bin/profile-mtc-checks +133 -0
  11. data/bin/tracy-profiler +0 -0
  12. data/docs/build-guide.md +536 -0
  13. data/docs/index.html +2778 -0
  14. data/docs/language-design.md +1519 -0
  15. data/docs/language-manual.md +1534 -0
  16. data/lib/milk_tea/base.rb +49 -0
  17. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +398 -0
  18. data/lib/milk_tea/bindings/bindgen/declaration.rb +319 -0
  19. data/lib/milk_tea/bindings/bindgen/emitter.rb +387 -0
  20. data/lib/milk_tea/bindings/bindgen/overrides.rb +134 -0
  21. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +622 -0
  22. data/lib/milk_tea/bindings/bindgen.rb +207 -0
  23. data/lib/milk_tea/bindings/cli.rb +121 -0
  24. data/lib/milk_tea/bindings/imported_bindings/defaults.rb +210 -0
  25. data/lib/milk_tea/bindings/imported_bindings/generator.rb +1114 -0
  26. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +190 -0
  27. data/lib/milk_tea/bindings/imported_bindings/naming.rb +286 -0
  28. data/lib/milk_tea/bindings/imported_bindings.rb +215 -0
  29. data/lib/milk_tea/bindings/opengl_registry.rb +547 -0
  30. data/lib/milk_tea/bindings/raw_bindings/defaults.rb +1338 -0
  31. data/lib/milk_tea/bindings/raw_bindings.rb +269 -0
  32. data/lib/milk_tea/bindings/steamworks.rb +629 -0
  33. data/lib/milk_tea/bindings/upstream_sources.rb +352 -0
  34. data/lib/milk_tea/bindings/vendored_box2d.rb +79 -0
  35. data/lib/milk_tea/bindings/vendored_c_library.rb +322 -0
  36. data/lib/milk_tea/bindings/vendored_cjson.rb +52 -0
  37. data/lib/milk_tea/bindings/vendored_flecs.rb +78 -0
  38. data/lib/milk_tea/bindings/vendored_glfw.rb +77 -0
  39. data/lib/milk_tea/bindings/vendored_libuv.rb +75 -0
  40. data/lib/milk_tea/bindings/vendored_pcre2.rb +84 -0
  41. data/lib/milk_tea/bindings/vendored_raylib.rb +131 -0
  42. data/lib/milk_tea/bindings/vendored_sdl3.rb +78 -0
  43. data/lib/milk_tea/bindings/vendored_steamworks.rb +71 -0
  44. data/lib/milk_tea/bindings/vendored_tool.rb +71 -0
  45. data/lib/milk_tea/bindings/vendored_tools.rb +23 -0
  46. data/lib/milk_tea/bindings/vendored_tracy.rb +37 -0
  47. data/lib/milk_tea/bindings.rb +23 -0
  48. data/lib/milk_tea/core/ast.rb +311 -0
  49. data/lib/milk_tea/core/async_runtime_installer.rb +28 -0
  50. data/lib/milk_tea/core/binding_types.rb +18 -0
  51. data/lib/milk_tea/core/bindings/attribute_binding.rb +58 -0
  52. data/lib/milk_tea/core/bindings/function_binding.rb +5 -0
  53. data/lib/milk_tea/core/bindings/module_binding.rb +58 -0
  54. data/lib/milk_tea/core/bindings/value_binding.rb +21 -0
  55. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +103 -0
  56. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +412 -0
  57. data/lib/milk_tea/core/c_backend/expressions.rb +468 -0
  58. data/lib/milk_tea/core/c_backend/feature_detection.rb +483 -0
  59. data/lib/milk_tea/core/c_backend/reachability.rb +398 -0
  60. data/lib/milk_tea/core/c_backend/reinterpret.rb +226 -0
  61. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1080 -0
  62. data/lib/milk_tea/core/c_backend/statements.rb +563 -0
  63. data/lib/milk_tea/core/c_backend/type_collectors.rb +1545 -0
  64. data/lib/milk_tea/core/c_backend/type_declaration.rb +223 -0
  65. data/lib/milk_tea/core/c_backend/type_system.rb +345 -0
  66. data/lib/milk_tea/core/c_backend.rb +287 -0
  67. data/lib/milk_tea/core/compatibility_helpers.rb +79 -0
  68. data/lib/milk_tea/core/compile_time/const_eval.rb +187 -0
  69. data/lib/milk_tea/core/compile_time.rb +329 -0
  70. data/lib/milk_tea/core/control_flow/builder.rb +582 -0
  71. data/lib/milk_tea/core/control_flow/constant_propagation.rb +143 -0
  72. data/lib/milk_tea/core/control_flow/dataflow.rb +74 -0
  73. data/lib/milk_tea/core/control_flow/definite_assignment.rb +79 -0
  74. data/lib/milk_tea/core/control_flow/graph.rb +90 -0
  75. data/lib/milk_tea/core/control_flow/liveness.rb +24 -0
  76. data/lib/milk_tea/core/control_flow/nullability_flow.rb +43 -0
  77. data/lib/milk_tea/core/control_flow/reachability.rb +22 -0
  78. data/lib/milk_tea/core/control_flow/termination.rb +31 -0
  79. data/lib/milk_tea/core/control_flow.rb +34 -0
  80. data/lib/milk_tea/core/cst.rb +48 -0
  81. data/lib/milk_tea/core/cst_builder.rb +19 -0
  82. data/lib/milk_tea/core/ir.rb +85 -0
  83. data/lib/milk_tea/core/keywords.rb +97 -0
  84. data/lib/milk_tea/core/lexer/character_classes.rb +60 -0
  85. data/lib/milk_tea/core/lexer/format_strings.rb +225 -0
  86. data/lib/milk_tea/core/lexer/heredocs.rb +199 -0
  87. data/lib/milk_tea/core/lexer/indentation.rb +62 -0
  88. data/lib/milk_tea/core/lexer/numbers.rb +96 -0
  89. data/lib/milk_tea/core/lexer/recovery.rb +32 -0
  90. data/lib/milk_tea/core/lexer/strings.rb +167 -0
  91. data/lib/milk_tea/core/lexer/symbols.rb +71 -0
  92. data/lib/milk_tea/core/lexer/trivia.rb +53 -0
  93. data/lib/milk_tea/core/lexer.rb +430 -0
  94. data/lib/milk_tea/core/lowering/artifacts.rb +26 -0
  95. data/lib/milk_tea/core/lowering/async/analysis.rb +245 -0
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +1399 -0
  97. data/lib/milk_tea/core/lowering/async/normalization.rb +459 -0
  98. data/lib/milk_tea/core/lowering/async.rb +714 -0
  99. data/lib/milk_tea/core/lowering/block.rb +1052 -0
  100. data/lib/milk_tea/core/lowering/calls.rb +1565 -0
  101. data/lib/milk_tea/core/lowering/declarations.rb +214 -0
  102. data/lib/milk_tea/core/lowering/dyn.rb +206 -0
  103. data/lib/milk_tea/core/lowering/events.rb +1054 -0
  104. data/lib/milk_tea/core/lowering/expressions.rb +1645 -0
  105. data/lib/milk_tea/core/lowering/foreign_cstr.rb +206 -0
  106. data/lib/milk_tea/core/lowering/functions.rb +242 -0
  107. data/lib/milk_tea/core/lowering/loops.rb +1087 -0
  108. data/lib/milk_tea/core/lowering/lowering_context.rb +80 -0
  109. data/lib/milk_tea/core/lowering/proc.rb +419 -0
  110. data/lib/milk_tea/core/lowering/resolve.rb +2516 -0
  111. data/lib/milk_tea/core/lowering/scans.rb +220 -0
  112. data/lib/milk_tea/core/lowering/str_buffer.rb +125 -0
  113. data/lib/milk_tea/core/lowering/utils.rb +1453 -0
  114. data/lib/milk_tea/core/lowering.rb +378 -0
  115. data/lib/milk_tea/core/module_binder.rb +181 -0
  116. data/lib/milk_tea/core/module_loader/errors.rb +21 -0
  117. data/lib/milk_tea/core/module_loader.rb +479 -0
  118. data/lib/milk_tea/core/module_path_resolver.rb +153 -0
  119. data/lib/milk_tea/core/module_roots.rb +88 -0
  120. data/lib/milk_tea/core/parser/attributes.rb +71 -0
  121. data/lib/milk_tea/core/parser/blocks.rb +119 -0
  122. data/lib/milk_tea/core/parser/declarations.rb +749 -0
  123. data/lib/milk_tea/core/parser/expressions.rb +624 -0
  124. data/lib/milk_tea/core/parser/recovery.rb +131 -0
  125. data/lib/milk_tea/core/parser/statements.rb +756 -0
  126. data/lib/milk_tea/core/parser/types.rb +271 -0
  127. data/lib/milk_tea/core/parser.rb +400 -0
  128. data/lib/milk_tea/core/prelude_installer.rb +29 -0
  129. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +917 -0
  130. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +87 -0
  131. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +300 -0
  132. data/lib/milk_tea/core/pretty_printer.rb +17 -0
  133. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +314 -0
  134. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +184 -0
  135. data/lib/milk_tea/core/semantic_analyzer/calls.rb +992 -0
  136. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1735 -0
  137. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +355 -0
  138. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +155 -0
  139. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +354 -0
  140. data/lib/milk_tea/core/semantic_analyzer/generics.rb +383 -0
  141. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +78 -0
  142. data/lib/milk_tea/core/semantic_analyzer/module_context.rb +35 -0
  143. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +1438 -0
  144. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +421 -0
  145. data/lib/milk_tea/core/semantic_analyzer/statements.rb +1308 -0
  146. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +588 -0
  147. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +307 -0
  148. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +851 -0
  149. data/lib/milk_tea/core/semantic_analyzer.rb +327 -0
  150. data/lib/milk_tea/core/token.rb +26 -0
  151. data/lib/milk_tea/core/token_stream.rb +30 -0
  152. data/lib/milk_tea/core/types/layout.rb +243 -0
  153. data/lib/milk_tea/core/types/predicates.rb +609 -0
  154. data/lib/milk_tea/core/types/registry.rb +83 -0
  155. data/lib/milk_tea/core/types/types.rb +1696 -0
  156. data/lib/milk_tea/core/types/visitor.rb +442 -0
  157. data/lib/milk_tea/core.rb +25 -0
  158. data/lib/milk_tea/dap/backends/lldb_dap.rb +158 -0
  159. data/lib/milk_tea/dap/protocol.rb +58 -0
  160. data/lib/milk_tea/dap/server/breakpoints.rb +66 -0
  161. data/lib/milk_tea/dap/server/debug_map.rb +291 -0
  162. data/lib/milk_tea/dap/server/handlers.rb +374 -0
  163. data/lib/milk_tea/dap/server/launch.rb +261 -0
  164. data/lib/milk_tea/dap/server/lldb_backend.rb +380 -0
  165. data/lib/milk_tea/dap/server/pause_diagnostics.rb +109 -0
  166. data/lib/milk_tea/dap/server/utilities.rb +160 -0
  167. data/lib/milk_tea/dap/server/wire.rb +55 -0
  168. data/lib/milk_tea/dap/server.rb +131 -0
  169. data/lib/milk_tea/dap/session.rb +152 -0
  170. data/lib/milk_tea/dap.rb +6 -0
  171. data/lib/milk_tea/lsp/dependency_resolution.rb +52 -0
  172. data/lib/milk_tea/lsp/diagnostics.rb +611 -0
  173. data/lib/milk_tea/lsp/protocol.rb +104 -0
  174. data/lib/milk_tea/lsp/server/call_hierarchy.rb +274 -0
  175. data/lib/milk_tea/lsp/server/code_actions.rb +446 -0
  176. data/lib/milk_tea/lsp/server/code_lens.rb +97 -0
  177. data/lib/milk_tea/lsp/server/completion.rb +1099 -0
  178. data/lib/milk_tea/lsp/server/configuration.rb +167 -0
  179. data/lib/milk_tea/lsp/server/debug_info.rb +45 -0
  180. data/lib/milk_tea/lsp/server/definition.rb +779 -0
  181. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +239 -0
  182. data/lib/milk_tea/lsp/server/execute_command.rb +25 -0
  183. data/lib/milk_tea/lsp/server/folding_range.rb +153 -0
  184. data/lib/milk_tea/lsp/server/formatting.rb +575 -0
  185. data/lib/milk_tea/lsp/server/hover.rb +1465 -0
  186. data/lib/milk_tea/lsp/server/inlay_hints.rb +204 -0
  187. data/lib/milk_tea/lsp/server/lifecycle.rb +234 -0
  188. data/lib/milk_tea/lsp/server/linked_editing_range.rb +43 -0
  189. data/lib/milk_tea/lsp/server/on_type_formatting.rb +73 -0
  190. data/lib/milk_tea/lsp/server/progress.rb +47 -0
  191. data/lib/milk_tea/lsp/server/references.rb +433 -0
  192. data/lib/milk_tea/lsp/server/rename.rb +598 -0
  193. data/lib/milk_tea/lsp/server/selection_range.rb +130 -0
  194. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1745 -0
  195. data/lib/milk_tea/lsp/server/signature_help.rb +200 -0
  196. data/lib/milk_tea/lsp/server/text_documents.rb +125 -0
  197. data/lib/milk_tea/lsp/server/type_hierarchy.rb +167 -0
  198. data/lib/milk_tea/lsp/server/utilities.rb +520 -0
  199. data/lib/milk_tea/lsp/server.rb +415 -0
  200. data/lib/milk_tea/lsp/workspace/analysis.rb +209 -0
  201. data/lib/milk_tea/lsp/workspace/caches.rb +260 -0
  202. data/lib/milk_tea/lsp/workspace/collection.rb +98 -0
  203. data/lib/milk_tea/lsp/workspace/definition_index.rb +184 -0
  204. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +282 -0
  205. data/lib/milk_tea/lsp/workspace/store.rb +154 -0
  206. data/lib/milk_tea/lsp/workspace/utilities.rb +490 -0
  207. data/lib/milk_tea/lsp/workspace.rb +127 -0
  208. data/lib/milk_tea/lsp.rb +13 -0
  209. data/lib/milk_tea/packages/atomic_write.rb +63 -0
  210. data/lib/milk_tea/packages/dependency_solver.rb +194 -0
  211. data/lib/milk_tea/packages/graph.rb +139 -0
  212. data/lib/milk_tea/packages/lock.rb +421 -0
  213. data/lib/milk_tea/packages/manager_cli.rb +485 -0
  214. data/lib/milk_tea/packages/manifest.rb +356 -0
  215. data/lib/milk_tea/packages/manifest_editor.rb +134 -0
  216. data/lib/milk_tea/packages/registry_metadata_provider.rb +34 -0
  217. data/lib/milk_tea/packages/registry_store.rb +420 -0
  218. data/lib/milk_tea/packages/services.rb +41 -0
  219. data/lib/milk_tea/packages/source_cache.rb +71 -0
  220. data/lib/milk_tea/packages/source_fetcher.rb +124 -0
  221. data/lib/milk_tea/packages/source_resolver.rb +389 -0
  222. data/lib/milk_tea/packages/version.rb +164 -0
  223. data/lib/milk_tea/packages.rb +16 -0
  224. data/lib/milk_tea/tooling/asset_pack.rb +141 -0
  225. data/lib/milk_tea/tooling/build.rb +1124 -0
  226. data/lib/milk_tea/tooling/build_cache.rb +240 -0
  227. data/lib/milk_tea/tooling/cli.rb +2688 -0
  228. data/lib/milk_tea/tooling/cst_formatter.rb +13 -0
  229. data/lib/milk_tea/tooling/debug_info_formatter.rb +456 -0
  230. data/lib/milk_tea/tooling/debug_map.rb +248 -0
  231. data/lib/milk_tea/tooling/docs_app.rb +369 -0
  232. data/lib/milk_tea/tooling/error_formatter.rb +86 -0
  233. data/lib/milk_tea/tooling/formatter.rb +787 -0
  234. data/lib/milk_tea/tooling/linter/doc_tags.rb +212 -0
  235. data/lib/milk_tea/tooling/linter/fix_engine.rb +237 -0
  236. data/lib/milk_tea/tooling/linter/flow_rules.rb +380 -0
  237. data/lib/milk_tea/tooling/linter/imports_platform.rb +841 -0
  238. data/lib/milk_tea/tooling/linter/release_rules.rb +744 -0
  239. data/lib/milk_tea/tooling/linter/reserved_names.rb +199 -0
  240. data/lib/milk_tea/tooling/linter/rules.rb +593 -0
  241. data/lib/milk_tea/tooling/linter/source_helpers.rb +407 -0
  242. data/lib/milk_tea/tooling/linter/trailing_comma.rb +139 -0
  243. data/lib/milk_tea/tooling/linter/visitors.rb +1286 -0
  244. data/lib/milk_tea/tooling/linter.rb +798 -0
  245. data/lib/milk_tea/tooling/project_scaffold.rb +82 -0
  246. data/lib/milk_tea/tooling/public/css/docs.css +166 -0
  247. data/lib/milk_tea/tooling/public/js/docs.js +94 -0
  248. data/lib/milk_tea/tooling/run.rb +408 -0
  249. data/lib/milk_tea/tooling/templates/wasm_shell.html +48 -0
  250. data/lib/milk_tea/tooling/toolchain_cli.rb +157 -0
  251. data/lib/milk_tea/tooling/views/404.erb +7 -0
  252. data/lib/milk_tea/tooling/views/index.erb +87 -0
  253. data/lib/milk_tea/tooling/views/layout.erb +69 -0
  254. data/lib/milk_tea/tooling/views/module.erb +97 -0
  255. data/lib/milk_tea/tooling/views/stdlib.erb +21 -0
  256. data/lib/milk_tea/tooling.rb +20 -0
  257. data/lib/milk_tea.rb +8 -0
  258. metadata +426 -0
@@ -0,0 +1,851 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MilkTea
4
+ class SemanticAnalyzer
5
+ class Checker
6
+ private
7
+
8
+ def build_analysis
9
+ Analysis.new(
10
+ ast: @ctx.ast,
11
+ module_name: @ctx.module_name,
12
+ module_kind: @ctx.module_kind,
13
+ directives: @ctx.ast.directives,
14
+ imports: @ctx.imports,
15
+ types: @ctx.types,
16
+ interfaces: @ctx.interfaces,
17
+ attributes: snapshot_attributes,
18
+ attribute_applications: snapshot_attribute_applications,
19
+ values: @ctx.top_level_values,
20
+ functions: @ctx.top_level_functions,
21
+ methods: snapshot_methods,
22
+ implemented_interfaces: snapshot_implemented_interfaces,
23
+ local_completion_frames: @local_completion_frames.dup.freeze,
24
+ binding_resolution: binding_resolution_snapshot,
25
+ callable_value_identifier_sites: @callable_value_identifier_sites.dup.freeze,
26
+ callable_value_member_access_sites: @callable_value_member_access_sites.dup.freeze,
27
+ required_unsafe_lines: @required_unsafe_lines.uniq.freeze,
28
+ uses_parallel_for: @uses_parallel_for,
29
+ resolved_expr_types: @resolved_expr_types.dup.freeze,
30
+ resolved_call_kinds: @resolved_call_kinds.dup.freeze,
31
+ const_values: @const_values.dup.freeze,
32
+ )
33
+ end
34
+
35
+ def install_builtin_types
36
+ INSTALLABLE_BUILTIN_TYPE_NAMES.each do |name|
37
+ @ctx.types[name] = case name
38
+ when "str"
39
+ Types::Registry.string_view
40
+ when "Subscription"
41
+ builtin_subscription_type
42
+ when "EventError"
43
+ builtin_event_error_type
44
+ when "struct_handle"
45
+ builtin_struct_handle_type
46
+ when "field_handle"
47
+ builtin_field_handle_type
48
+ when "callable_handle"
49
+ builtin_callable_handle_type
50
+ when "attribute_handle"
51
+ builtin_attribute_handle_type
52
+ when "member_handle"
53
+ builtin_member_handle_type
54
+ when "type"
55
+ builtin_type_meta_type
56
+ when "vec2"
57
+ Types::Vector.new("vec2", element_type: Types::BUILTIN_VECTOR_ELEMENT, width: 2)
58
+ when "vec3"
59
+ Types::Vector.new("vec3", element_type: Types::BUILTIN_VECTOR_ELEMENT, width: 3)
60
+ when "vec4"
61
+ Types::Vector.new("vec4", element_type: Types::BUILTIN_VECTOR_ELEMENT, width: 4)
62
+ when "ivec2"
63
+ Types::Vector.new("ivec2", element_type: Types::BUILTIN_IVECTOR_ELEMENT, width: 2)
64
+ when "ivec3"
65
+ Types::Vector.new("ivec3", element_type: Types::BUILTIN_IVECTOR_ELEMENT, width: 3)
66
+ when "ivec4"
67
+ Types::Vector.new("ivec4", element_type: Types::BUILTIN_IVECTOR_ELEMENT, width: 4)
68
+ when "mat3"
69
+ Types::Matrix.new("mat3", dim: 3)
70
+ when "mat4"
71
+ Types::Matrix.new("mat4", dim: 4)
72
+ when "quat"
73
+ Types::Quaternion.new("quat")
74
+ else
75
+ Types::Registry.primitive(name)
76
+ end
77
+ end
78
+ end
79
+
80
+ def builtin_subscription_type
81
+ Types::Subscription.new
82
+ end
83
+
84
+ def builtin_event_error_type
85
+ Types::Enum.new("EventError").define_members(@ctx.types.fetch("int"), ["full"]).define_member_values("full" => 0)
86
+ end
87
+
88
+ def builtin_struct_handle_type
89
+ Types::BUILTIN_STRUCT_HANDLE_TYPE
90
+ end
91
+
92
+ def builtin_field_handle_type
93
+ Types::BUILTIN_FIELD_HANDLE_TYPE
94
+ end
95
+
96
+ def builtin_callable_handle_type
97
+ Types::BUILTIN_CALLABLE_HANDLE_TYPE
98
+ end
99
+
100
+ def builtin_attribute_handle_type
101
+ Types::BUILTIN_ATTRIBUTE_HANDLE_TYPE
102
+ end
103
+
104
+ def builtin_member_handle_type
105
+ Types::BUILTIN_MEMBER_HANDLE_TYPE
106
+ end
107
+
108
+ def builtin_type_meta_type
109
+ Types::BUILTIN_TYPE_META_TYPE
110
+ end
111
+
112
+ def install_builtin_attributes
113
+ BUILTIN_ATTRIBUTE_NAMES.each do |name|
114
+ @ctx.attributes[name] = MilkTea.builtin_attribute_binding(name, @ctx.types)
115
+ end
116
+ end
117
+
118
+ def snapshot_attributes
119
+ @ctx.attributes.each_with_object({}) do |(name, binding), attributes|
120
+ next if binding.builtin
121
+
122
+ attributes[name] = binding
123
+ end.freeze
124
+ end
125
+
126
+ def snapshot_attribute_applications
127
+ @ctx.resolved_attribute_applications.each_with_object({}) do |(target_id, applications), snapshot|
128
+ snapshot[target_id] = applications
129
+ end.freeze
130
+ end
131
+
132
+ def snapshot_methods
133
+ @ctx.methods.each_with_object({}) do |(receiver_type, bindings), methods|
134
+ methods[receiver_type] = bindings.dup.freeze
135
+ end.freeze
136
+ end
137
+
138
+ def snapshot_implemented_interfaces
139
+ @ctx.implemented_interfaces.each_with_object({}) do |(receiver_type, interfaces), snapshot|
140
+ snapshot[receiver_type] = interfaces.dup.freeze
141
+ end.freeze
142
+ end
143
+
144
+ def install_imports
145
+ @ctx.ast.imports.each do |import|
146
+ with_error_node(import) do
147
+ alias_name = import.alias_name || import.path.parts.last
148
+ ensure_non_reserved_import_alias_name!(alias_name, kind_label: "import alias", line: import.line, column: import.column)
149
+ raise_sema_error("duplicate import alias #{alias_name}") if @ctx.imports.key?(alias_name)
150
+
151
+ module_binding = @ctx.imported_modules[import.path.to_s]
152
+ next if @allow_missing_imports && module_binding.nil?
153
+ raise_sema_error("unknown import #{import.path}") unless module_binding
154
+
155
+ @ctx.imports[alias_name] = module_binding
156
+ end
157
+ end
158
+ end
159
+
160
+ PRELUDE_MODULE_PATHS = %w[std.option std.result].freeze
161
+
162
+ def install_prelude_types
163
+ PRELUDE_MODULE_PATHS.each do |module_path|
164
+ next if module_path == @ctx.module_name
165
+
166
+ module_binding = @ctx.imported_modules[module_path]
167
+ unless module_binding
168
+ install_fallback_builtin_type(module_path)
169
+ next
170
+ end
171
+
172
+ module_binding.types.each do |type_name, type|
173
+ @ctx.types[type_name] = type unless @ctx.types.key?(type_name)
174
+ end
175
+
176
+ already_imported = @ctx.imports.any? { |_, existing_binding| existing_binding == module_binding }
177
+ @ctx.imports[module_path] = module_binding unless @ctx.imports.key?(module_path) || already_imported
178
+ end
179
+ end
180
+
181
+ def install_fallback_builtin_type(module_path)
182
+ case module_path
183
+ when "std.option"
184
+ @ctx.types["Option"] = Types::BUILTIN_OPTION_TYPE unless @ctx.types.key?("Option")
185
+ when "std.result"
186
+ @ctx.types["Result"] = Types::BUILTIN_RESULT_TYPE unless @ctx.types.key?("Result")
187
+ end
188
+ end
189
+
190
+ def expanded_declarations
191
+ Enumerator.new do |yielder|
192
+ @ctx.ast.declarations.each do |decl|
193
+ case decl
194
+ when AST::WhenStmt
195
+ body = when_chosen_body(decl)
196
+ if body
197
+ body.each { |nested| yielder << nested }
198
+ end
199
+ else
200
+ yielder << decl
201
+ end
202
+ end
203
+ end
204
+ end
205
+
206
+ def declare_named_types
207
+ expanded_declarations.each do |decl|
208
+ with_error_node(decl) do
209
+ case decl
210
+ when AST::StructDecl
211
+ validate_struct_layout!(decl)
212
+ validate_explicit_aggregate_c_name!(decl)
213
+ ensure_available_type_name!(decl.name)
214
+ @ctx.types[decl.name] = if decl.type_params.empty?
215
+ Types::Struct.new(
216
+ decl.name,
217
+ module_name: @ctx.module_name,
218
+ external: raw_module?,
219
+ packed: decl.packed,
220
+ alignment: decl.alignment,
221
+ linkage_name: decl.c_name,
222
+ lifetime_params: decl.lifetime_params,
223
+ )
224
+ else
225
+ Types::GenericStructDefinition.new(
226
+ decl.name,
227
+ decl.type_params.map(&:name),
228
+ module_name: @ctx.module_name,
229
+ external: raw_module?,
230
+ packed: decl.packed,
231
+ alignment: decl.alignment,
232
+ linkage_name: decl.c_name,
233
+ lifetime_params: decl.lifetime_params,
234
+ )
235
+ end
236
+ register_nested_struct_types(decl)
237
+ when AST::UnionDecl
238
+ validate_explicit_aggregate_c_name!(decl)
239
+ ensure_available_type_name!(decl.name)
240
+ @ctx.types[decl.name] = Types::Union.new(decl.name, module_name: @ctx.module_name, external: raw_module?, linkage_name: decl.c_name)
241
+ when AST::VariantDecl
242
+ ensure_available_type_name!(decl.name)
243
+ @ctx.types[decl.name] = if decl.type_params.empty?
244
+ Types::Variant.new(decl.name, module_name: @ctx.module_name)
245
+ else
246
+ Types::GenericVariantDefinition.new(
247
+ decl.name,
248
+ decl.type_params.map(&:name),
249
+ module_name: @ctx.module_name,
250
+ )
251
+ end
252
+ when AST::EnumDecl
253
+ ensure_available_type_name!(decl.name)
254
+ @ctx.types[decl.name] = Types::Enum.new(decl.name, module_name: @ctx.module_name, external: raw_module?)
255
+ when AST::FlagsDecl
256
+ ensure_available_type_name!(decl.name)
257
+ @ctx.types[decl.name] = Types::Flags.new(decl.name, module_name: @ctx.module_name, external: raw_module?)
258
+ when AST::OpaqueDecl
259
+ ensure_available_type_name!(decl.name)
260
+ @ctx.types[decl.name] = Types::Opaque.new(
261
+ decl.name,
262
+ module_name: @ctx.module_name,
263
+ external: raw_module?,
264
+ linkage_name: decl.c_name,
265
+ )
266
+ when AST::InterfaceDecl
267
+ ensure_available_type_name!(decl.name)
268
+ @ctx.interfaces[decl.name] = declare_interface_binding(decl)
269
+ end
270
+ end
271
+ rescue SemanticError => e
272
+ collect_structural_error(e)
273
+ end
274
+ end
275
+
276
+ def resolve_generic_type_param_constraints
277
+ expanded_declarations.each do |decl|
278
+ with_error_node(decl) do
279
+ next unless decl.is_a?(AST::StructDecl) || decl.is_a?(AST::VariantDecl) || decl.is_a?(AST::InterfaceDecl)
280
+ next if decl.type_params.empty?
281
+
282
+ constraints = resolve_type_param_constraints(decl.type_params)
283
+ if decl.is_a?(AST::InterfaceDecl)
284
+ @ctx.interfaces[decl.name] = @ctx.interfaces.fetch(decl.name).with(type_param_constraints: constraints)
285
+ else
286
+ @ctx.types.fetch(decl.name).define_type_param_constraints(constraints)
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ def resolve_type_aliases
293
+ @ctx.ast.declarations.grep(AST::TypeAliasDecl).each do |decl|
294
+ ensure_available_type_name!(decl.name)
295
+ @ctx.types[decl.name] = resolve_type_ref(decl.target)
296
+ rescue SemanticError => e
297
+ collect_structural_error(e)
298
+ end
299
+ end
300
+
301
+ def declare_attributes
302
+ expanded_declarations.grep(AST::AttributeDecl).each do |decl|
303
+ with_error_node(decl) do
304
+ raise_sema_error("duplicate attribute #{decl.name}") if @ctx.attributes.key?(decl.name)
305
+
306
+ params = []
307
+ seen = {}
308
+ decl.params.each do |param|
309
+ raise_sema_error("duplicate attribute parameter #{decl.name}.#{param.name}") if seen.key?(param.name)
310
+
311
+ seen[param.name] = true
312
+ params << Types::Registry.parameter(param.name, resolve_type_ref(param.type))
313
+ end
314
+
315
+ @ctx.attributes[decl.name] = AttributeBinding.new(
316
+ name: decl.name,
317
+ targets: decl.targets.freeze,
318
+ params: params.freeze,
319
+ module_name: @ctx.module_name,
320
+ builtin: false,
321
+ ast: decl,
322
+ )
323
+ end
324
+ end
325
+ end
326
+
327
+ def declare_interface_binding(decl)
328
+ if decl.type_params.any?
329
+ type_param_names = decl.type_params.map(&:name)
330
+ type_params_map = type_param_names.map { |n| [n, Types::TypeVar.new(n)] }.to_h
331
+ methods = {}
332
+
333
+ decl.methods.each do |method_decl|
334
+ method = resolve_interface_method_binding(method_decl, type_params: type_params_map, type_param_constraints: {})
335
+ raise_sema_error("duplicate method #{decl.name}.#{method.name}") if methods.key?(method.name)
336
+
337
+ methods[method.name] = method
338
+ end
339
+
340
+ GenericInterfaceBinding.new(
341
+ name: decl.name,
342
+ type_params: type_param_names.freeze,
343
+ type_param_constraints: {},
344
+ methods: methods.freeze,
345
+ ast: decl,
346
+ module_name: @ctx.module_name,
347
+ )
348
+ else
349
+ methods = {}
350
+
351
+ decl.methods.each do |method_decl|
352
+ method = resolve_interface_method_binding(method_decl)
353
+ raise_sema_error("duplicate method #{decl.name}.#{method.name}") if methods.key?(method.name)
354
+
355
+ methods[method.name] = method
356
+ end
357
+
358
+ InterfaceBinding.new(
359
+ name: decl.name,
360
+ methods: methods.freeze,
361
+ ast: decl,
362
+ module_name: @ctx.module_name,
363
+ )
364
+ end
365
+ end
366
+
367
+ def resolve_interface_method_binding(method_decl, type_params: {}, type_param_constraints: {})
368
+ raise_sema_error("interface method #{method_decl.name} cannot be async") if method_decl.async
369
+
370
+ params = []
371
+ seen = {}
372
+ method_decl.params.each do |param|
373
+ raise_sema_error("duplicate parameter #{param.name} in #{method_decl.name}") if seen.key?(param.name)
374
+
375
+ seen[param.name] = true
376
+ type = resolve_type_ref(param.type, type_params:, type_param_constraints:)
377
+ validate_parameter_ref_type!(type, function_name: method_decl.name, parameter_name: param.name, external: false)
378
+ validate_parameter_proc_type!(type, function_name: method_decl.name, parameter_name: param.name, external: false, foreign: false)
379
+ params << Types::Registry.parameter(param.name, type)
380
+ end
381
+
382
+ return_type = method_decl.return_type ? resolve_type_ref(method_decl.return_type, type_params:, type_param_constraints:) : @ctx.types.fetch("void")
383
+ validate_return_ref_type!(return_type, function_name: method_decl.name)
384
+ validate_return_proc_type!(return_type, function_name: method_decl.name)
385
+
386
+ InterfaceMethodBinding.new(
387
+ name: method_decl.name,
388
+ params: params.freeze,
389
+ return_type: return_type,
390
+ kind: method_decl.kind,
391
+ async: method_decl.async,
392
+ ast: method_decl,
393
+ )
394
+ end
395
+
396
+ def validate_struct_layout!(decl)
397
+ return unless decl.alignment
398
+
399
+ raise_sema_error("align(...) requires a positive alignment") unless decl.alignment.positive?
400
+ return if power_of_two?(decl.alignment)
401
+
402
+ raise_sema_error("align(...) requires a power-of-two alignment, got #{decl.alignment}")
403
+ end
404
+
405
+ def validate_explicit_aggregate_c_name!(decl)
406
+ return unless decl.c_name
407
+
408
+ raise_sema_error("explicit C names are only allowed on external structs and unions") unless raw_module?
409
+ return if !decl.respond_to?(:type_params) || decl.type_params.empty?
410
+
411
+ raise_sema_error("explicit C names are not supported on generic external structs")
412
+ end
413
+
414
+ def resolve_event_decl_type(decl, type_params: {}, type_param_constraints: {}, owner_type_name: nil, nested_types: nil)
415
+ raise_sema_error("event #{decl.name} capacity must be positive") unless decl.capacity.is_a?(Integer) && decl.capacity.positive?
416
+
417
+ payload_type = decl.payload_type ? resolve_type_ref(decl.payload_type, type_params:, type_param_constraints:, nested_types:) : nil
418
+ if payload_type
419
+ raise_sema_error("event #{decl.name} payload cannot be ref[T] in v1") if ref_type?(payload_type)
420
+ validate_stored_ref_type!(payload_type, "event #{decl.name} payload")
421
+ raise_sema_error("event #{decl.name} payload uses unsupported proc nesting") unless proc_storage_supported_type?(payload_type)
422
+ raise_sema_error("event #{decl.name} payload cannot use event storage type #{payload_type}") if noncopyable_event_storage_type?(payload_type)
423
+ end
424
+
425
+ Types::Event.new(
426
+ decl.name,
427
+ capacity: decl.capacity,
428
+ payload_type: payload_type,
429
+ module_name: @ctx.module_name,
430
+ visibility: decl.visibility,
431
+ owner_type_name: owner_type_name,
432
+ )
433
+ end
434
+
435
+ def resolve_aggregate_fields
436
+ expanded_declarations.each do |decl|
437
+ with_error_node(decl) do
438
+ next unless decl.is_a?(AST::StructDecl) || decl.is_a?(AST::UnionDecl)
439
+
440
+ struct_type = @ctx.types.fetch(decl.name)
441
+ struct_type.ast_declaration = decl if struct_type.respond_to?(:ast_declaration=)
442
+ type_params = if struct_type.is_a?(Types::GenericStructDefinition)
443
+ seen = {}
444
+ struct_type.type_params.each_with_object({}) do |name, params|
445
+ raise_sema_error("duplicate type parameter #{decl.name}[#{name}]") if seen.key?(name)
446
+
447
+ seen[name] = true
448
+ params[name] = Types::TypeVar.new(name)
449
+ end
450
+ else
451
+ {}
452
+ end
453
+ decl.lifetime_params.each do |lt|
454
+ type_params[lt] = Types::LifetimeRef.new(lt)
455
+ end if decl.respond_to?(:lifetime_params)
456
+ type_param_constraints = struct_type.is_a?(Types::GenericStructDefinition) ? struct_type.type_param_constraints : {}
457
+ fields = {}
458
+ events = {}
459
+ field_errors = []
460
+
461
+ auto_lifetimes = []
462
+
463
+ nested_scope = decl.is_a?(AST::StructDecl) ? resolve_nested_type_bindings(decl) : {}
464
+ if decl.is_a?(AST::StructDecl) && struct_type.respond_to?(:define_nested_types)
465
+ struct_type.define_nested_types(nested_scope)
466
+ define_nested_type_bindings_recursive(decl, parent_name: decl.name)
467
+ end
468
+
469
+ decl.fields.each do |field|
470
+ raise_sema_error("duplicate field #{decl.name}.#{field.name}") if fields.key?(field.name)
471
+ raise_sema_error("duplicate member #{decl.name}.#{field.name}") if events.key?(field.name)
472
+ unless raw_module?
473
+ ensure_non_reserved_type_binding_name!(
474
+ field.name,
475
+ kind_label: "field #{decl.name}",
476
+ line: field.respond_to?(:line) ? field.line : decl.line,
477
+ column: field.respond_to?(:column) ? field.column : nil,
478
+ )
479
+ end
480
+
481
+ begin
482
+ field_type = resolve_type_ref(field.type, type_params:, type_param_constraints:, nested_types: nested_scope)
483
+
484
+ # Auto-generate implicit lifetimes for bare ref[T] in struct fields
485
+ if ref_type_without_lifetime?(field_type)
486
+ auto_lt_name = "@_mt_#{auto_lifetimes.length}"
487
+ auto_lifetimes << auto_lt_name
488
+ type_params[auto_lt_name] = Types::LifetimeRef.new(auto_lt_name)
489
+ field_type = Types::Registry.generic_instance("ref", [auto_lt_name] + field_type.arguments)
490
+ end
491
+ if decl.respond_to?(:lifetime_params) && (lt = ref_lifetime(field_type))
492
+ unless decl.lifetime_params.include?(lt) || auto_lifetimes.include?(lt)
493
+ raise_sema_error("field #{decl.name}.#{field.name} uses lifetime #{lt} not declared on struct")
494
+ end
495
+ end
496
+ allow_lts = decl.respond_to?(:lifetime_params) ? (decl.lifetime_params + auto_lifetimes) : []
497
+ validate_stored_ref_type!(field_type, "field #{decl.name}.#{field.name}", allow_lifetimes: allow_lts)
498
+ unless proc_storage_supported_type?(field_type)
499
+ raise_sema_error("field #{decl.name}.#{field.name} uses unsupported proc nesting")
500
+ end
501
+ fields[field.name] = field_type
502
+ rescue SemanticError => e
503
+ fields[field.name] = @error_type
504
+ field_errors << e
505
+ @structural_errors << e if @structural_errors
506
+ end
507
+ end
508
+
509
+ unless field_errors.empty?
510
+ struct_type.define_fields(fields)
511
+ raise field_errors.first
512
+ end
513
+
514
+ if decl.is_a?(AST::StructDecl)
515
+ decl.events.each do |event_decl|
516
+ raise_sema_error("duplicate event #{decl.name}.#{event_decl.name}") if events.key?(event_decl.name)
517
+ raise_sema_error("duplicate member #{decl.name}.#{event_decl.name}") if fields.key?(event_decl.name)
518
+ unless raw_module?
519
+ ensure_non_reserved_type_binding_name!(
520
+ event_decl.name,
521
+ kind_label: "event #{decl.name}",
522
+ line: event_decl.line,
523
+ column: event_decl.column,
524
+ )
525
+ end
526
+
527
+ begin
528
+ events[event_decl.name] = resolve_event_decl_type(
529
+ event_decl,
530
+ type_params:,
531
+ type_param_constraints:,
532
+ owner_type_name: decl.name,
533
+ nested_types: nested_scope,
534
+ )
535
+ rescue SemanticError => e
536
+ collect_structural_error(e)
537
+ end
538
+ end
539
+ end
540
+
541
+ if decl.is_a?(AST::StructDecl)
542
+ resolve_nested_struct_fields(decl, type_params:, type_param_constraints:, external_nested_scope: nested_scope)
543
+ end
544
+ struct_type.define_fields(fields)
545
+ struct_type.define_events(events) if struct_type.respond_to?(:define_events)
546
+ end
547
+ rescue SemanticError => e
548
+ collect_structural_error(e)
549
+ end
550
+ end
551
+
552
+ def resolve_enum_members
553
+ expanded_declarations.each do |decl|
554
+ with_error_node(decl) do
555
+ next unless decl.is_a?(AST::EnumDecl) || decl.is_a?(AST::FlagsDecl)
556
+
557
+ enum_type = @ctx.types.fetch(decl.name)
558
+ backing_type = resolve_type_ref(decl.backing_type)
559
+ unless backing_type.is_a?(Types::Primitive) && backing_type.integer?
560
+ raise_sema_error("#{decl.name} backing type must be an integer primitive, got #{backing_type}")
561
+ end
562
+
563
+ member_names = []
564
+ decl.members.each do |member|
565
+ raise_sema_error("duplicate member #{decl.name}.#{member.name}") if member_names.include?(member.name)
566
+ unless raw_module?
567
+ ensure_non_reserved_type_binding_name!(
568
+ member.name,
569
+ kind_label: "member #{decl.name}",
570
+ line: member.respond_to?(:line) ? member.line : decl.line,
571
+ column: member.respond_to?(:column) ? member.column : nil,
572
+ )
573
+ end
574
+
575
+ member_names << member.name
576
+ end
577
+
578
+ enum_type.define_members(backing_type, member_names)
579
+
580
+ member_values = {}
581
+
582
+ decl.members.each do |member|
583
+ begin
584
+ actual_type = infer_expression(member.value, scopes: [], expected_type: backing_type)
585
+ const_value = evaluate_enum_member_const_value(member.value, enum_type:, member_values:)
586
+
587
+ compatible = types_compatible?(actual_type, backing_type, expression: member.value, scopes: [])
588
+ compatible ||= actual_type.is_a?(Types::EnumBase) && types_compatible?(actual_type.backing_type, backing_type, expression: member.value, scopes: [])
589
+ compatible ||= const_value.is_a?(Integer) && numeric_constant_fits_type?(const_value, backing_type)
590
+ raise_sema_error("member #{decl.name}.#{member.name} expects #{backing_type}, got #{actual_type}", member) unless compatible
591
+
592
+ raise_sema_error("member #{decl.name}.#{member.name} must be a compile-time integer constant", member) unless const_value.is_a?(Integer)
593
+
594
+ member_values[member.name] = const_value
595
+ rescue SemanticError => e
596
+ collect_structural_error(e)
597
+ end
598
+ end
599
+
600
+ enum_type.define_member_values(member_values)
601
+ end
602
+ rescue SemanticError => e
603
+ collect_structural_error(e)
604
+ end
605
+ end
606
+
607
+ def resolve_variant_arms
608
+ expanded_declarations.each do |decl|
609
+ with_error_node(decl) do
610
+ next unless decl.is_a?(AST::VariantDecl)
611
+
612
+ variant_type = @ctx.types.fetch(decl.name)
613
+ type_params = if variant_type.is_a?(Types::GenericVariantDefinition)
614
+ seen = {}
615
+ variant_type.type_params.each_with_object({}) do |name, params|
616
+ raise_sema_error("duplicate type parameter #{decl.name}[#{name}]") if seen.key?(name)
617
+
618
+ seen[name] = true
619
+ params[name] = Types::TypeVar.new(name)
620
+ end
621
+ else
622
+ {}
623
+ end
624
+ type_param_constraints = variant_type.is_a?(Types::GenericVariantDefinition) ? variant_type.type_param_constraints : {}
625
+ seen_arms = []
626
+ arms_hash = {}
627
+ decl.arms.each do |arm|
628
+ begin
629
+ raise_sema_error("duplicate arm #{decl.name}.#{arm.name}") if seen_arms.include?(arm.name)
630
+ unless raw_module?
631
+ ensure_non_reserved_type_binding_name!(
632
+ arm.name,
633
+ kind_label: "arm #{decl.name}",
634
+ line: arm.respond_to?(:line) ? arm.line : decl.line,
635
+ column: arm.respond_to?(:column) ? arm.column : nil,
636
+ )
637
+ end
638
+
639
+ seen_arms << arm.name
640
+ field_types = {}
641
+ seen_fields = []
642
+ arm_field_errors = []
643
+ arm.fields.each do |field|
644
+ begin
645
+ raise_sema_error("duplicate field #{arm.name}.#{field.name}") if seen_fields.include?(field.name)
646
+ unless raw_module?
647
+ ensure_non_reserved_type_binding_name!(
648
+ field.name,
649
+ kind_label: "field #{decl.name}.#{arm.name}",
650
+ line: field.respond_to?(:line) ? field.line : decl.line,
651
+ column: field.respond_to?(:column) ? field.column : nil,
652
+ )
653
+ end
654
+
655
+ seen_fields << field.name
656
+ field_type = resolve_type_ref(field.type, type_params:, type_param_constraints:)
657
+ validate_stored_ref_type!(field_type, "field #{decl.name}.#{arm.name}.#{field.name}")
658
+ unless proc_storage_supported_type?(field_type)
659
+ raise_sema_error("field #{decl.name}.#{arm.name}.#{field.name} uses unsupported proc nesting")
660
+ end
661
+ field_types[field.name] = field_type
662
+ rescue SemanticError => e
663
+ field_types[field.name] = @error_type
664
+ arm_field_errors << e
665
+ @structural_errors << e if @structural_errors
666
+ end
667
+ end
668
+
669
+ raise arm_field_errors.first unless arm_field_errors.empty?
670
+ arms_hash[arm.name] = field_types
671
+ rescue SemanticError => e
672
+ collect_structural_error(e)
673
+ end
674
+ end
675
+
676
+ variant_type.define_arms(arms_hash)
677
+ end
678
+ rescue SemanticError => e
679
+ collect_structural_error(e)
680
+ end
681
+ end
682
+
683
+ PRELUDE_TYPE_DEFINING_MODULES = {
684
+ "Option" => "std.option",
685
+ "Result" => "std.result",
686
+ }.freeze
687
+
688
+ def ensure_available_type_name!(name, line: nil, column: nil, length: nil)
689
+ unless raw_module? || (PRELUDE_TYPE_DEFINING_MODULES[name] == @ctx.module_name)
690
+ ensure_non_reserved_type_binding_name!(name, kind_label: "type", line:, column:, length:)
691
+ end
692
+ raise_sema_error("duplicate type #{name}") if @ctx.types.key?(name) || @ctx.interfaces.key?(name)
693
+ end
694
+
695
+ def ensure_available_value_name!(name, kind_label: "value", line: nil, column: nil, length: nil)
696
+ ensure_non_reserved_value_type_name!(name, kind_label:, line:, column:, length:)
697
+ raise_sema_error("duplicate value #{name}") if @ctx.top_level_values.key?(name) || @ctx.top_level_functions.key?(name)
698
+ end
699
+
700
+ def ensure_non_reserved_name!(name, reserved_names, kind_label:, line: nil, column: nil, length: nil)
701
+ return unless reserved_names.include?(name)
702
+
703
+ raise_sema_error("#{kind_label} #{name} uses reserved built-in type name #{name}", line:, column:, length:)
704
+ end
705
+
706
+ def ensure_non_reserved_value_type_name!(name, kind_label:, line: nil, column: nil, length: nil)
707
+ ensure_non_reserved_name!(name, Types::RESERVED_VALUE_TYPE_NAMES, kind_label:, line:, column:, length:)
708
+ end
709
+
710
+ def ensure_non_reserved_import_alias_name!(name, kind_label:, line: nil, column: nil, length: nil)
711
+ ensure_non_reserved_name!(name, Types::RESERVED_IMPORT_ALIAS_NAMES, kind_label:, line:, column:, length:)
712
+ end
713
+
714
+ def ensure_non_reserved_type_binding_name!(name, kind_label:, line: nil, column: nil, length: nil)
715
+ ensure_non_reserved_name!(name, Types::RESERVED_TYPE_BINDING_NAMES, kind_label:, line:, column:, length:)
716
+ end
717
+
718
+ def declare_top_level_values
719
+ expanded_declarations.each do |decl|
720
+ with_error_node(decl) do
721
+ case decl
722
+ when AST::ConstDecl
723
+ begin
724
+ ensure_available_value_name!(decl.name, kind_label: "constant", line: decl.line, column: decl.respond_to?(:column) ? decl.column : nil)
725
+ type = resolve_type_ref(decl.type)
726
+ validate_stored_ref_type!(type, "constant #{decl.name}")
727
+ raise_sema_error("constant #{decl.name} cannot store proc values") if contains_proc_type?(type)
728
+ @ctx.top_level_values[decl.name] = value_binding(
729
+ name: decl.name,
730
+ type: type,
731
+ mutable: false,
732
+ kind: :const,
733
+ )
734
+ rescue SemanticError => e
735
+ collect_structural_error(e)
736
+ @ctx.top_level_values[decl.name] = value_binding(
737
+ name: decl.name,
738
+ type: @error_type,
739
+ mutable: false,
740
+ kind: :const,
741
+ ) unless @ctx.top_level_values.key?(decl.name)
742
+ end
743
+ when AST::VarDecl
744
+ ensure_available_value_name!(decl.name, kind_label: "module variable", line: decl.line, column: decl.respond_to?(:column) ? decl.column : nil)
745
+ raise_sema_error("module variable #{decl.name} requires an explicit type") unless decl.type
746
+
747
+ type = resolve_type_ref(decl.type)
748
+ validate_stored_ref_type!(type, "module variable #{decl.name}")
749
+ @ctx.top_level_values[decl.name] = value_binding(
750
+ name: decl.name,
751
+ type: type,
752
+ mutable: true,
753
+ kind: :var,
754
+ )
755
+ when AST::EventDecl
756
+ ensure_available_value_name!(decl.name, kind_label: "event", line: decl.line, column: decl.column)
757
+ @ctx.top_level_values[decl.name] = value_binding(
758
+ name: decl.name,
759
+ type: resolve_event_decl_type(decl),
760
+ mutable: false,
761
+ kind: :event,
762
+ )
763
+ end
764
+ end
765
+ rescue SemanticError => e
766
+ collect_structural_error(e)
767
+ end
768
+ end
769
+
770
+ def ensure_non_reserved_primitive_name!(name, kind_label:, line: nil, column: nil, length: nil)
771
+ ensure_non_reserved_value_type_name!(name, kind_label:, line:, column:, length:)
772
+ end
773
+
774
+
775
+ def define_nested_type_bindings_recursive(parent_decl, parent_name: parent_decl.name)
776
+ parent_decl.nested_types.each do |nested|
777
+ qualified_name = "#{parent_name}.#{nested.name}"
778
+ nested_type = @ctx.types[qualified_name]
779
+ next unless nested_type.is_a?(Types::Struct)
780
+ nested_scope = resolve_nested_type_bindings(nested, parent_name: qualified_name)
781
+ nested_type.define_nested_types(nested_scope)
782
+ define_nested_type_bindings_recursive(nested, parent_name: qualified_name)
783
+ end
784
+ end
785
+
786
+ def resolve_nested_struct_fields(parent_decl, parent_name: parent_decl.name, type_params:, type_param_constraints:, external_nested_scope: {})
787
+ parent_decl.nested_types.each do |nested|
788
+ next unless nested.type_params.empty?
789
+ qualified_name = "#{parent_name}.#{nested.name}"
790
+ nested_type = @ctx.types[qualified_name]
791
+ next unless nested_type.is_a?(Types::Struct)
792
+ nested_type.ast_declaration = nested
793
+ nested_scope = nested_type.nested_types.merge(external_nested_scope)
794
+ fields = {}
795
+ nested.fields.each do |field|
796
+ raise_sema_error("duplicate field #{qualified_name}.#{field.name}") if fields.key?(field.name)
797
+ begin
798
+ field_type = resolve_type_ref(field.type, type_params:, type_param_constraints:, nested_types: nested_scope)
799
+ validate_stored_ref_type!(field_type, "field #{qualified_name}.#{field.name}")
800
+ fields[field.name] = field_type
801
+ rescue SemanticError => e
802
+ fields[field.name] = @error_type
803
+ @structural_errors << e if @structural_errors
804
+ end
805
+ end
806
+ nested_type.define_fields(fields)
807
+ nested_events = {}
808
+ nested.events.each do |event_decl|
809
+ raise_sema_error("duplicate event #{qualified_name}.#{event_decl.name}") if nested_events.key?(event_decl.name)
810
+ begin
811
+ nested_events[event_decl.name] = resolve_event_decl_type(event_decl, type_params:, type_param_constraints:, owner_type_name: qualified_name, nested_types: nested_scope)
812
+ rescue SemanticError => e
813
+ collect_structural_error(e)
814
+ end
815
+ end
816
+ nested_type.define_events(nested_events)
817
+ resolve_nested_struct_fields(nested, parent_name: qualified_name, type_params:, type_param_constraints:, external_nested_scope: nested_scope)
818
+ end
819
+ end
820
+
821
+ def resolve_nested_type_bindings(parent_decl, parent_name: parent_decl.name)
822
+ bindings = {}
823
+ parent_decl.nested_types.each do |nested|
824
+ qualified_name = "#{parent_name}.#{nested.name}"
825
+ nested_type = @ctx.types[qualified_name]
826
+ bindings[nested.name] = nested_type if nested_type
827
+ end
828
+ bindings
829
+ end
830
+
831
+ def register_nested_struct_types(parent_decl, parent_name: parent_decl.name)
832
+ parent_decl.nested_types.each do |nested|
833
+ qualified_name = "#{parent_name}.#{nested.name}"
834
+ ensure_available_type_name!(qualified_name)
835
+ nested_c_name = if @ctx.module_name && !raw_module?
836
+ "#{@ctx.module_name.to_s.tr('.', '_')}_#{qualified_name.tr('.', '_')}"
837
+ else
838
+ qualified_name.tr('.', '_')
839
+ end
840
+ if nested.type_params.empty?
841
+ @ctx.types[qualified_name] = Types::Struct.new(nested.name, module_name: @ctx.module_name, external: raw_module?, packed: nested.packed, alignment: nested.alignment, linkage_name: nested_c_name, lifetime_params: nested.lifetime_params)
842
+ else
843
+ @ctx.types[qualified_name] = Types::GenericStructDefinition.new(nested.name, nested.type_params.map(&:name), module_name: @ctx.module_name, external: raw_module?, packed: nested.packed, alignment: nested.alignment, linkage_name: nested_c_name, lifetime_params: nested.lifetime_params)
844
+ end
845
+ register_nested_struct_types(nested, parent_name: qualified_name)
846
+ end
847
+ end
848
+ end
849
+ end
850
+ end
851
+