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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/docs/language-design.md +1 -2
- data/docs/language-manual.md +12 -1
- data/lib/milk_tea/base.rb +1 -2
- data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
- data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
- data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
- data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
- data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
- data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
- data/lib/milk_tea/bindings/steamworks.rb +12 -16
- data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
- data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
- data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
- data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
- data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
- data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
- data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
- data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
- data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
- data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
- data/lib/milk_tea/core/ast.rb +109 -51
- data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
- data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
- data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
- data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
- data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
- data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
- data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
- data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
- data/lib/milk_tea/core/c_backend/statements.rb +528 -530
- data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
- data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
- data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
- data/lib/milk_tea/core/c_backend.rb +17 -9
- data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
- data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
- data/lib/milk_tea/core/compile_time.rb +32 -38
- data/lib/milk_tea/core/control_flow/builder.rb +3 -5
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
- data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
- data/lib/milk_tea/core/ir.rb +10 -10
- data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
- data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
- data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
- data/lib/milk_tea/core/lexer/indentation.rb +0 -2
- data/lib/milk_tea/core/lexer/numbers.rb +0 -2
- data/lib/milk_tea/core/lexer/recovery.rb +0 -2
- data/lib/milk_tea/core/lexer/strings.rb +0 -2
- data/lib/milk_tea/core/lexer/symbols.rb +0 -2
- data/lib/milk_tea/core/lexer/trivia.rb +0 -2
- data/lib/milk_tea/core/lexer.rb +0 -2
- data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
- data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
- data/lib/milk_tea/core/lowering/async/normalization.rb +5 -3
- data/lib/milk_tea/core/lowering/async.rb +627 -630
- data/lib/milk_tea/core/lowering/block.rb +413 -416
- data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
- data/lib/milk_tea/core/lowering/declarations.rb +180 -183
- data/lib/milk_tea/core/lowering/dyn.rb +48 -50
- data/lib/milk_tea/core/lowering/events.rb +983 -985
- data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
- data/lib/milk_tea/core/lowering/functions.rb +185 -188
- data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
- data/lib/milk_tea/core/lowering/proc.rb +363 -366
- data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
- data/lib/milk_tea/core/lowering/scans.rb +179 -181
- data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
- data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
- data/lib/milk_tea/core/lowering.rb +5 -7
- data/lib/milk_tea/core/module_binder.rb +0 -2
- data/lib/milk_tea/core/module_loader/errors.rb +4 -2
- data/lib/milk_tea/core/module_loader.rb +113 -20
- data/lib/milk_tea/core/module_path_resolver.rb +0 -2
- data/lib/milk_tea/core/module_roots.rb +6 -8
- data/lib/milk_tea/core/parser/attributes.rb +0 -2
- data/lib/milk_tea/core/parser/blocks.rb +0 -2
- data/lib/milk_tea/core/parser/declarations.rb +7 -9
- data/lib/milk_tea/core/parser/expressions.rb +15 -10
- data/lib/milk_tea/core/parser/recovery.rb +0 -2
- data/lib/milk_tea/core/parser/statements.rb +8 -2
- data/lib/milk_tea/core/parser/types.rb +12 -14
- data/lib/milk_tea/core/parser.rb +0 -2
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
- data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +14 -17
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
- data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +106 -109
- data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
- data/lib/milk_tea/core/types/layout.rb +21 -22
- data/lib/milk_tea/core/types/predicates.rb +0 -2
- data/lib/milk_tea/core/types/registry.rb +16 -18
- data/lib/milk_tea/core/types/visitor.rb +0 -4
- data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
- data/lib/milk_tea/dap/protocol.rb +1 -1
- data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
- data/lib/milk_tea/dap/server/debug_map.rb +0 -2
- data/lib/milk_tea/dap/server/handlers.rb +0 -2
- data/lib/milk_tea/dap/server/launch.rb +0 -2
- data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
- data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
- data/lib/milk_tea/dap/server/utilities.rb +0 -2
- data/lib/milk_tea/dap/server/wire.rb +0 -2
- data/lib/milk_tea/dap/server.rb +0 -2
- data/lib/milk_tea/lsp/diagnostics.rb +16 -16
- data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
- data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
- data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
- data/lib/milk_tea/lsp/server/completion.rb +873 -875
- data/lib/milk_tea/lsp/server/configuration.rb +129 -131
- data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
- data/lib/milk_tea/lsp/server/definition.rb +564 -565
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
- data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
- data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
- data/lib/milk_tea/lsp/server/formatting.rb +478 -480
- data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
- data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
- data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
- data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
- data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
- data/lib/milk_tea/lsp/server/progress.rb +0 -2
- data/lib/milk_tea/lsp/server/references.rb +316 -318
- data/lib/milk_tea/lsp/server/rename.rb +445 -447
- data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +1376 -1314
- data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
- data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
- data/lib/milk_tea/lsp/server/utilities.rb +397 -399
- data/lib/milk_tea/lsp/server.rb +0 -3
- data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
- data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
- data/lib/milk_tea/packages/atomic_write.rb +4 -5
- data/lib/milk_tea/packages/dependency_solver.rb +15 -15
- data/lib/milk_tea/packages/lock.rb +4 -4
- data/lib/milk_tea/packages/manager_cli.rb +1 -1
- data/lib/milk_tea/packages/manifest.rb +3 -3
- data/lib/milk_tea/packages/registry_store.rb +4 -6
- data/lib/milk_tea/packages/services.rb +16 -16
- data/lib/milk_tea/packages/source_cache.rb +4 -6
- data/lib/milk_tea/packages/source_resolver.rb +44 -44
- data/lib/milk_tea/packages/version.rb +8 -8
- data/lib/milk_tea/tooling/build.rb +3 -7
- data/lib/milk_tea/tooling/build_cache.rb +0 -2
- data/lib/milk_tea/tooling/cli.rb +10 -4
- data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
- data/lib/milk_tea/tooling/debug_map.rb +8 -10
- data/lib/milk_tea/tooling/docs_app.rb +0 -2
- data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
- data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
- data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
- data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
- data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
- data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
- data/lib/milk_tea/tooling/linter/rules.rb +87 -89
- data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
- data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
- data/lib/milk_tea/tooling/linter/visitors.rb +112 -54
- data/lib/milk_tea/tooling/linter.rb +0 -2
- data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
- data/lib/milk_tea/tooling/run.rb +0 -2
- data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
- data/std/cli.mt +13 -32
- data/std/color.mt +28 -28
- data/std/encoding.mt +4 -4
- data/std/graph.mt +1 -2
- data/std/hash.mt +14 -14
- data/std/http/server.mt +3 -3
- data/std/input.mt +1 -1
- data/std/json.mt +1 -1
- data/std/linear_algebra.mt +6 -6
- data/std/net/mux.mt +1 -1
- data/std/noise.mt +23 -23
- data/std/parse.mt +2 -2
- data/std/process.mt +3 -4
- data/std/sparse_set.mt +1 -1
- data/std/steering.mt +5 -5
- data/std/str.mt +1 -1
- data/std/tween.mt +4 -4
- data/std/utility.mt +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: efa0075ce73ffd0c92161f778399c599c6443e4375194a8bfeda883b3c29ea09
|
|
4
|
+
data.tar.gz: 978ab66cd06f4261edb72629f528c020890250ed7b57bbd75bee8cbe01e7e6a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
data/docs/language-design.md
CHANGED
|
@@ -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
|
|
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
|
|
data/docs/language-manual.md
CHANGED
|
@@ -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.
|
|
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,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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
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}:"
|
|
@@ -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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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")
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|