@tishlang/tish-format 2.2.7 → 2.8.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.
- package/bin/tish-format +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +5 -1
- package/crates/tish/src/cli_help.rs +12 -0
- package/crates/tish/src/main.rs +69 -11
- package/crates/tish_ast/src/ast.rs +6 -2
- package/crates/tish_builtins/src/array.rs +82 -1
- package/crates/tish_builtins/src/globals.rs +50 -16
- package/crates/tish_builtins/src/math.rs +63 -9
- package/crates/tish_builtins/src/number.rs +20 -1
- package/crates/tish_builtins/src/string.rs +68 -4
- package/crates/tish_builtins/src/typedarrays.rs +23 -16
- package/crates/tish_bytecode/src/compiler.rs +94 -28
- package/crates/tish_bytecode/tests/break_continue_bytecode.rs +19 -0
- package/crates/tish_compile/src/check.rs +1 -1
- package/crates/tish_compile/src/codegen.rs +1386 -42
- package/crates/tish_compile/src/infer.rs +4 -4
- package/crates/tish_compile/src/lib.rs +38 -0
- package/crates/tish_compile/src/resolve.rs +3 -2
- package/crates/tish_compile/src/types.rs +17 -0
- package/crates/tish_compile_js/src/codegen.rs +55 -4
- package/crates/tish_compile_js/src/tests_jsx.rs +44 -0
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +1 -0
- package/crates/tish_core/Cargo.toml +2 -0
- package/crates/tish_core/src/json.rs +135 -34
- package/crates/tish_core/src/lib.rs +23 -1
- package/crates/tish_core/src/value.rs +64 -11
- package/crates/tish_eval/src/eval.rs +144 -197
- package/crates/tish_eval/src/natives.rs +45 -45
- package/crates/tish_eval/src/regex.rs +35 -27
- package/crates/tish_eval/src/value.rs +8 -0
- package/crates/tish_fmt/Cargo.toml +1 -1
- package/crates/tish_fmt/src/lib.rs +45 -1
- package/crates/tish_lint/src/bin/tish-lint.rs +17 -8
- package/crates/tish_lint/src/lib.rs +197 -21
- package/crates/tish_lsp/Cargo.toml +6 -0
- package/crates/tish_lsp/src/import_goto.rs +52 -7
- package/crates/tish_lsp/src/main.rs +856 -140
- package/crates/tish_opt/src/lib.rs +5 -3
- package/crates/tish_parser/src/lib.rs +23 -5
- package/crates/tish_parser/src/parser.rs +15 -26
- package/crates/tish_resolve/src/lib.rs +188 -18
- package/crates/tish_runtime/src/lib.rs +58 -18
- package/crates/tish_ui/src/jsx.rs +2 -2
- package/crates/tish_vm/src/jit.rs +212 -10
- package/crates/tish_vm/src/vm.rs +39 -18
- package/crates/tish_wasm/src/lib.rs +116 -22
- 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
|
@@ -314,6 +314,7 @@ pub fn native_member_definition(
|
|
|
314
314
|
lsp_line: u32,
|
|
315
315
|
lsp_character: u32,
|
|
316
316
|
word: &str,
|
|
317
|
+
open_docs: &HashMap<Url, String>,
|
|
317
318
|
) -> Option<NativeMemberDefinition> {
|
|
318
319
|
let project_root = infer_project_root(file_path, roots)?;
|
|
319
320
|
let from_dir = file_path.parent()?;
|
|
@@ -357,7 +358,8 @@ pub fn native_member_definition(
|
|
|
357
358
|
|
|
358
359
|
if from_s.starts_with("./") || from_s.starts_with("../") {
|
|
359
360
|
if members.len() == 1 {
|
|
360
|
-
let loc =
|
|
361
|
+
let loc =
|
|
362
|
+
resolve_relative_tish(from_dir, from_s, members[0].as_ref(), open_docs)?;
|
|
361
363
|
return Some(NativeMemberDefinition {
|
|
362
364
|
location: loc,
|
|
363
365
|
doc: None,
|
|
@@ -422,6 +424,7 @@ pub fn definition_for_native_receiver_member(
|
|
|
422
424
|
lsp_line: u32,
|
|
423
425
|
lsp_character: u32,
|
|
424
426
|
word: &str,
|
|
427
|
+
open_docs: &HashMap<Url, String>,
|
|
425
428
|
) -> Option<Location> {
|
|
426
429
|
native_member_definition(
|
|
427
430
|
program,
|
|
@@ -432,11 +435,28 @@ pub fn definition_for_native_receiver_member(
|
|
|
432
435
|
lsp_line,
|
|
433
436
|
lsp_character,
|
|
434
437
|
word,
|
|
438
|
+
open_docs,
|
|
435
439
|
)
|
|
436
440
|
.map(|d| d.location)
|
|
437
441
|
}
|
|
438
442
|
|
|
439
|
-
|
|
443
|
+
/// Source text of a target module: the live editor buffer if the file is open with unsaved edits,
|
|
444
|
+
/// otherwise the on-disk contents. Reading the open buffer keeps cross-file goto-definition/hover in
|
|
445
|
+
/// sync with what the user sees — disk would give a stale line/column (or miss a not-yet-saved
|
|
446
|
+
/// export entirely). #148
|
|
447
|
+
fn module_source(can: &Path, u: &Url, open_docs: &HashMap<Url, String>) -> Option<String> {
|
|
448
|
+
match open_docs.get(u) {
|
|
449
|
+
Some(buf) => Some(buf.clone()),
|
|
450
|
+
None => std::fs::read_to_string(can).ok(),
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
fn resolve_relative_tish(
|
|
455
|
+
from_dir: &Path,
|
|
456
|
+
from_s: &str,
|
|
457
|
+
imported: &str,
|
|
458
|
+
open_docs: &HashMap<Url, String>,
|
|
459
|
+
) -> Option<Location> {
|
|
440
460
|
let target = from_dir.join(from_s.trim_start_matches("./"));
|
|
441
461
|
let target = if target.extension().is_none() {
|
|
442
462
|
target.with_extension("tish")
|
|
@@ -445,13 +465,17 @@ fn resolve_relative_tish(from_dir: &Path, from_s: &str, imported: &str) -> Optio
|
|
|
445
465
|
};
|
|
446
466
|
let can = target.canonicalize().ok()?;
|
|
447
467
|
let u = Url::from_file_path(&can).ok()?;
|
|
448
|
-
let src =
|
|
468
|
+
let src = module_source(&can, &u, open_docs)?;
|
|
449
469
|
let prog = tishlang_parser::parse(&src).ok()?;
|
|
450
470
|
crate::find_export(&prog, imported, &u, &src)
|
|
451
471
|
}
|
|
452
472
|
|
|
453
473
|
/// Resolve a relative default import (`import X from "./m"`) to the `export default` in the source.
|
|
454
|
-
fn resolve_relative_tish_default(
|
|
474
|
+
fn resolve_relative_tish_default(
|
|
475
|
+
from_dir: &Path,
|
|
476
|
+
from_s: &str,
|
|
477
|
+
open_docs: &HashMap<Url, String>,
|
|
478
|
+
) -> Option<Location> {
|
|
455
479
|
let target = from_dir.join(from_s.trim_start_matches("./"));
|
|
456
480
|
let target = if target.extension().is_none() {
|
|
457
481
|
target.with_extension("tish")
|
|
@@ -460,7 +484,7 @@ fn resolve_relative_tish_default(from_dir: &Path, from_s: &str) -> Option<Locati
|
|
|
460
484
|
};
|
|
461
485
|
let can = target.canonicalize().ok()?;
|
|
462
486
|
let u = Url::from_file_path(&can).ok()?;
|
|
463
|
-
let src =
|
|
487
|
+
let src = module_source(&can, &u, open_docs)?;
|
|
464
488
|
let prog = tishlang_parser::parse(&src).ok()?;
|
|
465
489
|
crate::find_default_export(&prog, &u, &src)
|
|
466
490
|
}
|
|
@@ -473,6 +497,7 @@ pub fn definition_for_import(
|
|
|
473
497
|
word: &str,
|
|
474
498
|
roots: &[PathBuf],
|
|
475
499
|
cargo_src_cache: &RwLock<HashMap<(PathBuf, String), PathBuf>>,
|
|
500
|
+
open_docs: &HashMap<Url, String>,
|
|
476
501
|
) -> Option<Location> {
|
|
477
502
|
if word.is_empty() {
|
|
478
503
|
return None;
|
|
@@ -506,9 +531,9 @@ pub fn definition_for_import(
|
|
|
506
531
|
// A default import binds the source module's `export default`, which has no name to
|
|
507
532
|
// match; resolve it directly. Named imports resolve by exported name.
|
|
508
533
|
return if is_default {
|
|
509
|
-
resolve_relative_tish_default(from_dir, from_s)
|
|
534
|
+
resolve_relative_tish_default(from_dir, from_s, open_docs)
|
|
510
535
|
} else {
|
|
511
|
-
resolve_relative_tish(from_dir, from_s, imported)
|
|
536
|
+
resolve_relative_tish(from_dir, from_s, imported, open_docs)
|
|
512
537
|
};
|
|
513
538
|
}
|
|
514
539
|
|
|
@@ -563,6 +588,26 @@ mod receiver_member_tests {
|
|
|
563
588
|
assert_eq!(mem, "setTitle");
|
|
564
589
|
}
|
|
565
590
|
|
|
591
|
+
// #148: cross-file goto-def must read the open editor buffer (unsaved edits), not disk.
|
|
592
|
+
#[test]
|
|
593
|
+
fn module_source_prefers_open_buffer_over_disk() {
|
|
594
|
+
use std::collections::HashMap;
|
|
595
|
+
use tower_lsp::lsp_types::Url;
|
|
596
|
+
// A path that does NOT exist on disk: the disk branch would fail, so a non-None result
|
|
597
|
+
// proves the open buffer was used.
|
|
598
|
+
let path = std::path::Path::new("/nonexistent/tish/module.tish");
|
|
599
|
+
let url = Url::parse("file:///nonexistent/tish/module.tish").unwrap();
|
|
600
|
+
let mut docs = HashMap::new();
|
|
601
|
+
docs.insert(url.clone(), "export fn live() {}".to_string());
|
|
602
|
+
assert_eq!(
|
|
603
|
+
super::module_source(path, &url, &docs).as_deref(),
|
|
604
|
+
Some("export fn live() {}"),
|
|
605
|
+
"open buffer must win over (here, absent) disk content"
|
|
606
|
+
);
|
|
607
|
+
// Not open + nonexistent on disk → None (disk read fails), no panic.
|
|
608
|
+
assert_eq!(super::module_source(path, &url, &HashMap::new()), None);
|
|
609
|
+
}
|
|
610
|
+
|
|
566
611
|
#[test]
|
|
567
612
|
fn native_pragma_parse_optional_doc() {
|
|
568
613
|
let src = r"// @tish-source window.innerHeight src/appkit/window_api.rs 289 | Height in points.
|