mt-lang 0.3.9 → 0.3.11

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 (204) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/docs/language-design.md +1 -2
  4. data/docs/language-manual.md +12 -1
  5. data/lib/milk_tea/base.rb +1 -2
  6. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
  7. data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
  8. data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
  9. data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
  10. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
  11. data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
  12. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
  13. data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
  14. data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
  15. data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
  16. data/lib/milk_tea/bindings/steamworks.rb +12 -16
  17. data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
  18. data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
  19. data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
  20. data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
  21. data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
  22. data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
  23. data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
  24. data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
  25. data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
  26. data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
  27. data/lib/milk_tea/core/ast.rb +109 -51
  28. data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
  29. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
  30. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
  31. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
  32. data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
  33. data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
  34. data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
  35. data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
  36. data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
  37. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
  38. data/lib/milk_tea/core/c_backend/statements.rb +528 -530
  39. data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
  40. data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
  41. data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
  42. data/lib/milk_tea/core/c_backend.rb +17 -9
  43. data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
  44. data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
  45. data/lib/milk_tea/core/compile_time.rb +32 -38
  46. data/lib/milk_tea/core/control_flow/builder.rb +3 -5
  47. data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
  48. data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
  49. data/lib/milk_tea/core/ir.rb +10 -10
  50. data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
  51. data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
  52. data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
  53. data/lib/milk_tea/core/lexer/indentation.rb +0 -2
  54. data/lib/milk_tea/core/lexer/numbers.rb +0 -2
  55. data/lib/milk_tea/core/lexer/recovery.rb +0 -2
  56. data/lib/milk_tea/core/lexer/strings.rb +0 -2
  57. data/lib/milk_tea/core/lexer/symbols.rb +0 -2
  58. data/lib/milk_tea/core/lexer/trivia.rb +0 -2
  59. data/lib/milk_tea/core/lexer.rb +0 -2
  60. data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
  61. data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
  62. data/lib/milk_tea/core/lowering/async/normalization.rb +5 -3
  63. data/lib/milk_tea/core/lowering/async.rb +627 -630
  64. data/lib/milk_tea/core/lowering/block.rb +413 -416
  65. data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
  66. data/lib/milk_tea/core/lowering/declarations.rb +180 -183
  67. data/lib/milk_tea/core/lowering/dyn.rb +48 -50
  68. data/lib/milk_tea/core/lowering/events.rb +983 -985
  69. data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
  70. data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
  71. data/lib/milk_tea/core/lowering/functions.rb +185 -188
  72. data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
  73. data/lib/milk_tea/core/lowering/proc.rb +363 -366
  74. data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
  75. data/lib/milk_tea/core/lowering/scans.rb +179 -181
  76. data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
  77. data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
  78. data/lib/milk_tea/core/lowering.rb +5 -7
  79. data/lib/milk_tea/core/module_binder.rb +0 -2
  80. data/lib/milk_tea/core/module_loader/errors.rb +4 -2
  81. data/lib/milk_tea/core/module_loader.rb +113 -20
  82. data/lib/milk_tea/core/module_path_resolver.rb +0 -2
  83. data/lib/milk_tea/core/module_roots.rb +6 -8
  84. data/lib/milk_tea/core/parser/attributes.rb +0 -2
  85. data/lib/milk_tea/core/parser/blocks.rb +0 -2
  86. data/lib/milk_tea/core/parser/declarations.rb +7 -9
  87. data/lib/milk_tea/core/parser/expressions.rb +15 -10
  88. data/lib/milk_tea/core/parser/recovery.rb +0 -2
  89. data/lib/milk_tea/core/parser/statements.rb +8 -2
  90. data/lib/milk_tea/core/parser/types.rb +12 -14
  91. data/lib/milk_tea/core/parser.rb +0 -2
  92. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
  93. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
  94. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
  95. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
  96. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
  97. data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
  98. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
  99. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
  100. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
  101. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +14 -17
  102. data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
  103. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
  104. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
  105. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
  106. data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
  107. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
  108. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
  109. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +106 -109
  110. data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
  111. data/lib/milk_tea/core/types/layout.rb +21 -22
  112. data/lib/milk_tea/core/types/predicates.rb +0 -2
  113. data/lib/milk_tea/core/types/registry.rb +16 -18
  114. data/lib/milk_tea/core/types/visitor.rb +0 -4
  115. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
  116. data/lib/milk_tea/dap/protocol.rb +1 -1
  117. data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
  118. data/lib/milk_tea/dap/server/debug_map.rb +0 -2
  119. data/lib/milk_tea/dap/server/handlers.rb +0 -2
  120. data/lib/milk_tea/dap/server/launch.rb +0 -2
  121. data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
  122. data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
  123. data/lib/milk_tea/dap/server/utilities.rb +0 -2
  124. data/lib/milk_tea/dap/server/wire.rb +0 -2
  125. data/lib/milk_tea/dap/server.rb +0 -2
  126. data/lib/milk_tea/lsp/diagnostics.rb +16 -16
  127. data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
  128. data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
  129. data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
  130. data/lib/milk_tea/lsp/server/completion.rb +873 -875
  131. data/lib/milk_tea/lsp/server/configuration.rb +129 -131
  132. data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
  133. data/lib/milk_tea/lsp/server/definition.rb +564 -565
  134. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
  135. data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
  136. data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
  137. data/lib/milk_tea/lsp/server/formatting.rb +478 -480
  138. data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
  139. data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
  140. data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
  141. data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
  142. data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
  143. data/lib/milk_tea/lsp/server/progress.rb +0 -2
  144. data/lib/milk_tea/lsp/server/references.rb +316 -318
  145. data/lib/milk_tea/lsp/server/rename.rb +445 -447
  146. data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
  147. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1376 -1314
  148. data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
  149. data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
  150. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
  151. data/lib/milk_tea/lsp/server/utilities.rb +397 -399
  152. data/lib/milk_tea/lsp/server.rb +0 -3
  153. data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
  154. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
  155. data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
  156. data/lib/milk_tea/packages/atomic_write.rb +4 -5
  157. data/lib/milk_tea/packages/dependency_solver.rb +15 -15
  158. data/lib/milk_tea/packages/lock.rb +4 -4
  159. data/lib/milk_tea/packages/manager_cli.rb +1 -1
  160. data/lib/milk_tea/packages/manifest.rb +3 -3
  161. data/lib/milk_tea/packages/registry_store.rb +4 -6
  162. data/lib/milk_tea/packages/services.rb +16 -16
  163. data/lib/milk_tea/packages/source_cache.rb +4 -6
  164. data/lib/milk_tea/packages/source_resolver.rb +44 -44
  165. data/lib/milk_tea/packages/version.rb +8 -8
  166. data/lib/milk_tea/tooling/build.rb +3 -7
  167. data/lib/milk_tea/tooling/build_cache.rb +0 -2
  168. data/lib/milk_tea/tooling/cli.rb +10 -4
  169. data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
  170. data/lib/milk_tea/tooling/debug_map.rb +8 -10
  171. data/lib/milk_tea/tooling/docs_app.rb +0 -2
  172. data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
  173. data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
  174. data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
  175. data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
  176. data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
  177. data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
  178. data/lib/milk_tea/tooling/linter/rules.rb +87 -89
  179. data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
  180. data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
  181. data/lib/milk_tea/tooling/linter/visitors.rb +112 -54
  182. data/lib/milk_tea/tooling/linter.rb +0 -2
  183. data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
  184. data/lib/milk_tea/tooling/run.rb +0 -2
  185. data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
  186. data/std/cli.mt +13 -32
  187. data/std/color.mt +28 -28
  188. data/std/encoding.mt +4 -4
  189. data/std/graph.mt +1 -2
  190. data/std/hash.mt +14 -14
  191. data/std/http/server.mt +3 -3
  192. data/std/input.mt +1 -1
  193. data/std/json.mt +1 -1
  194. data/std/linear_algebra.mt +6 -6
  195. data/std/net/mux.mt +1 -1
  196. data/std/noise.mt +23 -23
  197. data/std/parse.mt +2 -2
  198. data/std/process.mt +3 -4
  199. data/std/sparse_set.mt +1 -1
  200. data/std/steering.mt +5 -5
  201. data/std/str.mt +1 -1
  202. data/std/tween.mt +4 -4
  203. data/std/utility.mt +3 -3
  204. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61a19112e2810978ecf1ce56b1d1d1290a26bcb933b9e89857ffca77d1323392
