tsrs 0.0.0 → 0.18.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/LICENSE.txt +21 -0
- data/README.md +175 -3
- data/ext/tsrs/extconf.rb +121 -0
- data/ext/tsrs/include/tsrs.h +113 -0
- data/ext/tsrs/tsrs.c +261 -0
- data/lib/tsrs/backend.rb +66 -0
- data/lib/tsrs/check_result.rb +61 -0
- data/lib/tsrs/diagnosed.rb +21 -0
- data/lib/tsrs/diagnostic.rb +112 -0
- data/lib/tsrs/errors.rb +25 -0
- data/lib/tsrs/options.rb +62 -0
- data/lib/tsrs/session.rb +57 -0
- data/lib/tsrs/transpile_result.rb +54 -0
- data/lib/tsrs/version.rb +5 -0
- data/lib/tsrs.rb +76 -3
- data/licenses/README.md +11 -0
- data/licenses/tsrs-Apache-2.0.txt +55 -0
- data/licenses/tsrs-NOTICE.txt +416 -0
- data/rust/.cargo/config.toml +5 -0
- data/rust/Cargo.lock +1301 -0
- data/rust/Cargo.toml +39 -0
- data/rust/build.rs +77 -0
- data/rust/cbindgen.toml +25 -0
- data/rust/rust-toolchain.toml +5 -0
- data/rust/rustfmt.toml +3 -0
- data/rust/src/check.rs +136 -0
- data/rust/src/lib.rs +213 -0
- data/rust/src/options.rs +60 -0
- data/rust/src/result.rs +52 -0
- data/rust/src/session.rs +194 -0
- data/rust/src/status.rs +26 -0
- data/rust/src/transpile.rs +66 -0
- data/rust/src/worker.rs +84 -0
- data/sig/tsrs/backend.rbs +44 -0
- data/sig/tsrs/check_result.rbs +33 -0
- data/sig/tsrs/diagnosed.rbs +15 -0
- data/sig/tsrs/diagnostic.rbs +66 -0
- data/sig/tsrs/errors.rbs +37 -0
- data/sig/tsrs/options.rbs +19 -0
- data/sig/tsrs/session.rbs +26 -0
- data/sig/tsrs/transpile_result.rbs +29 -0
- data/sig/tsrs/types.rbs +5 -0
- data/sig/tsrs/version.rbs +5 -0
- data/sig/tsrs.rbs +27 -0
- data/tsrs.gemspec +45 -0
- metadata +53 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a87e1838e8352dbcb61cde9ed300cb2eca9f7b14006b6bb9f2aabe5f2565e16f
|
|
4
|
+
data.tar.gz: c14fe5ae5cb01af608eb90bff51ec4626530f7f8b1e47e80eb0482c539edede0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89c7cdc9f86f30d75517d16b45aeda776edc21fce6b466a8fa014f0d0c47fc0c6e376fbc44b4f8764187b147aceae99f831c0c30d55e097a9ecd900cc9b082f9
|
|
7
|
+
data.tar.gz: 8d21641227464c5ec4f33bff52da3a610c0ecc6b07bff8136cfda261426c663886c7b51e055c4ab84c91820e18ac130a4347591d3675982e6064536d0214d1c8
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marco Roth
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,5 +1,177 @@
|
|
|
1
|
-
|
|
1
|
+
<h2 align="center">🦀 tsrs for Ruby</h2>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<h4 align="center">A drop-in replacement for the TypeScript 7 compiler and language server, written in Rust.</h4>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<div align="center">Ruby bindings for <a href="https://github.com/oxc-project/tsrs">tsrs</a>, the Rust port of the TypeScript 7 type checker.</div><br/>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://rubygems.org/gems/tsrs"><img alt="Gem Version" src="https://img.shields.io/gem/v/tsrs"></a>
|
|
9
|
+
<a href="https://github.com/oxc-project/tsrs"><img alt="Documentation" src="https://img.shields.io/badge/oxc--project%2Ftsrs-documentation-green"></a>
|
|
10
|
+
<a href="https://github.com/marcoroth/tsrs-ruby/blob/main/LICENSE.txt"><img alt="License" src="https://img.shields.io/github/license/marcoroth/tsrs-ruby"></a>
|
|
11
|
+
<a href="https://github.com/marcoroth/tsrs-ruby/issues"><img alt="Issues" src="https://img.shields.io/github/issues/marcoroth/tsrs-ruby"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<br/>
|
|
15
|
+
|
|
16
|
+
### What is tsrs for Ruby?
|
|
17
|
+
|
|
18
|
+
Ruby bindings for [tsrs](https://github.com/oxc-project/tsrs), a drop-in replacement for the TypeScript 7 compiler and language server, written in Rust. Type check, compile and transpile TypeScript from Ruby, without the need for a JavaScript runtime.
|
|
19
|
+
|
|
20
|
+
Everything here is tsrs doing the work. For what the options mean and what it can do, the [TypeScript documentation](https://www.typescriptlang.org/tsconfig/) is the reference.
|
|
21
|
+
|
|
22
|
+
### Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bundle add tsrs
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Anywhere a precompiled gem is not published, the gem builds from source and needs the [Rust toolchain](https://rustup.rs). tsrs needs a recent Rust, 1.99.1 at the moment. `rust/rust-toolchain.toml` pins it, so rustup installs it for the build.
|
|
29
|
+
|
|
30
|
+
tsrs only runs on 64-bit platforms, so the gem doesn't support 32-bit ARM or x86.
|
|
31
|
+
|
|
32
|
+
### Versioning
|
|
33
|
+
|
|
34
|
+
The gem carries the version of tsrs it packages. Gem v0.18.0 bundles tsrs v0.18.0. `Tsrs.tsrs_version` reports what a given build was compiled against, and `Tsrs.typescript_version` reports the TypeScript version that tsrs release is a port of.
|
|
35
|
+
|
|
36
|
+
So the version tracks tsrs, not the Ruby API here. If the gem needs releasing again for the same tsrs version, that release adds a fourth digit, as in v0.18.0.1.
|
|
37
|
+
|
|
38
|
+
### Usage
|
|
39
|
+
|
|
40
|
+
#### Type checking
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
require "tsrs"
|
|
44
|
+
|
|
45
|
+
result = Tsrs.check(cwd: "app/javascript")
|
|
46
|
+
# => #<Tsrs::CheckResult status=2 errors=1 diagnostics=1>
|
|
47
|
+
|
|
48
|
+
result.success?
|
|
49
|
+
# => false
|
|
50
|
+
|
|
51
|
+
puts result
|
|
52
|
+
# app/javascript/src/index.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'.
|
|
53
|
+
|
|
54
|
+
result.errors.first.code
|
|
55
|
+
# => 2322
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Without arguments, tsc finds the `tsconfig.json` in `cwd`. You can also point it at a project, or at files:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
Tsrs.check(project: "app/javascript/tsconfig.json")
|
|
62
|
+
Tsrs.check("app/javascript/index.ts", strict: true)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`Tsrs.check` never writes anything, as with `tsc --noEmit`. `validate!` raises `Tsrs::TypeError` if there were errors, so a rake task can fail on them:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
task :typecheck do
|
|
69
|
+
Tsrs.check(cwd: "app/javascript").validate!
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Checking again and again
|
|
74
|
+
|
|
75
|
+
`Tsrs.check` runs tsc's command line, which is built to check once and exit, so a check's memory stays with the process. For anything long-lived, like a web server, a file watcher or a test suite that checks often, use a session instead:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
session = Tsrs::Session.new(cwd: "app/javascript")
|
|
79
|
+
|
|
80
|
+
session.check.validate! # tsconfig.json in cwd
|
|
81
|
+
session.check("admin/tsconfig.json").errors # or any other project
|
|
82
|
+
|
|
83
|
+
session.close
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`Tsrs::Session.open(cwd: ...) { |session| ... }` closes the session when the block returns. A session is tsrs's API server, the same one behind tsrs's Node API. Each check builds the program in a snapshot and releases it afterwards, so memory levels off instead of growing by about 38 MB a check. Checks report the same diagnostics as `Tsrs.check`. They pick up what changed on disk since the last check, including the `tsconfig.json`, and can run from several threads at once.
|
|
87
|
+
|
|
88
|
+
The project's `tsconfig.json` decides the compiler options: a session check takes none of its own. It never writes anything, and raises `Tsrs::CheckError` when there is no project to load.
|
|
89
|
+
|
|
90
|
+
#### Compiling
|
|
91
|
+
|
|
92
|
+
`Tsrs.compile` runs tsc and writes its outputs, the way `tsc` does:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
Tsrs.compile(project: "tsconfig.json", declaration: true)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`Tsrs.tsc` takes command-line arguments exactly as `tsc` would:
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
Tsrs.tsc("--listFilesOnly", cwd: "app/javascript").output
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Transpiling one file
|
|
105
|
+
|
|
106
|
+
`Tsrs.transpile` turns one TypeScript source into JavaScript without type checking it, like TypeScript's `transpileModule`. It doesn't look at the file system:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
Tsrs.transpile("export const answer: number = 42;", target: "es2020").code
|
|
110
|
+
# => "export const answer = 42;\n"
|
|
111
|
+
|
|
112
|
+
result = Tsrs.transpile(source, file_name: "app.tsx", jsx: "react-jsx", source_map: true)
|
|
113
|
+
result.code
|
|
114
|
+
result.map
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`Tsrs.transpile_declaration` emits the `.d.ts` for a source written for `isolatedDeclarations`:
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
Tsrs.transpile_declaration("export function greet(name: string): string { return name; }").code
|
|
121
|
+
# => "export declare function greet(name: string): string;\n"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
A source that doesn't parse raises `Tsrs::SyntaxError`, which carries the diagnostics.
|
|
125
|
+
|
|
126
|
+
#### Compiler options
|
|
127
|
+
|
|
128
|
+
Compiler options are tsc's, written in snake case or as tsc spells them. They are passed to tsc as command-line flags, so tsc reads them the way it always does:
|
|
129
|
+
|
|
130
|
+
| Ruby | tsc |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `strict: true` | `--strict` |
|
|
133
|
+
| `no_emit: false` | `--noEmit false` |
|
|
134
|
+
| `target: "es2022"` | `--target es2022` |
|
|
135
|
+
| `lib: ["es2022", "dom"]` | `--lib es2022,dom` |
|
|
136
|
+
| `"esModuleInterop" => true` | `--esModuleInterop` |
|
|
137
|
+
|
|
138
|
+
Options that only make sense in a terminal, like `watch`, `build`, `init` and `help`, raise `Tsrs::OptionError`. So does a hash, which tsc's command line can't express. Put options like `paths` in a `tsconfig.json`.
|
|
139
|
+
|
|
140
|
+
#### Diagnostics
|
|
141
|
+
|
|
142
|
+
Each `Tsrs::Diagnostic` has a `code`, a `category` (`:error`, `:warning`, `:suggestion` or `:message`), a `message`, a `file`, and a 1-based `line` and `column`. `start` and `finish` are offsets in UTF-16 code units, the unit TypeScript counts in. `message_chain` and `related_information` hold the elaborations tsc attaches, and `to_s` prints a diagnostic the way tsc does.
|
|
143
|
+
|
|
144
|
+
#### Threads and memory
|
|
145
|
+
|
|
146
|
+
Every call releases the GVL, so other Ruby threads keep running and several checks can run at once. The work runs on a few long-lived native threads with large stacks, since type checking recurses deeply.
|
|
147
|
+
|
|
148
|
+
Transpiling gives back all the memory it used, and so does checking with a `Tsrs::Session`. `Tsrs.check`, `Tsrs.compile` and `Tsrs.tsc` don't: tsrs runs them like `tsc`, a process that checks once and exits, so much of what they allocate stays with the process. That's fine for a rake task or CI. In a long-lived process, check with a session instead.
|
|
149
|
+
|
|
150
|
+
### Development
|
|
151
|
+
|
|
152
|
+
The gem is a C extension over a Rust crate. `rust/` builds a static library and generates the C header with [cbindgen](https://github.com/mozilla/cbindgen), `ext/tsrs/` wraps it, and `lib/` is the Ruby API over that.
|
|
153
|
+
|
|
154
|
+
tsrs doesn't publish its crates, so `rust/Cargo.toml` takes them from the release tag on GitHub. `rust/.cargo/config.toml` stamps the TypeScript version the way tsrs's own release builds do. The upstream workflow keeps the tag, that version, and the Rust toolchain in step with each tsrs release.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
bin/setup
|
|
158
|
+
bundle exec rake
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`sig/` is generated from the `#:` annotations next to the code. Regenerate it with `rake rbs` after changing a signature, and CI checks that it matches.
|
|
162
|
+
|
|
163
|
+
### Acknowledgements
|
|
164
|
+
|
|
165
|
+
[tsrs](https://github.com/oxc-project/tsrs) is maintained at [oxc-project/tsrs](https://github.com/oxc-project/tsrs), and is a port of [TypeScript](https://github.com/microsoft/TypeScript). This gem only calls into it. Thank you for building these tools!
|
|
166
|
+
|
|
167
|
+
### Contributing
|
|
168
|
+
|
|
169
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/marcoroth/tsrs-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/marcoroth/tsrs-ruby/blob/main/CODE_OF_CONDUCT.md).
|
|
170
|
+
|
|
171
|
+
Issues with type checking or emit belong [upstream](https://github.com/oxc-project/tsrs/issues), with a minimal reproduction, since this gem does none of that itself. Issues with the Ruby API, the build, or the bindings belong here.
|
|
172
|
+
|
|
173
|
+
### License
|
|
174
|
+
|
|
175
|
+
The Ruby, C, and Rust code in this gem is available under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
176
|
+
|
|
177
|
+
It builds against [tsrs](https://github.com/oxc-project/tsrs), which is Apache-2.0 licensed and a derivative of TypeScript. Its native extension embeds TypeScript's `lib.*.d.ts` files. tsrs's license and NOTICE travel with the gem in [`licenses/`](licenses).
|
data/ext/tsrs/extconf.rb
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mkmf"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
ext_dir = __dir__
|
|
7
|
+
root_dir = File.expand_path("../..", ext_dir)
|
|
8
|
+
|
|
9
|
+
rust_dir = File.join(root_dir, "rust")
|
|
10
|
+
|
|
11
|
+
unless File.exist?(File.join(rust_dir, "Cargo.toml"))
|
|
12
|
+
abort <<~MESSAGE
|
|
13
|
+
|
|
14
|
+
ERROR: Rust sources not found at #{rust_dir}.
|
|
15
|
+
|
|
16
|
+
MESSAGE
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
unless system("cargo --version > /dev/null 2>&1")
|
|
20
|
+
abort <<~MESSAGE
|
|
21
|
+
|
|
22
|
+
ERROR: Rust toolchain not found.
|
|
23
|
+
|
|
24
|
+
tsrs requires the Rust toolchain to compile from source.
|
|
25
|
+
|
|
26
|
+
Install Rust: https://rustup.rs
|
|
27
|
+
|
|
28
|
+
MESSAGE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
RUST_TARGETS = {
|
|
32
|
+
"aarch64-linux-gnu" => "aarch64-unknown-linux-gnu",
|
|
33
|
+
"aarch64-linux-musl" => "aarch64-unknown-linux-musl",
|
|
34
|
+
"arm64-darwin" => "aarch64-apple-darwin",
|
|
35
|
+
"x86_64-darwin" => "x86_64-apple-darwin",
|
|
36
|
+
"x86_64-linux-gnu" => "x86_64-unknown-linux-gnu",
|
|
37
|
+
"x86_64-linux-musl" => "x86_64-unknown-linux-musl",
|
|
38
|
+
}.freeze
|
|
39
|
+
|
|
40
|
+
cross_compiling = ENV.key?("RUBY_CC_VERSION")
|
|
41
|
+
target_platform = ENV.fetch("CARGO_BUILD_TARGET", nil)
|
|
42
|
+
|
|
43
|
+
if cross_compiling && target_platform.nil?
|
|
44
|
+
rcd_platform = ENV.fetch("RCD_PLATFORM", "")
|
|
45
|
+
target_platform = RUST_TARGETS[rcd_platform]
|
|
46
|
+
|
|
47
|
+
if target_platform.nil?
|
|
48
|
+
ruby_platform = RbConfig::CONFIG["arch"]
|
|
49
|
+
target_platform = RUST_TARGETS.values.find { |target| ruby_platform.include?(target.split("-").first) }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
header_path = File.join(ext_dir, "include", "tsrs.h")
|
|
54
|
+
|
|
55
|
+
FileUtils.mkdir_p(File.dirname(header_path))
|
|
56
|
+
|
|
57
|
+
target_dir = File.join(rust_dir, "target")
|
|
58
|
+
|
|
59
|
+
if target_platform
|
|
60
|
+
puts "tsrs: Cross-compiling Rust for target: #{target_platform}"
|
|
61
|
+
|
|
62
|
+
system("cd #{rust_dir} && rustup target add #{target_platform}") || warn("tsrs: Failed to add Rust target #{target_platform}")
|
|
63
|
+
|
|
64
|
+
cargo_args = "--release --locked --target #{target_platform}"
|
|
65
|
+
lib_dir = File.join(target_dir, target_platform, "release")
|
|
66
|
+
else
|
|
67
|
+
puts "tsrs: Compiling Rust library for native platform..."
|
|
68
|
+
|
|
69
|
+
cargo_args = "--release --locked"
|
|
70
|
+
lib_dir = File.join(target_dir, "release")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
unless system("cd #{rust_dir} && cargo build #{cargo_args}")
|
|
74
|
+
abort "ERROR: Failed to compile tsrs from Rust source."
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
unless File.exist?(header_path)
|
|
78
|
+
abort "ERROR: cbindgen did not generate #{header_path}. Try `cargo clean` in #{rust_dir} and reinstall."
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
static_lib = File.join(lib_dir, "libtsrs_ffi.a")
|
|
82
|
+
developing = File.exist?(File.join(root_dir, ".git"))
|
|
83
|
+
|
|
84
|
+
if File.exist?(static_lib) && !developing
|
|
85
|
+
vendored = File.join(ext_dir, "libtsrs_ffi.a")
|
|
86
|
+
|
|
87
|
+
FileUtils.cp(static_lib, vendored)
|
|
88
|
+
FileUtils.rm_rf(target_dir)
|
|
89
|
+
|
|
90
|
+
puts "tsrs: Static library vendored at #{vendored}, Rust build directory removed"
|
|
91
|
+
|
|
92
|
+
$LDFLAGS << " #{vendored}"
|
|
93
|
+
elsif File.exist?(static_lib)
|
|
94
|
+
puts "tsrs: Static library found at #{static_lib}"
|
|
95
|
+
|
|
96
|
+
$LDFLAGS << " #{static_lib}"
|
|
97
|
+
else
|
|
98
|
+
host_os = target_platform || RbConfig::CONFIG["host_os"]
|
|
99
|
+
|
|
100
|
+
lib_name = case host_os
|
|
101
|
+
when /darwin/
|
|
102
|
+
"libtsrs_ffi.dylib"
|
|
103
|
+
when /mingw|mswin|windows/
|
|
104
|
+
"tsrs_ffi.dll"
|
|
105
|
+
else
|
|
106
|
+
"libtsrs_ffi.so"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
lib_path = File.join(lib_dir, lib_name)
|
|
110
|
+
|
|
111
|
+
abort "ERROR: Shared library not found at #{lib_path}" unless File.exist?(lib_path)
|
|
112
|
+
|
|
113
|
+
puts "tsrs: Shared library found at #{lib_path} (dynamic)"
|
|
114
|
+
|
|
115
|
+
$LDFLAGS << " -L#{lib_dir} -ltsrs_ffi"
|
|
116
|
+
$LDFLAGS << " -Wl,-rpath,#{lib_dir}" if RbConfig::CONFIG["host_os"].match?(/darwin|linux/)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
$CFLAGS << " -I#{ext_dir}"
|
|
120
|
+
|
|
121
|
+
create_makefile("tsrs/tsrs")
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/* Generated by cbindgen, do not edit manually */
|
|
2
|
+
|
|
3
|
+
#include <stdbool.h>
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
#include <stddef.h>
|
|
6
|
+
|
|
7
|
+
#ifndef TSRS_H
|
|
8
|
+
#define TSRS_H
|
|
9
|
+
|
|
10
|
+
typedef enum TsrsErrorCode {
|
|
11
|
+
TSRS_ERROR_CODE_NONE = 0,
|
|
12
|
+
TSRS_ERROR_CODE_OPTION,
|
|
13
|
+
TSRS_ERROR_CODE_ENCODING,
|
|
14
|
+
TSRS_ERROR_CODE_TRANSPILE,
|
|
15
|
+
TSRS_ERROR_CODE_CHECK,
|
|
16
|
+
TSRS_ERROR_CODE_INTERNAL,
|
|
17
|
+
TSRS_ERROR_CODE_PANIC,
|
|
18
|
+
} TsrsErrorCode;
|
|
19
|
+
|
|
20
|
+
typedef struct TsrsSession TsrsSession;
|
|
21
|
+
|
|
22
|
+
typedef struct TsrsResult {
|
|
23
|
+
char *value;
|
|
24
|
+
uintptr_t value_len;
|
|
25
|
+
char *error;
|
|
26
|
+
enum TsrsErrorCode code;
|
|
27
|
+
} TsrsResult;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* # Safety
|
|
31
|
+
*
|
|
32
|
+
* `source` and `options_json` must be valid, nul-terminated UTF-8 strings.
|
|
33
|
+
*/
|
|
34
|
+
struct TsrsResult tsrs_transpile(const char *source, const char *options_json);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* # Safety
|
|
38
|
+
*
|
|
39
|
+
* `source` and `options_json` must be valid, nul-terminated UTF-8 strings.
|
|
40
|
+
*/
|
|
41
|
+
struct TsrsResult tsrs_transpile_declaration(const char *source, const char *options_json);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* # Safety
|
|
45
|
+
*
|
|
46
|
+
* `options_json` must be a valid, nul-terminated UTF-8 string.
|
|
47
|
+
*/
|
|
48
|
+
struct TsrsResult tsrs_check(const char *options_json);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* # Safety
|
|
52
|
+
*
|
|
53
|
+
* `cwd` must be a valid, nul-terminated UTF-8 string.
|
|
54
|
+
*/
|
|
55
|
+
struct TsrsSession *tsrs_session_new(const char *cwd);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Taken before a check that runs without the GVL, so that freeing the original meanwhile cannot free the session.
|
|
59
|
+
*
|
|
60
|
+
* # Safety
|
|
61
|
+
*
|
|
62
|
+
* `session` must be a live pointer from `tsrs_session_new` or `tsrs_session_retain`.
|
|
63
|
+
*/
|
|
64
|
+
struct TsrsSession *tsrs_session_retain(const struct TsrsSession *session);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* # Safety
|
|
68
|
+
*
|
|
69
|
+
* `session` must be a live pointer from `tsrs_session_new` or `tsrs_session_retain`, and `options_json` a valid,
|
|
70
|
+
* nul-terminated UTF-8 string.
|
|
71
|
+
*/
|
|
72
|
+
struct TsrsResult tsrs_session_check(const struct TsrsSession *session,
|
|
73
|
+
const char *options_json);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The pointer stays valid until `tsrs_session_free`.
|
|
77
|
+
*
|
|
78
|
+
* # Safety
|
|
79
|
+
*
|
|
80
|
+
* `session` must be a live pointer from `tsrs_session_new` or `tsrs_session_retain`, or null.
|
|
81
|
+
*/
|
|
82
|
+
void tsrs_session_close(const struct TsrsSession *session);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* # Safety
|
|
86
|
+
*
|
|
87
|
+
* `session` must be a pointer from `tsrs_session_new` or `tsrs_session_retain` that is not used afterwards, or null.
|
|
88
|
+
*/
|
|
89
|
+
void tsrs_session_free(struct TsrsSession *session);
|
|
90
|
+
|
|
91
|
+
char *tsrs_version(void);
|
|
92
|
+
|
|
93
|
+
char *tsrs_tsrs_version(void);
|
|
94
|
+
|
|
95
|
+
char *tsrs_typescript_version(void);
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* # Safety
|
|
99
|
+
*
|
|
100
|
+
* `value` must be a pointer this library returned, and must not be used afterwards.
|
|
101
|
+
*/
|
|
102
|
+
void tsrs_string_free(char *value);
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* # Safety
|
|
106
|
+
*
|
|
107
|
+
* `result` must be one this library returned, and must not be used afterwards.
|
|
108
|
+
*/
|
|
109
|
+
void tsrs_result_free(struct TsrsResult result);
|
|
110
|
+
|
|
111
|
+
struct TsrsResult tsrs_panic_for_test(void);
|
|
112
|
+
|
|
113
|
+
#endif /* TSRS_H */
|