@tishlang/tish-lsp 2.12.0 → 2.35.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/Cargo.toml +3 -0
- package/bin/tish-lsp +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +12 -2
- package/crates/tish/tests/fixtures/fs_parity_callbacks.tish +22 -0
- package/crates/tish/tests/fixtures/fs_parity_promises.tish +21 -0
- package/crates/tish/tests/fixtures/fs_parity_sync.tish +20 -0
- package/crates/tish/tests/fs_parity.rs +103 -0
- package/crates/tish/tests/integration_test.rs +80 -0
- package/crates/tish/tests/shortcircuit.rs +3 -3
- package/crates/tish_ast/src/ast.rs +84 -0
- package/crates/tish_builtins/Cargo.toml +1 -0
- package/crates/tish_builtins/src/array.rs +724 -72
- package/crates/tish_builtins/src/collections.rs +149 -40
- package/crates/tish_builtins/src/globals.rs +215 -25
- package/crates/tish_builtins/src/math.rs +65 -7
- package/crates/tish_builtins/src/number.rs +173 -0
- package/crates/tish_builtins/src/string.rs +263 -23
- package/crates/tish_bytecode/src/chunk.rs +7 -0
- package/crates/tish_bytecode/src/compiler.rs +611 -63
- package/crates/tish_bytecode/src/lib.rs +1 -1
- package/crates/tish_bytecode/src/opcode.rs +156 -2
- package/crates/tish_bytecode/src/serialize.rs +2 -0
- package/crates/tish_bytecode/tests/append_local_string_builder.rs +63 -0
- package/crates/tish_bytecode/tests/math_unary_intrinsic.rs +47 -0
- package/crates/tish_compile/src/codegen.rs +18219 -5283
- package/crates/tish_compile/src/infer.rs +1562 -30
- package/crates/tish_compile/src/lib.rs +29 -4
- package/crates/tish_compile/src/resolve.rs +151 -13
- package/crates/tish_compile/src/types.rs +224 -28
- package/crates/tish_compile/tests/dump_codegen.rs +21 -0
- package/crates/tish_compile/tests/perf_codegen_169_173.rs +8 -17
- package/crates/tish_compile/tests/perf_codegen_173_part3.rs +61 -0
- package/crates/tish_compile/tests/perf_codegen_174.rs +160 -0
- package/crates/tish_compile/tests/perf_codegen_175.rs +190 -0
- package/crates/tish_compile/tests/perf_codegen_176.rs +60 -0
- package/crates/tish_compile/tests/perf_codegen_177.rs +167 -0
- package/crates/tish_compile/tests/perf_codegen_178.rs +114 -0
- package/crates/tish_compile/tests/perf_codegen_178_rec.rs +124 -0
- package/crates/tish_compile/tests/perf_codegen_181.rs +36 -0
- package/crates/tish_compile/tests/perf_codegen_320.rs +211 -0
- package/crates/tish_compile/tests/perf_codegen_module_const_forof.rs +40 -0
- package/crates/tish_compile_js/src/codegen.rs +94 -3
- package/crates/tish_compile_js/src/tests_jsx.rs +27 -0
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +115 -2
- package/crates/tish_core/Cargo.toml +4 -0
- package/crates/tish_core/src/json.rs +109 -6
- package/crates/tish_core/src/lib.rs +222 -2
- package/crates/tish_core/src/shape.rs +4 -2
- package/crates/tish_core/src/uri.rs +45 -0
- package/crates/tish_core/src/value.rs +571 -35
- package/crates/tish_core/src/vmref.rs +14 -0
- package/crates/tish_eval/Cargo.toml +2 -1
- package/crates/tish_eval/src/eval.rs +1328 -101
- package/crates/tish_eval/src/natives.rs +283 -18
- package/crates/tish_eval/src/regex.rs +47 -1
- package/crates/tish_eval/src/value.rs +76 -21
- package/crates/tish_ffi/src/lib.rs +11 -1
- package/crates/tish_ffi/tests/double_free.rs +35 -0
- package/crates/tish_fmt/src/lib.rs +94 -1
- package/crates/tish_lexer/src/lib.rs +76 -0
- package/crates/tish_lexer/src/token.rs +4 -0
- package/crates/tish_lint/src/lib.rs +126 -0
- package/crates/tish_lsp/Cargo.toml +1 -1
- package/crates/tish_lsp/README.md +2 -1
- package/crates/tish_lsp/src/main.rs +378 -28
- package/crates/tish_native/src/build.rs +41 -0
- package/crates/tish_opt/src/lib.rs +20 -1
- package/crates/tish_parser/Cargo.toml +4 -0
- package/crates/tish_parser/src/lib.rs +68 -0
- package/crates/tish_parser/src/parser.rs +479 -28
- package/crates/tish_resolve/src/lib.rs +75 -5
- package/crates/tish_runtime/Cargo.toml +10 -1
- package/crates/tish_runtime/src/fs_ext.rs +359 -0
- package/crates/tish_runtime/src/http.rs +28 -10
- package/crates/tish_runtime/src/http_fetch.rs +150 -1
- package/crates/tish_runtime/src/http_hyper.rs +41 -18
- package/crates/tish_runtime/src/http_prefork.rs +72 -11
- package/crates/tish_runtime/src/lib.rs +651 -51
- package/crates/tish_runtime/src/timers.rs +49 -2
- package/crates/tish_ui/src/jsx.rs +21 -3
- package/crates/tish_vm/src/jit.rs +2514 -117
- package/crates/tish_vm/src/vm.rs +1479 -224
- package/package.json +1 -1
- package/platform/darwin-arm64/tish-lsp +0 -0
- package/platform/darwin-x64/tish-lsp +0 -0
- package/platform/linux-arm64/tish-lsp +0 -0
- package/platform/linux-x64/tish-lsp +0 -0
- package/platform/win32-x64/tish-lsp.exe +0 -0
|
@@ -118,6 +118,19 @@ fn optimize_statement(stmt: &Statement) -> Statement {
|
|
|
118
118
|
body: Box::new(optimize_statement(body)),
|
|
119
119
|
span: *span,
|
|
120
120
|
},
|
|
121
|
+
Statement::ForIn {
|
|
122
|
+
name,
|
|
123
|
+
name_span,
|
|
124
|
+
object,
|
|
125
|
+
body,
|
|
126
|
+
span,
|
|
127
|
+
} => Statement::ForIn {
|
|
128
|
+
name: Arc::clone(name),
|
|
129
|
+
name_span: *name_span,
|
|
130
|
+
object: optimize_expr(object),
|
|
131
|
+
body: Box::new(optimize_statement(body)),
|
|
132
|
+
span: *span,
|
|
133
|
+
},
|
|
121
134
|
Statement::Return { value, span } => Statement::Return {
|
|
122
135
|
value: value.as_ref().map(optimize_expr),
|
|
123
136
|
span: *span,
|
|
@@ -500,12 +513,18 @@ fn optimize_expr(expr: &Expr) -> Expr {
|
|
|
500
513
|
value: Box::new(optimize_expr(value)),
|
|
501
514
|
span: *span,
|
|
502
515
|
},
|
|
503
|
-
Expr::ArrowFunction {
|
|
516
|
+
Expr::ArrowFunction {
|
|
517
|
+
async_,
|
|
518
|
+
params,
|
|
519
|
+
body,
|
|
520
|
+
span,
|
|
521
|
+
} => {
|
|
504
522
|
let opt_body = match body {
|
|
505
523
|
ArrowBody::Expr(e) => ArrowBody::Expr(Box::new(optimize_expr(e))),
|
|
506
524
|
ArrowBody::Block(s) => ArrowBody::Block(Box::new(optimize_statement(s))),
|
|
507
525
|
};
|
|
508
526
|
Expr::ArrowFunction {
|
|
527
|
+
async_: *async_,
|
|
509
528
|
params: params.clone(),
|
|
510
529
|
body: opt_body,
|
|
511
530
|
span: *span,
|
|
@@ -9,3 +9,7 @@ repository = { workspace = true }
|
|
|
9
9
|
[dependencies]
|
|
10
10
|
tishlang_lexer = { path = "../tish_lexer", version = ">=0.1" }
|
|
11
11
|
tishlang_ast = { path = "../tish_ast", version = ">=0.1" }
|
|
12
|
+
# #381: grow the stack on demand during the recursive descent so deeply-nested source can't overflow
|
|
13
|
+
# the fixed OS thread stack before the MAX_PARSE_DEPTH bound converts it into a catchable error.
|
|
14
|
+
# (No-op shim on wasm32, matching tish_eval / tish_vm.)
|
|
15
|
+
stacker = "0.1"
|
|
@@ -33,6 +33,74 @@ mod tests {
|
|
|
33
33
|
use super::*;
|
|
34
34
|
use tishlang_ast::{CallArg, Expr, ObjectProp, Statement};
|
|
35
35
|
|
|
36
|
+
/// #381: pathologically nested source must return a catchable `Err`, NOT overflow the native
|
|
37
|
+
/// stack and abort the process. Exercises expression nesting (`((((…`), array nesting (`[[[[…`),
|
|
38
|
+
/// and prefix-op nesting (`-!-!…`) — all funnel through the depth-guarded `parse_unary`.
|
|
39
|
+
#[test]
|
|
40
|
+
fn deeply_nested_source_errors_instead_of_aborting() {
|
|
41
|
+
let n = 50_000;
|
|
42
|
+
for (open, close) in [("(", ")"), ("[", "]")] {
|
|
43
|
+
let src = format!("let x = {}1{}", open.repeat(n), close.repeat(n));
|
|
44
|
+
let r = parse(&src);
|
|
45
|
+
assert!(r.is_err(), "{n}× nested {open} should be a catchable Err, not an abort");
|
|
46
|
+
assert!(
|
|
47
|
+
r.unwrap_err().contains("nesting too deep"),
|
|
48
|
+
"expected a depth-limit error"
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
let prefix = format!("let x = {}1", "-".repeat(n));
|
|
52
|
+
assert!(parse(&prefix).is_err(), "deep prefix-op chain should error, not abort");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// The depth guard must not reject ordinary, modestly-nested code.
|
|
56
|
+
#[test]
|
|
57
|
+
fn normal_nesting_still_parses() {
|
|
58
|
+
assert!(parse("let x = ((((1 + 2))))").is_ok());
|
|
59
|
+
assert!(parse("let y = [[1, 2], [3, [4, [5]]]]").is_ok());
|
|
60
|
+
assert!(parse("fn f() { if (a) { if (b) { return 1 } } }").is_ok());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// #244: loose equality `==` / `!=` is rejected uniformly at parse (across every backend), with an
|
|
64
|
+
/// actionable message pointing at the strict form. `===` / `!==` still parse.
|
|
65
|
+
#[test]
|
|
66
|
+
fn loose_equality_is_rejected_at_parse() {
|
|
67
|
+
let eq = parse("let b = 1 == 1").unwrap_err();
|
|
68
|
+
assert!(eq.contains("'=='") && eq.contains("'==='"), "got: {eq}");
|
|
69
|
+
let ne = parse("let b = 1 != 2").unwrap_err();
|
|
70
|
+
assert!(ne.contains("'!='") && ne.contains("'!=='"), "got: {ne}");
|
|
71
|
+
// Rejected wherever an expression is parsed, not just at top level.
|
|
72
|
+
assert!(parse("fn f(x) { if (x == 0) { return 1 } return 0 }").is_err());
|
|
73
|
+
assert!(parse("let y = a != null && a.b").is_err());
|
|
74
|
+
// Strict forms are unaffected.
|
|
75
|
+
assert!(parse("let b = 1 === 1").is_ok());
|
|
76
|
+
assert!(parse("let b = 1 !== 2").is_ok());
|
|
77
|
+
assert!(parse("let y = a !== null && a.b").is_ok());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// #428: `async` in expression position parses as an async arrow (paren and single-param forms);
|
|
81
|
+
/// non-async arrows keep `async_: false`.
|
|
82
|
+
#[test]
|
|
83
|
+
fn async_arrow_expressions_parse() {
|
|
84
|
+
use tishlang_ast::Expr;
|
|
85
|
+
let arrow_async = |src: &str| -> bool {
|
|
86
|
+
let p = parse(src).expect("parse");
|
|
87
|
+
let Some(Statement::VarDecl { init: Some(e), .. }) = p.statements.first() else {
|
|
88
|
+
panic!("expected `let x = <arrow>`");
|
|
89
|
+
};
|
|
90
|
+
match e {
|
|
91
|
+
Expr::ArrowFunction { async_, .. } => *async_,
|
|
92
|
+
other => panic!("expected ArrowFunction, got {other:?}"),
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
assert!(arrow_async("let f = async () => 1"), "async paren arrow");
|
|
96
|
+
assert!(arrow_async("let g = async x => x + 1"), "async single-param arrow");
|
|
97
|
+
assert!(arrow_async("let h = async (a, b) => a + b"), "async multi-param arrow");
|
|
98
|
+
assert!(!arrow_async("let f = () => 1"), "plain arrow is not async");
|
|
99
|
+
assert!(!arrow_async("let g = x => x"), "plain single-param arrow is not async");
|
|
100
|
+
// `async` not followed by an arrow in expr position is an error, not a silent identifier.
|
|
101
|
+
assert!(parse("let x = async 5").is_err());
|
|
102
|
+
}
|
|
103
|
+
|
|
36
104
|
#[test]
|
|
37
105
|
fn test_async_fn_parse() {
|
|
38
106
|
let program = parse("async fn foo() { }").expect("parse async fn");
|