4
- data.tar.gz: f68d1016a49c1cf195b5d24c430e4bbccde2c1ad9c7b82523b9e51d9f899d2b6
3
+ metadata.gz: efa0075ce73ffd0c92161f778399c599c6443e4375194a8bfeda883b3c29ea09
4
+ data.tar.gz: 978ab66cd06f4261edb72629f528c020890250ed7b57bbd75bee8cbe01e7e6a1
5
5
  SHA512:
6
- metadata.gz: d7ffd6ea3d812428f451bbf304662a36a05986eb7ff2ec9a207364be7f37f81d84379e40325a155fd9565885d648503c73ab34fb1e851adbb1d5e53b193d696c
7
- data.tar.gz: caa0c4acb4264740d58d857214ff68c3b726bf9a08d5f894ddc25466066e898567fd45c3b1c0e0634902be9a993acec7f1006b146af811ec0b918c778f60b234
6
+ metadata.gz: b0516d11fd07ed4c2db9bfaa4d59735821cfc3245aca280118f87593e7fa1fb2fec3be0c8208efc87b91c4cd79215e3a593602b43e1d9811572fcdcced93c280
7
+ data.tar.gz: 1a27eb0e66b9b15330ae28273b59ddfa430a6e7439811c2ca196b685cb6e8379b56016bb3a6eed60b347582fd013d8ba29f0c7024fbec0c13b67592aff3e0eba
data/README.md CHANGED
@@ -30,6 +30,7 @@ Package manifests, build workflow, and run workflow are documented separately in
30
30
  - External files are the dedicated raw ABI surface, usually for generated or low-level `std.c.*` bindings.
