@tishlang/tish-format 3.8.6 → 3.9.2
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.
- package/bin/tish-format +0 -0
- package/crates/tish_compile/src/codegen.rs +675 -22
- package/crates/tish_compile/src/lib.rs +20 -0
- package/crates/tish_compile/src/types.rs +7 -0
- package/crates/tish_compile/tests/regr_682_module_statics.rs +189 -0
- package/crates/tish_compile/tests/regr_682_module_statics_off.rs +53 -0
- package/crates/tish_compile/tests/regr_684_closure_write_capture.rs +104 -0
- package/crates/tish_compile/tests/regr_684_with_module_statics.rs +35 -0
- package/crates/tish_compile/tests/regr_shadowing_local_and_builtin.rs +106 -0
- package/crates/tish_fmt/Cargo.toml +1 -1
- package/crates/tish_native/src/build.rs +161 -26
- package/package.json +1 -1
- package/platform/darwin-arm64/tish-fmt +0 -0
- package/platform/darwin-x64/tish-fmt +0 -0
- package/platform/linux-arm64/tish-fmt +0 -0
- package/platform/linux-x64/tish-fmt +0 -0
- package/platform/win32-x64/tish-fmt.exe +0 -0
|
@@ -224,18 +224,7 @@ pub fn build_via_cargo_with_config(
|
|
|
224
224
|
rust_main
|
|
225
225
|
};
|
|
226
226
|
|
|
227
|
-
let
|
|
228
|
-
.parent()
|
|
229
|
-
.ok_or_else(|| "invalid tishlang_runtime path (no parent)".to_string())?
|
|
230
|
-
.join("tish_ui");
|
|
231
|
-
let ui_dep = if rust_code.contains("tishlang_ui") {
|
|
232
|
-
format!(
|
|
233
|
-
"\ntishlang_ui = {{ path = {:?}, default-features = false, features = [\"runtime\"] }}\n",
|
|
234
|
-
tish_ui_path.display().to_string().replace('\\', "/")
|
|
235
|
-
)
|
|
236
|
-
} else {
|
|
237
|
-
String::new()
|
|
238
|
-
};
|
|
227
|
+
let ui_dep = ui_dep_toml(&runtime_path, rust_code);
|
|
239
228
|
|
|
240
229
|
let profile = nested_release_profile_toml();
|
|
241
230
|
let src_file = if build_config.artifact == NativeArtifact::StaticLib {
|
|
@@ -271,9 +260,18 @@ edition = "2021"
|
|
|
271
260
|
|
|
272
261
|
{}{}
|
|
273
262
|
[dependencies]
|
|
274
|
-
|
|
275
|
-
{}{}"#,
|
|
276
|
-
crate_section,
|
|
263
|
+
{}
|
|
264
|
+
{}{}{}"#,
|
|
265
|
+
crate_section,
|
|
266
|
+
profile,
|
|
267
|
+
runtime_dep_toml(&runtime_path, &features_str),
|
|
268
|
+
more_deps,
|
|
269
|
+
ui_dep,
|
|
270
|
+
if released_compiler_version().is_some() {
|
|
271
|
+
String::new()
|
|
272
|
+
} else {
|
|
273
|
+
tishlang_patch_section(&runtime_path, &more_deps)
|
|
274
|
+
}
|
|
277
275
|
);
|
|
278
276
|
|
|
279
277
|
fs::write(build_dir.join("Cargo.toml"), cargo_toml)
|
|
@@ -452,6 +450,141 @@ opt-level = 3
|
|
|
452
450
|
}
|
|
453
451
|
|
|
454
452
|
/// Read `version = "…"` from the `[package]` section of a crate's `Cargo.toml`.
|
|
453
|
+
/// The `tishlang_runtime` dependency line: registry version for a released compiler,
|
|
454
|
+
/// local path tree for dev builds.
|
|
455
|
+
fn runtime_dep_toml(runtime_path: &str, features_str: &str) -> String {
|
|
456
|
+
if let Some(v) = released_compiler_version() {
|
|
457
|
+
format!("tishlang_runtime = {{ version = {:?}{} }}", v, features_str)
|
|
458
|
+
} else {
|
|
459
|
+
format!("tishlang_runtime = {{ path = {:?}{} }}", runtime_path, features_str)
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/// The optional `tishlang_ui` dependency line (same source policy as the runtime).
|
|
464
|
+
fn ui_dep_toml(runtime_path: &str, rust_code: &str) -> String {
|
|
465
|
+
if !rust_code.contains("tishlang_ui") {
|
|
466
|
+
return String::new();
|
|
467
|
+
}
|
|
468
|
+
if let Some(v) = released_compiler_version() {
|
|
469
|
+
return format!(
|
|
470
|
+
"\ntishlang_ui = {{ version = {:?}, default-features = false, features = [\"runtime\"] }}\n",
|
|
471
|
+
v
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
let tish_ui_path = std::path::Path::new(runtime_path)
|
|
475
|
+
.parent()
|
|
476
|
+
.map(|p| p.join("tish_ui"))
|
|
477
|
+
.unwrap_or_default();
|
|
478
|
+
format!(
|
|
479
|
+
"\ntishlang_ui = {{ path = {:?}, default-features = false, features = [\"runtime\"] }}\n",
|
|
480
|
+
tish_ui_path.display().to_string().replace('\\', "/")
|
|
481
|
+
)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/// The compiler's own RELEASED version, or None for a dev/workspace build.
|
|
485
|
+
///
|
|
486
|
+
/// A released compiler is published together with the whole tishlang_* crate family at the
|
|
487
|
+
/// SAME version, so generated crates can depend on the runtime from crates.io — one source
|
|
488
|
+
/// for every tishlang crate, unified with any published native crate (tishlang_ios,
|
|
489
|
+
/// tishlang_desktop, user `cargo:` deps). Dev builds (workspace version 0.x / -dev) keep
|
|
490
|
+
/// the local path tree + the [patch.crates-io] pin instead.
|
|
491
|
+
fn released_compiler_version() -> Option<&'static str> {
|
|
492
|
+
let v = env!("CARGO_PKG_VERSION");
|
|
493
|
+
if v.starts_with("0.") || v.contains("dev") {
|
|
494
|
+
None
|
|
495
|
+
} else {
|
|
496
|
+
Some(v)
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/// `[package] name` from a crate dir's Cargo.toml (first table only, like read_crate_version).
|
|
501
|
+
fn read_crate_package_name(crate_dir: &Path) -> Option<String> {
|
|
502
|
+
let toml = fs::read_to_string(crate_dir.join("Cargo.toml")).ok()?;
|
|
503
|
+
for line in toml.lines() {
|
|
504
|
+
let line = line.trim();
|
|
505
|
+
if let Some(rest) = line.strip_prefix("name") {
|
|
506
|
+
let rest = rest.trim_start();
|
|
507
|
+
if let Some(rest) = rest.strip_prefix('=') {
|
|
508
|
+
return Some(rest.trim().trim_matches('"').to_string());
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if line.starts_with('[') && !line.starts_with("[package]") {
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
None
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/// `[patch.crates-io]` section pinning every `tishlang_*` crate in the local runtime tree
|
|
519
|
+
/// (the siblings of `runtime_path`) to that tree.
|
|
520
|
+
///
|
|
521
|
+
/// Why: the generated program depends on `tishlang_runtime` BY PATH, but registry-sourced
|
|
522
|
+
/// native crates (`cargo:` deps with a version, published hosts like `tishlang_ios` /
|
|
523
|
+
/// `tishlang_desktop`) declare `tishlang_core` / `tishlang_runtime` / `tishlang_ui` BY
|
|
524
|
+
/// VERSION. Cargo never unifies a path crate with a registry crate, so the build died with
|
|
525
|
+
/// "multiple different versions of crate `tishlang_core`" the moment a published native
|
|
526
|
+
/// crate entered the graph — publishing runtimes was pointless. The patch makes the
|
|
527
|
+
/// compiler's own tree the single source for every tishlang crate, whatever requested it.
|
|
528
|
+
///
|
|
529
|
+
/// Emitted whenever the program has ANY extra native dependency: even a path dep (an npm-
|
|
530
|
+
/// shipped crate like `@tishlang/tish-ios`) reaches the registry TRANSITIVELY through its own
|
|
531
|
+
/// `tishlang_core = "x"` version requirements. Builds with no native deps skip the section so
|
|
532
|
+
/// plain programs don't carry "unused patch" warnings.
|
|
533
|
+
fn tishlang_patch_section(runtime_path: &str, more_deps: &str) -> String {
|
|
534
|
+
let has_extra_dep = more_deps.lines().any(|l| {
|
|
535
|
+
let l = l.trim();
|
|
536
|
+
!l.is_empty() && l.contains('=') && !l.starts_with('#')
|
|
537
|
+
});
|
|
538
|
+
if !has_extra_dep {
|
|
539
|
+
return String::new();
|
|
540
|
+
}
|
|
541
|
+
// A patch entry only ever applies when the patched source's version SATISFIES the
|
|
542
|
+
// registry requirement it replaces. Dev/workspace trees carry 0.x placeholder
|
|
543
|
+
// versions that can never satisfy a released "3.x" requirement — emitting the
|
|
544
|
+
// patch there does nothing useful and destabilizes resolution for path-dep
|
|
545
|
+
// setups that already work. Only patch from a release-stamped tree.
|
|
546
|
+
let core_dir = Path::new(runtime_path)
|
|
547
|
+
.parent()
|
|
548
|
+
.map(|p| p.join("tish_core"));
|
|
549
|
+
let tree_is_released = core_dir
|
|
550
|
+
.as_deref()
|
|
551
|
+
.and_then(read_crate_version)
|
|
552
|
+
.map(|v| !v.starts_with("0."))
|
|
553
|
+
.unwrap_or(false);
|
|
554
|
+
if !tree_is_released {
|
|
555
|
+
return String::new();
|
|
556
|
+
}
|
|
557
|
+
let Some(crates_dir) = Path::new(runtime_path).parent() else {
|
|
558
|
+
return String::new();
|
|
559
|
+
};
|
|
560
|
+
let Ok(read) = fs::read_dir(crates_dir) else {
|
|
561
|
+
return String::new();
|
|
562
|
+
};
|
|
563
|
+
let mut entries: Vec<(String, String)> = Vec::new();
|
|
564
|
+
for e in read.flatten() {
|
|
565
|
+
let dir = e.path();
|
|
566
|
+
if !dir.join("Cargo.toml").exists() {
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
let Some(name) = read_crate_package_name(&dir) else {
|
|
570
|
+
continue;
|
|
571
|
+
};
|
|
572
|
+
if !name.starts_with("tishlang_") {
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
entries.push((name, dir.display().to_string().replace('\\', "/")));
|
|
576
|
+
}
|
|
577
|
+
if entries.is_empty() {
|
|
578
|
+
return String::new();
|
|
579
|
+
}
|
|
580
|
+
entries.sort();
|
|
581
|
+
let mut out = String::from("\n[patch.crates-io]\n");
|
|
582
|
+
for (name, path) in entries {
|
|
583
|
+
out.push_str(&format!("{} = {{ path = {:?} }}\n", name, path));
|
|
584
|
+
}
|
|
585
|
+
out
|
|
586
|
+
}
|
|
587
|
+
|
|
455
588
|
fn read_crate_version(crate_dir: &Path) -> Option<String> {
|
|
456
589
|
let toml = fs::read_to_string(crate_dir.join("Cargo.toml")).ok()?;
|
|
457
590
|
for line in toml.lines() {
|
|
@@ -925,15 +1058,8 @@ pub(crate) fn build_many_via_cargo(
|
|
|
925
1058
|
more_deps.push_str("\nmimalloc = \"0.1\"\n");
|
|
926
1059
|
}
|
|
927
1060
|
|
|
928
|
-
let tish_ui_path = std::path::Path::new(&runtime_path)
|
|
929
|
-
.parent()
|
|
930
|
-
.ok_or_else(|| "invalid tishlang_runtime path (no parent)".to_string())?
|
|
931
|
-
.join("tish_ui");
|
|
932
1061
|
let ui_dep = if needs_ui {
|
|
933
|
-
|
|
934
|
-
"\ntishlang_ui = {{ path = {:?}, default-features = false, features = [\"runtime\"] }}\n",
|
|
935
|
-
tish_ui_path.display().to_string().replace('\\', "/")
|
|
936
|
-
)
|
|
1062
|
+
ui_dep_toml(&runtime_path, "tishlang_ui")
|
|
937
1063
|
} else {
|
|
938
1064
|
String::new()
|
|
939
1065
|
};
|
|
@@ -979,9 +1105,18 @@ edition = "2021"
|
|
|
979
1105
|
|
|
980
1106
|
{}{}
|
|
981
1107
|
[dependencies]
|
|
982
|
-
|
|
983
|
-
{}{}"#,
|
|
984
|
-
bin_tables,
|
|
1108
|
+
{}
|
|
1109
|
+
{}{}{}"#,
|
|
1110
|
+
bin_tables,
|
|
1111
|
+
profile,
|
|
1112
|
+
runtime_dep_toml(&runtime_path, &features_str),
|
|
1113
|
+
more_deps,
|
|
1114
|
+
ui_dep,
|
|
1115
|
+
if released_compiler_version().is_some() {
|
|
1116
|
+
String::new()
|
|
1117
|
+
} else {
|
|
1118
|
+
tishlang_patch_section(&runtime_path, &more_deps)
|
|
1119
|
+
}
|
|
985
1120
|
);
|
|
986
1121
|
|
|
987
1122
|
fs::write(build_dir.join("Cargo.toml"), cargo_toml)
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|