konpeito 0.2.4 → 0.3.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +645 -0
- data/CHANGELOG.md +37 -0
- data/Justfile +107 -0
- data/README.md +143 -43
- data/konpeito.gemspec +3 -2
- data/lib/konpeito/cli/build_command.rb +21 -3
- data/lib/konpeito/cli/completion_command.rb +298 -0
- data/lib/konpeito/cli/deps_command.rb +129 -21
- data/lib/konpeito/cli/fmt_command.rb +24 -132
- data/lib/konpeito/cli/run_command.rb +29 -3
- data/lib/konpeito/cli.rb +45 -14
- data/lib/konpeito/codegen/builtin_methods.rb +16 -0
- data/lib/konpeito/codegen/cruby_backend.rb +76 -6
- data/lib/konpeito/codegen/jvm_generator.rb +100 -9
- data/lib/konpeito/codegen/llvm_generator.rb +907 -195
- data/lib/konpeito/dependency_resolver.rb +32 -9
- data/lib/konpeito/hir/builder.rb +369 -57
- data/lib/konpeito/hir/nodes.rb +25 -5
- data/lib/konpeito/type_checker/rbs_loader.rb +3 -2
- data/lib/konpeito/ui/app.rb +1 -1
- data/lib/konpeito/version.rb +1 -1
- data/lib/konpeito.rb +0 -7
- data/tools/konpeito-asm/src/konpeito/runtime/RubyDispatch.java +32 -0
- metadata +6 -23
- data/lib/konpeito/cli/lsp_command.rb +0 -40
- data/lib/konpeito/formatter/formatter.rb +0 -1214
- data/lib/konpeito/lsp/document_manager.rb +0 -820
- data/lib/konpeito/lsp/server.rb +0 -183
- data/lib/konpeito/lsp/transport.rb +0 -38
- data/test_native_array.rb +0 -172
- data/test_native_array_class.rb +0 -197
- data/test_native_class.rb +0 -151
data/Justfile
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Konpeito — Ruby AOT Native Compiler
|
|
2
|
+
# Task runner recipes (https://github.com/casey/just)
|
|
3
|
+
|
|
4
|
+
# Default recipe: show available recipes
|
|
5
|
+
default:
|
|
6
|
+
@just --list
|
|
7
|
+
|
|
8
|
+
# --- Development ---
|
|
9
|
+
|
|
10
|
+
# Install dependencies
|
|
11
|
+
setup:
|
|
12
|
+
bundle install
|
|
13
|
+
|
|
14
|
+
# Clean build artifacts and caches
|
|
15
|
+
clean:
|
|
16
|
+
rm -rf .konpeito_cache/
|
|
17
|
+
find . -name "*.bundle" -not -path "./vendor/*" -delete
|
|
18
|
+
find . -name "*.so" -not -path "./vendor/*" -delete
|
|
19
|
+
find . -name "*.jar" -not -path "./vendor/*" -delete
|
|
20
|
+
find . -name "*.class" -not -path "./vendor/*" -delete
|
|
21
|
+
find . -name "*.o" -not -path "./vendor/*" -delete
|
|
22
|
+
find . -name "*.ll" -not -path "./vendor/*" -delete
|
|
23
|
+
find . -name "*.bc" -not -path "./vendor/*" -delete
|
|
24
|
+
|
|
25
|
+
# Check environment (LLVM, Java, etc.)
|
|
26
|
+
doctor:
|
|
27
|
+
bundle exec ruby -Ilib bin/konpeito doctor
|
|
28
|
+
|
|
29
|
+
# --- Testing ---
|
|
30
|
+
|
|
31
|
+
# Run all unit tests
|
|
32
|
+
test:
|
|
33
|
+
bundle exec rake test
|
|
34
|
+
|
|
35
|
+
# Run a specific test file
|
|
36
|
+
test-file path:
|
|
37
|
+
bundle exec ruby -Ilib:test {{path}}
|
|
38
|
+
|
|
39
|
+
# Run conformance tests (all backends)
|
|
40
|
+
conformance:
|
|
41
|
+
bundle exec rake conformance
|
|
42
|
+
|
|
43
|
+
# Run conformance tests (native only)
|
|
44
|
+
conformance-native:
|
|
45
|
+
bundle exec rake conformance:native
|
|
46
|
+
|
|
47
|
+
# Run conformance tests (JVM only)
|
|
48
|
+
conformance-jvm:
|
|
49
|
+
bundle exec rake conformance:jvm
|
|
50
|
+
|
|
51
|
+
# --- Linting & Formatting ---
|
|
52
|
+
|
|
53
|
+
# Run RuboCop linter
|
|
54
|
+
lint:
|
|
55
|
+
bundle exec rubocop
|
|
56
|
+
|
|
57
|
+
# Run RuboCop with auto-fix
|
|
58
|
+
lint-fix:
|
|
59
|
+
bundle exec rubocop -A
|
|
60
|
+
|
|
61
|
+
# Format source files (via RuboCop)
|
|
62
|
+
fmt *args:
|
|
63
|
+
bundle exec ruby -Ilib bin/konpeito fmt {{args}}
|
|
64
|
+
|
|
65
|
+
# Check formatting (via RuboCop)
|
|
66
|
+
fmt-check:
|
|
67
|
+
bundle exec ruby -Ilib bin/konpeito fmt --check
|
|
68
|
+
|
|
69
|
+
# --- Build & Run ---
|
|
70
|
+
|
|
71
|
+
# Compile a Ruby file to CRuby extension
|
|
72
|
+
build *args:
|
|
73
|
+
bundle exec ruby -Ilib bin/konpeito build {{args}}
|
|
74
|
+
|
|
75
|
+
# Compile and run a Ruby file
|
|
76
|
+
run *args:
|
|
77
|
+
bundle exec ruby -Ilib bin/konpeito run {{args}}
|
|
78
|
+
|
|
79
|
+
# Type-check a Ruby file
|
|
80
|
+
check *args:
|
|
81
|
+
bundle exec ruby -Ilib bin/konpeito check {{args}}
|
|
82
|
+
|
|
83
|
+
# --- Benchmarks ---
|
|
84
|
+
|
|
85
|
+
# Run a benchmark (e.g., just bench native_internal)
|
|
86
|
+
bench name:
|
|
87
|
+
bundle exec ruby benchmark/{{name}}_bench.rb
|
|
88
|
+
|
|
89
|
+
# List available benchmarks
|
|
90
|
+
bench-list:
|
|
91
|
+
@ls benchmark/*_bench.rb | sed 's|benchmark/||; s|_bench.rb||'
|
|
92
|
+
|
|
93
|
+
# --- Install ---
|
|
94
|
+
|
|
95
|
+
# Build and install gem locally
|
|
96
|
+
install:
|
|
97
|
+
gem build konpeito.gemspec && gem install konpeito-*.gem && rm -f konpeito-*.gem
|
|
98
|
+
|
|
99
|
+
# --- Tools ---
|
|
100
|
+
|
|
101
|
+
# Start LSP server
|
|
102
|
+
lsp:
|
|
103
|
+
bundle exec ruby -Ilib bin/konpeito lsp
|
|
104
|
+
|
|
105
|
+
# Generate shell completion
|
|
106
|
+
completion shell:
|
|
107
|
+
bundle exec ruby -Ilib bin/konpeito completion {{shell}}
|
data/README.md
CHANGED
|
@@ -16,6 +16,81 @@ Konpeito uses a three-tier type resolution strategy:
|
|
|
16
16
|
|
|
17
17
|
Adding an RBS signature promotes a dynamic fallback to static dispatch. The compiler tells you where the boundaries are — fix them if you want, or leave them dynamic. Your call.
|
|
18
18
|
|
|
19
|
+
## What Gets Compiled
|
|
20
|
+
|
|
21
|
+
Konpeito compiles your `.rb` source files into native code. Understanding the boundary between compiled and non-compiled code is key:
|
|
22
|
+
|
|
23
|
+
**Compiled (native code):**
|
|
24
|
+
- All `.rb` files you pass to `konpeito build`
|
|
25
|
+
- Files resolved via `require` / `require_relative` at compile time (when source is available on the load path via `-I`)
|
|
26
|
+
- Within compiled code: type-resolved operations become native CPU instructions; unresolved operations fall back to `rb_funcallv` (CRuby's dynamic dispatch) with a compiler warning
|
|
27
|
+
|
|
28
|
+
**Not compiled (loaded at runtime by CRuby):**
|
|
29
|
+
- Installed gems referenced by `require` — the compiler detects these and emits `rb_require` calls so CRuby loads them at runtime
|
|
30
|
+
- Standard libraries (`json`, `net/http`, `fileutils`, etc.) — same treatment
|
|
31
|
+
- Any Ruby code running in the host CRuby process outside the compiled extension
|
|
32
|
+
|
|
33
|
+
The compiled extension and CRuby coexist in the same process. Native code calls CRuby C API functions (`rb_define_class`, `rb_funcallv`, `rb_ary_push`, etc.), so compiled code can freely create Ruby objects, call Ruby methods, and interact with any loaded gem. The speed gain comes from the parts where Konpeito resolves types and emits native instructions instead of going through Ruby's method dispatch.
|
|
34
|
+
|
|
35
|
+
This leads to two usage patterns:
|
|
36
|
+
|
|
37
|
+
### Pattern 1: Extension Library
|
|
38
|
+
|
|
39
|
+
Compile performance-critical code into a CRuby extension (`.bundle` / `.so`). Your main application stays as regular Ruby and loads the compiled code via `require`:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# math.rb — compiled by Konpeito
|
|
43
|
+
module MyMath
|
|
44
|
+
def self.sum_up_to(n)
|
|
45
|
+
total = 0
|
|
46
|
+
i = 1
|
|
47
|
+
while i <= n
|
|
48
|
+
total += i
|
|
49
|
+
i += 1
|
|
50
|
+
end
|
|
51
|
+
total
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
konpeito build math.rb # → math.bundle
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
# app.rb — regular Ruby, NOT compiled
|
|
62
|
+
require_relative "math"
|
|
63
|
+
puts MyMath.sum_up_to(10_000_000) # calls into compiled native code
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Your code can `require` installed gems freely. The compiler compiles your code and emits runtime `require` calls for the gems, so everything works together at runtime:
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
# my_app.rb — compiled by Konpeito
|
|
70
|
+
require "kumiki" # gem — loaded at runtime by CRuby
|
|
71
|
+
include Kumiki
|
|
72
|
+
|
|
73
|
+
class MyComponent < Component
|
|
74
|
+
# ... your code is compiled natively
|
|
75
|
+
# ... calls to kumiki methods go through rb_funcallv (dynamic dispatch)
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This is the pattern shown in [Hello World](#hello-world) below.
|
|
80
|
+
|
|
81
|
+
### Pattern 2: Whole Application
|
|
82
|
+
|
|
83
|
+
Compile an entire Ruby application including framework code — the compiler traces all `require` statements on the load path specified by `-I` and compiles everything into a single extension:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
konpeito build -I /path/to/kumiki/lib counter.rb # → counter.bundle (971 KB)
|
|
87
|
+
ruby -r ./counter -e "" # load and run
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The difference from Pattern 1: framework code (kumiki) is also compiled, enabling direct dispatch, monomorphization, and inlining across the entire codebase. Without `-I`, only your code is compiled (~50 KB) and the framework is loaded at runtime — this still works, but method calls into the framework go through dynamic dispatch.
|
|
91
|
+
|
|
92
|
+
See [Tutorial](docs/tutorial.md) for step-by-step walkthroughs of both patterns with working examples.
|
|
93
|
+
|
|
19
94
|
## Quick Start
|
|
20
95
|
|
|
21
96
|
### Prerequisites
|
|
@@ -65,18 +140,20 @@ Write a small Ruby file:
|
|
|
65
140
|
|
|
66
141
|
```ruby
|
|
67
142
|
# math.rb
|
|
68
|
-
|
|
69
|
-
a
|
|
70
|
-
|
|
143
|
+
module MyMath
|
|
144
|
+
def self.add(a, b)
|
|
145
|
+
a + b
|
|
146
|
+
end
|
|
71
147
|
|
|
72
|
-
def sum_up_to(n)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
148
|
+
def self.sum_up_to(n)
|
|
149
|
+
total = 0
|
|
150
|
+
i = 1
|
|
151
|
+
while i <= n
|
|
152
|
+
total = total + i
|
|
153
|
+
i = i + 1
|
|
154
|
+
end
|
|
155
|
+
total
|
|
78
156
|
end
|
|
79
|
-
total
|
|
80
157
|
end
|
|
81
158
|
```
|
|
82
159
|
|
|
@@ -88,19 +165,26 @@ konpeito build math.rb # produces math.bundle (macOS), math.so (Linux),
|
|
|
88
165
|
|
|
89
166
|
```ruby
|
|
90
167
|
require_relative "math"
|
|
91
|
-
puts add(3, 4) # => 7
|
|
92
|
-
puts sum_up_to(100) # => 5050
|
|
168
|
+
puts MyMath.add(3, 4) # => 7
|
|
169
|
+
puts MyMath.sum_up_to(100) # => 5050
|
|
93
170
|
```
|
|
94
171
|
|
|
95
|
-
|
|
172
|
+
### CLI Overview
|
|
96
173
|
|
|
97
174
|
```bash
|
|
98
|
-
konpeito
|
|
99
|
-
konpeito
|
|
100
|
-
konpeito
|
|
101
|
-
konpeito
|
|
175
|
+
konpeito build src/main.rb # compile to CRuby extension
|
|
176
|
+
konpeito build --target jvm -o app.jar src/main.rb # compile to standalone JAR
|
|
177
|
+
konpeito run src/main.rb # build and run in one step
|
|
178
|
+
konpeito check src/main.rb # type check only (no codegen)
|
|
179
|
+
konpeito init my_project # scaffold a new project
|
|
180
|
+
konpeito test # run project tests
|
|
181
|
+
konpeito fmt # format source files
|
|
182
|
+
konpeito watch src/main.rb # auto-recompile on changes
|
|
183
|
+
konpeito doctor # check your environment
|
|
102
184
|
```
|
|
103
185
|
|
|
186
|
+
For detailed options and examples, see [CLI Reference](docs/cli-reference.md).
|
|
187
|
+
|
|
104
188
|
## Features
|
|
105
189
|
|
|
106
190
|
- **HM Type Inference** — Types are inferred automatically. No annotations needed for most code.
|
|
@@ -118,9 +202,38 @@ konpeito fmt --check # check formatting without modifying
|
|
|
118
202
|
- **Pattern Matching** — Full `case/in` support with array, hash, guard, and capture patterns.
|
|
119
203
|
- **Modern Ruby Syntax** — `_1`/`_2` numbered params, `it`, endless methods, `class << self`, safe navigation (`&.`), and more.
|
|
120
204
|
- **Concurrency** — Fiber, Thread, Mutex, ConditionVariable, SizedQueue, and Ractor (with `Ractor::Port`, `Ractor.select`, `Ractor[:key]` local storage, `name:`, `monitor`/`unmonitor`). JVM Ractor uses Virtual Threads for scheduling but does not enforce object isolation — objects are shared by reference, unlike CRuby's strict isolation model.
|
|
121
|
-
- **Built-in Tooling** — Formatter (`fmt`),
|
|
205
|
+
- **Built-in Tooling** — Formatter (`fmt`), debug info (`-g`), and profiling (`--profile`).
|
|
122
206
|
- **Castella UI** — A reactive GUI framework for the JVM backend (see below).
|
|
123
207
|
|
|
208
|
+
## Supported Ruby Syntax
|
|
209
|
+
|
|
210
|
+
Konpeito supports most Ruby 4.0 syntax:
|
|
211
|
+
|
|
212
|
+
| Category | Supported |
|
|
213
|
+
|----------|-----------|
|
|
214
|
+
| Literals | Integer, Float, String, Symbol, Array, Hash, Regexp, Range, Heredoc, nil/true/false |
|
|
215
|
+
| String interpolation | `"Hello #{name}"` |
|
|
216
|
+
| Variables | Local, `@instance`, `@@class`, `$global` |
|
|
217
|
+
| Control flow | `if`/`unless`, `while`/`until`, `for`, `case`/`when`, `case`/`in`, `break`, `next`, `return` |
|
|
218
|
+
| Methods & OOP | Classes, modules, inheritance, `super`, `attr_accessor`, method visibility (`private`/`protected`) |
|
|
219
|
+
| Blocks & closures | `yield`, `block_given?`, Proc, Lambda, `&blk` |
|
|
220
|
+
| Pattern matching | Literals, arrays, hashes, guards (`if`), captures (`=>`), pins (`^`), rest (`*`) |
|
|
221
|
+
| Exceptions | `begin`/`rescue`/`else`/`ensure`, custom exception classes |
|
|
222
|
+
| Modern syntax | `_1`/`_2` numbered params, `it`, endless methods, `class << self`, `&.` safe navigation |
|
|
223
|
+
| Operators | Full overloading (`+`, `-`, `*`, `==`, `<=>`, etc.), compound assignment (`+=`, `\|\|=`, `&&=`) |
|
|
224
|
+
| Arguments | Keyword args, rest args (`*args`), keyword rest (`**kwargs`), splat (`foo(*arr)`) |
|
|
225
|
+
| Concurrency | Fiber, Thread, Mutex, ConditionVariable, SizedQueue, Ractor (JVM) |
|
|
226
|
+
| Misc | `alias`, `defined?`, open classes, multi-assignment, `%w`/`%i` literals |
|
|
227
|
+
|
|
228
|
+
### Not Supported (by design)
|
|
229
|
+
|
|
230
|
+
- `eval`, `instance_eval`, `class_eval`
|
|
231
|
+
- `define_method`, `method_missing`
|
|
232
|
+
- `ObjectSpace`, `Binding`
|
|
233
|
+
- Dynamic `require`/`load` (variable-based require)
|
|
234
|
+
|
|
235
|
+
For the complete specification, see [Language Specification](docs/language-specification.md).
|
|
236
|
+
|
|
124
237
|
## JVM Backend
|
|
125
238
|
|
|
126
239
|
Konpeito can also compile to JVM bytecode, producing standalone JAR files:
|
|
@@ -370,45 +483,32 @@ app.run
|
|
|
370
483
|
|
|
371
484
|
## Performance
|
|
372
485
|
|
|
373
|
-
Konpeito
|
|
486
|
+
Konpeito targets compute-heavy, typed loops where unboxed arithmetic and backend optimizations can make a meaningful difference. Actual speedups depend heavily on the workload, input data, and hardware — the numbers below are from one specific environment and should be taken as rough indicators, not guarantees.
|
|
374
487
|
|
|
375
488
|
### LLVM Backend (CRuby Extension)
|
|
376
489
|
|
|
377
|
-
|
|
378
|
-
|---|---|
|
|
379
|
-
| N-Body simulation (5M steps) | **81x** faster |
|
|
380
|
-
| Numeric method inlining (abs, even?, odd?) | **25-29x** faster |
|
|
381
|
-
| Range enumerable (each, reduce, select) | **40-53x** faster |
|
|
382
|
-
| Integer#times (nested, typed) | **891-972x** faster |
|
|
383
|
-
| Typed reduce over Array[Integer] | **7x** faster |
|
|
384
|
-
| Loop sum (n=100) | **18x** faster |
|
|
385
|
-
| Typed counter loop (LICM + LLVM O2) | **5,345x** faster |
|
|
386
|
-
| StaticArray/NativeArray sum (4 elements) | **65x** faster |
|
|
387
|
-
| StaticArray/NativeArray sum (16 elements) | **232x** faster |
|
|
490
|
+
Typical speedup ranges observed on our test machine (vs Ruby YJIT):
|
|
388
491
|
|
|
389
|
-
|
|
492
|
+
- **Numeric loops** (arithmetic, counters, reductions): often **5–80x** faster, depending on how much of the loop body can be fully unboxed
|
|
493
|
+
- **Native data structures** (NativeArray, StaticArray): **~10–60x** faster for tight element-access loops
|
|
494
|
+
- **Iterator inlining** (each, map, reduce, times): **~7–50x** faster with typed arrays or ranges
|
|
390
495
|
|
|
391
|
-
|
|
496
|
+
These figures reflect native-internal performance — the loop itself runs entirely inside compiled code. Cross-boundary calls (Ruby ↔ native) see smaller gains due to interop overhead.
|
|
392
497
|
|
|
393
|
-
|
|
498
|
+
**Where Konpeito is slower:** Pattern matching (`case/in`) is currently **~2–3x slower** than YJIT — Ruby's VM is highly optimized for this. String operations (NativeString) are also slower than CRuby's mature string implementation due to conversion overhead. Workloads that are I/O-bound, rely heavily on dynamic features, or hit areas where YJIT already excels may see no benefit or even regressions.
|
|
394
499
|
|
|
395
|
-
|
|
396
|
-
|---|---|---|---|
|
|
397
|
-
| Multiply Add (realistic) | 196 ms | 5.0 ms | **39x** faster |
|
|
398
|
-
| Compute Chain (realistic) | 300 ms | 5.1 ms | **59x** faster |
|
|
399
|
-
| Arithmetic Intensive (realistic) | 272 ms | 5.0 ms | **55x** faster |
|
|
400
|
-
| Loop Sum (realistic) | 107 ms | 2.6 ms | **41x** faster |
|
|
401
|
-
| Fibonacci fib(30) x 10 (recursive) | 300 ms | 9.8 ms | **31x** faster |
|
|
500
|
+
### JVM Backend (Standalone JAR)
|
|
402
501
|
|
|
403
|
-
|
|
502
|
+
For numeric workloads, the JVM backend typically shows **~30–60x** speedups over Ruby YJIT, benefiting from HotSpot's JIT on top of Konpeito's static type resolution. I/O-bound or polymorphic code will see less improvement.
|
|
404
503
|
|
|
405
|
-
> **
|
|
504
|
+
> **Test environment:** Apple M4 Max, Ruby 4.0.1 + YJIT, Java 21.0.10 (HotSpot), macOS 15. Results will vary on different hardware and configurations.
|
|
406
505
|
|
|
407
506
|
## Documentation
|
|
408
507
|
|
|
409
508
|
### User Guides
|
|
410
509
|
|
|
411
510
|
- **[Getting Started](docs/getting-started.md)** — Installation, Hello World, first project, Castella UI tutorial
|
|
511
|
+
- **[Tutorial](docs/tutorial.md)** — Extension library and whole-application compilation patterns
|
|
412
512
|
- **[CLI Reference](docs/cli-reference.md)** — All commands, options, and configuration
|
|
413
513
|
- **[API Reference](docs/api-reference.md)** — Castella UI widgets, native data structures, standard library
|
|
414
514
|
|
|
@@ -439,7 +539,7 @@ This project was developed collaboratively between a human director ([Yasushi It
|
|
|
439
539
|
|
|
440
540
|
Konpeito is in an early stage. Bugs and undocumented limitations should be expected. Actively improving — bug reports and feedback are very welcome.
|
|
441
541
|
|
|
442
|
-
|
|
542
|
+
Both LLVM and JVM backends are tested against the project's conformance test suite covering core language features (control flow, classes, blocks, exceptions, pattern matching, concurrency, etc.). The LLVM backend has been successfully used to compile and run [kumiki](https://github.com/i2y/kumiki)'s `all_widgets_demo.rb` — a non-trivial reactive GUI application with 20+ widget types — as a CRuby extension.
|
|
443
543
|
|
|
444
544
|
## Contributing
|
|
445
545
|
|
data/konpeito.gemspec
CHANGED
|
@@ -21,6 +21,8 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
22
22
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
23
23
|
spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
|
|
24
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
25
|
+
spec.metadata["documentation_uri"] = "#{spec.homepage}/blob/main/docs/getting-started.md"
|
|
24
26
|
|
|
25
27
|
spec.files = Dir.chdir(__dir__) do
|
|
26
28
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -35,9 +37,8 @@ Gem::Specification.new do |spec|
|
|
|
35
37
|
|
|
36
38
|
spec.add_dependency "prism"
|
|
37
39
|
spec.add_dependency "rbs"
|
|
38
|
-
spec.add_dependency "language_server-protocol", "~> 3.17"
|
|
39
40
|
|
|
40
41
|
# ruby-llvm is optional — only needed for native/CRuby extension compilation (--target native).
|
|
41
|
-
# JVM backend (--target jvm), type checking,
|
|
42
|
+
# JVM backend (--target jvm), type checking, and formatting work without it.
|
|
42
43
|
# Install manually: gem install ruby-llvm
|
|
43
44
|
end
|
|
@@ -16,11 +16,14 @@ module Konpeito
|
|
|
16
16
|
parse_options!
|
|
17
17
|
|
|
18
18
|
if args.empty?
|
|
19
|
-
|
|
19
|
+
source_file = find_default_source
|
|
20
|
+
unless source_file
|
|
21
|
+
error("No source file specified. Usage: konpeito build <source.rb>")
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
source_file = args.first
|
|
20
25
|
end
|
|
21
26
|
|
|
22
|
-
source_file = args.first
|
|
23
|
-
|
|
24
27
|
unless File.exist?(source_file)
|
|
25
28
|
error("File not found: #{source_file}")
|
|
26
29
|
end
|
|
@@ -204,6 +207,16 @@ module Konpeito
|
|
|
204
207
|
size_str = File.exist?(output_file) ? " (#{format_size(File.size(output_file))})" : ""
|
|
205
208
|
emit("Finished", "in #{duration_str} -> #{output_file}#{size_str}")
|
|
206
209
|
end
|
|
210
|
+
|
|
211
|
+
# Show usage hint (skip for --run and --lib)
|
|
212
|
+
unless options[:run_after] || options[:library]
|
|
213
|
+
if options[:target] == :jvm
|
|
214
|
+
emit("Hint", "java -jar #{output_file}")
|
|
215
|
+
else
|
|
216
|
+
ext_name = File.basename(output_file, File.extname(output_file))
|
|
217
|
+
emit("Hint", "ruby -r ./#{ext_name} -e \"YourModule.method\"")
|
|
218
|
+
end
|
|
219
|
+
end
|
|
207
220
|
end
|
|
208
221
|
rescue Konpeito::DependencyError => e
|
|
209
222
|
display_dependency_error(e)
|
|
@@ -215,6 +228,11 @@ module Konpeito
|
|
|
215
228
|
$stderr.puts "Error: #{e.message}"
|
|
216
229
|
exit 1
|
|
217
230
|
end
|
|
231
|
+
|
|
232
|
+
def find_default_source
|
|
233
|
+
candidates = ["src/main.rb", "main.rb", "app.rb"]
|
|
234
|
+
candidates.find { |f| File.exist?(f) }
|
|
235
|
+
end
|
|
218
236
|
end
|
|
219
237
|
end
|
|
220
238
|
end
|