31
31
  - Module lookup resolves `a.b.c` to `a/b/c.mt`.
32
32
  - Inside a package, the file path relative to `package.source_root` defines the module name; platform-specific files such as `name.linux.mt` still map to module `name`.
33
+ - Circular module imports are supported via forward-declaration bindings and two-pass checking. Cycle members see each other's type declarations in the first pass and full type information in the second pass.
33
34
  - In ordinary files, `import` statements appear only at the top.
34
35
  - In external files, leading `import` statements are allowed after `external`.
35
36
  - Only external files accept `include`, `link`, and `compiler_flag` directives.
@@ -314,6 +315,7 @@ Rules:
314
315
  - Compile-time reflection over validated attributes uses `has_attribute`, `attribute_of`, `attribute_arg[T]`, `field_of`, and `callable_of`.
315
316
  - `field_of(...)`, `callable_of(...)`, and `attribute_of(...)` produce compile-time handle values with source-visible handle types `field_handle`, `callable_handle`, and `attribute_handle`.
316
317
  - The current C backend lowers `packed` / `align(...)` attributes with GNU-style `__attribute__((...))`, so these layout controls currently require a Clang/GCC-family compiler. On Windows that means Clang or GCC-family toolchains such as MinGW; `cl.exe` is not a supported backend for these attributes today. On wasm/browser targets the same feature works through Emscripten `emcc`, which is Clang-based.
318
+ - Keywords and reserved words are accepted as variant arm names, struct/union field names, enum/flags member names, lifetime parameters (`@return`), type parameters (`Box[return]`), and named constructor arguments (`Meta(return = 1)`). Primitive type names (`int`, `str`, `ref`, etc.) remain reserved and cannot be used in these positions.
317
319
 
318
320
  Enum and flags values support the full set of comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`) against values of the same enum type and against their backing integer type. Comparisons use the underlying integer backing values. Flags also support bitwise operators (`|`, `&`, `^`, `~`).
319
321
 
@@ -490,7 +490,7 @@ Milk Tea has first-class compiler support for multithreading. The threading mode
490
490
  parallel for i in 0..entity_count:
491
491
  positions[i] += velocities[i] * dt
492
492
 
493
- # Structured fork-join: each do block runs on a separate thread
493
+ # Structured fork-join: each statement runs on a separate thread
494
494
  parallel:
495
495
  textures = load_textures(path)
496
496
  sounds = load_sounds(path)
@@ -501,7 +501,6 @@ Design choices:
501
501
  - **Structured, not fire-and-forget.** All `parallel for` and `parallel:` blocks are synchronous barriers — the calling thread blocks until all work completes. This guarantees that captured local variables remain alive for the duration and eliminates lifetime concerns without ownership annotations.
502
502
  - **Compile-time safety.** `ref[T]` captures are rejected because mutable aliases across thread boundaries create data races. The `parallel:` block enforces single-writer-or-multiple-readers: if one statement writes a variable, no other block may read or write it.
503
503
  - **Value capture, pointer-based arrays.** Scalars and spans are captured by value (the span's data pointer still references the original storage). Arrays are captured as pointers to their first element, so writes in the worker affect the original array.
504
- - **`do` is a keyword.** It is recognized inside `parallel:` blocks to introduce each concurrent unit of work.
505
504
  - **Real OS threads via libuv.** Thread dispatch uses `uv_thread_create` / `uv_thread_join`, consistent with `std.thread` and `std.sync`. CPU count is detected at runtime via `uv_cpu_info`. The first chunk runs on the calling thread to avoid unnecessary dispatch when the workload is small.
506
505
  - **No forced dependency.** The build system automatically detects `parallel for` and `parallel:` usage via a sema-level flag and links libuv only when needed.
507
506
 
@@ -51,6 +51,7 @@ Rules:
51
51
  - Valid platform filename suffixes are `linux`, `windows`, and `wasm`.
52
52
  - The platform suffix is not part of the module name. `import a.b.c` stays the same on every target.
53
53
  - Milk Tea does not have a source-level conditional compilation syntax such as `#if`, `#ifdef`, or per-declaration platform attributes.
54
+ - Circular module imports are supported. When two modules import each other, the compiler uses forward-declaration bindings for the first pass and full type-checked bindings for the second pass, enabling cross-module type references and constructors in cycle groups.
54
55
 
55
56
  ## 2. Lexical Rules
56
57
 
@@ -360,6 +361,17 @@ Compile-time reflection over validated attributes uses `has_attribute`, `attribu
360
361
 
361
362
  The current C backend lowers `packed` / `align(...)` attributes with GNU-style `__attribute__((...))`, so these layout controls currently require a Clang/GCC-family compiler. On Windows that means Clang or GCC-family toolchains such as MinGW; `cl.exe` is not a supported backend for these attributes today. On wasm/browser targets the same feature works through Emscripten `emcc`, which is Clang-based.
362
363
 
364
+ Language-level keywords and reserved words are accepted as:
365
+ - variant arm names (`return(val: int)`, `if(arg: bool)`)
366
+ - struct and union field names (`return: int`, `let: str`)
367
+ - enum and flags member names (`return = 1`, `if = 6`)
368
+ - variant arm payload field names (`execute(return: int)`)
369
+ - lifetime parameter names (`struct Buf[@return]`)
370
+ - type parameter names (`struct Box[return]`, `identity[type]`)
371
+ - named arguments in struct/variant literals (`Meta(return = 1)`)
372
+
373
+ Primitive type names (`int`, `str`, `bool`, `ref`, `ptr`, `span`, `type`, etc.) remain reserved and cannot be used as names.
374
+
363
375
  ### 3.4a Enum and flags operators
364
376
 
365
377
  Enum and flags values support the full set of comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`) against values of the same enum type and against their backing integer type. Comparisons use the underlying integer backing values.
@@ -746,7 +758,6 @@ parallel:
746
758
  Rules:
747
759
 
748
760
  - A `parallel:` block must contain at least two statements.
749
- - `do` is a contextual keyword — only recognized inside `parallel:` blocks, not reserved globally.
750
761
  - Each statement must not contain `break`, `continue`, `return`, or `defer`.
751
762
  - The compiler enforces single-writer-or-multiple-readers: if a variable is written in one statement, no other block may access it.
752
763
  - Captured `ref[T]` values are rejected at compile time.
data/lib/milk_tea/base.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "pathname"
4
4
 
5
5
  module MilkTea
6
- VERSION = "0.3.9"
6
+ VERSION = "0.3.11"
7
7
 
8
8
  def self.root
9
9
  @root ||= Pathname.new(File.expand_path("../..", __dir__))
@@ -23,7 +23,6 @@ module MilkTea
23
23
  def self.installed_as_gem?
24
24
  root.to_s.match?(%r{/gems/mt-lang-})
25
25
  end
26
- private_class_method :installed_as_gem?
27
26
 
28
27
  def self.writable_root_for(root)
29
28
  resolved = Pathname.new(File.expand_path(root.to_s))
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module Bindgen
5
5
  class Generator
6
6
  module GeneratorAstParser
7
- private
8
-
9
7
  def dump_ast
10
8
  Tempfile.create(["milk-tea-bindgen", ".c"]) do |translation_unit|
11
9
  @translation_unit_path = translation_unit.path
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module Bindgen
5
5
  class Generator
6
6
  module GeneratorDeclaration
7
- private
8
-
9
7
  def select_record_declarations(nodes)
10
8
  selected = {}
11
9
  type_aliases = []
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module Bindgen
5
5
  class Generator
6
6
  module GeneratorEmitter
7
- private
8
-
9
7
  def emitted_name(raw_name)
10
8
  return raw_name unless @strip_leading_underscores
11
9
 
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module Bindgen
5
5
  class Generator
6
6
  module GeneratorOverrides
7
- private
8
-
9
7
  def function_param_type_override(function_name, param_name)
10
8
  @function_param_type_overrides.dig(function_name, param_name)
11
9
  end
@@ -4,64 +4,62 @@ module MilkTea
4
4
  module Bindgen
5
5
  class Generator
6
6
  module GeneratorTypeMapper
7
- private
8
-
9
7
  def map_c_type(qual_type, context:)
10
8
  normalized = normalize_c_type(qual_type)
11
9
  raise BindgenError, "missing C type for #{context}" if normalized.empty?
12
10
  normalized, nullability = extract_top_level_nullability(normalized)
13
11
  mapped_type = if array_type?(normalized)
14
- map_array_type(normalized, context:)
15
- elsif function_pointer_type?(normalized)
16
- map_function_pointer_type(normalized, context:)
17
- else
18
- pointer_candidate = strip_pointer_suffix_qualifiers(normalized)
19
- if pointer_type?(pointer_candidate)
20
- if va_list_pointer?(pointer_candidate)
21
- synthesize_typedef_dependency("va_list")
22
- "va_list"
23
- elsif c_string_pointer?(pointer_candidate)
24
- "cstr"
25
- else
26
- pointee = pointer_candidate.sub(/\s*\*\z/, "")
27
- pointer_name = top_level_const_qualified?(pointee) ? "const_ptr" : "ptr"
28
- "#{pointer_name}[#{map_c_type(pointee, context:)}]"
29
- end
30
- else
31
- unqualified = strip_qualifiers(normalized)
32
- if unqualified == "__va_list_tag" || unqualified == "struct __va_list_tag"
33
- synthesize_typedef_dependency("__va_list_tag")
34
- "__va_list_tag"
35
- elsif standard_typedef_primitive(unqualified)
36
- standard_typedef_primitive(unqualified)
37
- elsif PRIMITIVE_TYPE_MAP.key?(unqualified)
38
- PRIMITIVE_TYPE_MAP.fetch(unqualified)
39
- elsif @type_overrides.key?(unqualified)
40
- @type_overrides.fetch(unqualified)
41
- elsif unqualified.start_with?("long") || unqualified.start_with?("unsigned long") || unqualified.start_with?("signed long")
42
- map_long_type(unqualified, context:)
43
- elsif unqualified.start_with?("struct ") || unqualified.start_with?("union ") || unqualified.start_with?("enum ")
44
- tag_name = unqualified.split.last
45
- @type_overrides.fetch(tag_name) do
46
- if unqualified.start_with?("struct ")
47
- record_name_for(unqualified)
48
- elsif unqualified.start_with?("union ")
49
- record_name_for(unqualified)
50
- else
51
- enum_name_for(unqualified)
52
- end
53
- end
54
- elsif unqualified.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/)
55
- if known_generated_type_name?(unqualified, @visible_typedef_names)
56
- visible_type_name(unqualified)
57
- else
58
- raise BindgenError, "unknown referenced C type #{unqualified.inspect} for #{context}"
59
- end
60
- else
61
- raise BindgenError, "unsupported C type #{qual_type.inspect} for #{context}"
62
- end
63
- end
64
- end
12
+ map_array_type(normalized, context:)
13
+ elsif function_pointer_type?(normalized)
14
+ map_function_pointer_type(normalized, context:)
15
+ else
16
+ pointer_candidate = strip_pointer_suffix_qualifiers(normalized)
17
+ if pointer_type?(pointer_candidate)
18
+ if va_list_pointer?(pointer_candidate)
19
+ synthesize_typedef_dependency("va_list")
20
+ "va_list"
21
+ elsif c_string_pointer?(pointer_candidate)
22
+ "cstr"
23
+ else
24
+ pointee = pointer_candidate.sub(/\s*\*\z/, "")
25
+ pointer_name = top_level_const_qualified?(pointee) ? "const_ptr" : "ptr"
26
+ "#{pointer_name}[#{map_c_type(pointee, context:)}]"
27
+ end
28
+ else
29
+ unqualified = strip_qualifiers(normalized)
30
+ if unqualified == "__va_list_tag" || unqualified == "struct __va_list_tag"
31
+ synthesize_typedef_dependency("__va_list_tag")
32
+ "__va_list_tag"
33
+ elsif standard_typedef_primitive(unqualified)
34
+ standard_typedef_primitive(unqualified)
35
+ elsif PRIMITIVE_TYPE_MAP.key?(unqualified)
36
+ PRIMITIVE_TYPE_MAP.fetch(unqualified)
37
+ elsif @type_overrides.key?(unqualified)
38
+ @type_overrides.fetch(unqualified)
39
+ elsif unqualified.start_with?("long") || unqualified.start_with?("unsigned long") || unqualified.start_with?("signed long")
40
+ map_long_type(unqualified, context:)
41
+ elsif unqualified.start_with?("struct ") || unqualified.start_with?("union ") || unqualified.start_with?("enum ")
42
+ tag_name = unqualified.split.last
43
+ @type_overrides.fetch(tag_name) do
44
+ if unqualified.start_with?("struct ")
45
+ record_name_for(unqualified)
46
+ elsif unqualified.start_with?("union ")
47
+ record_name_for(unqualified)
48
+ else
49
+ enum_name_for(unqualified)
50
+ end
51
+ end
52
+ elsif unqualified.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/)
53
+ if known_generated_type_name?(unqualified, @visible_typedef_names)
54
+ visible_type_name(unqualified)
55
+ else
56
+ raise BindgenError, "unknown referenced C type #{unqualified.inspect} for #{context}"
57
+ end
58
+ else
59
+ raise BindgenError, "unsupported C type #{qual_type.inspect} for #{context}"
60
+ end
61
+ end
62
+ end
65
63
 
66
64
  apply_nullability(mapped_type, nullability)
67
65
  end
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module ImportedBindings
5
5
  class Generator
6
6
  module GeneratorPolicy
7
- private
8
-
9
7
  def load_policy
10
8
  JSON.parse(File.read(@policy_path))
11
9
  rescue Errno::ENOENT
@@ -914,13 +912,13 @@ module MilkTea
914
912
  signature = +""
915
913
  signature << "public " if visibility == :public
916
914
  signature << case kind
917
- when :static
918
- "static function "
919
- when :editable
920
- "editable function "
921
- else
922
- "function "
923
- end
915
+ when :static
916
+ "static function "
917
+ when :editable
918
+ "editable function "
919
+ else
920
+ "function "
921
+ end
924
922
  signature << name
925
923
  signature << render_type_params(type_params)
926
924
  signature << "(#{params.join(', ')}) -> #{return_type}:"
@@ -4,8 +4,6 @@ module MilkTea
4
4
  module ImportedBindings
5
5
  class Generator
6
6
  module GeneratorMethodSource
7
- private
8
-
9
7
  def load_method_sources(method_specs)
10
8
  method_specs.each_with_object({}) do |spec, sources|
11
9
  next unless spec[:module_name]
@@ -85,8 +85,6 @@ module MilkTea
85
85
  uniform
86
86
  ].freeze
87
87
 
88
- private
89
-
90
88
  def normalize_opengl_snake_case(name)
91
89
  tokens = name.to_s.split("_").reject(&:empty?)
92
90
  normalized = []
@@ -175,12 +173,12 @@ module MilkTea
175
173
 
176
174
  def normalize_opengl_terminal_suffix(name, raw_name)
177
175
  normalized = if name.end_with?("indexedfv")
178
- "#{name.delete_suffix('indexedfv')}indexed_float_values"
179
- elsif name.end_with?("indexedf")
180
- "#{name.delete_suffix('indexedf')}indexed_float"
181
- else
182
- name
183
- end
176
+ "#{name.delete_suffix('indexedfv')}indexed_float_values"
177
+ elsif name.end_with?("indexedf")
178
+ "#{name.delete_suffix('indexedf')}indexed_float"
179
+ else
180
+ name
181
+ end
184
182
 
185
183
  raw_text = raw_name.to_s
186
184
  if raw_text.end_with?("i") && normalized.end_with?("i")
@@ -205,8 +205,6 @@ module MilkTea
205
205
  Formatter.format_source(source, path: generated_module_path, mode: :tidy)
206
206
  end
207
207
 
208
- private
209
-
210
208
  include GeneratorPolicy
211
209
  include GeneratorMethodSource
212
210
  include GeneratorNaming
@@ -23,18 +23,16 @@ module MilkTea
23
23
  FeatureEntry = Data.define(:name, :api, :number, :blocks)
24
24
  ExtensionEntry = Data.define(:name, :supported, :blocks)
25
25
 
26
- module_function
27
-
28
- def helper_header_path(root: MilkTea.root)
26
+ def self.helper_header_path(root: MilkTea.root)
29
27
  root.join("std/c/#{HELPER_HEADER_BASENAME}")
30
28
  end
31
29
 
32
- def source(root: MilkTea.root)
30
+ def self.source(root: MilkTea.root)
33
31
  UpstreamSources.default_sources(root:).find { |entry| entry.name == SOURCE_NAME } ||
34
32
  raise(Error, "missing upstream source definition for #{SOURCE_NAME}")
35
33
  end
36
34
 
37
- def prepare!(root: MilkTea.root, api: DEFAULT_API, version: DEFAULT_VERSION, profile: DEFAULT_PROFILE, extensions: [])
35
+ def self.prepare!(root: MilkTea.root, api: DEFAULT_API, version: DEFAULT_VERSION, profile: DEFAULT_PROFILE, extensions: [])
38
36
  registry_source = source(root:)
39
37
  registry_source.bootstrap!
40
38
 
@@ -90,8 +88,6 @@ module MilkTea
90
88
  )
91
89
  end
92
90
 
93
- private
94
-
95
91
  def parse_registry
96
92
  document = REXML::Document.new(@xml_source)
97
93
  root = document.root
@@ -38,26 +38,24 @@ module MilkTea
38
38
  windows: "steam_api64.dll",
39
39
  }.freeze
40
40
 
41
- module_function
42
-
43
- def helper_header_path(root: MilkTea.root)
41
+ def self.helper_header_path(root: MilkTea.root)
44
42
  root.join("std/c/#{HELPER_HEADER_BASENAME}")
45
43
  end
46
44
 
47
- def source(root: MilkTea.root)
45
+ def self.source(root: MilkTea.root)
48
46
  UpstreamSources.default_sources(root:).find { |entry| entry.name == SOURCE_NAME } ||
49
47
  raise(Error, "missing upstream source definition for #{SOURCE_NAME}")
50
48
  end
51
49
 
52
- def host_platform
50
+ def self.host_platform
53
51
  MilkTea.host_platform
54
52
  end
55
53
 
56
- def default_link_libraries(platform: host_platform)
54
+ def self.default_link_libraries(platform: host_platform)
57
55
  [LINK_LIBRARY_NAME_BY_PLATFORM.fetch(platform)]
58
56
  end
59
57
 
60
- def sdk_root(root: MilkTea.root, env: ENV, bootstrap: false)
58
+ def self.sdk_root(root: MilkTea.root, env: ENV, bootstrap: false)
61
59
  candidates = []
62
60
  env_root = env[SDK_ROOT_ENV_VAR]
63
61
  candidates << canonical_sdk_root(env_root) if env_root && !env_root.empty?
@@ -76,7 +74,7 @@ module MilkTea
76
74
  candidates.find { |path| sdk_layout_present?(path) }
77
75
  end
78
76
 
79
- def api_json_path(root: MilkTea.root, env: ENV, bootstrap: false)
77
+ def self.api_json_path(root: MilkTea.root, env: ENV, bootstrap: false)
80
78
  explicit_path = env[API_JSON_ENV_VAR]
81
79
  if explicit_path && !explicit_path.empty?
82
80
  candidate = Pathname.new(File.expand_path(explicit_path))
@@ -94,7 +92,7 @@ module MilkTea
94
92
  raise Error, "Steamworks metadata not found under #{resolved_sdk_root}"
95
93
  end
96
94
 
97
- def redistributable_directory(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
95
+ def self.redistributable_directory(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
98
96
  resolved_sdk_root = sdk_root(root:, env:, bootstrap:)
99
97
  return unless resolved_sdk_root
100
98
 
@@ -104,7 +102,7 @@ module MilkTea
104
102
  nil
105
103
  end
106
104
 
107
- def import_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
105
+ def self.import_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
108
106
  directory = redistributable_directory(root:, env:, platform:, bootstrap:)
109
107
  return unless directory
110
108
 
@@ -114,7 +112,7 @@ module MilkTea
114
112
  nil
115
113
  end
116
114
 
117
- def runtime_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
115
+ def self.runtime_library_path(root: MilkTea.root, env: ENV, platform: host_platform, bootstrap: false)
118
116
  directory = redistributable_directory(root:, env:, platform:, bootstrap:)
119
117
  return unless directory
120
118
 
@@ -124,7 +122,7 @@ module MilkTea
124
122
  nil
125
123
  end
126
124
 
127
- def prepare!(root: MilkTea.root, env: ENV)
125
+ def self.prepare!(root: MilkTea.root, env: ENV)
128
126
  path = helper_header_path(root:)
129
127
  existing = File.exist?(path)
130
128
  json_path = api_json_path(root:, env:, bootstrap: !existing)
@@ -139,7 +137,7 @@ module MilkTea
139
137
  path.to_s
140
138
  end
141
139
 
142
- def canonical_sdk_root(path)
140
+ def self.canonical_sdk_root(path)
143
141
  root = Pathname.new(File.expand_path(path.to_s))
144
142
  sdk_child = root.join("sdk")
145
143
  return sdk_child if sdk_layout_present?(sdk_child)
@@ -148,7 +146,7 @@ module MilkTea
148
146
  end
149
147
  private_class_method :canonical_sdk_root
150
148
 
151
- def sdk_layout_present?(root)
149
+ def self.sdk_layout_present?(root)
152
150
  File.file?(root.join(API_JSON_RELATIVE_PATH))
153
151
  end
154
152
  private_class_method :sdk_layout_present?
@@ -280,8 +278,6 @@ module MilkTea
280
278
  lines.join("\n") + "\n"
281
279
  end
282
280
 
283
- private
284
-
285
281
  def metadata
286
282
  @metadata ||= JSON.parse(@json_source)
287
283
  rescue JSON::ParserError => e
@@ -38,8 +38,6 @@ module MilkTea
38
38
  end
39
39
  end
40
40
 
41
- private
42
-
43
41
  def run_git!(*args)
44
42
  stdout, stderr, status = Open3.capture3("git", *args)
45
43
  return if status.success?
@@ -51,13 +49,11 @@ module MilkTea
51
49
  end
52
50
  end
53
51
 
54
- module_function
55
-
56
- def revisions_path(root: MilkTea.root)
52
+ def self.revisions_path(root: MilkTea.root)
57
53
  Pathname.new(File.expand_path(root.to_s)).join(CONFIG_DIR, REVISIONS_FILE)
58
54
  end
59
55
 
60
- def load_version_overrides(root: MilkTea.root)
56
+ def self.load_version_overrides(root: MilkTea.root)
61
57
  path = revisions_path(root:)
62
58
  return {} unless File.file?(path)
63
59
 
@@ -78,7 +74,7 @@ module MilkTea
78
74
  overrides
79
75
  end
80
76
 
81
- def load_sentinel_overrides(root: MilkTea.root)
77
+ def self.load_sentinel_overrides(root: MilkTea.root)
82
78
  path = revisions_path(root:)
83
79
  return {} unless File.file?(path)
84
80
 
@@ -95,7 +91,7 @@ module MilkTea
95
91
  overrides
96
92
  end
97
93
 
98
- def write_version_override(name, revision, root: MilkTea.root)
94
+ def self.write_version_override(name, revision, root: MilkTea.root)
99
95
  path = revisions_path(root:)
100
96
  data = File.file?(path) ? (YAML.safe_load(File.read(path)) || {}) : {}
101
97
  existing = data[name.to_s]
@@ -108,7 +104,7 @@ module MilkTea
108
104
  File.write(path, data.to_yaml)
109
105
  end
110
106
 
111
- def remove_version_override(name, root: MilkTea.root)
107
+ def self.remove_version_override(name, root: MilkTea.root)
112
108
  path = revisions_path(root:)
113
109
  return unless File.file?(path)
114
110
 
@@ -121,7 +117,7 @@ module MilkTea
121
117
  end
122
118
  end
123
119
 
124
- def resolve_ref(repository_url, ref)
120
+ def self.resolve_ref(repository_url, ref)
125
121
  return ref if ref.match?(/\A[0-9a-f]{40}\z/i)
126
122
 
127
123
  output, status = Open3.capture2("git", "ls-remote", "--refs", repository_url, ref.to_s)
@@ -140,11 +136,11 @@ module MilkTea
140
136
  lines.first.split(/\s+/, 2).first
141
137
  end
142
138
 
143
- def find_source(name, root: MilkTea.root)
139
+ def self.find_source(name, root: MilkTea.root)
144
140
  default_sources(root:).find { |source| source.name == name.to_s }
145
141
  end
146
142
 
147
- def default_sources(root: MilkTea.root)
143
+ def self.default_sources(root: MilkTea.root)
148
144
  data = MilkTea.writable_root_for(root)
149
145
  sources = [
150
146
  Source.new(
@@ -338,11 +334,11 @@ module MilkTea
338
334
  sources
339
335
  end
340
336
 
341
- def bootstrap_all!(root: MilkTea.root)
337
+ def self.bootstrap_all!(root: MilkTea.root)
342
338
  default_sources(root:).map(&:bootstrap!)
343
339
  end
344
340
 
345
- def bootstrap_one(name, root: MilkTea.root)
341
+ def self.bootstrap_one(name, root: MilkTea.root)
346
342
  source = find_source(name, root:)
347
343
  raise Error, "unknown upstream source: #{name}" unless source
348
344
 
@@ -22,9 +22,7 @@ module MilkTea
22
22
  -lm
23
23
  ].freeze
24
24
 
25
- module_function
26
-
27
- def library(root: MilkTea.root)
25
+ def self.library(root: MilkTea.root)
28
26
  resolved_root = Pathname.new(File.expand_path(root.to_s))
29
27
  @libraries ||= {}
30
28
  @libraries[resolved_root.to_s] ||= VendoredCLibrary::CMake.new(
@@ -40,39 +38,39 @@ module MilkTea
40
38
  )
41
39
  end
42
40
 
43
- def source_root(root: MilkTea.root)
41
+ def self.source_root(root: MilkTea.root)
44
42
  MilkTea.writable_root_for(root).join("third_party/box2d-upstream")
45
43
  end
46
44
 
47
- def include_root(root: MilkTea.root)
45
+ def self.include_root(root: MilkTea.root)
48
46
  source_root(root:).join("include")
49
47
  end
50
48
 
51
- def header_root(root: MilkTea.root)
49
+ def self.header_root(root: MilkTea.root)
52
50
  include_root(root:).join("box2d")
53
51
  end
54
52
 
55
- def build_root(root: MilkTea.root)
53
+ def self.build_root(root: MilkTea.root)
56
54
  MilkTea.writable_root_for(root).join("tmp/vendored-box2d")
57
55
  end
58
56
 
59
- def install_root(root: MilkTea.root)
57
+ def self.install_root(root: MilkTea.root)
60
58
  MilkTea.writable_root_for(root).join("tmp/vendored-box2d-prefix")
61
59
  end
62
60
 
63
- def archive_path(root: MilkTea.root)
61
+ def self.archive_path(root: MilkTea.root)
64
62
  install_root(root:).join("lib/libbox2d.a")
65
63
  end
66
64
 
67
- def include_flags(root: MilkTea.root)
65
+ def self.include_flags(root: MilkTea.root)
68
66
  library(root:).include_flags
69
67
  end
70
68
 
71
- def link_flags(root: MilkTea.root)
69
+ def self.link_flags(root: MilkTea.root)
72
70
  library(root:).link_flags
73
71
  end
74
72
 
75
- def prepare!(root: MilkTea.root, **kwargs)
73
+ def self.prepare!(root: MilkTea.root, **kwargs)
76
74
  library(root:).prepare!(**kwargs)
77
75
  end
78
76
  end
@@ -12,9 +12,7 @@ module MilkTea
12
12
  -lm
13
13
  ].freeze
14
14
 
15
- module_function
16
-
17
- def library(root: MilkTea.root)
15
+ def self.library(root: MilkTea.root)
18
16
  resolved_root = Pathname.new(File.expand_path(root.to_s))
19
17
  @libraries ||= {}
20
18
  @libraries[resolved_root.to_s] ||= VendoredCLibrary::Archive.new(
@@ -29,23 +27,23 @@ module MilkTea
29
27
  )
30
28
  end
31
29
 
32
- def source_root(root: MilkTea.root)
30
+ def self.source_root(root: MilkTea.root)
33
31
  MilkTea.writable_root_for(root).join("third_party/cjson-upstream")
34
32
  end
35
33
 
36
- def build_root(root: MilkTea.root)
34
+ def self.build_root(root: MilkTea.root)
37
35
  MilkTea.writable_root_for(root).join("tmp/vendored-cjson")
38
36
  end
39
37
 
40
- def archive_path(root: MilkTea.root)
38
+ def self.archive_path(root: MilkTea.root)
41
39
  build_root(root:).join("libcjson.a")
42
40
  end
43
41
 
44
- def link_flags(root: MilkTea.root)
42
+ def self.link_flags(root: MilkTea.root)
45
43
  library(root:).link_flags
46
44
  end
47
45
 
48
- def prepare!(root: MilkTea.root, **kwargs)
46
+ def self.prepare!(root: MilkTea.root, **kwargs)
49
47
  library(root:).prepare!(**kwargs)
50
48
  end
51
49
  end