diff --git a/baml_language/Cargo.lock b/baml_language/Cargo.lock index c2b29a408c..2f2f5396ab 100644 --- a/baml_language/Cargo.lock +++ b/baml_language/Cargo.lock @@ -621,6 +621,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "serde_core", + "serde_json", "serde_path_to_error", "serde_urlencoded", "sha1", @@ -988,6 +989,7 @@ dependencies = [ "baml_compiler_parser", "baml_compiler_syntax", "baml_workspace", + "bitflags 2.11.1", "indexmap", "insta", "rowan 0.16.1", @@ -7684,6 +7686,21 @@ dependencies = [ name = "tools_sccache" version = "0.1.0" +[[package]] +name = "tools_semantic_tokens" +version = "0.0.0-beta" +dependencies = [ + "anyhow", + "axum", + "baml_lsp2_actions", + "baml_lsp2_actions_tests", + "baml_project", + "clap", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "tower" version = "0.5.3" diff --git a/baml_language/Cargo.toml b/baml_language/Cargo.toml index a502eaa1fa..38cc325d9c 100644 --- a/baml_language/Cargo.toml +++ b/baml_language/Cargo.toml @@ -81,6 +81,7 @@ sys_native = { path = "crates/sys_native", default-features = false } baml_db = { path = "crates/baml_db" } baml_fmt = { path = "crates/baml_fmt" } baml_lsp2_actions = { path = "crates/baml_lsp2_actions" } +baml_lsp2_actions_tests = { path = "crates/baml_lsp2_actions_tests" } baml_lsp_server = { path = "crates/baml_lsp_server", default-features = false } baml_project = { path = "crates/baml_project" } baml_release = { path = "crates/baml_release" } @@ -128,6 +129,7 @@ aws-sigv4 = { path = "forks/aws-sigv4", package = "forked_aws_sigv4" } aws-bedrock = { path = "forks/aws-bedrock", package = "forked_aws_bedrock" } google-cloud-auth = { path = "forks/google-cloud-auth", package = "forked_google_cloud_auth" } axum = { version = "0.8.4", default-features = false, features = [ "http1", "matched-path", "original-uri", "query", "tokio", "ws" ] } +bitflags = "2" # Native `borsh` derives on the entire Program type graph (bex_vm_types + # baml_type + baml_exec envelope). The pack envelope was previously # bitcode-with-serde; borsh's native derive avoids both the bitcode crate diff --git a/baml_language/crates/baml_cli/src/paint.rs b/baml_language/crates/baml_cli/src/paint.rs index c9181a77d6..0e324bacb2 100644 --- a/baml_language/crates/baml_cli/src/paint.rs +++ b/baml_language/crates/baml_cli/src/paint.rs @@ -103,7 +103,8 @@ fn style_for(token_type: SemanticTokenType) -> Style { T::Parameter => Style::new().color256(173), T::Namespace => Style::new().cyan().bright(), T::String | T::Regexp => Style::new().green(), - T::Number => Style::new().yellow().bright(), + T::EscapeSequence => Style::new().color256(214), + T::Number | T::Boolean => Style::new().yellow().bright(), T::Comment => Style::new().color256(244), T::Decorator => Style::new().color256(179), T::Operator => Style::new().color256(245), diff --git a/baml_language/crates/baml_compiler2_ast/src/lower_expr_body.rs b/baml_language/crates/baml_compiler2_ast/src/lower_expr_body.rs index 9e816d76b1..fcea22c614 100644 --- a/baml_language/crates/baml_compiler2_ast/src/lower_expr_body.rs +++ b/baml_language/crates/baml_compiler2_ast/src/lower_expr_body.rs @@ -52,6 +52,14 @@ fn is_ident_token(kind: SyntaxKind) -> bool { | SyntaxKind::KW_INTERFACE | SyntaxKind::KW_EXTENDS | SyntaxKind::KW_REQUIRES + // Contextual keywords re-lexed from a `Word`: still lower by text + // (the literal/identifier arms below switch on the text), so they + // must read as ident tokens just as they did when they were `Word`. + | SyntaxKind::KW_AS + | SyntaxKind::KW_TYPE + | SyntaxKind::KW_TRUE + | SyntaxKind::KW_FALSE + | SyntaxKind::KW_NULL ) } diff --git a/baml_language/crates/baml_compiler2_hir/src/builder.rs b/baml_language/crates/baml_compiler2_hir/src/builder.rs index 967249871b..d1074a71d5 100644 --- a/baml_language/crates/baml_compiler2_hir/src/builder.rs +++ b/baml_language/crates/baml_compiler2_hir/src/builder.rs @@ -960,7 +960,7 @@ impl<'db> SemanticIndexBuilder<'db> { let binding_visible_from = source_map.pattern_span(clause.binding).start(); self.register_local_pattern( clause.binding, - DefinitionSite::PatternBinding(clause.binding), + DefinitionSite::CatchBinding(clause.binding), body, source_map, binding_visible_from, @@ -969,7 +969,7 @@ impl<'db> SemanticIndexBuilder<'db> { let st_visible_from = source_map.pattern_span(st_pat).start(); self.register_local_pattern( st_pat, - DefinitionSite::PatternBinding(st_pat), + DefinitionSite::CatchBinding(st_pat), body, source_map, st_visible_from, @@ -1435,6 +1435,7 @@ impl<'db> SemanticIndexBuilder<'db> { self.class_depth -= 1; let local_id = self.item_tree.alloc_interface(i, default_method_ids); + ItemTree::collect_interface_spans(&mut self.item_tree_source_map, local_id, i); let loc = InterfaceLoc::new(self.db, self.file, local_id); self.type_contributions.push(( i.name.clone(), diff --git a/baml_language/crates/baml_compiler2_hir/src/item_tree.rs b/baml_language/crates/baml_compiler2_hir/src/item_tree.rs index 627c3ff0e8..cd52ada06e 100644 --- a/baml_language/crates/baml_compiler2_hir/src/item_tree.rs +++ b/baml_language/crates/baml_compiler2_hir/src/item_tree.rs @@ -370,6 +370,11 @@ pub struct ItemTreeSourceMap { pub enum_variant_spans: FxHashMap, Vec>, /// `name_span` for each function. pub function_name_spans: FxHashMap, TextRange>, + /// `name_span` for each interface's fields, parallel to `Interface::fields`. + pub interface_field_spans: FxHashMap, Vec>, + /// `name_span` for each interface's required methods, parallel to + /// `Interface::required_methods`. + pub interface_method_spans: FxHashMap, Vec>, } // ── ItemTree ───────────────────────────────────────────────────────────────── @@ -624,6 +629,22 @@ impl ItemTree { source_map.enum_variant_spans.insert(id, spans); } + /// Populate source map spans for an interface allocated via `alloc_interface`. + pub fn collect_interface_spans( + source_map: &mut ItemTreeSourceMap, + id: LocalItemId, + iface_def: &ast::InterfaceDef, + ) { + let field_spans: Vec = iface_def.fields.iter().map(|f| f.name_span).collect(); + source_map.interface_field_spans.insert(id, field_spans); + let method_spans: Vec = iface_def + .required_methods + .iter() + .map(|m| m.name_span) + .collect(); + source_map.interface_method_spans.insert(id, method_spans); + } + /// Allocate an interface (BEP-044) in the `ItemTree`. /// /// `default_method_ids` are the `FunctionMarker` ids for any default diff --git a/baml_language/crates/baml_compiler2_hir/src/semantic_index.rs b/baml_language/crates/baml_compiler2_hir/src/semantic_index.rs index c38c45877e..4f2c7883b9 100644 --- a/baml_language/crates/baml_compiler2_hir/src/semantic_index.rs +++ b/baml_language/crates/baml_compiler2_hir/src/semantic_index.rs @@ -50,8 +50,12 @@ pub enum DefinitionSite { Statement(StmtId), /// Defined as a function parameter (with its index). Parameter(usize), - /// Defined by a pattern binding (match arm, catch arm, catch clause, etc.). + /// Defined by a pattern binding (match arm, if-let, etc.). PatternBinding(PatId), + /// The error (and optional stack-trace) binding of a `catch (e) { … }` + /// clause. Like a function parameter — a value bound by the clause and + /// scoped to its body — so it is highlighted as a parameter. + CatchBinding(PatId), } // ── BindingId ──────────────────────────────────────────────────────────────── diff --git a/baml_language/crates/baml_compiler2_mir/src/lower.rs b/baml_language/crates/baml_compiler2_mir/src/lower.rs index 1f970e733e..e3ae7f4fef 100644 --- a/baml_language/crates/baml_compiler2_mir/src/lower.rs +++ b/baml_language/crates/baml_compiler2_mir/src/lower.rs @@ -2935,8 +2935,21 @@ impl<'db> LoweringContext<'db> { } } - fn pattern_binding_is_captured(&self, pattern: AstPatId) -> bool { - self.any_pattern_binding_is_captured(pattern, DefinitionSite::PatternBinding(pattern)) + // Catch-clause bindings (`catch (e, ctx)`) are registered in the semantic + // index under `DefinitionSite::CatchBinding`, not `PatternBinding`, so the + // catch-lowering paths must query with the matching site. + fn record_catch_binding_local(&mut self, pattern: AstPatId, name: &Name, local: Local) { + if let Some(binding_id) = self.binding_id_for_pattern_site_name( + pattern, + DefinitionSite::CatchBinding(pattern), + name, + ) { + self.binding_locals.insert(binding_id, local); + } + } + + fn catch_binding_is_captured(&self, pattern: AstPatId) -> bool { + self.any_pattern_binding_is_captured(pattern, DefinitionSite::CatchBinding(pattern)) } fn binding_id_for_name_at(&self, expr_id: AstExprId, name: &Name) -> Option { @@ -14216,7 +14229,7 @@ impl LoweringContext<'_> { // shows up in bytecode instead of an anonymous `_N` temp. Only do this // for single-clause catches with a non-captured binding. let single_clause_binding_name = clauses.first().and_then(|c| { - if clauses.len() == 1 && !self.pattern_binding_is_captured(c.binding) { + if clauses.len() == 1 && !self.catch_binding_is_captured(c.binding) { self.body.patterns[c.binding] .binding_name(&self.body.patterns) .cloned() @@ -14252,7 +14265,7 @@ impl LoweringContext<'_> { let binding_name = self.body.patterns[clause.binding] .binding_name(&self.body.patterns) .cloned(); - let binding_is_captured = self.pattern_binding_is_captured(clause.binding); + let binding_is_captured = self.catch_binding_is_captured(clause.binding); let (binding_local, binding_copy_local) = match binding_name.clone() { Some(name) if binding_is_captured => { let local = self.builder.declare_local( @@ -14263,11 +14276,11 @@ impl LoweringContext<'_> { None, false, ); - self.record_pattern_binding_local(clause.binding, &name, local); + self.record_catch_binding_local(clause.binding, &name, local); (Some(local), Some(local)) } Some(name) => { - self.record_pattern_binding_local(clause.binding, &name, error_local); + self.record_catch_binding_local(clause.binding, &name, error_local); (Some(error_local), None) } None => (None, None), @@ -14279,7 +14292,7 @@ impl LoweringContext<'_> { let name = self.body.patterns[st_pat] .binding_name(&self.body.patterns) .cloned(); - let is_captured = self.pattern_binding_is_captured(st_pat); + let is_captured = self.catch_binding_is_captured(st_pat); match name.clone() { Some(name) if is_captured => { let local = self.builder.declare_local( @@ -14290,11 +14303,11 @@ impl LoweringContext<'_> { None, false, ); - self.record_pattern_binding_local(st_pat, &name, local); + self.record_catch_binding_local(st_pat, &name, local); (Some(name), Some(local)) } Some(name) => { - self.record_pattern_binding_local(st_pat, &name, payload); + self.record_catch_binding_local(st_pat, &name, payload); (Some(name), Some(payload)) } None => (None, None), diff --git a/baml_language/crates/baml_compiler2_tir/src/inference.rs b/baml_language/crates/baml_compiler2_tir/src/inference.rs index cdc29262ba..12d600dfa9 100644 --- a/baml_language/crates/baml_compiler2_tir/src/inference.rs +++ b/baml_language/crates/baml_compiler2_tir/src/inference.rs @@ -160,6 +160,108 @@ pub(crate) fn inference_owner_scope( } } +/// The expression body + source map of an inference-bearing scope, plus the +/// scope id to feed `infer_scope_types`. +#[derive(Clone)] +pub struct ScopeBody<'db> { + /// The inference-owner scope (`Function` / `Let` / `Lambda`). + pub scope: ScopeId<'db>, + pub expr_body: ExprBody, + pub source_map: AstSourceMap, +} + +/// The body + source map of the scope that owns `scope_id`'s inference (its +/// nearest `Function` / `Let` / `Lambda`) — the uniform map from a scope to its +/// expression body, covering function bodies, top-level `let` initializers, and +/// lambda/closure bodies (including nested ones and `spawn`/block bodies that +/// lower to closures). +/// +/// The single place that resolves a scope to its body, so consumers (e.g. the +/// LSP semantic layer) never reimplement the per-scope-kind lookup that +/// `infer_scope_types` performs internally. +pub fn scope_body<'db>(db: &'db dyn crate::Db, scope_id: ScopeId<'db>) -> Option> { + let file = scope_id.file(db); + let index = baml_compiler2_ppir::file_semantic_index(db, file); + let owner = inference_owner_scope(index, scope_id.file_scope_id(db)); + let (expr_body, source_map) = fetch_scope_body(db, file, index, owner)?; + Some(ScopeBody { + scope: index.scope_ids[owner.index() as usize], + expr_body, + source_map, + }) +} + +/// The inference-owner scope of `scope_id` (its nearest enclosing `Function` / +/// `Let` / `Lambda` body) WITHOUT fetching or cloning the body — the cheap +/// key-normalization counterpart to [`scope_body`]. Use it to memoize a +/// per-body index (e.g. the LSP `scope_resolution_index`) under one stable +/// Salsa key, so sibling block/template scopes that share an owner don't each +/// rebuild the same body index under a distinct key. +pub fn scope_inference_owner<'db>(db: &'db dyn crate::Db, scope_id: ScopeId<'db>) -> ScopeId<'db> { + let index = baml_compiler2_ppir::file_semantic_index(db, scope_id.file(db)); + let owner = inference_owner_scope(index, scope_id.file_scope_id(db)); + index.scope_ids[owner.index() as usize] +} + +/// Fetch the `(ExprBody, AstSourceMap)` for an inference-owner scope. +fn fetch_scope_body<'db>( + db: &'db dyn crate::Db, + file: SourceFile, + index: &baml_compiler2_hir::semantic_index::FileSemanticIndex<'db>, + owner: FileScopeId, +) -> Option<(ExprBody, AstSourceMap)> { + let scope = &index.scopes[owner.index() as usize]; + match scope.kind { + ScopeKind::Function => { + let item_tree = baml_compiler2_ppir::file_item_tree(db, file); + let (local_id, _) = item_tree + .functions + .iter() + .find(|(_, f)| f.span == scope.range && scope.name.as_ref() == Some(&f.name))?; + let func_loc = baml_compiler2_hir::loc::FunctionLoc::new(db, file, *local_id); + let body = baml_compiler2_ppir::function_body(db, func_loc); + let baml_compiler2_hir::body::FunctionBody::Expr(eb) = body.as_ref() else { + return None; + }; + let sm = baml_compiler2_ppir::function_body_source_map(db, func_loc)?; + Some((eb.clone(), sm)) + } + ScopeKind::Let => { + let item_tree = baml_compiler2_ppir::file_item_tree(db, file); + let (local_id, _) = item_tree + .lets + .iter() + .find(|(_, l)| l.span == scope.range && scope.name.as_ref() == Some(&l.name))?; + let let_loc = baml_compiler2_hir::loc::LetLoc::new(db, file, *local_id); + let body = baml_compiler2_hir::body::let_body(db, let_loc); + let baml_compiler2_hir::body::LetBody::Expr(eb) = body.as_ref() else { + return None; + }; + let sm = baml_compiler2_hir::body::let_body_source_map(db, let_loc)?; + Some((eb.clone(), sm)) + } + ScopeKind::Lambda => { + // The lambda body is nested inside the enclosing Function/Let body; + // descend to it by span. + let mut parent = scope.parent; + let enclosing = loop { + let p = parent?; + if matches!( + index.scopes[p.index() as usize].kind, + ScopeKind::Function | ScopeKind::Let + ) { + break p; + } + parent = index.scopes[p.index() as usize].parent; + }; + let (eb, sm) = fetch_scope_body(db, file, index, enclosing)?; + let (_, lambda_body, lambda_sm, _) = find_lambda_by_span(&eb, &sm, scope.range)?; + Some((lambda_body.clone(), lambda_sm.clone())) + } + _ => None, + } +} + fn enclosing_type_generics( item_tree: &baml_compiler2_hir::item_tree::ItemTree, type_name: &Name, diff --git a/baml_language/crates/baml_compiler2_tir/src/resolve.rs b/baml_language/crates/baml_compiler2_tir/src/resolve.rs index 7df1bb6c43..ce465178c9 100644 --- a/baml_language/crates/baml_compiler2_tir/src/resolve.rs +++ b/baml_language/crates/baml_compiler2_tir/src/resolve.rs @@ -192,3 +192,119 @@ pub fn resolve_path_at<'db>( ResolvedName::Unknown } + +/// Resolve a path *prefix* that names a namespace — a package (`baml`, `root`) +/// and/or a namespace within it (`baml.json`, `root.llm`). +/// +/// Unlike item resolution this answers "is this prefix a real namespace at all", +/// so a prefix that names nothing (a typo) returns `None` and can stay neutral +/// instead of being painted as a bogus namespace. `Some(is_builtin)` reports +/// whether the namespace lives in a builtin / dependency package (`baml`, ...) +/// rather than the file's own package, so the caller can mark it `defaultLibrary`. +pub fn resolve_namespace_prefix( + db: &dyn crate::Db, + file: SourceFile, + segments: &[Name], +) -> Option { + let first = segments.first()?; + let pkg_info = baml_compiler2_hir::file_package::file_package(db, file); + let own_pkg_id = PackageId::new(db, pkg_info.package); + let res_ctx = crate::package_interface::package_resolution_context(db, own_pkg_id); + + // Segment 0 is a package: `root` is the file's own package; anything else is + // a literal package name. + let pkg_name = if first.as_str() == "root" { + res_ctx.own_package_name.clone() + } else { + first.clone() + }; + let pkg_items = res_ctx.items_for_package(db, &pkg_name)?; + + // The remaining segments must be a (possibly empty) prefix of a real + // namespace path in that package. Empty = the package root itself. + let ns_prefix = &segments[1..]; + let is_namespace = ns_prefix.is_empty() + || pkg_items + .namespaces + .keys() + .any(|k| k.starts_with(ns_prefix)); + if !is_namespace { + return None; + } + + Some(pkg_name.as_str() != res_ctx.own_package_name.as_str()) +} + +/// Resolve `Enum.Variant` — the leaf of an enum-rooted type path, e.g. the +/// `North` in a match pattern `Direction.North` (a type expression). +/// +/// Goes through the same package-resolution system as item/namespace lookup: +/// `resolve_path_at` resolves the prefix (local or `baml`/dep, possibly +/// namespaced) to an enum, then the leaf is verified against that enum's actual +/// variants. Returns `true` only for a real variant, so a typo'd `Enum.Nope` +/// stays a plain type rather than a bogus `enumMember`. +pub fn resolve_enum_variant( + db: &dyn crate::Db, + file: SourceFile, + at_offset: TextSize, + segments: &[Name], +) -> bool { + let Some((variant, prefix)) = segments.split_last() else { + return false; + }; + if prefix.is_empty() { + return false; + } + let (ResolvedName::Item(def) | ResolvedName::Builtin(def)) = + resolve_path_at(db, file, at_offset, prefix, None) + else { + return false; + }; + let Definition::Enum(enum_loc) = def else { + return false; + }; + let item_tree = baml_compiler2_ppir::file_item_tree(db, enum_loc.file(db)); + item_tree[enum_loc.id(db)] + .variants + .iter() + .any(|v| v.name == *variant) +} + +/// Resolve a field `field` of the type named by `type_segments` (a class or +/// interface), through the same package-resolution system as item/namespace/ +/// variant lookup. Returns `true` only when the field actually exists on that +/// type — used to classify the two sides of an interface field link +/// (`name as display_name`) as `property` only when they resolve. +pub fn resolve_field( + db: &dyn crate::Db, + file: SourceFile, + at_offset: TextSize, + type_segments: &[Name], + field: &Name, +) -> bool { + if type_segments.is_empty() { + return false; + } + let (ResolvedName::Item(def) | ResolvedName::Builtin(def)) = + resolve_path_at(db, file, at_offset, type_segments, None) + else { + return false; + }; + match def { + Definition::Class(loc) => { + let item_tree = baml_compiler2_ppir::file_item_tree(db, loc.file(db)); + item_tree[loc.id(db)] + .fields + .iter() + .any(|f| f.name == *field) + } + Definition::Interface(loc) => { + let item_tree = baml_compiler2_ppir::file_item_tree(db, loc.file(db)); + item_tree[loc.id(db)] + .fields + .iter() + .any(|f| f.name == *field) + } + _ => false, + } +} diff --git a/baml_language/crates/baml_compiler_parser/src/parser.rs b/baml_language/crates/baml_compiler_parser/src/parser.rs index 44d77112b8..d145b8e14e 100644 --- a/baml_language/crates/baml_compiler_parser/src/parser.rs +++ b/baml_language/crates/baml_compiler_parser/src/parser.rs @@ -1799,11 +1799,13 @@ impl<'a> Parser<'a> { hashes_seen += 1; i += 1; if hashes_seen == hash_count { - // Found all hashes, now skip basic trivia to find next token + // Found all hashes, now skip basic trivia to find next token. while i < self.tokens.len() && self.is_basic_trivia(self.tokens[i].kind) { i += 1; } - return Some(i); + // `None` if the hashes run to EOF with no token after them, + // so callers never index past the end on incomplete input. + return (i < self.tokens.len()).then_some(i); } } else if self.is_basic_trivia(token.kind) { i += 1; @@ -1966,7 +1968,9 @@ impl<'a> Parser<'a> { // Must be followed by opening quote - check after consuming hashes // We need to peek ahead past the hashes to see if there's a quote let quote_pos = self.find_token_after_hashes(opening_hashes); - if quote_pos.is_none() || quote_pos.map(|i| self.tokens[i].kind) != Some(TokenKind::Quote) { + // `find_token_after_hashes` can point at the EOF slot (== tokens.len()) + // on incomplete input, so index through `get` rather than `[]`. + if quote_pos.and_then(|i| self.tokens.get(i)).map(|t| t.kind) != Some(TokenKind::Quote) { // Just hashes, not a raw string return false; } @@ -3074,7 +3078,7 @@ impl<'a> Parser<'a> { self.expect(TokenKind::LParen); self.parse_type(); if self.at_contextual_kw("as") { - self.bump(); + self.bump_contextual_kw_as("as", SyntaxKind::KW_AS); } else { self.error_unexpected_token("`as`".to_string()); } @@ -3728,7 +3732,7 @@ impl<'a> Parser<'a> { } if p.at_contextual_kw("as") { - p.bump(); + p.bump_contextual_kw_as("as", SyntaxKind::KW_AS); } else { p.error_unexpected_token("`as`".to_string()); } @@ -3821,7 +3825,7 @@ impl<'a> Parser<'a> { fn parse_associated_type_decl(&mut self, require_binding: bool) { self.with_node(SyntaxKind::ASSOCIATED_TYPE_DECL, |p| { if p.at_contextual_kw("type") { - p.bump(); + p.bump_contextual_kw_as("type", SyntaxKind::KW_TYPE); } else { p.error_unexpected_token("`type`".to_string()); } @@ -5984,7 +5988,7 @@ impl<'a> Parser<'a> { let lhs_start = self.find_previous_expr_start_after(expr_start); self.wrap_events_in_node(lhs_start, SyntaxKind::UPCAST_EXPR); self.bump(); // . - self.bump(); // contextual `as` + self.bump_contextual_kw_as("as", SyntaxKind::KW_AS); self.parse_generic_args(); self.finish_node(); } else if op == TokenKind::Dot || op == TokenKind::Dollar { @@ -6367,12 +6371,12 @@ impl<'a> Parser<'a> { { // env.FIELD sugar (not followed by `(`) — desugar to baml.env.get_or_panic("FIELD") self.parse_env_access(); - } else if text == "true" || text == "false" { - // Boolean literal - self.bump(); + } else if text == "true" { + self.bump_contextual_kw_as("true", SyntaxKind::KW_TRUE); + } else if text == "false" { + self.bump_contextual_kw_as("false", SyntaxKind::KW_FALSE); } else if text == "null" { - // Null literal - self.bump(); + self.bump_contextual_kw_as("null", SyntaxKind::KW_NULL); } else { // Identifier or path (could be multi-segment like baml.HttpMethod.Get) self.parse_path_or_ident(); @@ -7911,7 +7915,7 @@ impl<'a> Parser<'a> { self.with_node(SyntaxKind::TYPE_ALIAS_DEF, |p| { // 'type' keyword if p.at(TokenKind::Word) && p.current().map(|t| t.text == "type").unwrap_or(false) { - p.bump(); + p.bump_contextual_kw_as("type", SyntaxKind::KW_TYPE); } else { p.error_unexpected_token("'type' keyword".to_string()); } diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index f08373a2af..a217d5ff54 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -186,6 +186,49 @@ ast_node!(TypeExpr, TYPE_EXPR); ast_node!(Attribute, ATTRIBUTE); ast_node!(TypeBuilderBlock, TYPE_BUILDER_BLOCK); ast_node!(DynamicTypeDef, DYNAMIC_TYPE_DEF); +ast_node!(ObjectField, OBJECT_FIELD); +ast_node!(GenericParam, GENERIC_PARAM); + +impl CallArg { + /// The name of a named argument `name = value` — a leading `WORD` (or + /// `client`) immediately followed by `=`. `None` for a positional argument + /// (whose first element is the value expression, not a name token). + pub fn name(&self) -> Option { + let mut elements = self + .syntax + .children_with_tokens() + .filter(|element| !element.kind().is_trivia()); + let first = elements.next()?.into_token()?; + if !matches!(first.kind(), SyntaxKind::WORD | SyntaxKind::KW_CLIENT) { + return None; + } + (elements.next()?.kind() == SyntaxKind::EQUALS).then_some(first) + } +} + +impl ObjectField { + /// The bare-word key of `key: value` (or shorthand `key`). + /// + /// `None` when the key is a string literal (`"key": value`): such a key is a + /// child node, not a bare word. + pub fn key(&self) -> Option { + self.syntax + .children_with_tokens() + .find(|element| !element.kind().is_trivia()) + .and_then(rowan::NodeOrToken::into_token) + .filter(|token| matches!(token.kind(), SyntaxKind::WORD | SyntaxKind::KW_CLIENT)) + } +} + +impl GenericParam { + /// The declared parameter name (`T` in ``). + pub fn name(&self) -> Option { + self.syntax + .children_with_tokens() + .filter_map(rowan::NodeOrToken::into_token) + .find(|token| token.kind() == SyntaxKind::WORD) + } +} /// Parts of a union member for token-based parsing. /// @@ -338,11 +381,7 @@ impl UnionMemberParts { { return None; } - if !self - .tokens - .iter() - .any(|t| t.kind() == SyntaxKind::WORD && t.text() == "as") - { + if !self.tokens.iter().any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } let dot_idx = self @@ -466,10 +505,7 @@ impl TypeExpr { { return None; } - if !tokens - .iter() - .any(|t| t.kind() == SyntaxKind::WORD && t.text() == "as") - { + if !tokens.iter().any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } let dot_idx = tokens.iter().rposition(|t| t.kind() == SyntaxKind::DOT)?; @@ -2137,7 +2173,7 @@ impl InterfaceFieldLink { .find(|token| { !token.kind().is_trivia() && is_member_name_token(token.kind()) - && !(token.kind() == SyntaxKind::WORD && token.text() == "as") + && token.kind() != SyntaxKind::KW_AS }) } @@ -2150,7 +2186,7 @@ impl InterfaceFieldLink { .filter_map(rowan::NodeOrToken::into_token) .filter(|token| !token.kind().is_trivia()) { - if token.kind() == SyntaxKind::WORD && token.text() == "as" { + if token.kind() == SyntaxKind::KW_AS { after_as = true; continue; } @@ -2166,7 +2202,7 @@ impl InterfaceFieldLink { self.syntax .children_with_tokens() .filter_map(rowan::NodeOrToken::into_token) - .find(|token| token.kind() == SyntaxKind::WORD && token.text() == "as") + .find(|token| token.kind() == SyntaxKind::KW_AS) } } @@ -2793,16 +2829,15 @@ impl TestDef { } impl TypeAliasDef { - /// Get the type alias name. - /// Note: "type" is parsed as a WORD token, not a keyword, so we skip it. + /// Get the type alias name — the first direct WORD child (the `type` + /// keyword is a `KW_TYPE` token, so no skipping is needed). pub fn name(&self) -> Option { self.syntax .children_with_tokens() .filter_map(rowan::NodeOrToken::into_token) - .filter(|token| { + .find(|token| { token.kind() == SyntaxKind::WORD && token.parent() == Some(self.syntax.clone()) }) - .nth(1) // Skip "type" keyword (which is a WORD), get the actual name } /// Get the aliased type expression. @@ -3740,7 +3775,11 @@ impl BlockExpr { | SyntaxKind::INTEGER_LITERAL | SyntaxKind::FLOAT_LITERAL | SyntaxKind::STRING_LITERAL - | SyntaxKind::RAW_STRING_LITERAL => Some(BlockElement::ExprToken(t)), + | SyntaxKind::RAW_STRING_LITERAL + // Boolean / null literals are re-lexed contextual keywords. + | SyntaxKind::KW_TRUE + | SyntaxKind::KW_FALSE + | SyntaxKind::KW_NULL => Some(BlockElement::ExprToken(t)), _ => None, } } diff --git a/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs b/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs index dd2b57b9f2..fc01def5df 100644 --- a/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs +++ b/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs @@ -52,6 +52,12 @@ pub enum SyntaxKind { KW_IS, KW_DYNAMIC, KW_WITH, + // Contextual keywords re-lexed from a `Word` at parse time (no lexer token). + KW_AS, // `.as` cast / `(T as I)` / `field as field` + KW_TYPE, // associated-type / type-alias `type Name ...` + KW_TRUE, // `true` boolean literal + KW_FALSE, // `false` boolean literal + KW_NULL, // `null` literal // Literals WORD, // Any word (non-keyword identifier) @@ -547,6 +553,7 @@ impl SyntaxKind { | Self::KW_LET | Self::KW_CONST | Self::KW_IN + | Self::KW_IS | Self::KW_BREAK | Self::KW_CONTINUE | Self::KW_RETURN @@ -562,6 +569,9 @@ impl SyntaxKind { | Self::KW_WATCH | Self::KW_INSTANCEOF | Self::KW_DYNAMIC + | Self::KW_WITH + | Self::KW_AS + | Self::KW_TYPE ) } } diff --git a/baml_language/crates/baml_fmt/src/ast/declarations.rs b/baml_language/crates/baml_fmt/src/ast/declarations.rs index ffd7da1ac7..7663e9f073 100644 --- a/baml_language/crates/baml_fmt/src/ast/declarations.rs +++ b/baml_language/crates/baml_fmt/src/ast/declarations.rs @@ -1349,7 +1349,7 @@ impl Printable for ImplementsTarget { /// BEP-057 associated type declaration or implementation witness. #[derive(Debug)] pub struct AssociatedTypeDecl { - pub keyword: t::Word, + pub keyword: t::TypeKw, pub name: t::Word, pub bound: Option<(t::Extends, Type)>, pub default: Option<(t::Equals, Type)>, @@ -1438,7 +1438,7 @@ impl Printable for AssociatedTypeDecl { #[derive(Debug)] pub struct InterfaceFieldLink { pub interface_field: t::Word, - pub as_token: t::Word, + pub as_token: t::As, pub class_field: t::Word, } @@ -3307,8 +3307,7 @@ impl Printable for TemplateStringDecl { /// Corresponds to a [`SyntaxKind::TYPE_ALIAS_DEF`] node. #[derive(Debug)] pub struct TypeAliasDecl { - /// For some reason, type is not currently a keyword - pub keyword: t::Word, + pub keyword: t::TypeKw, pub name: t::Word, pub equals: t::Equals, pub type_expr: Type, @@ -3322,7 +3321,7 @@ impl FromCST for TypeAliasDecl { let mut it = SyntaxNodeIter::new(&node); - // keyword: "type" (it's actually just a WORD, not a keyword) + // keyword: `type` (KW_TYPE) let keyword = it.expect_parse()?; // name diff --git a/baml_language/crates/baml_fmt/src/ast/expressions.rs b/baml_language/crates/baml_fmt/src/ast/expressions.rs index 5bb925934f..375cabf7e3 100644 --- a/baml_language/crates/baml_fmt/src/ast/expressions.rs +++ b/baml_language/crates/baml_fmt/src/ast/expressions.rs @@ -151,6 +151,9 @@ impl FromCST for Expression { SyntaxKind::FLOAT_LITERAL => Expression::Literal(Literal::Float( t::FloatLiteral::new_from_span(elem.text_range()), )), + SyntaxKind::KW_TRUE | SyntaxKind::KW_FALSE | SyntaxKind::KW_NULL => { + Literal::from_cst(elem).map(Expression::Literal)? + } SyntaxKind::WORD => PathExpr::from_cst(elem).map(Expression::Path)?, SyntaxKind::PATH_EXPR => { // The parser wraps any postfix `<...>` in a PATH_EXPR. When the @@ -414,6 +417,8 @@ pub enum Literal { String(t::QuotedString), Integer(t::IntegerLiteral), Float(t::FloatLiteral), + /// `true` / `false` / `null`. + Keyword(t::KeywordLiteral), } impl FromCST for Literal { @@ -422,8 +427,11 @@ impl FromCST for Literal { SyntaxKind::STRING_LITERAL => Ok(Literal::String(t::QuotedString::from_cst(elem)?)), SyntaxKind::INTEGER_LITERAL => Ok(Literal::Integer(t::IntegerLiteral::from_cst(elem)?)), SyntaxKind::FLOAT_LITERAL => Ok(Literal::Float(t::FloatLiteral::from_cst(elem)?)), + SyntaxKind::KW_TRUE | SyntaxKind::KW_FALSE | SyntaxKind::KW_NULL => { + Ok(Literal::Keyword(t::KeywordLiteral::from_cst(elem)?)) + } _ => Err(StrongAstError::UnexpectedKindDesc { - expected_desc: "STRING_LITERAL, INTEGER_LITERAL, or FLOAT_LITERAL".into(), + expected_desc: "a literal".into(), found: elem.kind(), at: elem.text_range(), }), @@ -445,6 +453,7 @@ impl Literal { } Literal::Integer(i) => Some(usize::from(i.span().len())), Literal::Float(f) => Some(usize::from(f.span().len())), + Literal::Keyword(k) => Some(usize::from(k.span().len())), } } } @@ -455,6 +464,7 @@ impl Printable for Literal { Literal::String(s) => printer.print_raw_token(s), Literal::Integer(i) => printer.print_raw_token(i), Literal::Float(f) => printer.print_raw_token(f), + Literal::Keyword(k) => printer.print_raw_token(k), } PrintInfo::default_single_line() } @@ -463,6 +473,7 @@ impl Printable for Literal { Literal::String(s) => s.leftmost_token(), Literal::Integer(i) => i.span(), Literal::Float(f) => f.span(), + Literal::Keyword(k) => k.span(), } } fn rightmost_token(&self) -> TextRange { @@ -470,6 +481,7 @@ impl Printable for Literal { Literal::String(s) => s.rightmost_token(), Literal::Integer(i) => i.span(), Literal::Float(f) => f.span(), + Literal::Keyword(k) => k.span(), } } } diff --git a/baml_language/crates/baml_fmt/src/ast/tokens.rs b/baml_language/crates/baml_fmt/src/ast/tokens.rs index 05a55760ec..f1f09468b2 100644 --- a/baml_language/crates/baml_fmt/src/ast/tokens.rs +++ b/baml_language/crates/baml_fmt/src/ast/tokens.rs @@ -89,6 +89,8 @@ define_keyword_tokens! { "dynamic" => SyntaxKind::KW_DYNAMIC => Dynamic; "with" => SyntaxKind::KW_WITH => With; "throws" => SyntaxKind::KW_THROWS => Throws; + "type" => SyntaxKind::KW_TYPE => TypeKw; + "as" => SyntaxKind::KW_AS => As; } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -521,6 +523,40 @@ impl KnownKind for IntegerLiteral { } } +/// A boolean / null literal — `true` (`KW_TRUE`), `false` (`KW_FALSE`), or +/// `null` (`KW_NULL`). One token type spanning the three re-lexed kinds. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct KeywordLiteral { + pub token_span: TextRange, +} +impl KeywordLiteral { + /// Does not verify that the span is actually a boolean/null literal token. + #[must_use] + pub fn new_from_span(token_span: TextRange) -> Self { + Self { token_span } + } +} +impl FromCST for KeywordLiteral { + fn from_cst(elem: SyntaxElement) -> Result { + let token = StrongAstError::assert_is_token(elem)?; + match token.kind() { + SyntaxKind::KW_TRUE | SyntaxKind::KW_FALSE | SyntaxKind::KW_NULL => { + Ok(Self::new_from_span(token.text_range())) + } + found => Err(StrongAstError::UnexpectedKindDesc { + expected_desc: "KW_TRUE, KW_FALSE, or KW_NULL".into(), + found, + at: token.text_range(), + }), + } + } +} +impl Token for KeywordLiteral { + fn span(&self) -> TextRange { + self.token_span + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FloatLiteral { pub token_span: TextRange, diff --git a/baml_language/crates/baml_fmt/src/ast/types.rs b/baml_language/crates/baml_fmt/src/ast/types.rs index 1526987de9..6281a042f5 100644 --- a/baml_language/crates/baml_fmt/src/ast/types.rs +++ b/baml_language/crates/baml_fmt/src/ast/types.rs @@ -432,7 +432,7 @@ impl UnionTypeMember { let open_paren = t::LParen::from_cst(first)?; if it.peek().map(SyntaxElement::kind) == Some(SyntaxKind::TYPE_EXPR) { let base: Type = it.expect_parse()?; - let as_token: t::Word = it.expect_parse()?; + let as_token: t::As = it.expect_parse()?; let interface: Type = it.expect_parse()?; let close_paren: t::RParen = it.expect_parse()?; let dot: t::Dot = it.expect_parse()?; @@ -755,7 +755,7 @@ impl Printable for GenericType { pub struct AssociatedProjectionType { pub open_paren: t::LParen, pub base: Box, - pub as_token: t::Word, + pub as_token: t::As, pub interface: Box, pub close_paren: t::RParen, pub dot: t::Dot, diff --git a/baml_language/crates/baml_lsp2_actions/Cargo.toml b/baml_language/crates/baml_lsp2_actions/Cargo.toml index 56c37098bc..706f7c6953 100644 --- a/baml_language/crates/baml_lsp2_actions/Cargo.toml +++ b/baml_language/crates/baml_lsp2_actions/Cargo.toml @@ -16,6 +16,7 @@ baml_compiler_diagnostics = { workspace = true } baml_compiler_parser = { workspace = true } baml_compiler_syntax = { workspace = true } sys_jinja_types = { workspace = true } +bitflags = { workspace = true } indexmap = { workspace = true } rowan = { workspace = true } salsa = { workspace = true } diff --git a/baml_language/crates/baml_lsp2_actions/src/completions.rs b/baml_language/crates/baml_lsp2_actions/src/completions.rs index f9c89788d3..0e15f45861 100644 --- a/baml_language/crates/baml_lsp2_actions/src/completions.rs +++ b/baml_language/crates/baml_lsp2_actions/src/completions.rs @@ -1323,7 +1323,8 @@ fn local_variable_ty( // StmtId is in a nested ExprBody, not the outer function's body. find_binding_ty_for_local(db, file, at_offset, site) } - baml_compiler2_hir::semantic_index::DefinitionSite::PatternBinding(_) => { + baml_compiler2_hir::semantic_index::DefinitionSite::PatternBinding(_) + | baml_compiler2_hir::semantic_index::DefinitionSite::CatchBinding(_) => { find_binding_ty_for_local(db, file, at_offset, site) } } @@ -1398,7 +1399,8 @@ fn find_binding_ty_for_local( extract_pat_from_stmt(target_body, stmt_id) } } - baml_compiler2_hir::semantic_index::DefinitionSite::PatternBinding(pat_id) => Some(pat_id), + baml_compiler2_hir::semantic_index::DefinitionSite::PatternBinding(pat_id) + | baml_compiler2_hir::semantic_index::DefinitionSite::CatchBinding(pat_id) => Some(pat_id), baml_compiler2_hir::semantic_index::DefinitionSite::Parameter(_) => None, }; diff --git a/baml_language/crates/baml_lsp2_actions/src/definition.rs b/baml_language/crates/baml_lsp2_actions/src/definition.rs index a0a5be00d3..466734c82f 100644 --- a/baml_language/crates/baml_lsp2_actions/src/definition.rs +++ b/baml_language/crates/baml_lsp2_actions/src/definition.rs @@ -149,8 +149,8 @@ fn local_definition_location( let range = sig_map.param_spans.get(param_idx).copied()?; Some(Location { file, range }) } - DefinitionSite::PatternBinding(pat_id) => { - // Navigate to the pattern binding. + DefinitionSite::PatternBinding(pat_id) | DefinitionSite::CatchBinding(pat_id) => { + // Navigate to the pattern / catch binding. let source_map = baml_compiler2_hir::body::function_body_source_map(db, func_loc)?; let range = source_map.pattern_span(pat_id); Some(Location { file, range }) @@ -423,11 +423,54 @@ fn resolve_field_access_at( range: *name_range, }) } - // A virtual interface method/field resolves only to a slot (the interface - // and the member name), not to a statically-known body or class field, so - // there is no single definition site to jump to. - MemberResolution::InterfaceVirtualMethod { .. } - | MemberResolution::InterfaceVirtualField { .. } => None, + MemberResolution::InterfaceVirtualMethod { iface_loc, method } => { + // A virtual interface-method call: only the slot (interface + name) is + // known statically, so navigate to the declaration in the interface — + // the required signature, or the default method's definition. + let target_file = iface_loc.file(db); + let target_item_tree = baml_compiler2_hir::file_item_tree(db, target_file); + let target_source_map = baml_compiler2_hir::file_item_tree_source_map(db, target_file); + let iface = &target_item_tree[iface_loc.id(db)]; + if let Some(method_idx) = iface + .required_methods + .iter() + .position(|m| m.name == *method) + { + let method_spans = target_source_map + .interface_method_spans + .get(&iface_loc.id(db))?; + return Some(Location { + file: target_file, + range: method_spans[method_idx], + }); + } + let default_id = iface + .default_methods + .iter() + .copied() + .find(|&fn_id| target_item_tree[fn_id].name == *method)?; + let name_range = target_source_map.function_name_spans.get(&default_id)?; + Some(Location { + file: target_file, + range: *name_range, + }) + } + MemberResolution::InterfaceVirtualField { iface_loc, field } => { + // A virtual interface-field access: navigate to the field declaration + // in the declaring interface. + let target_file = iface_loc.file(db); + let target_item_tree = baml_compiler2_hir::file_item_tree(db, target_file); + let target_source_map = baml_compiler2_hir::file_item_tree_source_map(db, target_file); + let iface = &target_item_tree[iface_loc.id(db)]; + let field_idx = iface.fields.iter().position(|f| f.name == *field)?; + let field_spans = target_source_map + .interface_field_spans + .get(&iface_loc.id(db))?; + Some(Location { + file: target_file, + range: field_spans[field_idx], + }) + } } } diff --git a/baml_language/crates/baml_lsp2_actions/src/definition_at_tests.rs b/baml_language/crates/baml_lsp2_actions/src/definition_at_tests.rs index 2c31dab44a..75401edcb1 100644 --- a/baml_language/crates/baml_lsp2_actions/src/definition_at_tests.rs +++ b/baml_language/crates/baml_lsp2_actions/src/definition_at_tests.rs @@ -428,4 +428,74 @@ function Foo(t: TypeValue) -> string { "Should navigate to keyword-named method 'implements', got: {desc}" ); } + + #[test] + fn test_goto_def_interface_field() { + let test = CursorTest::new( + r#" +interface Named { + fullname: string +} + +class Person { + display_name: string + + implements Named { + fullname as display_name + } +} + +function ReadName(p: Person) -> string { + return p.as.<[CURSOR]fullname +} +"#, + ); + + let loc = test.goto_definition(); + let desc = loc + .as_ref() + .map(|l| test.format_location_with_name(l)) + .unwrap_or_else(|| "No definition found".into()); + // Assert the exact target location (interface field `Named.fullname` at + // 3:3), so the test can't pass by landing on the `fullname as ...` alias + // entry or the interface header (both of which also read "-> fullname"). + assert!( + desc.contains(":3:3 -> fullname"), + "Should navigate to the interface field declaration Named.fullname (3:3), got: {desc}" + ); + } + + #[test] + fn test_goto_def_interface_method() { + let test = CursorTest::new( + r#" +interface Serializer { + function encode(self) -> string +} + +class Data { + implements Serializer { + function encode(self) -> string { return "json" } + } +} + +function PickText(d: Data) -> string { + return d.as.<[CURSOR]encode() +} +"#, + ); + + let loc = test.goto_definition(); + let desc = loc + .as_ref() + .map(|l| test.format_location_with_name(l)) + .unwrap_or_else(|| "No definition found".into()); + // Assert the exact target location (interface method `Serializer.encode` + // at 3:12), so the test can't pass by landing on the class impl method or + // the interface header (both of which also read "-> encode"). + assert!( + desc.contains(":3:12 -> encode"), + "Should navigate to the interface method declaration Serializer.encode (3:12), got: {desc}" + ); + } } diff --git a/baml_language/crates/baml_lsp2_actions/src/describe.rs b/baml_language/crates/baml_lsp2_actions/src/describe.rs index 0dd15f431d..0a13f7d7fc 100644 --- a/baml_language/crates/baml_lsp2_actions/src/describe.rs +++ b/baml_language/crates/baml_lsp2_actions/src/describe.rs @@ -550,6 +550,9 @@ fn describe_locals(db: &dyn Db, files: &[SourceFile], name: &str) -> Vec inference .binding_type(pat_id) .map(crate::utils::display_ty) diff --git a/baml_language/crates/baml_lsp2_actions/src/lib.rs b/baml_language/crates/baml_lsp2_actions/src/lib.rs index b02a07109d..7a8f90a88c 100644 --- a/baml_language/crates/baml_lsp2_actions/src/lib.rs +++ b/baml_language/crates/baml_lsp2_actions/src/lib.rs @@ -107,6 +107,8 @@ pub use listing::{ }; pub use outline::{OutlineItem, file_outline}; pub use search::{SymbolInfo, search_symbols}; -pub use tokens::{SemanticToken, SemanticTokenType, TOKEN_TYPES, semantic_tokens}; +pub use tokens::{ + ModifierSet, SemanticToken, SemanticTokenType, TOKEN_MODIFIERS, TOKEN_TYPES, semantic_tokens, +}; pub use type_info::{FunctionParamInfo, TypeInfo, type_at}; pub use usages::usages_at; diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index b9d5727fcb..f8299b118b 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -1,36 +1,41 @@ //! Semantic tokens for BAML files (compiler2 / `lsp2_actions` version). //! -//! Provides `semantic_tokens(db, file) -> Vec` using a hybrid -//! CST + compiler2 approach: +//! `semantic_tokens(db, file) -> Vec` is a single document-order +//! walk of the CST. Classification follows rust-analyzer's model: //! -//! - **Structural tokens** (keywords, comments, strings, numbers, operators) -//! come from a single CST walk with syntactic classification. +//! - **Structural tokens** (keywords, punctuation, strings, comments, numbers) +//! are classified syntactically by token kind — the syntax tree only supplies +//! positions and these non-name tokens. //! -//! - **Expression bodies** use compiler2's type-aware classification. -//! `infer_scope_types(db, scope_id)` gives `ExprId → Ty`, and -//! `function_body_source_map` gives `ExprId → TextRange`. We pre-build a -//! `TextRange → SemanticTokenType` map from these two sources and consult it -//! during the CST walk so tokens are emitted in document order without -//! sorting. +//! - **Identifiers inside expression bodies** are classified by what they +//! *resolve to*, via a pre-built resolution index (`index`) keyed by exact +//! name spans. The type system is never used to pick a tag; only resolution +//! facts (`MemberResolution`, `ResolvedName`, `DefinitionKind`) are. There is +//! no substring scanning. //! -//! - **Type expressions** in annotations use CST node kinds (already works -//! for structural classification; name resolution upgrades keyword vs -//! class vs enum). - -use std::collections::HashMap; - -use baml_base::SourceFile; -use baml_compiler_syntax::{SyntaxKind, SyntaxNode, SyntaxToken}; -use baml_compiler2_ast::{Expr, ExprBody}; -use baml_compiler2_hir::{ - body::FunctionBody, contributions::Definition, loc::FunctionLoc, scope::ScopeKind, +//! - **Declaration names** are classified by their declaring node and carry the +//! `declaration` modifier; a reference is classified the same way as its +//! definition. + +use baml_base::{Name, SourceFile}; +use baml_compiler_syntax::{ + SyntaxKind, SyntaxNode, SyntaxToken, + ast::{ + CallArg, ClassDef, GenericParam, ImplementsBlock, ImplementsTarget, InterfaceFieldLink, + ObjectField, TypeExpr, + }, }; -use baml_compiler2_tir::ty::Ty; -use rowan::NodeOrToken; -use text_size::TextRange; +use baml_compiler2_tir::resolve::{ + resolve_enum_variant, resolve_field, resolve_name_at, resolve_namespace_prefix, resolve_path_at, +}; +use rowan::{NodeOrToken, WalkEvent, ast::AstNode}; +use text_size::{TextRange, TextSize}; use crate::Db; +mod classify; +mod index; + // ── SemanticTokenType ───────────────────────────────────────────────────────── /// The semantic token type for a BAML file. @@ -63,6 +68,10 @@ pub enum SemanticTokenType { Regexp, Operator, Decorator, + EscapeSequence, + /// Boolean literal (`true` / `false`) — a custom type beyond the standard + /// LSP legend, mirroring rust-analyzer's `boolean`. + Boolean, } /// Token type legend — order determines the LSP legend index. @@ -92,6 +101,8 @@ pub const TOKEN_TYPES: &[SemanticTokenType] = &[ SemanticTokenType::Regexp, SemanticTokenType::Operator, SemanticTokenType::Decorator, + SemanticTokenType::EscapeSequence, + SemanticTokenType::Boolean, ]; impl SemanticTokenType { @@ -132,672 +143,747 @@ impl SemanticTokenType { Self::Regexp => "regexp", Self::Operator => "operator", Self::Decorator => "decorator", + Self::EscapeSequence => "escapeSequence", + Self::Boolean => "boolean", } } } +// ── Semantic token modifiers ──────────────────────────────────────────────────── + +bitflags::bitflags! { + /// LSP semantic token modifiers as a bitset (the `tokenModifiers` bitset). + /// + /// Modifiers decorate a token's base type with facts derived from what the + /// name resolves to — never from syntax. Each flag's bit is its index in + /// [`TOKEN_MODIFIERS`], which is what `server_capabilities()` advertises. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] + pub struct ModifierSet: u32 { + /// The token is the definition site (`function foo` -> `foo`). + const DECLARATION = 1 << 0; + /// The entity comes from the `baml` standard library. + const DEFAULT_LIBRARY = 1 << 1; + /// The entity is marked deprecated. + const DEPRECATED = 1 << 2; + /// The binding cannot be reassigned (e.g. a `const`). + const READONLY = 1 << 3; + /// The entity is asynchronous (an `await`/`spawn` target). + const ASYNC = 1 << 4; + } +} + +/// Modifier legend — the LSP `tokenModifiers` names in bit order. +/// +/// The order MUST match the bit positions in [`ModifierSet`] and what is +/// advertised in `server_capabilities()`. +pub const TOKEN_MODIFIERS: &[&str] = &[ + "declaration", + "defaultLibrary", + "deprecated", + "readonly", + "async", +]; + +impl ModifierSet { + /// The set modifiers' LSP names, in legend order. + pub fn names(self) -> impl Iterator { + TOKEN_MODIFIERS + .iter() + .enumerate() + .filter(move |(i, _)| self.bits() & (1 << i) != 0) + .map(|(_, name)| *name) + } +} + // ── SemanticToken ───────────────────────────────────────────────────────────── /// A classified token ready for LSP encoding. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct SemanticToken { pub range: TextRange, pub token_type: SemanticTokenType, + pub modifiers: ModifierSet, } -// ── Public entry point ──────────────────────────────────────────────────────── - -/// Compute semantic tokens for a file. -/// -/// Always returns tokens in document order (required by the LSP -/// `textDocument/semanticTokens/full` contract). -/// -/// Regular function (not a Salsa query). Internally calls Salsa-cached queries -/// (`infer_scope_types`, `function_body`, `function_body_source_map`, -/// `file_semantic_index`, `syntax_tree`). -pub fn semantic_tokens(db: &dyn Db, file: SourceFile) -> Vec { - let root = baml_compiler_parser::syntax_tree(db, file); - let mut out = Vec::new(); - visit_node(db, file, &root, &mut out); - out -} - -// ── CST walker ─────────────────────────────────────────────────────────────── +/// A token type paired with its modifiers — the unit a classifier produces. +type Class = (SemanticTokenType, ModifierSet); -/// Emit a token for a single non-whitespace leaf token. -fn emit_token(token: &SyntaxToken, token_type: SemanticTokenType, out: &mut Vec) { - if !token.kind().is_whitespace() { - out.push(SemanticToken { - range: token.text_range(), - token_type, - }); - } +/// The class for a declaration name: `ty` + the `declaration` modifier. +fn decl(ty: SemanticTokenType) -> Class { + (ty, ModifierSet::DECLARATION) } -/// Emit `token_type` for every non-trivia leaf token under `node`. -fn emit_node(node: &SyntaxNode, token_type: SemanticTokenType, out: &mut Vec) { - for child in node.descendants_with_tokens() { - if let NodeOrToken::Token(t) = child { - emit_token(&t, token_type, out); - } - } +/// A plain (modifier-free) class. +fn plain(ty: SemanticTokenType) -> Class { + (ty, ModifierSet::empty()) } -/// Dispatch a node to its visitor. -fn visit_node(db: &dyn Db, file: SourceFile, node: &SyntaxNode, out: &mut Vec) { - match node.kind() { - // Comment nodes (headers are nodes, not just tokens) - ref n if n.is_comment() => emit_node(node, SemanticTokenType::Comment, out), - // String literals — emit the whole thing as String - SyntaxKind::STRING_LITERAL | SyntaxKind::RAW_STRING_LITERAL => { - emit_node(node, SemanticTokenType::String, out); - } - SyntaxKind::ATTRIBUTE | SyntaxKind::BLOCK_ATTRIBUTE => { - visit_attribute(db, file, node, out); - } - SyntaxKind::TYPE_ALIAS_DEF => visit_type_alias_def(db, file, node, out), - SyntaxKind::ENUM_DEF => visit_word_as(db, file, node, SemanticTokenType::Enum, out), - SyntaxKind::ENUM_VARIANT => { - visit_word_as(db, file, node, SemanticTokenType::EnumMember, out); - } - SyntaxKind::CLASS_DEF => visit_word_as(db, file, node, SemanticTokenType::Class, out), - SyntaxKind::FIELD => visit_word_as(db, file, node, SemanticTokenType::Property, out), - SyntaxKind::FUNCTION_DEF => visit_function_def(db, file, node, out), - SyntaxKind::PARAMETER => { - visit_word_as(db, file, node, SemanticTokenType::Parameter, out); - } - SyntaxKind::TYPE_EXPR => visit_type_expr(db, file, node, out), - SyntaxKind::LET_STMT => { - visit_first_word_as(db, file, node, SemanticTokenType::Variable, out); - } - SyntaxKind::CLIENT_TYPE => { - visit_word_as(db, file, node, SemanticTokenType::Type, out); - } - SyntaxKind::CONFIG_ITEM => visit_config_item(db, file, node, out), - SyntaxKind::CLIENT_DEF | SyntaxKind::RETRY_POLICY_DEF => { - visit_word_as(db, file, node, SemanticTokenType::Struct, out); - } - SyntaxKind::TEST_DEF => visit_word_as(db, file, node, SemanticTokenType::Struct, out), - SyntaxKind::TEMPLATE_STRING_DEF => { - visit_word_as(db, file, node, SemanticTokenType::Function, out); - } - SyntaxKind::PROMPT_FIELD => { - visit_word_as(db, file, node, SemanticTokenType::Property, out); - } - SyntaxKind::CLIENT_FIELD => visit_client_field(db, file, node, out), - _ => visit_children(db, file, node, out), - } +/// Whether a `FUNCTION_DEF` / `METHOD_SIG` node is declared inside a class, +/// interface, or implements block — i.e. it is a method, not a free function. +fn in_method_context(node: &SyntaxNode) -> bool { + node.ancestors().skip(1).any(|a| { + matches!( + a.kind(), + SyntaxKind::CLASS_DEF + | SyntaxKind::INTERFACE_DEF + | SyntaxKind::IMPLEMENTS_BLOCK + | SyntaxKind::IMPLEMENTS_FOR + ) + }) } -/// Classify a leaf token syntactically. -fn visit_token(token: &SyntaxToken, out: &mut Vec) { +/// Push a classified token. +fn emit(range: TextRange, class: Class, out: &mut Vec) { out.push(SemanticToken { - range: token.text_range(), - token_type: match token.kind() { - ref kind if kind.is_whitespace() => return, - ref kind if kind.is_keyword() => SemanticTokenType::Keyword, - ref kind if kind.is_operator() => SemanticTokenType::Operator, - ref kind if kind.is_comment() => SemanticTokenType::Comment, - SyntaxKind::INTEGER_LITERAL | SyntaxKind::FLOAT_LITERAL => SemanticTokenType::Number, - _ => return, - }, + range, + token_type: class.0, + modifiers: class.1, }); } -/// Walk all children, dispatching nodes and tokens. -fn visit_children(db: &dyn Db, file: SourceFile, node: &SyntaxNode, out: &mut Vec) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => visit_token(&t, out), - } - } -} - -/// Visit a node where all WORD tokens are classified as `word_type`. -fn visit_word_as( - db: &dyn Db, - file: SourceFile, - node: &SyntaxNode, - word_type: SemanticTokenType, - out: &mut Vec, -) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => match t.kind() { - SyntaxKind::WORD => emit_token(&t, word_type, out), - _ => visit_token(&t, out), - }, - } - } -} - -/// Visit a node where the first WORD token is classified as `word_type`. -fn visit_first_word_as( - db: &dyn Db, - file: SourceFile, - node: &SyntaxNode, - word_type: SemanticTokenType, - out: &mut Vec, -) { - let mut found_word = false; - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => { - if !found_word && t.kind() == SyntaxKind::WORD { - found_word = true; - emit_token(&t, word_type, out); - } else { - visit_token(&t, out); - } +/// Emit a string/byte-string literal, splitting backslash escape sequences +/// (`\n`, `\t`, `\xNN`, `\u{..}`, `\"`, ...) out as `EscapeSequence` while the +/// surrounding text stays `String`. The lexer leaves escapes undecoded, so we +/// scan the literal text ourselves (rust-analyzer does the same). +fn string_with_escapes(node: &SyntaxNode, out: &mut Vec) { + let base: usize = node.text_range().start().into(); + let text = node.text().to_string(); + let bytes = text.as_bytes(); + let span = |a: usize, b: usize| { + TextRange::new( + TextSize::new(u32::try_from(a).unwrap_or(u32::MAX)), + TextSize::new(u32::try_from(b).unwrap_or(u32::MAX)), + ) + }; + + let mut i = 0; + let mut text_start = 0; + while i < bytes.len() { + if bytes[i] == b'\\' && i + 1 < bytes.len() { + if i > text_start { + emit( + span(base + text_start, base + i), + plain(SemanticTokenType::String), + out, + ); } + let len = escape_len(&text[i..]); + emit( + span(base + i, base + i + len), + plain(SemanticTokenType::EscapeSequence), + out, + ); + i += len; + text_start = i; + } else { + i += 1; } } -} - -/// Visit a `CONFIG_ITEM` node — key as Property. -fn visit_config_item( - db: &dyn Db, - file: SourceFile, - node: &SyntaxNode, - out: &mut Vec, -) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => match t.kind() { - ref k if k.is_keyword() => emit_token(&t, SemanticTokenType::Property, out), - SyntaxKind::WORD => emit_token(&t, SemanticTokenType::Property, out), - _ => visit_token(&t, out), - }, - } + if text_start < bytes.len() { + emit( + span(base + text_start, base + bytes.len()), + plain(SemanticTokenType::String), + out, + ); } } -/// Visit a `CLIENT_FIELD` node — `client` keyword as Property. -fn visit_client_field( - db: &dyn Db, - file: SourceFile, - node: &SyntaxNode, - out: &mut Vec, -) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => match t.kind() { - SyntaxKind::KW_CLIENT => emit_token(&t, SemanticTokenType::Property, out), - _ => visit_token(&t, out), - }, - } +/// Byte length of the escape sequence at the start of `s` (which begins `\`). +fn escape_len(s: &str) -> usize { + let bytes = s.as_bytes(); + match bytes.get(1) { + // `\xNN` — backslash, x, two hex digits. + Some(b'x') => 4.min(s.len()), + // `\u{...}` — through the closing brace. + Some(b'u') if bytes.get(2) == Some(&b'{') => s.find('}').map_or(2, |i| i + 1), + // `\n`, `\t`, `\r`, `\0`, `\\`, `\"`, `\'`, `\u` (no brace), ... + Some(_) => 2, + // A trailing backslash (shouldn't occur before the closing quote). + None => 1, } } -/// Visit an `ATTRIBUTE` or `BLOCK_ATTRIBUTE` node — all content as Decorator. -fn visit_attribute(db: &dyn Db, file: SourceFile, node: &SyntaxNode, out: &mut Vec) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => match t.kind() { - SyntaxKind::AT_AT | SyntaxKind::AT | SyntaxKind::WORD => { - emit_token(&t, SemanticTokenType::Decorator, out); - } - ref k if k.is_keyword() => emit_token(&t, SemanticTokenType::Decorator, out), - _ => visit_token(&t, out), - }, - } - } -} - -/// Visit a `TYPE_ALIAS_DEF` — "type" word as Keyword, name as Type. -fn visit_type_alias_def( - db: &dyn Db, - file: SourceFile, - node: &SyntaxNode, - out: &mut Vec, -) { - let mut found_keyword = false; // "type" is a WORD in the grammar - let mut found_name = false; - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => { - if !found_keyword && t.kind() == SyntaxKind::WORD { - found_keyword = true; - emit_token(&t, SemanticTokenType::Keyword, out); - } else if !found_name && t.kind() == SyntaxKind::WORD { - found_name = true; - emit_token(&t, SemanticTokenType::Type, out); - } else { - visit_token(&t, out); - } +/// Emit every non-trivia leaf under `node` with one type (comments/strings). +fn emit_node(node: &SyntaxNode, token_type: SemanticTokenType, out: &mut Vec) { + for child in node.descendants_with_tokens() { + if let NodeOrToken::Token(t) = child { + if !t.kind().is_whitespace() { + emit(t.text_range(), plain(token_type), out); } } } } -/// Resolve a type name to a `SemanticTokenType` using compiler2. -/// -/// Checks the package items for classes, enums, and type aliases. -/// Falls back to `Type` for primitive keywords. -fn resolve_type_name(db: &dyn Db, file: SourceFile, name: &str) -> SemanticTokenType { - if matches!( - name, - "int" - | "float" - | "string" - | "bool" - | "map" - | "unknown" - | "never" - | "image" - | "audio" - | "video" - | "pdf" - | "null" - ) { - return SemanticTokenType::Type; - } - - // Look up in package items. - let pkg_info = baml_compiler2_hir::file_package::file_package(db, file); - let pkg_id = baml_compiler2_hir::package::PackageId::new(db, pkg_info.package); - let pkg_items = baml_compiler2_hir::package::package_items(db, pkg_id); - let name_obj = baml_base::Name::new(name); - - match pkg_items.lookup_type(&pkg_info.namespace_path, &name_obj) { - Some(Definition::Class(_)) => SemanticTokenType::Class, - Some(Definition::Enum(_)) => SemanticTokenType::Enum, - Some(Definition::TypeAlias(_)) => SemanticTokenType::Type, - _ => SemanticTokenType::Namespace, - } -} +// ── Public entry point ──────────────────────────────────────────────────────── -/// Visit a `TYPE_EXPR` node — resolve WORD tokens to their definition kind. -fn visit_type_expr(db: &dyn Db, file: SourceFile, node: &SyntaxNode, out: &mut Vec) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => visit_node(db, file, &n, out), - NodeOrToken::Token(t) => match t.kind() { - SyntaxKind::WORD => { - emit_token(&t, resolve_type_name(db, file, t.text()), out); - } - _ => visit_token(&t, out), - }, - } - } +/// Compute semantic tokens for a file. +/// +/// Always returns tokens in document order (required by the LSP +/// `textDocument/semanticTokens/full` contract). +/// +/// A Salsa query: the result is memoized per file and recomputed only when an +/// input it reads changes (`syntax_tree`, `file_semantic_index`, +/// `infer_scope_types`, `function_body`, source maps). It therefore cannot go +/// stale, and a repeated request for an unchanged file is served from cache +/// without re-walking the CST. +#[salsa::tracked(returns(clone))] +pub fn semantic_tokens(db: &dyn Db, file: SourceFile) -> Vec { + let root = baml_compiler_parser::syntax_tree(db, file); + // Full document: classify every token, so build the merged whole-file index + // (itself a merge of per-scope salsa-cached indices) and resolve from it. + let index = index::build(db, file); + let walk = Walk { + db, + file, + resolve: Box::new(move |range| index.get(&range).copied()), + range: None, + }; + let mut out = Vec::new(); + walk.run(&root, &mut out); + out } -/// Visit a `FUNCTION_DEF` node. -/// -/// Handles the header (name, params, return type) via CST. For expression -/// bodies (`EXPR_FUNCTION_BODY`) switches to `ExprBodyVisitor` which uses -/// compiler2 type information for richer classification. -fn visit_function_def( +/// Semantic tokens for a viewport `range` only — rust-analyzer's +/// `highlight_range`. Names are resolved on demand through +/// `index::resolve_token_class`, so only the scopes the viewport touches are +/// indexed (the rest of the file is never resolved). Not a Salsa query — keying +/// on the range would blow the cache; the underlying per-scope indices and name +/// resolution it calls *are* memoized. +pub fn semantic_tokens_in_range( db: &dyn Db, file: SourceFile, - node: &SyntaxNode, - out: &mut Vec, -) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => { - if n.kind() == SyntaxKind::EXPR_FUNCTION_BODY { - // Try to build the type-aware visitor for the expression body. - if let Some(visitor) = - ExprBodyVisitor::for_function_at(db, file, node.text_range().start()) - { - visitor.visit_children(&n, out); - } else { - // Fall back to pure-CST walk if compiler2 data is unavailable. - visit_children(db, file, &n, out); - } - } else { - visit_node(db, file, &n, out); - } - } - NodeOrToken::Token(t) => match t.kind() { - SyntaxKind::WORD => emit_token(&t, SemanticTokenType::Function, out), - _ => visit_token(&t, out), - }, - } - } + start: u32, + end: u32, +) -> Vec { + let range = TextRange::new(start.into(), end.into()); + let root = baml_compiler_parser::syntax_tree(db, file); + let walk = Walk { + db, + file, + resolve: Box::new(move |r| index::resolve_token_class(db, file, r)), + range: Some(range), + }; + let mut out = Vec::new(); + walk.run(&root, &mut out); + // The range gate is per-subtree; trim the boundary tokens to exactly `range`. + out.retain(|t| range.intersect(t.range).is_some()); + out } -// ── ExprBodyVisitor ─────────────────────────────────────────────────────────── +// ── Walker ───────────────────────────────────────────────────────────────────── -/// Visitor for expression function bodies. +/// A document-order CST walk that classifies each token exactly once. /// -/// Pre-builds a `TextRange → SemanticTokenType` resolution map from compiler2's -/// `infer_scope_types` and `function_body_source_map`, then walks the CST in -/// document order. Leaf tokens are checked against the map first; if there is -/// no entry the normal syntactic classifier is used. -struct ExprBodyVisitor<'db> { +/// `resolve` resolves an identifier inside an expression body to its +/// classification; a declaration name is classified by its declaring node; +/// every other token is syntactic. For a full-document walk `resolve` is the +/// merged whole-file index; a range walk resolves on demand per scope +/// (rust-analyzer's `Semantics::resolve` model — only visited scopes pay). +struct Walk<'db> { db: &'db dyn Db, file: SourceFile, - resolution_map: HashMap, + resolve: Box Option + 'db>, + /// For a viewport request: subtrees that don't intersect this range are + /// skipped entirely, so their scopes are never resolved. + range: Option, } -impl<'db> ExprBodyVisitor<'db> { - /// Try to build an `ExprBodyVisitor` for the function whose `FUNCTION_DEF` - /// node starts at `node_start`. - /// - /// 1. Find the function in the item tree by matching its span start. - /// 2. Load `function_body` — only proceeds if it is `FunctionBody::Expr`. - /// 3. Load `function_body_source_map` — provides `ExprId → TextRange`. - /// 4. Load `infer_scope_types` for the function scope — provides - /// `ExprId → Ty` and `PatId → Ty`. - /// 5. Pre-build a `TextRange → SemanticTokenType` map. - fn for_function_at( - db: &'db dyn Db, - file: SourceFile, - node_start: text_size::TextSize, - ) -> Option { - let item_tree = baml_compiler2_hir::file_item_tree(db, file); - - // Find the function whose span starts at node_start (the FUNCTION_DEF node). - let (func_local_id, _func_data) = item_tree - .functions - .iter() - .find(|(_, f)| f.span.start() == node_start)?; - - let func_loc = FunctionLoc::new(db, file, *func_local_id); - - // Only expression-body functions benefit from type-aware classification. - let body = baml_compiler2_hir::body::function_body(db, func_loc); - let FunctionBody::Expr(expr_body) = body.as_ref() else { - return None; - }; - - // Source map: ExprId → TextRange. - let source_map = baml_compiler2_hir::body::function_body_source_map(db, func_loc)?; - - // Find the function scope for infer_scope_types. - let index = baml_compiler2_hir::file_semantic_index(db, file); - let func_scope_file_id = index - .scopes - .iter() - .enumerate() - .find(|(_, s)| s.kind == ScopeKind::Function && s.range.start() == node_start) - .map(|(i, _)| { - #[allow(clippy::cast_possible_truncation)] - baml_compiler2_hir::scope::FileScopeId::new(i as u32) - })?; - - let func_scope_id = index.scope_ids[func_scope_file_id.index() as usize]; - let inference = baml_compiler2_tir::inference::infer_scope_types(db, func_scope_id); - - let file_text = file.text(db); - let resolution_map = build_resolution_map(expr_body, &source_map, inference, file_text); - - Some(Self { - db, - file, - resolution_map, - }) +impl Walk<'_> { + /// The single document-order driver: a flat `preorder_with_tokens()` walk + /// (rust-analyzer's `traverse`). Each `Enter(Node)` either hands a complex + /// subtree to its wholesale handler and skips it, or descends; each + /// `Enter(Token)` is classified from its parent kind ([`classify_token`]) + /// with a syntactic fallback ([`Self::token`]). + fn run(&self, root: &SyntaxNode, out: &mut Vec) { + let mut preorder = root.preorder_with_tokens(); + while let Some(event) = preorder.next() { + match event { + WalkEvent::Enter(NodeOrToken::Node(node)) => { + // Range gate: a subtree disjoint from the viewport is skipped + // wholesale, so its tokens are never classified and its scope + // never resolved. + if let Some(r) = self.range { + if r.intersect(node.text_range()).is_none() { + preorder.skip_subtree(); + continue; + } + } + // A node whose classification spans its whole subtree with + // custom traversal (strings, comments, type exprs, object + // literals, generators) is handled wholesale; skipping it + // prevents the flat loop from re-visiting its descendants. + if self.wholesale(&node, out) { + preorder.skip_subtree(); + } + } + WalkEvent::Enter(NodeOrToken::Token(token)) => { + if token.kind().is_whitespace() { + continue; + } + match classify_token(&token) { + Some(class) => emit(token.text_range(), class, out), + None => self.token(&token, out), + } + } + WalkEvent::Leave(_) => {} + } + } } - /// Dispatch a single node inside an expression body. - fn visit_node(&self, node: &SyntaxNode, out: &mut Vec) { + /// Classify a node whose logic spans its entire subtree, emitting all of its + /// descendant tokens. Returns `true` if `node` was such a node (the caller + /// then skips the subtree), `false` to let the flat loop descend normally. + fn wholesale(&self, node: &SyntaxNode, out: &mut Vec) -> bool { + if node.kind().is_comment() { + emit_node(node, SemanticTokenType::Comment, out); + return true; + } match node.kind() { - ref n if n.is_comment() => emit_node(node, SemanticTokenType::Comment, out), - SyntaxKind::STRING_LITERAL | SyntaxKind::RAW_STRING_LITERAL => { - emit_node(node, SemanticTokenType::String, out); - } - SyntaxKind::TYPE_EXPR => visit_type_expr(self.db, self.file, node, out), - SyntaxKind::LET_STMT => { - self.visit_first_word_as(node, SemanticTokenType::Variable, out); + // Escape-processing literals: split out `\n`, `\xNN`, `\u{..}`, ... + SyntaxKind::STRING_LITERAL | SyntaxKind::BYTE_STRING_LITERAL => { + string_with_escapes(node, out); } - SyntaxKind::OBJECT_FIELD | SyntaxKind::OBJECT_LITERAL => { - self.visit_children(node, out); + // Raw / unquoted strings do not process escapes. + SyntaxKind::RAW_STRING_LITERAL | SyntaxKind::UNQUOTED_STRING => { + emit_node(node, SemanticTokenType::String, out); } - _ => self.visit_children(node, out), + SyntaxKind::BACKTICK_STRING_LITERAL => self.backtick_string(node, out), + SyntaxKind::TYPE_EXPR => self.type_expr(node, out), + SyntaxKind::OBJECT_LITERAL => self.object_literal(node, out), + SyntaxKind::GENERATOR_DEF => self.generator_def(node, out), + SyntaxKind::INTERFACE_FIELD_LINK => self.interface_field_link(node, out), + _ => return false, } + true } - /// Classify a leaf token. Resolution map wins over syntactic defaults. - fn visit_token(&self, token: &SyntaxToken, out: &mut Vec) { - if let Some(&token_type) = self.resolution_map.get(&token.text_range()) { - emit_token(token, token_type, out); - } else { - visit_token(token, out); + /// Classify a single leaf token. A WORD consults the resolution index (an + /// unresolved one is left neutral, never guessed); every other token is + /// purely syntactic. + fn token(&self, token: &SyntaxToken, out: &mut Vec) { + let kind = token.kind(); + if kind.is_whitespace() { + return; } - } - - /// Walk all children. - fn visit_children(&self, node: &SyntaxNode, out: &mut Vec) { - for child in node.children_with_tokens() { - match child { - NodeOrToken::Node(n) => self.visit_node(&n, out), - NodeOrToken::Token(t) => self.visit_token(&t, out), + // Boolean / null literals: a dedicated `KW_TRUE`/`KW_FALSE`/`KW_NULL` + // token (value position, re-lexed by the parser). `true`/`false` -> + // `boolean`. `null` is the null type's literal, so it goes through the + // shared builtin classification (defaultLibrary `type`) — matching its + // type position and every other builtin, instead of reading as a keyword. + match kind { + SyntaxKind::KW_TRUE | SyntaxKind::KW_FALSE => { + emit(token.text_range(), plain(SemanticTokenType::Boolean), out); + return; + } + SyntaxKind::KW_NULL => { + let class = classify::classify_primitive(token.text()) + .unwrap_or_else(|| plain(SemanticTokenType::Keyword)); + emit(token.text_range(), class, out); + return; } + _ => {} } + if kind == SyntaxKind::WORD { + if let Some(class) = (self.resolve)(token.text_range()) { + emit(token.text_range(), class, out); + } + return; + } + let token_type = if kind.is_keyword() { + SemanticTokenType::Keyword + } else if kind.is_operator() { + SemanticTokenType::Operator + } else if kind.is_comment() { + SemanticTokenType::Comment + } else if matches!( + kind, + SyntaxKind::INTEGER_LITERAL | SyntaxKind::FLOAT_LITERAL | SyntaxKind::BIGINT_LITERAL + ) { + SemanticTokenType::Number + } else { + return; + }; + emit(token.text_range(), plain(token_type), out); } - /// First WORD as `word_type`, rest dispatched normally. - fn visit_first_word_as( + /// A structural primitive for the wholesale handlers: walk a node's direct + /// children, classifying each direct token by `classify` (with a syntactic + /// fallback) and recursing each child node through [`Self::run`]. A `None` + /// result falls back to the token's own classification ([`Self::token`]). + fn tokens( &self, node: &SyntaxNode, - word_type: SemanticTokenType, out: &mut Vec, + mut classify: impl FnMut(&SyntaxToken) -> Option, ) { - let mut found_word = false; for child in node.children_with_tokens() { match child { - NodeOrToken::Node(n) => self.visit_node(&n, out), - NodeOrToken::Token(t) => { - if !found_word && t.kind() == SyntaxKind::WORD { - found_word = true; - emit_token(&t, word_type, out); - } else { - self.visit_token(&t, out); - } - } + NodeOrToken::Node(n) => self.run(&n, out), + NodeOrToken::Token(t) => match classify(&t) { + Some(class) => emit(t.text_range(), class, out), + None => self.token(&t, out), + }, } } } -} - -// ── Resolution map builder ──────────────────────────────────────────────────── -/// Map a `Ty` to a `SemanticTokenType` for expression-level tokens. -/// -/// Returns `None` for unknown/error types so they don't get classified. -fn ty_to_token_type(ty: &Ty) -> Option { - match ty { - Ty::Class(..) => Some(SemanticTokenType::Class), - Ty::Enum(..) => Some(SemanticTokenType::Enum), - Ty::EnumVariant(..) => Some(SemanticTokenType::EnumMember), - Ty::TypeAlias(..) => Some(SemanticTokenType::Type), - Ty::Function { .. } => Some(SemanticTokenType::Function), - // Primitives, lists, maps, unions etc. — don't highlight specially - _ => None, - } -} - -/// Build a `TextRange → SemanticTokenType` map from compiler2 type information. -/// -/// Iterates all expressions in `expr_body`. For each expression whose type -/// we can classify and whose source range we know, inserts an entry. The -/// `ExprBodyVisitor` then consults this map during its CST walk. -/// -/// Key mappings: -/// -/// - `Expr::Path(names)` — single-segment path; `expr_span` is exactly the -/// identifier's range. Ty from `ScopeInference::expression_type`. -/// -/// - `Expr::MemberAccess { member, .. }` — `expr_span` covers `base.member`. -/// We extract just the member name by text-scanning the tail of the span. -/// -/// - `Expr::Object { type_name, fields, .. }` — the constructor name is -/// inside the `expr_span`; extracted via text search. Field names are -/// emitted as Property (only if the object expression resolves to a class -/// and the field name appears in the span). -/// -/// - `PatternKind::Bind` (with or without a `narrow`) — bound variable names -/// are classified as Variable. -fn build_resolution_map( - expr_body: &ExprBody, - source_map: &baml_compiler2_ast::AstSourceMap, - inference: &baml_compiler2_tir::inference::ScopeInference<'_>, - file_text: &str, -) -> HashMap { - let mut map: HashMap = HashMap::new(); - - for (expr_id, expr) in expr_body.exprs.iter() { - match expr { - Expr::Path(names) if !names.is_empty() => { - if names.len() == 1 { - // Single-segment path: the expr_span is exactly the identifier range. - let span = source_map.expr_span(expr_id); - if span.is_empty() { - continue; - } - // Only classify if we have a type for this expression. - if let Some(ty) = inference.expression_type(expr_id) { - if let Some(token_type) = ty_to_token_type(ty) { - map.insert(span, token_type); - } - } - } else { - // Multi-segment path (e.g. `Status.Active`, `obj.field`, `baml.env.get`). - // Intermediate segments (between root and last) are Property. - // The final segment gets a type-aware classification from the - // expression type (e.g. EnumMember for `Status.Active`). - if let Some(seg_spans) = source_map.path_segment_spans.get(&expr_id) { - let last_idx = seg_spans.len().saturating_sub(1); - for (i, span) in seg_spans.iter().enumerate().skip(1) { - if i == last_idx { - continue; - } - if !span.is_empty() { - map.insert(*span, SemanticTokenType::Property); - } - } - // Final segment → type-aware classification - if let Some(final_span) = seg_spans.last() { - if !final_span.is_empty() { - let token_type = inference - .expression_type(expr_id) - .and_then(ty_to_token_type) - .unwrap_or(SemanticTokenType::Property); - map.insert(*final_span, token_type); - } + /// A `TYPE_EXPR` — each (possibly dotted) type name resolved to what it + /// names. A qualified name like `baml.iter.Iterator` resolves the whole path: + /// the leaf is the resolved type, earlier segments are namespaces. Builtins + /// (stdlib types, primitives) are marked `defaultLibrary`. + fn type_expr(&self, node: &SyntaxNode, out: &mut Vec) { + let children: Vec<_> = node.children_with_tokens().collect(); + let mut i = 0; + while i < children.len() { + // A type name starts at a WORD; gather any dotted continuation. + if let NodeOrToken::Token(t) = &children[i] { + if t.kind() == SyntaxKind::WORD { + let mut segments = vec![t.clone()]; + let mut j = i + 1; + while let (Some(NodeOrToken::Token(dot)), Some(NodeOrToken::Token(word))) = + (children.get(j), children.get(j + 1)) + { + if dot.kind() != SyntaxKind::DOT || word.kind() != SyntaxKind::WORD { + break; } + emit(dot.text_range(), plain(SemanticTokenType::Operator), out); + segments.push(word.clone()); + j += 2; } + self.type_run(&segments, out); + i = j; + continue; } } + match &children[i] { + NodeOrToken::Node(n) => self.run(n, out), + NodeOrToken::Token(t) => self.token(t, out), + } + i += 1; + } + } - Expr::MemberAccess { member, .. } => { - // expr_span covers `base.member` — extract only the member name. - let span = source_map.expr_span(expr_id); - if span.is_empty() { - continue; - } - let start: usize = span.start().into(); - let end: usize = span.end().into(); - if end > file_text.len() { - continue; - } - let text = &file_text[start..end]; - let member_str = member.as_str(); - // The member name is at the end of the span (after the last dot). - if let Some(offset) = text.rfind(member_str) { - // Verify the character before is a dot (avoids substring false matches). - let dot_pos = if offset > 0 { offset - 1 } else { 0 }; - if offset > 0 && text.as_bytes().get(dot_pos) != Some(&b'.') { - continue; - } - let member_start = start + offset; - let member_end = member_start + member_str.len(); - if member_start < member_end && member_end <= file_text.len() { - let member_range = TextRange::new( - member_start.try_into().unwrap_or_default(), - member_end.try_into().unwrap_or_default(), - ); - map.insert(member_range, SemanticTokenType::Property); - } + /// Classify one (possibly dotted) type name run. + fn type_run(&self, segments: &[SyntaxToken], out: &mut Vec) { + if let [single] = segments { + let class = classify_type_token( + self.db, + self.file, + single.text(), + single.text_range().start(), + ); + emit(single.text_range(), class, out); + return; + } + // Qualified `a.b.Type`: resolve each prefix segment the same way the + // value-position index does — a real namespace (builtin-flagged) or, if + // not a namespace (e.g. the base type of an associated-type path), a + // type. Never a blindly-guessed namespace. + let names: Vec = segments.iter().map(|t| Name::new(t.text())).collect(); + let (leaf, prefix) = segments.split_last().expect("non-empty run"); + for (i, seg) in prefix.iter().enumerate() { + let class = match resolve_namespace_prefix(self.db, self.file, &names[0..=i]) { + Some(builtin) => classify::namespace_class(builtin), + None => { + classify_type_token(self.db, self.file, seg.text(), seg.text_range().start()) } + }; + emit(seg.text_range(), class, out); + } + let resolved = resolve_path_at(self.db, self.file, leaf.text_range().start(), &names, None); + let class = classify::classify_resolved(&resolved).unwrap_or_else(|| { + // An unresolved qualified leaf: a verified enum variant (the prefix + // resolves to an enum and the leaf is one of its variants) is an + // `enumMember` — e.g. `Direction.North` in a match pattern, which is + // a type expression. Otherwise it is still a type. + if resolve_enum_variant(self.db, self.file, leaf.text_range().start(), &names) { + plain(SemanticTokenType::EnumMember) + } else { + plain(SemanticTokenType::Type) } + }); + emit(leaf.text_range(), class, out); + } - Expr::Object { - type_name, fields, .. - } => { - let span = source_map.expr_span(expr_id); - if span.is_empty() { - continue; - } - let span_start: usize = span.start().into(); - let span_end: usize = span.end().into(); - if span_end > file_text.len() { - continue; + /// An `interface_field as class_field` link inside an `implements` block. + /// The interface field resolves against the implemented interface and the + /// class field against the enclosing class; each highlights as a `Property` + /// only when it actually resolves (the `as` keyword stays syntactic). + fn interface_field_link(&self, node: &SyntaxNode, out: &mut Vec) { + let link = InterfaceFieldLink::cast(node.clone()); + // The class field's owning type is the enclosing class. + let class_name: Option = node + .ancestors() + .find_map(ClassDef::cast) + .and_then(|c| c.name()) + .map(|t| Name::new(t.text())); + // The interface field's owning type is the implements-block target. + let iface_segments: Vec = node + .ancestors() + .find_map(ImplementsBlock::cast) + .and_then(|b| b.syntax().children().find_map(ImplementsTarget::cast)) + .and_then(|t| t.type_expr()) + .map(|te| type_path_segments(&te)) + .unwrap_or_default(); + let field_of = |segments: &[Name], tok: &SyntaxToken| { + resolve_field( + self.db, + self.file, + tok.text_range().start(), + segments, + &Name::new(tok.text()), + ) + .then_some(plain(SemanticTokenType::Property)) + }; + self.tokens(node, out, |t| { + let here = Some(t.text_range()); + if link + .as_ref() + .and_then(baml_compiler_syntax::InterfaceFieldLink::interface_field) + .map(|x| x.text_range()) + == here + { + return field_of(&iface_segments, t); + } + if link + .as_ref() + .and_then(baml_compiler_syntax::InterfaceFieldLink::class_field) + .map(|x| x.text_range()) + == here + { + return class_name + .as_ref() + .and_then(|cn| field_of(std::slice::from_ref(cn), t)); + } + None + }); + } + + /// An `OBJECT_LITERAL` — the constructed type name as a `Class` reference, + /// then the body dispatched (field keys + value expressions). The name is a + /// bare WORD for `Foo { … }` but a leading `PATH_EXPR` (`Foo`) when the + /// construction is generic. + fn object_literal(&self, node: &SyntaxNode, out: &mut Vec) { + let mut typed = false; // classified the constructed type name yet + for child in node.children_with_tokens() { + match child { + NodeOrToken::Token(t) if !typed && t.kind() == SyntaxKind::WORD => { + typed = true; + emit(t.text_range(), plain(SemanticTokenType::Class), out); } - let span_text = &file_text[span_start..span_end]; - - // Classify the constructor type name. - let name_str = type_name.to_string(); - if let Some(offset) = span_text.find(&name_str) { - let name_start = span_start + offset; - let name_end = name_start + name_str.len(); - let name_range = TextRange::new( - name_start.try_into().unwrap_or_default(), - name_end.try_into().unwrap_or_default(), - ); - // Use the expression type if available. - let token_type = inference - .expression_type(expr_id) - .and_then(ty_to_token_type) - .unwrap_or(SemanticTokenType::Class); - map.insert(name_range, token_type); + // `Foo { … }` — name + generic args are a leading `PATH_EXPR`. + NodeOrToken::Node(n) if !typed && n.kind() == SyntaxKind::PATH_EXPR => { + typed = true; + self.object_type_path(&n, out); } + NodeOrToken::Node(n) => self.run(&n, out), + NodeOrToken::Token(t) => self.token(&t, out), + } + } + } - // Classify field names as Property. - for (field_name, _field_expr) in fields { - let field_str = field_name.as_str(); - if let Some(offset) = span_text.find(field_str) { - let field_start = span_start + offset; - let field_end = field_start + field_str.len(); - let field_range = TextRange::new( - field_start.try_into().unwrap_or_default(), - field_end.try_into().unwrap_or_default(), - ); - map.insert(field_range, SemanticTokenType::Property); - } - } + /// The leading `Foo<...>` of a generic object construction: the type name as + /// a `Class`; the `GENERIC_ARGS` dispatched so their type args resolve. + fn object_type_path(&self, node: &SyntaxNode, out: &mut Vec) { + let mut named = false; + self.tokens(node, out, |t| { + (!named && t.kind() == SyntaxKind::WORD).then(|| { + named = true; + plain(SemanticTokenType::Class) + }) + }); + } + + /// A `BACKTICK_STRING_LITERAL` (BEP-049 interpolated string) — literal content + /// (delimiters, text, punctuation) as `String`; interpolations (`${ expr }`) + /// and block tags (`${for ...}`, `${if ...}`) are child nodes holding real + /// code, dispatched so their identifiers resolve through the index. + fn backtick_string(&self, node: &SyntaxNode, out: &mut Vec) { + self.tokens(node, out, |t| { + (!t.kind().is_whitespace()).then_some(plain(SemanticTokenType::String)) + }); + } + + /// A `GENERATOR_DEF` — the name as a `Struct` declaration. The `{ … }` body + /// is parsed opaquely (generators are deprecated) into raw tokens, so the + /// value strings aren't `STRING_LITERAL` nodes; classify by shape — `key:` + /// words as `Property`, value tokens as `String`. + fn generator_def(&self, node: &SyntaxNode, out: &mut Vec) { + let mut body = false; // past the opening `{` + let mut value = false; // after `:`, before `,` / `}` + let mut named = false; + self.tokens(node, out, |t| match t.kind() { + SyntaxKind::KW_GENERATOR => Some(plain(SemanticTokenType::Keyword)), + SyntaxKind::L_BRACE => { + body = true; + None + } + SyntaxKind::R_BRACE => { + value = false; + None + } + SyntaxKind::COLON if body => { + value = true; + None + } + SyntaxKind::COMMA if body => { + value = false; + None } + SyntaxKind::WORD if !body && !named => { + named = true; + Some(decl(SemanticTokenType::Struct)) + } + SyntaxKind::WORD if body && !value => Some(plain(SemanticTokenType::Property)), + k if body && value && !k.is_whitespace() && !k.is_comment() => { + Some(plain(SemanticTokenType::String)) + } + _ => None, + }); + } +} - _ => {} +/// The leading dotted path segments of a type expression (`baml.x.Iface` -> +/// `[baml, x, Iface]`), stopping at any generic arguments. +fn type_path_segments(te: &TypeExpr) -> Vec { + let mut segments = Vec::new(); + for element in te.syntax().children_with_tokens() { + match element { + NodeOrToken::Token(t) if t.kind().is_trivia() => {} + NodeOrToken::Token(t) if t.kind() == SyntaxKind::WORD => { + segments.push(Name::new(t.text())); + } + NodeOrToken::Token(t) if t.kind() == SyntaxKind::DOT => {} + // Stop at generics (`<...>`) or anything past the path. + _ => break, } } + segments +} - // Classify pattern binding names as Variable. - for (pat_id, pattern) in expr_body.patterns.iter() { - let Some(name) = pattern.binding_name(&expr_body.patterns) else { - continue; - }; - let name_str = name.as_str(); - - let span = source_map.pattern_span(pat_id); - if span.is_empty() { - continue; +/// Classify a single leaf token from its parent kind, reproducing what the old +/// per-node handlers emitted for direct child tokens. Stateful position checks +/// (which WORD is the name, a key before its `:`) are read off the typed AST or +/// preceding siblings. Returns `None` for tokens with no parent-driven class, so +/// the caller falls back to the syntactic classification ([`Walk::token`]). +fn classify_token(token: &SyntaxToken) -> Option { + let parent = token.parent()?; + let kind = token.kind(); + let word = kind == SyntaxKind::WORD; + match parent.kind() { + SyntaxKind::ATTRIBUTE | SyntaxKind::BLOCK_ATTRIBUTE => { + (matches!(kind, SyntaxKind::AT_AT | SyntaxKind::AT | SyntaxKind::WORD) + || kind.is_keyword()) + .then_some(plain(SemanticTokenType::Decorator)) } - let span_start: usize = span.start().into(); - let span_end: usize = span.end().into(); - if span_end > file_text.len() { - continue; + SyntaxKind::CLIENT_TYPE => word.then_some(plain(SemanticTokenType::Type)), + SyntaxKind::CONFIG_ITEM => { + (kind.is_keyword() || word).then_some(plain(SemanticTokenType::Property)) } - let pat_text = &file_text[span_start..span_end]; - if let Some(offset) = pat_text.find(name_str) { - let name_start = span_start + offset; - let name_end = name_start + name_str.len(); - let name_range = TextRange::new( - name_start.try_into().unwrap_or_default(), - name_end.try_into().unwrap_or_default(), - ); - map.insert(name_range, SemanticTokenType::Variable); + SyntaxKind::CLIENT_FIELD => { + (kind == SyntaxKind::KW_CLIENT).then_some(plain(SemanticTokenType::Property)) + } + // A generic parameter declaration (`T` in `class Box`, ``): + // the leading name as a `TypeParameter` declaration; a bound is a child + // `TYPE_EXPR` and classifies on its own. + SyntaxKind::GENERIC_PARAM => GenericParam::cast(parent) + .and_then(|p| p.name()) + .filter(|name| name.text_range() == token.text_range()) + .map(|_| decl(SemanticTokenType::TypeParameter)), + SyntaxKind::ENUM_DEF => word.then_some(decl(SemanticTokenType::Enum)), + SyntaxKind::ENUM_VARIANT => word.then_some(decl(SemanticTokenType::EnumMember)), + SyntaxKind::CLASS_DEF => word.then_some(decl(SemanticTokenType::Class)), + SyntaxKind::INTERFACE_DEF => word.then_some(decl(SemanticTokenType::Interface)), + SyntaxKind::FIELD | SyntaxKind::PROMPT_FIELD => { + word.then_some(decl(SemanticTokenType::Property)) + } + SyntaxKind::PARAMETER => word.then_some(decl(SemanticTokenType::Parameter)), + // `let x`, match-arm bindings, etc.: the bound name is a declaration. + SyntaxKind::BINDING_PATTERN => word.then_some(decl(SemanticTokenType::Variable)), + // The catch binding(s) `catch (e, stack) { … }` — parameter-like locals + // bound by the clause and scoped to its body (consistent with uses, + // which resolve via DefinitionSite::CatchBinding -> parameter). + SyntaxKind::CATCH_BINDING | SyntaxKind::CATCH_STACK_TRACE_BINDING => { + word.then_some(decl(SemanticTokenType::Parameter)) + } + SyntaxKind::CLIENT_DEF | SyntaxKind::RETRY_POLICY_DEF | SyntaxKind::TEST_DEF => { + word.then_some(decl(SemanticTokenType::Struct)) } + SyntaxKind::TEMPLATE_STRING_DEF => word.then_some(decl(SemanticTokenType::Function)), + // The name as a `Function`, or a `Method` inside a class / interface / + // implements block. + SyntaxKind::FUNCTION_DEF | SyntaxKind::METHOD_SIG => word.then(|| { + decl(if in_method_context(&parent) { + SemanticTokenType::Method + } else { + SemanticTokenType::Function + }) + }), + SyntaxKind::TYPE_ALIAS_DEF | SyntaxKind::ASSOCIATED_TYPE_DECL => { + classify_type_decl_word(token) + } + // A bare-word key (before the `:`) is a `Property`; a string key and the + // value expression are dispatched as nodes. + SyntaxKind::OBJECT_FIELD => ObjectField::cast(parent) + .and_then(|f| f.key()) + .filter(|key| key.text_range() == token.text_range()) + .map(|_| plain(SemanticTokenType::Property)), + // A named argument `name = value` at a call site: the name refers to the + // callee's parameter. + SyntaxKind::CALL_ARG => CallArg::cast(parent) + .and_then(|a| a.name()) + .filter(|name| name.text_range() == token.text_range()) + .map(|_| plain(SemanticTokenType::Parameter)), + _ => None, + } +} + +/// Classify a WORD inside a `TYPE_ALIAS_DEF` (`type X = …`), an associated-type +/// *declaration* (`type Item [extends Bound] [= Default]`), or an associated-type +/// *binding* (`Item = string` inside `Iterator<…>`). The leading `type` keywords +/// (WORDs in the grammar) are `Keyword`; the type name is `Type` — a declaration +/// when introduced by `type`, otherwise a reference (a binding names an existing +/// associated type). Bounds / values are child `TYPE_EXPR`s classified on their +/// own. +fn classify_type_decl_word(token: &SyntaxToken) -> Option { + if token.kind() != SyntaxKind::WORD { + return None; } + let parent = token.parent()?; + // The name is the first direct WORD (bounds/values are child TYPE_EXPRs). + let first_word = parent + .children_with_tokens() + .filter_map(NodeOrToken::into_token) + .find(|t| t.kind() == SyntaxKind::WORD)?; + if first_word.text_range() != token.text_range() { + return None; + } + // Introduced by a `type` keyword => a declaration; otherwise a binding. + let is_decl = parent + .children_with_tokens() + .filter_map(NodeOrToken::into_token) + .any(|t| t.kind() == SyntaxKind::KW_TYPE); + let ty = SemanticTokenType::Type; + Some(if is_decl { decl(ty) } else { plain(ty) }) +} - map +// ── Type-name classification (annotations) ────────────────────────────────────── + +/// Builtin primitive type keywords. These are not `Definition`s (so they don't +/// resolve to an item), but they are part of the language's standard surface, so +/// they are classified as `Type` with the `defaultLibrary` modifier. +/// Classify a type-expression name token. +/// +/// Resolves the name through the real resolver (the same path used by go-to-def), +/// so user types, dependency types, and `baml` stdlib types are all classified by +/// what they actually name. Builtins (resolved stdlib types and primitives) get +/// `defaultLibrary`. A name in type position that doesn't resolve is still a +/// type (e.g. a type parameter or an as-yet-undefined type) — only an explicit +/// path *prefix* is a namespace, which the caller handles. +fn classify_type_token(db: &dyn Db, file: SourceFile, name: &str, offset: TextSize) -> Class { + if let Some(class) = classify::classify_primitive(name) { + return class; + } + let resolved = resolve_name_at(db, file, offset, &Name::new(name)); + classify::classify_resolved(&resolved).unwrap_or_else(|| plain(SemanticTokenType::Type)) } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs new file mode 100644 index 0000000000..af2f0d98b3 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs @@ -0,0 +1,132 @@ +//! Map a resolved entity to a semantic token type + modifiers. +//! +//! BAML's analog of rust-analyzer's `highlight_def`: classification is driven by +//! what a name *resolves to*, never by syntactic context — and the type system is +//! not consulted here, only resolution facts. A reference is classified the same +//! way as its definition; the caller adds `ModifierSet::DECLARATION` at +//! definition sites. + +use baml_compiler2_hir::{ + contributions::{Definition, DefinitionKind}, + semantic_index::DefinitionSite, +}; +use baml_compiler2_tir::{inference::MemberResolution, resolve::ResolvedName}; + +use super::{ModifierSet, SemanticTokenType}; + +/// Primitive type names — the built-in scalar / collection types. +const PRIMITIVE_TYPES: &[&str] = &[ + "int", + "bigint", + "float", + "string", + "bool", + "bytes", + "uint8array", + "null", + "void", + "image", + "audio", + "video", + "pdf", + "json", + "map", + "unknown", + "never", +]; + +/// Classify a name iff it is a primitive type (`string`, `int`, ...): a +/// `defaultLibrary` `Type`. Used for both type-position names and value-position +/// path roots (`string.from(...)`), so a primitive is highlighted identically +/// wherever it appears. +pub(super) fn classify_primitive(name: &str) -> Option<(SemanticTokenType, ModifierSet)> { + PRIMITIVE_TYPES + .contains(&name) + .then_some((SemanticTokenType::Type, ModifierSet::DEFAULT_LIBRARY)) +} + +/// A namespace classification, flagged `defaultLibrary` when it belongs to a +/// builtin / dependency package (`baml`, ...) rather than the file's own +/// package. Shared by value-position (path roots/tails) and type-position +/// (`type_run`) so a namespace is highlighted identically wherever it appears. +pub(super) fn namespace_class(is_builtin: bool) -> (SemanticTokenType, ModifierSet) { + let modifiers = if is_builtin { + ModifierSet::DEFAULT_LIBRARY + } else { + ModifierSet::empty() + }; + (SemanticTokenType::Namespace, modifiers) +} + +/// The base token type for a definition kind. +/// +/// Mirrors `baml_cli::paint::kind_style` so terminal `describe` highlighting and +/// LSP semantic tokens agree on the palette. +pub(super) fn token_type_for_kind(kind: DefinitionKind) -> SemanticTokenType { + use DefinitionKind as K; + use SemanticTokenType as T; + match kind { + K::Class => T::Class, + K::Enum => T::Enum, + K::Interface => T::Interface, + K::TypeAlias | K::AssociatedType => T::Type, + K::Function | K::TemplateString => T::Function, + K::Method => T::Method, + K::Client | K::Test | K::RetryPolicy => T::Struct, + K::Field => T::Property, + K::Variant => T::EnumMember, + K::Parameter => T::Parameter, + K::Let | K::Binding => T::Variable, + } +} + +/// Classify a resolved bare name / path root. +/// +/// Returns `None` for unresolved names so the walker can fall back to a neutral +/// classification rather than guessing. +pub(super) fn classify_resolved( + resolved: &ResolvedName<'_>, +) -> Option<(SemanticTokenType, ModifierSet)> { + match resolved { + ResolvedName::Local { + definition_site, .. + } => { + let token_type = match definition_site { + // Function parameters and catch bindings highlight as parameters. + Some(DefinitionSite::Parameter(_) | DefinitionSite::CatchBinding(_)) => { + SemanticTokenType::Parameter + } + // `let` bindings and pattern bindings are both plain variables. + _ => SemanticTokenType::Variable, + }; + Some((token_type, ModifierSet::empty())) + } + ResolvedName::Item(def) => Some((token_type_for_definition(*def), ModifierSet::empty())), + ResolvedName::Builtin(def) => Some(( + token_type_for_definition(*def), + ModifierSet::DEFAULT_LIBRARY, + )), + ResolvedName::Unknown => None, + } +} + +/// The base token type for a resolved top-level definition. +pub(super) fn token_type_for_definition(def: Definition<'_>) -> SemanticTokenType { + token_type_for_kind(def.kind()) +} + +/// Classify a member access / path segment resolution. +pub(super) fn classify_member(res: &MemberResolution<'_>) -> (SemanticTokenType, ModifierSet) { + use MemberResolution as M; + use SemanticTokenType as T; + let token_type = match res { + M::Field { .. } | M::InterfaceVirtualField { .. } => T::Property, + M::Variant { .. } => T::EnumMember, + M::Free { .. } => T::Function, + M::BoundMethod { .. } + | M::UnboundMethod { .. } + | M::InterfaceConcreteMethod { .. } + | M::InterfaceVirtualMethod { .. } => T::Method, + }; + (token_type, ModifierSet::empty()) +} diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs new file mode 100644 index 0000000000..a76bf3f30d --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs @@ -0,0 +1,246 @@ +//! Per-file resolution index for expression-body name occurrences. +//! +//! For every inference-bearing scope (function body, lambda/closure, top-level +//! `let` initializer — reached uniformly via `scope_body`), records the exact +//! source span of each classifiable name occurrence -> (token type, modifiers): +//! +//! - **path roots** (`x`, `foo`, `baml`, `Status`) resolved by offset, +//! - **local-rooted path segments** (`obj.a.b`) from `path_member_resolutions`, +//! - **type/package-rooted path leaves** (`Status.Active`, `baml.env.get`) from +//! the path expression's `resolution` / `resolve_path_at`, with inner segments +//! as namespaces, +//! - **member accesses** (`p.name`, `s.Celebrate()`) from `resolution`. +//! +//! Spans come from the AST source map (`path_segment_span`, +//! `member_access_member_span`) — never substring scanning — and kinds come from +//! name resolution — never the `Ty`. Pattern bindings (`let x`, match arms) are +//! handled by the walker from their `BINDING_PATTERN` CST nodes, not here. + +use std::{collections::HashMap, sync::Arc}; + +use baml_base::SourceFile; +use baml_compiler2_ast::{Expr, ExprBody, ExprId}; +use baml_compiler2_hir::scope::{ScopeId, ScopeKind}; +use baml_compiler2_tir::{ + inference::{ScopeInference, infer_scope_types, scope_body, scope_inference_owner}, + resolve::{ResolvedName, resolve_name_at, resolve_namespace_prefix, resolve_path_at}, +}; +use text_size::{TextRange, TextSize}; + +use super::{ModifierSet, SemanticTokenType, classify}; +use crate::Db; + +/// A classification keyed by the exact source span of a name occurrence. +pub(super) type ResolutionIndex = HashMap; + +/// Record `class` at `span` unless the span is empty or already classified +/// (first writer wins, matching document order). +fn record(index: &mut ResolutionIndex, span: TextRange, class: (SemanticTokenType, ModifierSet)) { + if !span.is_empty() { + index.entry(span).or_insert(class); + } +} + +/// On-demand classification of a single name token: which scope's inference +/// owns the expression at `range`, indexed lazily and cached per scope. +/// +/// This is the rust-analyzer `Semantics::resolve(token)` model — a viewport / +/// range request only pays for the scopes it actually touches, instead of +/// resolving every scope in the file up front. +pub(super) fn resolve_token_class( + db: &dyn Db, + file: SourceFile, + range: TextRange, +) -> Option<(SemanticTokenType, ModifierSet)> { + let sem_index = baml_compiler2_hir::file_semantic_index(db, file); + // Walk innermost scope -> ancestors. The token's expression may be indexed + // by an enclosing inference-bearing scope rather than the innermost one + // (e.g. a `test ... with ` clause, or a value spanning nested + // scopes), so probe up the chain — each `scope_resolution_index` is cached. + let mut fsi = sem_index.scope_at_offset(range.start(), None); + loop { + let scope_id = sem_index.scope_ids[fsi.index() as usize]; + // Normalize to the inference-owner scope so sibling block/template + // scopes that share an owner body hit one Salsa cache entry instead of + // each rebuilding the same `scope_resolution_index` under a distinct key + // (the `build` whole-file path already keys by the owner scope id). + let owner = scope_inference_owner(db, scope_id); + if let Some(class) = scope_resolution_index(db, owner).get(&range).copied() { + return Some(class); + } + match sem_index.scopes[fsi.index() as usize].parent { + Some(parent) => fsi = parent, + None => return None, + } + } +} + +/// The resolution index for one inference-bearing scope's body — span -> (token +/// type, modifiers) for every classifiable name occurrence in it. Salsa-cached +/// per `ScopeId` (rust-analyzer's body-granularity memoization): the first token +/// resolved in a scope pays for indexing its whole body; the rest are lookups. +#[salsa::tracked(returns(clone))] +pub(super) fn scope_resolution_index(db: &dyn Db, scope_id: ScopeId<'_>) -> Arc { + let mut index = ResolutionIndex::new(); + // `scope_body` resolves `scope_id` to its inference owner (a Function / + // Lambda / Let), so a token inside a `spawn`/block scope indexes — and is + // found in — its owning body's index. + if let Some(body) = scope_body(db, scope_id) { + let inference = infer_scope_types(db, body.scope); + index_function( + db, + scope_id.file(db), + &body.expr_body, + &body.source_map, + inference, + &mut index, + ); + } + Arc::new(index) +} + +/// Whole-file resolution index — the merge of every inference-bearing scope's +/// (per-scope, salsa-cached) index. A full-document request classifies every +/// token anyway, so it builds the merge; editing one scope only invalidates +/// that scope's `scope_resolution_index`, not the whole file. A range request +/// instead resolves on demand via [`resolve_token_class`]. +pub(super) fn build(db: &dyn Db, file: SourceFile) -> ResolutionIndex { + let mut index = ResolutionIndex::new(); + let sem_index = baml_compiler2_hir::file_semantic_index(db, file); + for (i, scope) in sem_index.scopes.iter().enumerate() { + if scope.is_template_body + || !matches!( + scope.kind, + ScopeKind::Function | ScopeKind::Lambda | ScopeKind::Let + ) + { + continue; + } + for (&span, &class) in scope_resolution_index(db, sem_index.scope_ids[i]).iter() { + record(&mut index, span, class); + } + } + index +} + +/// Index every classifiable name occurrence in one function body. +fn index_function( + db: &dyn Db, + file: SourceFile, + expr_body: &ExprBody, + source_map: &baml_compiler2_ast::AstSourceMap, + inference: &ScopeInference<'_>, + index: &mut ResolutionIndex, +) { + for (expr_id, expr) in expr_body.exprs.iter() { + match expr { + Expr::Path(segments) if !segments.is_empty() => { + let seg_span = source_map.path_segment_span(expr_id, 0); + // For a generic-applied callee (`id(...)`), segment 0's span + // covers the whole `id`; narrow it to the root identifier so + // it matches the WORD token the walker emits. + let root_span = TextRange::at(seg_span.start(), TextSize::of(segments[0].as_str())); + let resolved_root = resolve_name_at(db, file, root_span.start(), &segments[0]); + match classify::classify_resolved(&resolved_root) { + Some(class) => record(index, root_span, class), + // A primitive type as a path root (`string.from(...)`) — the + // same `defaultLibrary` Type as in type position. + None if classify::classify_primitive(segments[0].as_str()).is_some() => { + if let Some(class) = classify::classify_primitive(segments[0].as_str()) { + record(index, root_span, class); + } + } + // Root of a dotted path: a namespace ONLY if it actually + // resolves as one (a real package/namespace), never guessed — + // a typo'd prefix stays neutral. + None if segments.len() > 1 => { + if let Some(builtin) = resolve_namespace_prefix(db, file, &segments[0..1]) { + record(index, root_span, classify::namespace_class(builtin)); + } + } + None => {} + } + + if segments.len() > 1 { + index_path_tail(db, file, expr_id, segments, source_map, inference, index); + } + } + + // `a.b` and `a?.b` (null chaining) — classify the member name from + // the inference. Interface members (casts, `Self` methods) now record + // a resolution like any other member, so an unresolved one is a real + // unknown (e.g. a typo) and stays neutral. + Expr::MemberAccess { .. } | Expr::OptionalMemberAccess { .. } => { + if let Some(res) = inference.resolution(expr_id) { + record( + index, + source_map.member_access_member_span(expr_id), + classify::classify_member(res), + ); + } + } + + _ => {} + } + } +} + +/// Classify the non-root segments of a multi-segment path. +fn index_path_tail( + db: &dyn Db, + file: SourceFile, + expr_id: ExprId, + segments: &[baml_base::Name], + source_map: &baml_compiler2_ast::AstSourceMap, + inference: &ScopeInference<'_>, + index: &mut ResolutionIndex, +) { + // A local/parameter root (`self`, a `let` binding — resolved by offset, a + // cache hit) means the whole tail is member accesses, never namespace/type + // segments. + let root_span = source_map.path_segment_span(expr_id, 0); + let local_root = matches!( + resolve_name_at(db, file, root_span.start(), &segments[0]), + ResolvedName::Local { .. } + ); + // Per-segment member resolutions for local-rooted paths (`obj.a.b`). + let members = inference.path_member_resolution(expr_id); + let leaf = segments.len() - 1; + + for k in 1..segments.len() { + let span = source_map.path_segment_span(expr_id, k); + // 1. A recorded field/variant/method resolution wins. + if let Some(res) = members.and_then(|m| m.get(k - 1)) { + record(index, span, classify::classify_member(res)); + continue; + } + // 2. A type-rooted leaf member (e.g. `Status.Active`) lives in + // `resolution`, not `path_member_resolution`. + if k == leaf && members.is_none() { + if let Some(res) = inference.resolution(expr_id) { + record(index, span, classify::classify_member(res)); + continue; + } + } + // 3. A local's members are never namespaces. Real members (including + // interface `Self` methods/fields) now carry a resolution handled + // above; anything still unresolved here is a genuine unknown (a typo), + // so leave it neutral rather than emit a bogus namespace. + if local_root { + continue; + } + // 4. Package/type-rooted: resolve the prefix so a namespace prefix stays + // a namespace while a type segment is classified as one. + let resolved = resolve_path_at(db, file, span.start(), &segments[0..=k], None); + match classify::classify_resolved(&resolved) { + Some(class) => record(index, span, class), + // A namespace ONLY if the prefix actually resolves as one — never + // guessed, so a typo'd segment stays neutral instead of bogus-namespace. + None => { + if let Some(builtin) = resolve_namespace_prefix(db, file, &segments[0..=k]) { + record(index, span, classify::namespace_class(builtin)); + } + } + } + } +} diff --git a/baml_language/crates/baml_lsp2_actions/src/type_info.rs b/baml_language/crates/baml_lsp2_actions/src/type_info.rs index c65c353b17..acb4d3fd7b 100644 --- a/baml_language/crates/baml_lsp2_actions/src/type_info.rs +++ b/baml_language/crates/baml_lsp2_actions/src/type_info.rs @@ -701,11 +701,19 @@ fn local_type_info( }) } - DefinitionSite::PatternBinding(_) => { - // Pattern bindings — report as local variable with unknown type for now. + DefinitionSite::PatternBinding(pat_id) | DefinitionSite::CatchBinding(pat_id) => { + // Resolve the binding type from inference (matching completions) so + // hover agrees with completion type info instead of reporting + // "unknown". `PatId` is body-local, so walk the use-site's scope + // chain (collision-safe) rather than probing the enclosing function + // body first, which could match a same-index binding in another body + // for pattern/catch bindings inside closures or nested blocks. + let ty_str = find_binding_ty_in_scopes(db, index, scope_id, pat_id) + .map(|ty| display_local_binding_ty(db, file, &ty)) + .unwrap_or_else(|| "unknown".to_string()); Some(TypeInfo::LocalVar { name: name.as_str().to_string(), - ty: "unknown".to_string(), + ty: ty_str, }) } } diff --git a/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs b/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs index a4c7f0f392..be8110a31c 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs +++ b/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs @@ -6,3 +6,5 @@ pub mod updater; mod test_files { include!(concat!(env!("OUT_DIR"), "/generated_lsp2_tests.rs")); } +mod range_tokens_test; +mod typing_robustness_test; diff --git a/baml_language/crates/baml_lsp2_actions_tests/src/range_tokens_test.rs b/baml_language/crates/baml_lsp2_actions_tests/src/range_tokens_test.rs new file mode 100644 index 0000000000..83be845c7c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/src/range_tokens_test.rs @@ -0,0 +1,53 @@ +//! Validates the on-demand range path: `semantic_tokens_in_range(range)` must +//! equal the full `semantic_tokens()` result filtered to that range, for every +//! sub-range — the rust-analyzer `highlight_range` correctness property. + +#[cfg(test)] +mod tests { + use std::path::Path; + + use baml_lsp2_actions::tokens::{semantic_tokens, semantic_tokens_in_range}; + use baml_project::ProjectDatabase; + + fn check(src: &str) { + let mut db = ProjectDatabase::new(); + db.set_project_root(Path::new(".")); + let file = db.add_or_update_file(Path::new("range.baml"), src); + + let full = semantic_tokens(&db, file); + + // Every contiguous window of the full token stream defines a range; the + // range query over that window must reproduce exactly the windowed tokens. + for i in 0..full.len() { + for j in i..full.len() { + let range = full[i].range.cover(full[j].range); + let expected: Vec<_> = full + .iter() + .filter(|t| range.intersect(t.range).is_some()) + .cloned() + .collect(); + let actual = + semantic_tokens_in_range(&db, file, range.start().into(), range.end().into()); + assert_eq!( + actual, expected, + "range {range:?} mismatch\n expected: {expected:?}\n actual: {actual:?}" + ); + } + } + } + + #[test] + fn range_equals_filtered_full() { + check( + r#"class Box { v: T } +interface Greeter { function greet(self) -> string } +function use_it(b: Box) -> int { + let xs = [1, 2, 3]; + let f = spawn with baml.spawn.options() { baml.sys.sleep(baml.time.Duration.from_milliseconds(5n)); 1 }; + let g = b.v + (await f); + g +} +"#, + ); + } +} diff --git a/baml_language/crates/baml_lsp2_actions_tests/src/runner.rs b/baml_language/crates/baml_lsp2_actions_tests/src/runner.rs index 7bde5fa90a..652b56e7b1 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/src/runner.rs +++ b/baml_language/crates/baml_lsp2_actions_tests/src/runner.rs @@ -374,9 +374,15 @@ fn format_semantic_tokens_results( let len = end_offset - start_offset; let text = &file_content[start_offset..end_offset]; let token_type_str = token.token_type.as_str(); + let mods: Vec<&str> = token.modifiers.names().collect(); + let mods_str = if mods.is_empty() { + String::new() + } else { + format!(" [{}]", mods.join(",")) + }; output.push_str(&format!( - "// {filename}:{line}:{col} ({token_type_str}) len={len} {text:?}\n" + "// {filename}:{line}:{col} ({token_type_str}){mods_str} len={len} {text:?}\n" )); } diff --git a/baml_language/crates/baml_lsp2_actions_tests/src/typing_robustness_test.rs b/baml_language/crates/baml_lsp2_actions_tests/src/typing_robustness_test.rs new file mode 100644 index 0000000000..a90cec20a6 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/src/typing_robustness_test.rs @@ -0,0 +1,207 @@ +//! Robustness: the semantic-tokens classifier (and the resolution it drives) +//! must never panic on the *incomplete* / mid-edit source that exists at every +//! keystroke — not just on the static, valid fixtures. +//! +//! Two shapes of "typing": +//! - prefixes of a source (typing forward, incomplete tail), and +//! - inserting content one char at a time *inside an already-closed nested +//! scope* (function body, match arm, implements block, lambda, catch/spawn +//! body, call args) — a different family of partial states. +//! +//! Each intermediate string is run through `semantic_tokens` + a couple of +//! `semantic_tokens_in_range` queries under `catch_unwind`; a panic fails the +//! test and prints the offending input. A fresh db per probe avoids salsa +//! revision bloat over the thousands of edits. + +#[cfg(test)] +mod tests { + use std::{ + panic::AssertUnwindSafe, + path::{Path, PathBuf}, + }; + + use baml_lsp2_actions::tokens::{semantic_tokens, semantic_tokens_in_range}; + use baml_project::ProjectDatabase; + + /// Short sources exercising the trickier constructs, each typed forward one + /// char at a time (so e.g. a half-typed raw string or `.as<` is probed). + const CURATED: &[&str] = &[ + "function f() -> string { baml.json.stringify({\"x\": 1n, \"b\": true, \"n\": null}) }", + "enum E { A, B }\nfunction g(e: E) -> int { match (e) { E.A => 0, E.B => 1 } }", + "interface I { name: string }\nclass C { dn: string\n implements I { name as dn }\n}", + "function h(x: int) -> int throws string { throw \"x\" }\n\ + function j() -> int { h(1) catch (e) { _ => e } }", + "class Box { v: T }\n\ + function k(b: Box) -> int {\n\ + let f = spawn with baml.spawn.options() { baml.time.Duration.from_milliseconds(5n); 1 };\n\ + b.v + (await f)\n\ + }", + "function s(q: string, n: int = 1) -> int { n }\n\ + function u() -> int { s(q = \"a\", n = 2) }", + "type Alias = int[]\ninterface It { type Item\n function next(self) -> Item }", + "function o(p: Person?) -> string? { p?.name }\nclass Person { name: string }", + // Raw strings — the construct whose incomplete state panicked the parser. + "function r() -> string { #\"raw text\"# }", + "function r2() -> string { ##\"two #hashes\"## }", + // Backtick template string with interpolation. + "function b() -> string { `hello ${1 + 2}` }", + // String escapes + a client block. + "client Cl { provider \"openai\" }\nfunction e() -> string { \"\\n\\t\\u{1f600}\" }", + ]; + + /// `(prefix, content, suffix)` — `content` is typed one char at a time + /// *between* `prefix` and `suffix`, which stay structurally complete. + const NESTED: &[(&str, &str, &str)] = &[ + ( + "enum E { A }\nfunction f() -> int {\n ", + "baml.json.stringify({\"a\": 1n}).length() + E.A", + "\n}", + ), + ( + "enum E { A, B }\nfunction g(e: E) -> int {\n match (e) {\n E.A => ", + "baml.time.Duration.from_milliseconds(5n)", + ",\n E.B => 1\n }\n}", + ), + ( + "interface I { name: string }\nclass C {\n dn: string\n implements I {\n ", + "name as dn", + "\n }\n}", + ), + ( + "enum E { A }\nfunction h() -> int {\n let m = (x: int) -> int {\n ", + "x + E.A", + "\n };\n m(1)\n}", + ), + ( + "function j(x: int) -> int throws string {\n throw \"e\"\n}\n\ + function k() -> int {\n j(1) catch (e) {\n _ => ", + "e", + "\n }\n}", + ), + ( + "function s() -> int {\n let f = spawn with baml.spawn.options() {\n ", + "baml.sys.sleep(baml.time.Duration.from_milliseconds(5n)); 1", + "\n };\n await f\n}", + ), + ( + "function q(a: string, b: int = 1) -> int { b }\nfunction r() -> int {\n q(", + "a = \"x\", b = 2", + ")\n}", + ), + ]; + + fn make_db() -> ProjectDatabase { + let mut db = ProjectDatabase::new(); + db.set_project_root(Path::new(".")); + db + } + + /// Run the classifier (full + range) on one input, catching any panic. The + /// db is reused across probes so the `baml` stdlib is built once, not per + /// keystroke (rebuilding it each time is ~100x slower). + fn survives(db: &mut ProjectDatabase, input: &str) -> bool { + std::panic::catch_unwind(AssertUnwindSafe(|| { + let file = db.add_or_update_file(Path::new("typing.baml"), input); + // Full document (the index path an editor calls once). + let _ = semantic_tokens(&*db, file); + // Viewport-sized windows (the on-demand range path editors call per + // scroll) at the start, middle, and end of the document. + let len = u32::try_from(input.len()).unwrap_or(u32::MAX); + let window = 200u32.min(len); + for start in [ + 0, + len.saturating_sub(window) / 2, + len.saturating_sub(window), + ] { + let _ = semantic_tokens_in_range(&*db, file, start, (start + window).min(len)); + } + })) + .is_ok() + } + + fn type_prefixes(db: &mut ProjectDatabase, src: &str) { + for end in 1..=src.len() { + if src.is_char_boundary(end) { + let input = &src[..end]; + assert!( + survives(db, input), + "panicked typing prefix ({end}B):\n{input}\n" + ); + } + } + } + + fn type_in_scope(db: &mut ProjectDatabase, prefix: &str, content: &str, suffix: &str) { + for k in 0..=content.len() { + if content.is_char_boundary(k) { + let input = format!("{prefix}{}{suffix}", &content[..k]); + assert!( + survives(db, &input), + "panicked typing in a nested scope ({k}B):\n{input}\n" + ); + } + } + } + + fn fixture_sources() -> Vec { + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test_files/semantic_tokens"); + let mut sources = Vec::new(); + for entry in std::fs::read_dir(&dir).into_iter().flatten().flatten() { + let path = entry.path(); + if path.extension().and_then(|e| e.to_str()) != Some("baml") { + continue; + } + if let Ok(content) = std::fs::read_to_string(&path) { + // The source is everything before the `//----` snapshot block. + let source = content + .split("//----") + .next() + .unwrap_or_default() + .to_string(); + if !source.trim().is_empty() { + sources.push(source); + } + } + } + sources + } + + #[test] + fn no_crash_typing_curated() { + let mut db = make_db(); + for src in CURATED { + type_prefixes(&mut db, src); + } + } + + #[test] + fn no_crash_typing_in_nested_scope() { + let mut db = make_db(); + for (prefix, content, suffix) in NESTED { + type_in_scope(&mut db, prefix, content, suffix); + } + } + + /// Thorough broad sweep: type *every committed fixture* one char at a time, + /// full length. This rebuilds the resolution index per keystroke for ~80 + /// real-world files, so it runs for minutes and is `#[ignore]`d — run it + /// on-demand (`cargo test -p baml_lsp2_actions_tests -- --ignored typing`) + /// when touching the parser/classifier. The always-run `curated` + nested + /// tests carry the fast, fine-grained construct coverage. + #[test] + #[ignore = "slow broad fuzz (~minutes); run with --ignored"] + fn no_crash_typing_fixtures() { + let mut db = make_db(); + for src in fixture_sources() { + for end in 1..=src.len() { + if src.is_char_boundary(end) { + let input = &src[..end]; + assert!( + survives(&mut db, input), + "panicked typing fixture prefix ({end}B):\n{input}\n" + ); + } + } + } + } +} diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/array_pattern.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/array_pattern.baml new file mode 100644 index 0000000000..cc4e828374 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/array_pattern.baml @@ -0,0 +1,37 @@ +// Array destructure in let-else: bare identifiers inside a pattern are +// TYPE patterns by default, so the binding names need explicit `let` +// markers. The whole pattern is refutable on `int[]` because the array +// could be shorter than two elements. +function FirstTwo(xs: int[]) -> int { + let [let a, let b] = xs else { return -1; }; + a + b +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// array_pattern.baml:1:1 (comment) len=71 "// Array destructure in let-else: bare identifiers inside a pattern are" +// array_pattern.baml:2:1 (comment) len=69 "// TYPE patterns by default, so the binding names need explicit `let`" +// array_pattern.baml:3:1 (comment) len=71 "// markers. The whole pattern is refutable on `int[]` because the array" +// array_pattern.baml:4:1 (comment) len=38 "// could be shorter than two elements." +// array_pattern.baml:5:1 (keyword) len=8 "function" +// array_pattern.baml:5:10 (function) [declaration] len=8 "FirstTwo" +// array_pattern.baml:5:19 (parameter) [declaration] len=2 "xs" +// array_pattern.baml:5:23 (type) [defaultLibrary] len=3 "int" +// array_pattern.baml:5:33 (type) [defaultLibrary] len=3 "int" +// array_pattern.baml:6:3 (keyword) len=3 "let" +// array_pattern.baml:6:8 (keyword) len=3 "let" +// array_pattern.baml:6:12 (variable) [declaration] len=1 "a" +// array_pattern.baml:6:15 (keyword) len=3 "let" +// array_pattern.baml:6:19 (variable) [declaration] len=1 "b" +// array_pattern.baml:6:22 (operator) len=1 "=" +// array_pattern.baml:6:24 (parameter) len=2 "xs" +// array_pattern.baml:6:27 (keyword) len=4 "else" +// array_pattern.baml:6:34 (keyword) len=6 "return" +// array_pattern.baml:6:41 (operator) len=1 "-" +// array_pattern.baml:6:42 (number) len=1 "1" +// array_pattern.baml:7:3 (variable) len=1 "a" +// array_pattern.baml:7:5 (operator) len=1 "+" +// array_pattern.baml:7:7 (variable) len=1 "b" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/attributes.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/attributes.baml new file mode 100644 index 0000000000..26496ab5c9 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/attributes.baml @@ -0,0 +1,24 @@ +// Field attributes (`@description`, `@alias`) classified as decorators. +class Resume { + name string @description("the candidate's full name") + email string @alias("email_address") +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// attributes.baml:1:1 (comment) len=72 "// Field attributes (`@description`, `@alias`) classified as decorators." +// attributes.baml:2:1 (keyword) len=5 "class" +// attributes.baml:2:7 (class) [declaration] len=6 "Resume" +// attributes.baml:3:3 (property) [declaration] len=4 "name" +// attributes.baml:3:8 (type) [defaultLibrary] len=6 "string" +// attributes.baml:3:15 (decorator) len=1 "@" +// attributes.baml:3:16 (decorator) len=11 "description" +// attributes.baml:3:28 (string) len=27 "\"the candidate's full name\"" +// attributes.baml:4:3 (property) [declaration] len=5 "email" +// attributes.baml:4:9 (type) [defaultLibrary] len=6 "string" +// attributes.baml:4:16 (decorator) len=1 "@" +// attributes.baml:4:17 (decorator) len=5 "alias" +// attributes.baml:4:23 (string) len=15 "\"email_address\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/backtick_string.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/backtick_string.baml new file mode 100644 index 0000000000..94dafa6239 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/backtick_string.baml @@ -0,0 +1,29 @@ +// BEP-049 backtick interpolated strings: literal text is `string`, while +// `${ expr }` interpolations are real code (resolved through the index). +function Greeting(name: string, count: int) -> string { + `Hello ${name}, you have ${count} messages` +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// backtick_string.baml:1:1 (comment) len=73 "// BEP-049 backtick interpolated strings: literal text is `string`, while" +// backtick_string.baml:2:1 (comment) len=73 "// `${ expr }` interpolations are real code (resolved through the index)." +// backtick_string.baml:3:1 (keyword) len=8 "function" +// backtick_string.baml:3:10 (function) [declaration] len=8 "Greeting" +// backtick_string.baml:3:19 (parameter) [declaration] len=4 "name" +// backtick_string.baml:3:25 (type) [defaultLibrary] len=6 "string" +// backtick_string.baml:3:33 (parameter) [declaration] len=5 "count" +// backtick_string.baml:3:40 (type) [defaultLibrary] len=3 "int" +// backtick_string.baml:3:48 (type) [defaultLibrary] len=6 "string" +// backtick_string.baml:4:3 (string) len=1 "`" +// backtick_string.baml:4:4 (string) len=5 "Hello" +// backtick_string.baml:4:12 (parameter) len=4 "name" +// backtick_string.baml:4:17 (string) len=1 "," +// backtick_string.baml:4:19 (string) len=3 "you" +// backtick_string.baml:4:23 (string) len=4 "have" +// backtick_string.baml:4:30 (parameter) len=5 "count" +// backtick_string.baml:4:37 (string) len=8 "messages" +// backtick_string.baml:4:45 (string) len=1 "`" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/bigint_literals.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/bigint_literals.baml new file mode 100644 index 0000000000..bfc73eda28 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/bigint_literals.baml @@ -0,0 +1,29 @@ +// Bigint literals (`42n`) should highlight as numbers, like int/float. + +function BigMath() -> bigint { + let a: bigint = 42n; + let b = a + 100n; + b +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// bigint_literals.baml:1:1 (comment) len=71 "// Bigint literals (`42n`) should highlight as numbers, like int/float." +// bigint_literals.baml:3:1 (keyword) len=8 "function" +// bigint_literals.baml:3:10 (function) [declaration] len=7 "BigMath" +// bigint_literals.baml:3:23 (type) [defaultLibrary] len=6 "bigint" +// bigint_literals.baml:4:3 (keyword) len=3 "let" +// bigint_literals.baml:4:7 (variable) [declaration] len=1 "a" +// bigint_literals.baml:4:10 (type) [defaultLibrary] len=6 "bigint" +// bigint_literals.baml:4:17 (operator) len=1 "=" +// bigint_literals.baml:4:19 (number) len=3 "42n" +// bigint_literals.baml:5:3 (keyword) len=3 "let" +// bigint_literals.baml:5:7 (variable) [declaration] len=1 "b" +// bigint_literals.baml:5:9 (operator) len=1 "=" +// bigint_literals.baml:5:11 (variable) len=1 "a" +// bigint_literals.baml:5:13 (operator) len=1 "+" +// bigint_literals.baml:5:15 (number) len=4 "100n" +// bigint_literals.baml:6:3 (variable) len=1 "b" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml new file mode 100644 index 0000000000..0d4462181d --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml @@ -0,0 +1,151 @@ +class TestClassAlias { + key string @alias("key-dash") + @description(#" + This is a description for key + af asdf + "#) + key2 string @alias("key21") @alias("key22") + key3 string @alias("key with space") + key4 string @alias("key.with.punctuation/123") +} + +class HasTwoBlockAttributes { + name string + @@description("A test") + @@alias("AKAHasTwo") +} + +class HasThreeBlockAttributes { + name string + @@description("A test") + @@alias("AKAHasTwo") + @@description("A second description") +} + +// error: Attribute "@description" can only be defined once. +// --> class/attributes.baml:20 +// | +// 19 | name string +// 20 | @@description("A test") +// | +// error: Attribute "@description" can only be defined once. +// --> class/attributes.baml:22 +// | +// 21 | @@alias("AKAHasTwo") +// 22 | @@description("A second description") +// | +// error: Attribute "@description" can only be defined once. +// --> class/attributes.baml:20 +// | +// 19 | name string +// 20 | @@description("A test") +// | + +//---- +//- diagnostics +// error: Duplicate attribute `@alias` +// ╭─[ block_attributes.baml:7:31 ] +// │ +// 7 │ key2 string @alias("key21") @alias("key22") +// │ ───────┬─────── ───────┬─────── +// │ ╰───────────────────────── `@alias` first applied here +// │ │ +// │ ╰───────── duplicate `@alias` — only the last takes effect +// │ +// │ Note: Error code: E0014 +// ───╯ +// error: Duplicate attribute `@description` +// ╭─[ block_attributes.baml:22:3 ] +// │ +// 20 │ @@description("A test") +// │ ───────────┬─────────── +// │ ╰───────────── `@description` first applied here +// │ +// 22 │ @@description("A second description") +// │ ──────────────────┬────────────────── +// │ ╰──────────────────── duplicate `@description` — only the last takes effect +// │ +// │ Note: Error code: E0014 +// ────╯ +// +//- semantic_tokens +// block_attributes.baml:1:1 (keyword) len=5 "class" +// block_attributes.baml:1:7 (class) [declaration] len=14 "TestClassAlias" +// block_attributes.baml:2:3 (property) [declaration] len=3 "key" +// block_attributes.baml:2:7 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:2:14 (decorator) len=1 "@" +// block_attributes.baml:2:15 (decorator) len=5 "alias" +// block_attributes.baml:2:21 (string) len=10 "\"key-dash\"" +// block_attributes.baml:3:3 (decorator) len=1 "@" +// block_attributes.baml:3:4 (decorator) len=11 "description" +// block_attributes.baml:3:16 (string) len=1 "#" +// block_attributes.baml:3:17 (string) len=1 "\"" +// block_attributes.baml:4:6 (string) len=4 "This" +// block_attributes.baml:4:11 (string) len=2 "is" +// block_attributes.baml:4:14 (string) len=1 "a" +// block_attributes.baml:4:16 (string) len=11 "description" +// block_attributes.baml:4:28 (string) len=3 "for" +// block_attributes.baml:4:32 (string) len=3 "key" +// block_attributes.baml:5:6 (string) len=2 "af" +// block_attributes.baml:5:9 (string) len=4 "asdf" +// block_attributes.baml:6:4 (string) len=1 "\"" +// block_attributes.baml:6:5 (string) len=1 "#" +// block_attributes.baml:7:3 (property) [declaration] len=4 "key2" +// block_attributes.baml:7:8 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:7:15 (decorator) len=1 "@" +// block_attributes.baml:7:16 (decorator) len=5 "alias" +// block_attributes.baml:7:22 (string) len=7 "\"key21\"" +// block_attributes.baml:7:31 (decorator) len=1 "@" +// block_attributes.baml:7:32 (decorator) len=5 "alias" +// block_attributes.baml:7:38 (string) len=7 "\"key22\"" +// block_attributes.baml:8:3 (property) [declaration] len=4 "key3" +// block_attributes.baml:8:8 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:8:15 (decorator) len=1 "@" +// block_attributes.baml:8:16 (decorator) len=5 "alias" +// block_attributes.baml:8:22 (string) len=16 "\"key with space\"" +// block_attributes.baml:9:3 (property) [declaration] len=4 "key4" +// block_attributes.baml:9:8 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:9:15 (decorator) len=1 "@" +// block_attributes.baml:9:16 (decorator) len=5 "alias" +// block_attributes.baml:9:22 (string) len=26 "\"key.with.punctuation/123\"" +// block_attributes.baml:12:1 (keyword) len=5 "class" +// block_attributes.baml:12:7 (class) [declaration] len=21 "HasTwoBlockAttributes" +// block_attributes.baml:13:3 (property) [declaration] len=4 "name" +// block_attributes.baml:13:8 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:14:3 (decorator) len=2 "@@" +// block_attributes.baml:14:5 (decorator) len=11 "description" +// block_attributes.baml:14:17 (string) len=8 "\"A test\"" +// block_attributes.baml:15:3 (decorator) len=2 "@@" +// block_attributes.baml:15:5 (decorator) len=5 "alias" +// block_attributes.baml:15:11 (string) len=11 "\"AKAHasTwo\"" +// block_attributes.baml:18:1 (keyword) len=5 "class" +// block_attributes.baml:18:7 (class) [declaration] len=23 "HasThreeBlockAttributes" +// block_attributes.baml:19:3 (property) [declaration] len=4 "name" +// block_attributes.baml:19:8 (type) [defaultLibrary] len=6 "string" +// block_attributes.baml:20:3 (decorator) len=2 "@@" +// block_attributes.baml:20:5 (decorator) len=11 "description" +// block_attributes.baml:20:17 (string) len=8 "\"A test\"" +// block_attributes.baml:21:3 (decorator) len=2 "@@" +// block_attributes.baml:21:5 (decorator) len=5 "alias" +// block_attributes.baml:21:11 (string) len=11 "\"AKAHasTwo\"" +// block_attributes.baml:22:3 (decorator) len=2 "@@" +// block_attributes.baml:22:5 (decorator) len=11 "description" +// block_attributes.baml:22:17 (string) len=22 "\"A second description\"" +// block_attributes.baml:25:1 (comment) len=60 "// error: Attribute \"@description\" can only be defined once." +// block_attributes.baml:26:1 (comment) len=34 "// --> class/attributes.baml:20" +// block_attributes.baml:27:1 (comment) len=7 "// |" +// block_attributes.baml:28:1 (comment) len=21 "// 19 | name string" +// block_attributes.baml:29:1 (comment) len=33 "// 20 | @@description(\"A test\")" +// block_attributes.baml:30:1 (comment) len=7 "// |" +// block_attributes.baml:31:1 (comment) len=60 "// error: Attribute \"@description\" can only be defined once." +// block_attributes.baml:32:1 (comment) len=34 "// --> class/attributes.baml:22" +// block_attributes.baml:33:1 (comment) len=7 "// |" +// block_attributes.baml:34:1 (comment) len=30 "// 21 | @@alias(\"AKAHasTwo\")" +// block_attributes.baml:35:1 (comment) len=47 "// 22 | @@description(\"A second description\")" +// block_attributes.baml:36:1 (comment) len=7 "// |" +// block_attributes.baml:37:1 (comment) len=60 "// error: Attribute \"@description\" can only be defined once." +// block_attributes.baml:38:1 (comment) len=34 "// --> class/attributes.baml:20" +// block_attributes.baml:39:1 (comment) len=7 "// |" +// block_attributes.baml:40:1 (comment) len=21 "// 19 | name string" +// block_attributes.baml:41:1 (comment) len=33 "// 20 | @@description(\"A test\")" +// block_attributes.baml:42:1 (comment) len=7 "// |" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/break_continue.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/break_continue.baml index 7af0612973..921c13d9b2 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/break_continue.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/break_continue.baml @@ -26,39 +26,53 @@ function SumOdds() -> int { // //- semantic_tokens // break_continue.baml:1:1 (keyword) len=8 "function" -// break_continue.baml:1:10 (function) len=9 "FindFirst" -// break_continue.baml:1:25 (type) len=3 "int" +// break_continue.baml:1:10 (function) [declaration] len=9 "FindFirst" +// break_continue.baml:1:25 (type) [defaultLibrary] len=3 "int" // break_continue.baml:2:3 (keyword) len=3 "let" -// break_continue.baml:2:7 (variable) len=6 "result" +// break_continue.baml:2:7 (variable) [declaration] len=6 "result" // break_continue.baml:2:14 (operator) len=1 "=" // break_continue.baml:2:16 (number) len=1 "0" // break_continue.baml:3:3 (keyword) len=5 "while" +// break_continue.baml:3:10 (boolean) len=4 "true" // break_continue.baml:4:5 (keyword) len=2 "if" +// break_continue.baml:4:9 (variable) len=6 "result" // break_continue.baml:4:16 (operator) len=2 "==" // break_continue.baml:4:19 (number) len=1 "5" // break_continue.baml:5:7 (keyword) len=5 "break" +// break_continue.baml:7:5 (variable) len=6 "result" // break_continue.baml:7:12 (operator) len=1 "=" +// break_continue.baml:7:14 (variable) len=6 "result" // break_continue.baml:7:21 (operator) len=1 "+" // break_continue.baml:7:23 (number) len=1 "1" +// break_continue.baml:9:3 (variable) len=6 "result" // break_continue.baml:12:1 (keyword) len=8 "function" -// break_continue.baml:12:10 (function) len=7 "SumOdds" -// break_continue.baml:12:23 (type) len=3 "int" +// break_continue.baml:12:10 (function) [declaration] len=7 "SumOdds" +// break_continue.baml:12:23 (type) [defaultLibrary] len=3 "int" // break_continue.baml:13:3 (keyword) len=3 "let" +// break_continue.baml:13:7 (variable) [declaration] len=3 "sum" // break_continue.baml:13:11 (operator) len=1 "=" // break_continue.baml:13:13 (number) len=1 "0" // break_continue.baml:14:3 (keyword) len=3 "for" // break_continue.baml:14:8 (keyword) len=3 "let" +// break_continue.baml:14:12 (variable) [declaration] len=1 "i" // break_continue.baml:14:14 (operator) len=1 "=" // break_continue.baml:14:16 (number) len=1 "0" +// break_continue.baml:14:19 (variable) len=1 "i" // break_continue.baml:14:21 (operator) len=1 "<" // break_continue.baml:14:23 (number) len=2 "10" +// break_continue.baml:14:27 (variable) len=1 "i" // break_continue.baml:14:29 (operator) len=2 "+=" // break_continue.baml:14:32 (number) len=1 "1" // break_continue.baml:15:5 (keyword) len=2 "if" +// break_continue.baml:15:9 (variable) len=1 "i" // break_continue.baml:15:11 (operator) len=1 "%" // break_continue.baml:15:13 (number) len=1 "2" // break_continue.baml:15:15 (operator) len=2 "==" // break_continue.baml:15:18 (number) len=1 "0" // break_continue.baml:16:7 (keyword) len=8 "continue" +// break_continue.baml:18:5 (variable) len=3 "sum" // break_continue.baml:18:9 (operator) len=1 "=" +// break_continue.baml:18:11 (variable) len=3 "sum" // break_continue.baml:18:15 (operator) len=1 "+" +// break_continue.baml:18:17 (variable) len=1 "i" +// break_continue.baml:20:3 (variable) len=3 "sum" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/byte_strings.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/byte_strings.baml new file mode 100644 index 0000000000..2fa2530925 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/byte_strings.baml @@ -0,0 +1,197 @@ +// Byte string literal tests + +function ByteStringBasic() -> int { + let data = b"hello"; + data.length() +} + +function ByteStringEmpty() -> int { + let data = b""; + data.length() +} + +function ByteStringHexEscapes() -> int { + let data = b"\x48\x65\x6c\x6c\x6f"; + data.length() +} + +function ByteStringStandardEscapes() -> int { + let data = b"\n\t\r\0\\\""; + data.length() +} + +function ByteStringIndexAccess() -> int? { + let data = b"\x41\x42\x43"; + data.at(0) +} + +// Byte strings in expressions +function ByteStringInCondition() -> int { + if (b"abc".length() > 0) { + 1 + } else { + 0 + } +} + +function ByteStringEquality() -> bool { + b"abc" == b"abc" +} + +// Byte string as function argument +function ByteStringPassAndReturn(data: uint8array) -> int { + data.length() +} + +// Byte string index write (mutable) +function ByteStringMutate() -> int? { + let data = b"\x00\x00\x00"; + data[0] = 42; + data.at(0) +} + +// Direct index read (data[0], not .at(0)) +function ByteStringDirectIndexRead() -> int { + let data = b"\x41\x42\x43"; + data[0] +} + +// Byte string literal as function call argument +function ByteStringLiteralAsArg() -> int { + ByteStringPassAndReturn(b"abc") +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// byte_strings.baml:1:1 (comment) len=28 "// Byte string literal tests" +// byte_strings.baml:3:1 (keyword) len=8 "function" +// byte_strings.baml:3:10 (function) [declaration] len=15 "ByteStringBasic" +// byte_strings.baml:3:31 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:4:5 (keyword) len=3 "let" +// byte_strings.baml:4:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:4:14 (operator) len=1 "=" +// byte_strings.baml:4:16 (string) len=8 "b\"hello\"" +// byte_strings.baml:5:5 (variable) len=4 "data" +// byte_strings.baml:5:10 (method) len=6 "length" +// byte_strings.baml:8:1 (keyword) len=8 "function" +// byte_strings.baml:8:10 (function) [declaration] len=15 "ByteStringEmpty" +// byte_strings.baml:8:31 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:9:5 (keyword) len=3 "let" +// byte_strings.baml:9:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:9:14 (operator) len=1 "=" +// byte_strings.baml:9:16 (string) len=3 "b\"\"" +// byte_strings.baml:10:5 (variable) len=4 "data" +// byte_strings.baml:10:10 (method) len=6 "length" +// byte_strings.baml:13:1 (keyword) len=8 "function" +// byte_strings.baml:13:10 (function) [declaration] len=20 "ByteStringHexEscapes" +// byte_strings.baml:13:36 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:14:5 (keyword) len=3 "let" +// byte_strings.baml:14:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:14:14 (operator) len=1 "=" +// byte_strings.baml:14:16 (string) len=2 "b\"" +// byte_strings.baml:14:18 (escapeSequence) len=4 "\\x48" +// byte_strings.baml:14:22 (escapeSequence) len=4 "\\x65" +// byte_strings.baml:14:26 (escapeSequence) len=4 "\\x6c" +// byte_strings.baml:14:30 (escapeSequence) len=4 "\\x6c" +// byte_strings.baml:14:34 (escapeSequence) len=4 "\\x6f" +// byte_strings.baml:14:38 (string) len=1 "\"" +// byte_strings.baml:15:5 (variable) len=4 "data" +// byte_strings.baml:15:10 (method) len=6 "length" +// byte_strings.baml:18:1 (keyword) len=8 "function" +// byte_strings.baml:18:10 (function) [declaration] len=25 "ByteStringStandardEscapes" +// byte_strings.baml:18:41 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:19:5 (keyword) len=3 "let" +// byte_strings.baml:19:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:19:14 (operator) len=1 "=" +// byte_strings.baml:19:16 (string) len=2 "b\"" +// byte_strings.baml:19:18 (escapeSequence) len=2 "\\n" +// byte_strings.baml:19:20 (escapeSequence) len=2 "\\t" +// byte_strings.baml:19:22 (escapeSequence) len=2 "\\r" +// byte_strings.baml:19:24 (escapeSequence) len=2 "\\0" +// byte_strings.baml:19:26 (escapeSequence) len=2 "\\\\" +// byte_strings.baml:19:28 (escapeSequence) len=2 "\\\"" +// byte_strings.baml:19:30 (string) len=1 "\"" +// byte_strings.baml:20:5 (variable) len=4 "data" +// byte_strings.baml:20:10 (method) len=6 "length" +// byte_strings.baml:23:1 (keyword) len=8 "function" +// byte_strings.baml:23:10 (function) [declaration] len=21 "ByteStringIndexAccess" +// byte_strings.baml:23:37 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:24:5 (keyword) len=3 "let" +// byte_strings.baml:24:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:24:14 (operator) len=1 "=" +// byte_strings.baml:24:16 (string) len=2 "b\"" +// byte_strings.baml:24:18 (escapeSequence) len=4 "\\x41" +// byte_strings.baml:24:22 (escapeSequence) len=4 "\\x42" +// byte_strings.baml:24:26 (escapeSequence) len=4 "\\x43" +// byte_strings.baml:24:30 (string) len=1 "\"" +// byte_strings.baml:25:5 (variable) len=4 "data" +// byte_strings.baml:25:10 (method) len=2 "at" +// byte_strings.baml:25:13 (number) len=1 "0" +// byte_strings.baml:28:1 (comment) len=30 "// Byte strings in expressions" +// byte_strings.baml:29:1 (keyword) len=8 "function" +// byte_strings.baml:29:10 (function) [declaration] len=21 "ByteStringInCondition" +// byte_strings.baml:29:37 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:30:5 (keyword) len=2 "if" +// byte_strings.baml:30:9 (string) len=6 "b\"abc\"" +// byte_strings.baml:30:16 (method) len=6 "length" +// byte_strings.baml:30:25 (operator) len=1 ">" +// byte_strings.baml:30:27 (number) len=1 "0" +// byte_strings.baml:31:9 (number) len=1 "1" +// byte_strings.baml:32:7 (keyword) len=4 "else" +// byte_strings.baml:33:9 (number) len=1 "0" +// byte_strings.baml:37:1 (keyword) len=8 "function" +// byte_strings.baml:37:10 (function) [declaration] len=18 "ByteStringEquality" +// byte_strings.baml:37:34 (type) [defaultLibrary] len=4 "bool" +// byte_strings.baml:38:5 (string) len=6 "b\"abc\"" +// byte_strings.baml:38:12 (operator) len=2 "==" +// byte_strings.baml:38:15 (string) len=6 "b\"abc\"" +// byte_strings.baml:41:1 (comment) len=35 "// Byte string as function argument" +// byte_strings.baml:42:1 (keyword) len=8 "function" +// byte_strings.baml:42:10 (function) [declaration] len=23 "ByteStringPassAndReturn" +// byte_strings.baml:42:34 (parameter) [declaration] len=4 "data" +// byte_strings.baml:42:40 (type) [defaultLibrary] len=10 "uint8array" +// byte_strings.baml:42:55 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:43:5 (parameter) len=4 "data" +// byte_strings.baml:43:10 (method) len=6 "length" +// byte_strings.baml:46:1 (comment) len=36 "// Byte string index write (mutable)" +// byte_strings.baml:47:1 (keyword) len=8 "function" +// byte_strings.baml:47:10 (function) [declaration] len=16 "ByteStringMutate" +// byte_strings.baml:47:32 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:48:5 (keyword) len=3 "let" +// byte_strings.baml:48:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:48:14 (operator) len=1 "=" +// byte_strings.baml:48:16 (string) len=2 "b\"" +// byte_strings.baml:48:18 (escapeSequence) len=4 "\\x00" +// byte_strings.baml:48:22 (escapeSequence) len=4 "\\x00" +// byte_strings.baml:48:26 (escapeSequence) len=4 "\\x00" +// byte_strings.baml:48:30 (string) len=1 "\"" +// byte_strings.baml:49:5 (variable) len=4 "data" +// byte_strings.baml:49:10 (number) len=1 "0" +// byte_strings.baml:49:13 (operator) len=1 "=" +// byte_strings.baml:49:15 (number) len=2 "42" +// byte_strings.baml:50:5 (variable) len=4 "data" +// byte_strings.baml:50:10 (method) len=2 "at" +// byte_strings.baml:50:13 (number) len=1 "0" +// byte_strings.baml:53:1 (comment) len=42 "// Direct index read (data[0], not .at(0))" +// byte_strings.baml:54:1 (keyword) len=8 "function" +// byte_strings.baml:54:10 (function) [declaration] len=25 "ByteStringDirectIndexRead" +// byte_strings.baml:54:41 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:55:5 (keyword) len=3 "let" +// byte_strings.baml:55:9 (variable) [declaration] len=4 "data" +// byte_strings.baml:55:14 (operator) len=1 "=" +// byte_strings.baml:55:16 (string) len=2 "b\"" +// byte_strings.baml:55:18 (escapeSequence) len=4 "\\x41" +// byte_strings.baml:55:22 (escapeSequence) len=4 "\\x42" +// byte_strings.baml:55:26 (escapeSequence) len=4 "\\x43" +// byte_strings.baml:55:30 (string) len=1 "\"" +// byte_strings.baml:56:5 (variable) len=4 "data" +// byte_strings.baml:56:10 (number) len=1 "0" +// byte_strings.baml:59:1 (comment) len=48 "// Byte string literal as function call argument" +// byte_strings.baml:60:1 (keyword) len=8 "function" +// byte_strings.baml:60:10 (function) [declaration] len=22 "ByteStringLiteralAsArg" +// byte_strings.baml:60:38 (type) [defaultLibrary] len=3 "int" +// byte_strings.baml:61:5 (function) len=23 "ByteStringPassAndReturn" +// byte_strings.baml:61:29 (string) len=6 "b\"abc\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/call_named_args.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/call_named_args.baml new file mode 100644 index 0000000000..f9df075d9e --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/call_named_args.baml @@ -0,0 +1,41 @@ +// Named (optional) arguments at a call site: `name = value`. The argument +// name refers to the callee's parameter and should highlight as a parameter. + +function Search(query: string, max_results: int = 10) -> int { + query.length() + max_results +} + +function UseIt() -> int { + Search(query = "hello", max_results = 5) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// call_named_args.baml:1:1 (comment) len=74 "// Named (optional) arguments at a call site: `name = value`. The argument" +// call_named_args.baml:2:1 (comment) len=77 "// name refers to the callee's parameter and should highlight as a parameter." +// call_named_args.baml:4:1 (keyword) len=8 "function" +// call_named_args.baml:4:10 (function) [declaration] len=6 "Search" +// call_named_args.baml:4:17 (parameter) [declaration] len=5 "query" +// call_named_args.baml:4:24 (type) [defaultLibrary] len=6 "string" +// call_named_args.baml:4:32 (parameter) [declaration] len=11 "max_results" +// call_named_args.baml:4:45 (type) [defaultLibrary] len=3 "int" +// call_named_args.baml:4:49 (operator) len=1 "=" +// call_named_args.baml:4:51 (number) len=2 "10" +// call_named_args.baml:4:58 (type) [defaultLibrary] len=3 "int" +// call_named_args.baml:5:3 (parameter) len=5 "query" +// call_named_args.baml:5:9 (method) len=6 "length" +// call_named_args.baml:5:18 (operator) len=1 "+" +// call_named_args.baml:5:20 (parameter) len=11 "max_results" +// call_named_args.baml:8:1 (keyword) len=8 "function" +// call_named_args.baml:8:10 (function) [declaration] len=5 "UseIt" +// call_named_args.baml:8:21 (type) [defaultLibrary] len=3 "int" +// call_named_args.baml:9:3 (function) len=6 "Search" +// call_named_args.baml:9:10 (parameter) len=5 "query" +// call_named_args.baml:9:16 (operator) len=1 "=" +// call_named_args.baml:9:18 (string) len=7 "\"hello\"" +// call_named_args.baml:9:27 (parameter) len=11 "max_results" +// call_named_args.baml:9:39 (operator) len=1 "=" +// call_named_args.baml:9:41 (number) len=1 "5" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml new file mode 100644 index 0000000000..de376ef0b1 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml @@ -0,0 +1,229 @@ +// BEP-034 spawn options — `spawn ... with baml.spawn.options(cancel = tok)`. +// +// Helpers are top-level functions (test-block locals hit the known +// local-boxing VM bug; see ns_cancel_cascade/cancel_cascade.baml). +// +// Only deterministic, `await`-based assertions live here: a CancelToken fires +// the spawn's effective token via an async watcher, so reading `f.state()` +// immediately after `tok.cancel()` would race the watcher. `await` blocks +// until the future settles, so its outcome is deterministic. + +// Awaiting a token-cancelled spawn re-throws `Cancelled`, which is catchable. +function await_token_cancelled_catches() -> int { + let tok = baml.spawn.CancelToken.new(); + let f = spawn with baml.spawn.options(cancel = tok) { + baml.sys.sleep(baml.time.Duration.from_milliseconds(60000n)); + 42 + }; + let _ = tok.cancel(); + (await f) catch (e) { baml.panics.Cancelled => 0 } +} + +test "await_token_cancelled_catches" { + assert.is_true(baml.deep_equals(await_token_cancelled_catches(), 0)) +} + +// An un-fired token leaves the spawn to complete normally — the option must +// not perturb the happy path. +function uncancelled_token_completes() -> int { + let tok = baml.spawn.CancelToken.new(); + let f = spawn with baml.spawn.options(cancel = tok) { 42 }; + await f +} + +test "uncancelled_token_completes" { + assert.is_true(baml.deep_equals(uncancelled_token_completes(), 42)) +} + +// `CancelToken.cancel()` is synchronous on the token, so `is_cancelled()` +// observes the transition immediately (no future / watcher involved). +function token_is_cancelled_reflects_cancel() -> bool[] { + let tok = baml.spawn.CancelToken.new(); + let before = tok.is_cancelled(); + let _ = tok.cancel(); + let after = tok.is_cancelled(); + [before, after] +} + +test "token_is_cancelled_reflects_cancel" { + assert.is_true(baml.deep_equals(token_is_cancelled_reflects_cancel(), [false, true])) +} + +// `detach = true` opts out of the parent cascade but must not break normal +// completion (its survival/cascade-independence is verified by construction in +// the engine: a detached spawn gets a fresh effective token). +function detached_spawn_completes() -> int { + let f = spawn with baml.spawn.options(detach = true) { 42 }; + await f +} + +test "detached_spawn_completes" { + assert.is_true(baml.deep_equals(detached_spawn_completes(), 42)) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// cancel_token.baml:1:1 (comment) len=79 "// BEP-034 spawn options — `spawn ... with baml.spawn.options(cancel = tok)`." +// cancel_token.baml:2:1 (comment) len=2 "//" +// cancel_token.baml:3:1 (comment) len=67 "// Helpers are top-level functions (test-block locals hit the known" +// cancel_token.baml:4:1 (comment) len=67 "// local-boxing VM bug; see ns_cancel_cascade/cancel_cascade.baml)." +// cancel_token.baml:5:1 (comment) len=2 "//" +// cancel_token.baml:6:1 (comment) len=78 "// Only deterministic, `await`-based assertions live here: a CancelToken fires" +// cancel_token.baml:7:1 (comment) len=75 "// the spawn's effective token via an async watcher, so reading `f.state()`" +// cancel_token.baml:8:1 (comment) len=74 "// immediately after `tok.cancel()` would race the watcher. `await` blocks" +// cancel_token.baml:9:1 (comment) len=61 "// until the future settles, so its outcome is deterministic." +// cancel_token.baml:11:1 (comment) len=78 "// Awaiting a token-cancelled spawn re-throws `Cancelled`, which is catchable." +// cancel_token.baml:12:1 (keyword) len=8 "function" +// cancel_token.baml:12:10 (function) [declaration] len=29 "await_token_cancelled_catches" +// cancel_token.baml:12:45 (type) [defaultLibrary] len=3 "int" +// cancel_token.baml:13:5 (keyword) len=3 "let" +// cancel_token.baml:13:9 (variable) [declaration] len=3 "tok" +// cancel_token.baml:13:13 (operator) len=1 "=" +// cancel_token.baml:13:15 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:13:20 (keyword) len=5 "spawn" +// cancel_token.baml:13:26 (class) [defaultLibrary] len=11 "CancelToken" +// cancel_token.baml:13:38 (method) len=3 "new" +// cancel_token.baml:14:5 (keyword) len=3 "let" +// cancel_token.baml:14:9 (variable) [declaration] len=1 "f" +// cancel_token.baml:14:11 (operator) len=1 "=" +// cancel_token.baml:14:13 (keyword) len=5 "spawn" +// cancel_token.baml:14:19 (keyword) len=4 "with" +// cancel_token.baml:14:24 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:14:29 (keyword) len=5 "spawn" +// cancel_token.baml:14:35 (function) len=7 "options" +// cancel_token.baml:14:43 (parameter) len=6 "cancel" +// cancel_token.baml:14:50 (operator) len=1 "=" +// cancel_token.baml:14:52 (variable) len=3 "tok" +// cancel_token.baml:15:9 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:15:14 (namespace) [defaultLibrary] len=3 "sys" +// cancel_token.baml:15:18 (function) len=5 "sleep" +// cancel_token.baml:15:24 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:15:29 (namespace) [defaultLibrary] len=4 "time" +// cancel_token.baml:15:34 (class) [defaultLibrary] len=8 "Duration" +// cancel_token.baml:15:43 (method) len=17 "from_milliseconds" +// cancel_token.baml:15:61 (number) len=6 "60000n" +// cancel_token.baml:16:9 (number) len=2 "42" +// cancel_token.baml:18:5 (keyword) len=3 "let" +// cancel_token.baml:18:11 (operator) len=1 "=" +// cancel_token.baml:18:13 (variable) len=3 "tok" +// cancel_token.baml:18:17 (method) len=6 "cancel" +// cancel_token.baml:19:6 (keyword) len=5 "await" +// cancel_token.baml:19:12 (variable) len=1 "f" +// cancel_token.baml:19:15 (keyword) len=5 "catch" +// cancel_token.baml:19:22 (parameter) [declaration] len=1 "e" +// cancel_token.baml:19:27 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:19:31 (operator) len=1 "." +// cancel_token.baml:19:32 (namespace) [defaultLibrary] len=6 "panics" +// cancel_token.baml:19:38 (operator) len=1 "." +// cancel_token.baml:19:39 (class) [defaultLibrary] len=9 "Cancelled" +// cancel_token.baml:19:52 (number) len=1 "0" +// cancel_token.baml:22:1 (keyword) len=4 "test" +// cancel_token.baml:22:6 (string) len=31 "\"await_token_cancelled_catches\"" +// cancel_token.baml:23:5 (namespace) [defaultLibrary] len=6 "assert" +// cancel_token.baml:23:12 (function) len=7 "is_true" +// cancel_token.baml:23:20 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:23:25 (function) len=11 "deep_equals" +// cancel_token.baml:23:37 (function) len=29 "await_token_cancelled_catches" +// cancel_token.baml:23:70 (number) len=1 "0" +// cancel_token.baml:26:1 (comment) len=78 "// An un-fired token leaves the spawn to complete normally — the option must" +// cancel_token.baml:27:1 (comment) len=30 "// not perturb the happy path." +// cancel_token.baml:28:1 (keyword) len=8 "function" +// cancel_token.baml:28:10 (function) [declaration] len=27 "uncancelled_token_completes" +// cancel_token.baml:28:43 (type) [defaultLibrary] len=3 "int" +// cancel_token.baml:29:5 (keyword) len=3 "let" +// cancel_token.baml:29:9 (variable) [declaration] len=3 "tok" +// cancel_token.baml:29:13 (operator) len=1 "=" +// cancel_token.baml:29:15 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:29:20 (keyword) len=5 "spawn" +// cancel_token.baml:29:26 (class) [defaultLibrary] len=11 "CancelToken" +// cancel_token.baml:29:38 (method) len=3 "new" +// cancel_token.baml:30:5 (keyword) len=3 "let" +// cancel_token.baml:30:9 (variable) [declaration] len=1 "f" +// cancel_token.baml:30:11 (operator) len=1 "=" +// cancel_token.baml:30:13 (keyword) len=5 "spawn" +// cancel_token.baml:30:19 (keyword) len=4 "with" +// cancel_token.baml:30:24 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:30:29 (keyword) len=5 "spawn" +// cancel_token.baml:30:35 (function) len=7 "options" +// cancel_token.baml:30:43 (parameter) len=6 "cancel" +// cancel_token.baml:30:50 (operator) len=1 "=" +// cancel_token.baml:30:52 (variable) len=3 "tok" +// cancel_token.baml:30:59 (number) len=2 "42" +// cancel_token.baml:31:5 (keyword) len=5 "await" +// cancel_token.baml:31:11 (variable) len=1 "f" +// cancel_token.baml:34:1 (keyword) len=4 "test" +// cancel_token.baml:34:6 (string) len=29 "\"uncancelled_token_completes\"" +// cancel_token.baml:35:5 (namespace) [defaultLibrary] len=6 "assert" +// cancel_token.baml:35:12 (function) len=7 "is_true" +// cancel_token.baml:35:20 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:35:25 (function) len=11 "deep_equals" +// cancel_token.baml:35:37 (function) len=27 "uncancelled_token_completes" +// cancel_token.baml:35:68 (number) len=2 "42" +// cancel_token.baml:38:1 (comment) len=74 "// `CancelToken.cancel()` is synchronous on the token, so `is_cancelled()`" +// cancel_token.baml:39:1 (comment) len=70 "// observes the transition immediately (no future / watcher involved)." +// cancel_token.baml:40:1 (keyword) len=8 "function" +// cancel_token.baml:40:10 (function) [declaration] len=34 "token_is_cancelled_reflects_cancel" +// cancel_token.baml:40:50 (type) [defaultLibrary] len=4 "bool" +// cancel_token.baml:41:5 (keyword) len=3 "let" +// cancel_token.baml:41:9 (variable) [declaration] len=3 "tok" +// cancel_token.baml:41:13 (operator) len=1 "=" +// cancel_token.baml:41:15 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:41:20 (keyword) len=5 "spawn" +// cancel_token.baml:41:26 (class) [defaultLibrary] len=11 "CancelToken" +// cancel_token.baml:41:38 (method) len=3 "new" +// cancel_token.baml:42:5 (keyword) len=3 "let" +// cancel_token.baml:42:9 (variable) [declaration] len=6 "before" +// cancel_token.baml:42:16 (operator) len=1 "=" +// cancel_token.baml:42:18 (variable) len=3 "tok" +// cancel_token.baml:42:22 (method) len=12 "is_cancelled" +// cancel_token.baml:43:5 (keyword) len=3 "let" +// cancel_token.baml:43:11 (operator) len=1 "=" +// cancel_token.baml:43:13 (variable) len=3 "tok" +// cancel_token.baml:43:17 (method) len=6 "cancel" +// cancel_token.baml:44:5 (keyword) len=3 "let" +// cancel_token.baml:44:9 (variable) [declaration] len=5 "after" +// cancel_token.baml:44:15 (operator) len=1 "=" +// cancel_token.baml:44:17 (variable) len=3 "tok" +// cancel_token.baml:44:21 (method) len=12 "is_cancelled" +// cancel_token.baml:45:6 (variable) len=6 "before" +// cancel_token.baml:45:14 (variable) len=5 "after" +// cancel_token.baml:48:1 (keyword) len=4 "test" +// cancel_token.baml:48:6 (string) len=36 "\"token_is_cancelled_reflects_cancel\"" +// cancel_token.baml:49:5 (namespace) [defaultLibrary] len=6 "assert" +// cancel_token.baml:49:12 (function) len=7 "is_true" +// cancel_token.baml:49:20 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:49:25 (function) len=11 "deep_equals" +// cancel_token.baml:49:37 (function) len=34 "token_is_cancelled_reflects_cancel" +// cancel_token.baml:49:76 (boolean) len=5 "false" +// cancel_token.baml:49:83 (boolean) len=4 "true" +// cancel_token.baml:52:1 (comment) len=75 "// `detach = true` opts out of the parent cascade but must not break normal" +// cancel_token.baml:53:1 (comment) len=79 "// completion (its survival/cascade-independence is verified by construction in" +// cancel_token.baml:54:1 (comment) len=62 "// the engine: a detached spawn gets a fresh effective token)." +// cancel_token.baml:55:1 (keyword) len=8 "function" +// cancel_token.baml:55:10 (function) [declaration] len=24 "detached_spawn_completes" +// cancel_token.baml:55:40 (type) [defaultLibrary] len=3 "int" +// cancel_token.baml:56:5 (keyword) len=3 "let" +// cancel_token.baml:56:9 (variable) [declaration] len=1 "f" +// cancel_token.baml:56:11 (operator) len=1 "=" +// cancel_token.baml:56:13 (keyword) len=5 "spawn" +// cancel_token.baml:56:19 (keyword) len=4 "with" +// cancel_token.baml:56:24 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:56:29 (keyword) len=5 "spawn" +// cancel_token.baml:56:35 (function) len=7 "options" +// cancel_token.baml:56:43 (parameter) len=6 "detach" +// cancel_token.baml:56:50 (operator) len=1 "=" +// cancel_token.baml:56:52 (boolean) len=4 "true" +// cancel_token.baml:56:60 (number) len=2 "42" +// cancel_token.baml:57:5 (keyword) len=5 "await" +// cancel_token.baml:57:11 (variable) len=1 "f" +// cancel_token.baml:60:1 (keyword) len=4 "test" +// cancel_token.baml:60:6 (string) len=26 "\"detached_spawn_completes\"" +// cancel_token.baml:61:5 (namespace) [defaultLibrary] len=6 "assert" +// cancel_token.baml:61:12 (function) len=7 "is_true" +// cancel_token.baml:61:20 (namespace) [defaultLibrary] len=4 "baml" +// cancel_token.baml:61:25 (function) len=11 "deep_equals" +// cancel_token.baml:61:37 (function) len=24 "detached_spawn_completes" +// cancel_token.baml:61:65 (number) len=2 "42" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_all_keyword.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_all_keyword.baml new file mode 100644 index 0000000000..7a6c2ac8ee --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_all_keyword.baml @@ -0,0 +1,113 @@ +// End-to-end test for catch_all keyword: parsing, HIR, TIR, codegen + +function MayFailIntOrString(x: int) -> string { + match (x) { + 0 => throw "string error", + 1 => throw 42, + _ => "ok" + } +} + +// Non-exhaustive catch — partial handling is fine +function PartialCatch(x: int) -> string { + MayFailIntOrString(x) catch (e) { + string => "caught string" + } +} + +// Exhaustive catch_all — wildcard covers everything +function CatchAllWildcard(x: int) -> string { + MayFailIntOrString(x) catch_all (e) { + _ => "caught all" + } +} + +// catch_all with all types explicitly handled +function CatchAllTyped(x: int) -> string { + MayFailIntOrString(x) catch_all (e) { + string => "caught string", + int => "caught int" + } +} + +// Chained: catch handles string, catch_all handles rest +function CatchThenCatchAll(x: int) -> string { + MayFailIntOrString(x) catch (e) { + string => "caught string" + } catch_all (e2) { + _ => "caught rest" + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// catch_all_keyword.baml:1:1 (comment) len=68 "// End-to-end test for catch_all keyword: parsing, HIR, TIR, codegen" +// catch_all_keyword.baml:3:1 (keyword) len=8 "function" +// catch_all_keyword.baml:3:10 (function) [declaration] len=18 "MayFailIntOrString" +// catch_all_keyword.baml:3:29 (parameter) [declaration] len=1 "x" +// catch_all_keyword.baml:3:32 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:3:40 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:4:5 (keyword) len=5 "match" +// catch_all_keyword.baml:4:12 (parameter) len=1 "x" +// catch_all_keyword.baml:5:9 (number) len=1 "0" +// catch_all_keyword.baml:5:14 (keyword) len=5 "throw" +// catch_all_keyword.baml:5:20 (string) len=14 "\"string error\"" +// catch_all_keyword.baml:6:9 (number) len=1 "1" +// catch_all_keyword.baml:6:14 (keyword) len=5 "throw" +// catch_all_keyword.baml:6:20 (number) len=2 "42" +// catch_all_keyword.baml:7:14 (string) len=4 "\"ok\"" +// catch_all_keyword.baml:11:1 (comment) len=52 "// Non-exhaustive catch — partial handling is fine" +// catch_all_keyword.baml:12:1 (keyword) len=8 "function" +// catch_all_keyword.baml:12:10 (function) [declaration] len=12 "PartialCatch" +// catch_all_keyword.baml:12:23 (parameter) [declaration] len=1 "x" +// catch_all_keyword.baml:12:26 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:12:34 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:13:5 (function) len=18 "MayFailIntOrString" +// catch_all_keyword.baml:13:24 (parameter) len=1 "x" +// catch_all_keyword.baml:13:27 (keyword) len=5 "catch" +// catch_all_keyword.baml:13:34 (parameter) [declaration] len=1 "e" +// catch_all_keyword.baml:14:9 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:14:19 (string) len=15 "\"caught string\"" +// catch_all_keyword.baml:18:1 (comment) len=54 "// Exhaustive catch_all — wildcard covers everything" +// catch_all_keyword.baml:19:1 (keyword) len=8 "function" +// catch_all_keyword.baml:19:10 (function) [declaration] len=16 "CatchAllWildcard" +// catch_all_keyword.baml:19:27 (parameter) [declaration] len=1 "x" +// catch_all_keyword.baml:19:30 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:19:38 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:20:5 (function) len=18 "MayFailIntOrString" +// catch_all_keyword.baml:20:24 (parameter) len=1 "x" +// catch_all_keyword.baml:20:27 (keyword) len=9 "catch_all" +// catch_all_keyword.baml:20:38 (parameter) [declaration] len=1 "e" +// catch_all_keyword.baml:21:14 (string) len=12 "\"caught all\"" +// catch_all_keyword.baml:25:1 (comment) len=46 "// catch_all with all types explicitly handled" +// catch_all_keyword.baml:26:1 (keyword) len=8 "function" +// catch_all_keyword.baml:26:10 (function) [declaration] len=13 "CatchAllTyped" +// catch_all_keyword.baml:26:24 (parameter) [declaration] len=1 "x" +// catch_all_keyword.baml:26:27 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:26:35 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:27:5 (function) len=18 "MayFailIntOrString" +// catch_all_keyword.baml:27:24 (parameter) len=1 "x" +// catch_all_keyword.baml:27:27 (keyword) len=9 "catch_all" +// catch_all_keyword.baml:27:38 (parameter) [declaration] len=1 "e" +// catch_all_keyword.baml:28:9 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:28:19 (string) len=15 "\"caught string\"" +// catch_all_keyword.baml:29:9 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:29:16 (string) len=12 "\"caught int\"" +// catch_all_keyword.baml:33:1 (comment) len=56 "// Chained: catch handles string, catch_all handles rest" +// catch_all_keyword.baml:34:1 (keyword) len=8 "function" +// catch_all_keyword.baml:34:10 (function) [declaration] len=17 "CatchThenCatchAll" +// catch_all_keyword.baml:34:28 (parameter) [declaration] len=1 "x" +// catch_all_keyword.baml:34:31 (type) [defaultLibrary] len=3 "int" +// catch_all_keyword.baml:34:39 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:35:5 (function) len=18 "MayFailIntOrString" +// catch_all_keyword.baml:35:24 (parameter) len=1 "x" +// catch_all_keyword.baml:35:27 (keyword) len=5 "catch" +// catch_all_keyword.baml:35:34 (parameter) [declaration] len=1 "e" +// catch_all_keyword.baml:36:9 (type) [defaultLibrary] len=6 "string" +// catch_all_keyword.baml:36:19 (string) len=15 "\"caught string\"" +// catch_all_keyword.baml:37:7 (keyword) len=9 "catch_all" +// catch_all_keyword.baml:37:18 (parameter) [declaration] len=2 "e2" +// catch_all_keyword.baml:38:14 (string) len=13 "\"caught rest\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_param.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_param.baml new file mode 100644 index 0000000000..2f75c3595d --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_param.baml @@ -0,0 +1,39 @@ +// The catch binding `e` should highlight as a parameter, consistently between +// its declaration and its uses in the catch body. + +function MayFail(x: int) -> string throws string { + throw "boom" +} + +function Handled(x: int) -> string { + MayFail(x) catch (e) { + _ => e + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// catch_param.baml:1:1 (comment) len=78 "// The catch binding `e` should highlight as a parameter, consistently between" +// catch_param.baml:2:1 (comment) len=50 "// its declaration and its uses in the catch body." +// catch_param.baml:4:1 (keyword) len=8 "function" +// catch_param.baml:4:10 (function) [declaration] len=7 "MayFail" +// catch_param.baml:4:18 (parameter) [declaration] len=1 "x" +// catch_param.baml:4:21 (type) [defaultLibrary] len=3 "int" +// catch_param.baml:4:29 (type) [defaultLibrary] len=6 "string" +// catch_param.baml:4:36 (keyword) len=6 "throws" +// catch_param.baml:4:43 (type) [defaultLibrary] len=6 "string" +// catch_param.baml:5:3 (keyword) len=5 "throw" +// catch_param.baml:5:9 (string) len=6 "\"boom\"" +// catch_param.baml:8:1 (keyword) len=8 "function" +// catch_param.baml:8:10 (function) [declaration] len=7 "Handled" +// catch_param.baml:8:18 (parameter) [declaration] len=1 "x" +// catch_param.baml:8:21 (type) [defaultLibrary] len=3 "int" +// catch_param.baml:8:29 (type) [defaultLibrary] len=6 "string" +// catch_param.baml:9:3 (function) len=7 "MayFail" +// catch_param.baml:9:11 (parameter) len=1 "x" +// catch_param.baml:9:14 (keyword) len=5 "catch" +// catch_param.baml:9:21 (parameter) [declaration] len=1 "e" +// catch_param.baml:10:10 (parameter) len=1 "e" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_throw.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_throw.baml new file mode 100644 index 0000000000..c2d5148a01 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_throw.baml @@ -0,0 +1,41 @@ +// `match`, `throw`, and `catch` error handling. +function MayFail(x: int) -> string { + match (x) { + 0 => throw "boom", + _ => "ok" + } +} + +function Handled(x: int) -> string { + MayFail(x) catch (e) { + _ => "caught" + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// catch_throw.baml:1:1 (comment) len=48 "// `match`, `throw`, and `catch` error handling." +// catch_throw.baml:2:1 (keyword) len=8 "function" +// catch_throw.baml:2:10 (function) [declaration] len=7 "MayFail" +// catch_throw.baml:2:18 (parameter) [declaration] len=1 "x" +// catch_throw.baml:2:21 (type) [defaultLibrary] len=3 "int" +// catch_throw.baml:2:29 (type) [defaultLibrary] len=6 "string" +// catch_throw.baml:3:3 (keyword) len=5 "match" +// catch_throw.baml:3:10 (parameter) len=1 "x" +// catch_throw.baml:4:5 (number) len=1 "0" +// catch_throw.baml:4:10 (keyword) len=5 "throw" +// catch_throw.baml:4:16 (string) len=6 "\"boom\"" +// catch_throw.baml:5:10 (string) len=4 "\"ok\"" +// catch_throw.baml:9:1 (keyword) len=8 "function" +// catch_throw.baml:9:10 (function) [declaration] len=7 "Handled" +// catch_throw.baml:9:18 (parameter) [declaration] len=1 "x" +// catch_throw.baml:9:21 (type) [defaultLibrary] len=3 "int" +// catch_throw.baml:9:29 (type) [defaultLibrary] len=6 "string" +// catch_throw.baml:10:3 (function) len=7 "MayFail" +// catch_throw.baml:10:11 (parameter) len=1 "x" +// catch_throw.baml:10:14 (keyword) len=5 "catch" +// catch_throw.baml:10:21 (parameter) [declaration] len=1 "e" +// catch_throw.baml:11:10 (string) len=8 "\"caught\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/class.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/class.baml index d7ae6617df..f1d0c70b23 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/class.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/class.baml @@ -128,99 +128,171 @@ function fo() -> int { // //- semantic_tokens // class.baml:1:1 (keyword) len=5 "class" -// class.baml:1:7 (class) len=5 "Color" -// class.baml:2:3 (property) len=3 "red" -// class.baml:2:7 (type) len=3 "int" -// class.baml:3:3 (property) len=5 "green" -// class.baml:3:9 (type) len=3 "int" -// class.baml:4:3 (property) len=4 "blue" -// class.baml:4:8 (type) len=3 "int" +// class.baml:1:7 (class) [declaration] len=5 "Color" +// class.baml:2:3 (property) [declaration] len=3 "red" +// class.baml:2:7 (type) [defaultLibrary] len=3 "int" +// class.baml:3:3 (property) [declaration] len=5 "green" +// class.baml:3:9 (type) [defaultLibrary] len=3 "int" +// class.baml:4:3 (property) [declaration] len=4 "blue" +// class.baml:4:8 (type) [defaultLibrary] len=3 "int" // class.baml:6:3 (keyword) len=8 "function" -// class.baml:6:12 (function) len=7 "get_red" -// class.baml:6:20 (parameter) len=4 "self" -// class.baml:6:29 (type) len=3 "int" +// class.baml:6:12 (method) [declaration] len=7 "get_red" +// class.baml:6:20 (parameter) [declaration] len=4 "self" +// class.baml:6:29 (type) [defaultLibrary] len=3 "int" +// class.baml:7:5 (parameter) len=4 "self" +// class.baml:7:10 (property) len=3 "red" // class.baml:10:3 (keyword) len=8 "function" -// class.baml:10:12 (function) len=9 "get_green" -// class.baml:10:22 (parameter) len=4 "self" -// class.baml:10:31 (type) len=3 "int" +// class.baml:10:12 (method) [declaration] len=9 "get_green" +// class.baml:10:22 (parameter) [declaration] len=4 "self" +// class.baml:10:31 (type) [defaultLibrary] len=3 "int" +// class.baml:11:5 (parameter) len=4 "self" +// class.baml:11:10 (property) len=5 "green" // class.baml:14:3 (keyword) len=8 "function" -// class.baml:14:12 (function) len=8 "get_blue" -// class.baml:14:21 (parameter) len=4 "self" -// class.baml:14:30 (type) len=3 "int" +// class.baml:14:12 (method) [declaration] len=8 "get_blue" +// class.baml:14:21 (parameter) [declaration] len=4 "self" +// class.baml:14:30 (type) [defaultLibrary] len=3 "int" +// class.baml:15:5 (parameter) len=4 "self" +// class.baml:15:10 (property) len=4 "blue" // class.baml:19:1 (keyword) len=8 "function" -// class.baml:19:10 (function) len=3 "foo" -// class.baml:19:19 (type) len=3 "int" +// class.baml:19:10 (function) [declaration] len=3 "foo" +// class.baml:19:19 (type) [defaultLibrary] len=3 "int" // class.baml:20:3 (keyword) len=3 "let" +// class.baml:20:7 (variable) [declaration] len=6 "colors" // class.baml:20:14 (operator) len=1 "=" +// class.baml:21:5 (class) len=5 "Color" +// class.baml:21:13 (property) len=3 "red" // class.baml:21:18 (number) len=3 "255" +// class.baml:21:23 (property) len=5 "green" // class.baml:21:30 (number) len=1 "0" +// class.baml:21:33 (property) len=4 "blue" // class.baml:21:39 (number) len=1 "0" +// class.baml:22:5 (class) len=5 "Color" +// class.baml:22:13 (property) len=3 "red" // class.baml:22:18 (number) len=1 "0" +// class.baml:22:21 (property) len=5 "green" // class.baml:22:28 (number) len=3 "255" +// class.baml:22:33 (property) len=4 "blue" // class.baml:22:39 (number) len=1 "0" +// class.baml:23:5 (class) len=5 "Color" +// class.baml:23:13 (property) len=3 "red" // class.baml:23:18 (number) len=1 "0" +// class.baml:23:21 (property) len=5 "green" // class.baml:23:28 (number) len=1 "0" +// class.baml:23:31 (property) len=4 "blue" // class.baml:23:37 (number) len=3 "255" // class.baml:26:3 (keyword) len=3 "let" +// class.baml:26:7 (variable) [declaration] len=9 "first_red" // class.baml:26:17 (operator) len=1 "=" +// class.baml:26:19 (variable) len=6 "colors" // class.baml:26:26 (number) len=1 "0" +// class.baml:26:29 (method) len=7 "get_red" // class.baml:27:3 (keyword) len=3 "let" +// class.baml:27:7 (variable) [declaration] len=12 "second_green" // class.baml:27:20 (operator) len=1 "=" +// class.baml:27:22 (variable) len=6 "colors" // class.baml:27:29 (number) len=1 "1" +// class.baml:27:32 (property) len=5 "green" // class.baml:29:3 (keyword) len=3 "let" +// class.baml:29:7 (variable) [declaration] len=3 "sum" // class.baml:29:11 (operator) len=1 "=" +// class.baml:29:13 (variable) len=6 "colors" // class.baml:29:20 (number) len=1 "0" +// class.baml:29:23 (property) len=3 "red" // class.baml:29:27 (operator) len=1 "+" +// class.baml:29:29 (variable) len=6 "colors" // class.baml:29:36 (number) len=1 "1" +// class.baml:29:39 (property) len=5 "green" // class.baml:29:45 (operator) len=1 "+" +// class.baml:29:47 (variable) len=6 "colors" // class.baml:29:54 (number) len=1 "2" +// class.baml:29:57 (property) len=4 "blue" // class.baml:31:3 (keyword) len=3 "let" +// class.baml:31:7 (variable) [declaration] len=6 "nested" // class.baml:31:14 (operator) len=1 "=" +// class.baml:31:17 (variable) len=6 "colors" // class.baml:31:24 (number) len=1 "0" +// class.baml:31:27 (method) len=7 "get_red" +// class.baml:31:38 (variable) len=6 "colors" // class.baml:31:45 (number) len=1 "1" +// class.baml:31:48 (method) len=9 "get_green" +// class.baml:31:61 (variable) len=6 "colors" // class.baml:31:68 (number) len=1 "2" +// class.baml:31:71 (method) len=8 "get_blue" +// class.baml:33:3 (variable) len=3 "sum" // class.baml:33:7 (operator) len=1 "+" +// class.baml:33:9 (variable) len=6 "nested" // class.baml:33:16 (number) len=1 "0" // class.baml:33:19 (operator) len=1 "+" +// class.baml:33:21 (variable) len=6 "nested" // class.baml:33:28 (number) len=1 "1" // class.baml:33:31 (operator) len=1 "+" +// class.baml:33:33 (variable) len=6 "nested" // class.baml:33:40 (number) len=1 "2" // class.baml:36:1 (comment) len=50 "// Make sure only real fields get the highlighting" // class.baml:37:1 (keyword) len=8 "function" -// class.baml:37:10 (function) len=2 "fo" -// class.baml:37:18 (type) len=3 "int" +// class.baml:37:10 (function) [declaration] len=2 "fo" +// class.baml:37:18 (type) [defaultLibrary] len=3 "int" // class.baml:38:3 (keyword) len=3 "let" +// class.baml:38:7 (variable) [declaration] len=6 "colors" // class.baml:38:14 (operator) len=1 "=" +// class.baml:39:5 (class) len=5 "Color" +// class.baml:39:13 (property) len=2 "re" // class.baml:39:17 (number) len=3 "255" +// class.baml:39:22 (property) len=4 "gree" // class.baml:39:28 (number) len=1 "0" +// class.baml:39:31 (property) len=3 "blu" // class.baml:39:36 (number) len=1 "0" +// class.baml:40:5 (class) len=5 "Color" +// class.baml:40:13 (property) len=2 "re" // class.baml:40:17 (number) len=1 "0" +// class.baml:40:20 (property) len=4 "gree" // class.baml:40:26 (number) len=3 "255" +// class.baml:40:31 (property) len=3 "blu" // class.baml:40:36 (number) len=1 "0" +// class.baml:41:5 (class) len=5 "Color" +// class.baml:41:13 (property) len=2 "re" // class.baml:41:17 (number) len=1 "0" +// class.baml:41:20 (property) len=4 "gree" // class.baml:41:26 (number) len=1 "0" +// class.baml:41:29 (property) len=3 "blu" // class.baml:41:34 (number) len=3 "255" // class.baml:44:3 (keyword) len=3 "let" +// class.baml:44:7 (variable) [declaration] len=9 "first_red" // class.baml:44:17 (operator) len=1 "=" +// class.baml:44:19 (variable) len=6 "colors" // class.baml:44:26 (number) len=1 "0" // class.baml:45:3 (keyword) len=3 "let" +// class.baml:45:7 (variable) [declaration] len=12 "second_green" // class.baml:45:20 (operator) len=1 "=" +// class.baml:45:22 (variable) len=6 "colors" // class.baml:45:29 (number) len=1 "1" // class.baml:47:3 (keyword) len=3 "let" +// class.baml:47:7 (variable) [declaration] len=3 "sum" // class.baml:47:11 (operator) len=1 "=" +// class.baml:47:13 (variable) len=6 "colors" // class.baml:47:20 (number) len=1 "0" // class.baml:47:26 (operator) len=1 "+" +// class.baml:47:28 (variable) len=6 "colors" // class.baml:47:35 (number) len=1 "1" // class.baml:47:43 (operator) len=1 "+" +// class.baml:47:45 (variable) len=6 "colors" // class.baml:47:52 (number) len=1 "2" // class.baml:49:3 (keyword) len=3 "let" +// class.baml:49:7 (variable) [declaration] len=6 "nested" // class.baml:49:14 (operator) len=1 "=" +// class.baml:49:17 (variable) len=6 "colors" // class.baml:49:24 (number) len=1 "0" +// class.baml:49:37 (variable) len=6 "colors" // class.baml:49:44 (number) len=1 "1" +// class.baml:49:59 (variable) len=6 "colors" // class.baml:49:66 (number) len=1 "2" +// class.baml:51:3 (variable) len=3 "sum" // class.baml:51:7 (operator) len=1 "+" +// class.baml:51:9 (variable) len=6 "nested" // class.baml:51:16 (number) len=1 "0" // class.baml:51:19 (operator) len=1 "+" +// class.baml:51:21 (variable) len=6 "nested" // class.baml:51:28 (number) len=1 "1" // class.baml:51:31 (operator) len=1 "+" +// class.baml:51:33 (variable) len=6 "nested" // class.baml:51:40 (number) len=1 "2" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/client.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/client.baml index c39e65a266..35ccde1012 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/client.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/client.baml @@ -27,28 +27,24 @@ client RetryClient { // client.baml:1:7 (operator) len=1 "<" // client.baml:1:8 (type) len=3 "llm" // client.baml:1:11 (operator) len=1 ">" -// client.baml:1:13 (struct) len=8 "MyClient" +// client.baml:1:13 (struct) [declaration] len=8 "MyClient" // client.baml:2:3 (property) len=8 "provider" // client.baml:3:3 (property) len=7 "options" // client.baml:4:5 (property) len=5 "model" -// client.baml:4:11 (string) len=1 "\"" -// client.baml:4:12 (string) len=5 "gpt-4" -// client.baml:4:17 (string) len=1 "\"" +// client.baml:4:11 (string) len=7 "\"gpt-4\"" // client.baml:5:5 (property) len=10 "max_tokens" // client.baml:5:16 (number) len=3 "100" // client.baml:9:1 (keyword) len=12 "retry_policy" -// client.baml:9:14 (struct) len=7 "MyRetry" +// client.baml:9:14 (struct) [declaration] len=7 "MyRetry" // client.baml:10:3 (property) len=11 "max_retries" // client.baml:10:15 (number) len=1 "3" // client.baml:13:1 (keyword) len=6 "client" // client.baml:13:7 (operator) len=1 "<" // client.baml:13:8 (type) len=3 "llm" // client.baml:13:11 (operator) len=1 ">" -// client.baml:13:13 (struct) len=11 "RetryClient" +// client.baml:13:13 (struct) [declaration] len=11 "RetryClient" // client.baml:14:3 (property) len=8 "provider" // client.baml:15:3 (property) len=12 "retry_policy" // client.baml:16:3 (property) len=7 "options" // client.baml:17:5 (property) len=5 "model" -// client.baml:17:11 (string) len=1 "\"" -// client.baml:17:12 (string) len=24 "claude-opus-4-1-20250805" -// client.baml:17:36 (string) len=1 "\"" +// client.baml:17:11 (string) len=26 "\"claude-opus-4-1-20250805\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/config_dictionary.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/config_dictionary.baml new file mode 100644 index 0000000000..a5ad499642 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/config_dictionary.baml @@ -0,0 +1,165 @@ +client MyClient { + provider openai + // dictionary test + options { + // no commas + max_tokens 100 + array_key_with_quoted_unquoted [ "abc", "abc", "ccc" ] + // separate by commas + key2 "some random value", hello "world", thing "hello" + block_string #"hello there my frien + d"# + inline_raw_string #"inline "raw" string,,"# + "string key" "value with spaces" + booleanValue true + stringKey "true" + array1 [ + "one" + "two" + ] + // a comment and new empty_lines + + array2 [ "one", "two" ] + array3Numbers [ 1, 2, 3 ] + nestedKey { + key "value" + key2 "value2" + nestedArray [ "yes", "queen"] + number 10 + } + oneMoreValueToTestBrokenness "value" + myInteger 100 + // array of objects with nested config blocks (no colons) + tools [ + { + server_label "parallel_web_search" + server_url "https://example.com" + headers { + "x-api-key" myapikey + authorization "Bearer token" + } + type "mcp" + } + { + another_tool "value" + } + ] + block_string #" + hello there my friend + {# a comment in a prompt #} + "# + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// config_dictionary.baml:1:1 (keyword) len=6 "client" +// config_dictionary.baml:1:7 (operator) len=1 "<" +// config_dictionary.baml:1:8 (type) len=3 "llm" +// config_dictionary.baml:1:11 (operator) len=1 ">" +// config_dictionary.baml:1:13 (struct) [declaration] len=8 "MyClient" +// config_dictionary.baml:2:3 (property) len=8 "provider" +// config_dictionary.baml:3:3 (comment) len=18 "// dictionary test" +// config_dictionary.baml:4:3 (property) len=7 "options" +// config_dictionary.baml:5:5 (comment) len=12 "// no commas" +// config_dictionary.baml:6:5 (property) len=10 "max_tokens" +// config_dictionary.baml:6:16 (number) len=3 "100" +// config_dictionary.baml:7:5 (property) len=30 "array_key_with_quoted_unquoted" +// config_dictionary.baml:7:38 (string) len=5 "\"abc\"" +// config_dictionary.baml:7:45 (string) len=5 "\"abc\"" +// config_dictionary.baml:7:52 (string) len=5 "\"ccc\"" +// config_dictionary.baml:8:5 (comment) len=21 "// separate by commas" +// config_dictionary.baml:9:5 (property) len=4 "key2" +// config_dictionary.baml:9:10 (string) len=19 "\"some random value\"" +// config_dictionary.baml:9:31 (property) len=5 "hello" +// config_dictionary.baml:9:37 (string) len=7 "\"world\"" +// config_dictionary.baml:9:46 (property) len=5 "thing" +// config_dictionary.baml:9:52 (string) len=7 "\"hello\"" +// config_dictionary.baml:10:6 (property) len=12 "block_string" +// config_dictionary.baml:10:19 (string) len=1 "#" +// config_dictionary.baml:10:20 (string) len=1 "\"" +// config_dictionary.baml:10:21 (string) len=5 "hello" +// config_dictionary.baml:10:27 (string) len=5 "there" +// config_dictionary.baml:10:33 (string) len=2 "my" +// config_dictionary.baml:10:36 (string) len=5 "frien" +// config_dictionary.baml:11:17 (string) len=1 "d" +// config_dictionary.baml:11:18 (string) len=1 "\"" +// config_dictionary.baml:11:19 (string) len=1 "#" +// config_dictionary.baml:12:5 (property) len=17 "inline_raw_string" +// config_dictionary.baml:12:23 (string) len=1 "#" +// config_dictionary.baml:12:24 (string) len=1 "\"" +// config_dictionary.baml:12:25 (string) len=6 "inline" +// config_dictionary.baml:12:32 (string) len=1 "\"" +// config_dictionary.baml:12:33 (string) len=3 "raw" +// config_dictionary.baml:12:36 (string) len=1 "\"" +// config_dictionary.baml:12:38 (string) len=6 "string" +// config_dictionary.baml:12:44 (string) len=1 "," +// config_dictionary.baml:12:45 (string) len=1 "," +// config_dictionary.baml:12:46 (string) len=1 "\"" +// config_dictionary.baml:12:47 (string) len=1 "#" +// config_dictionary.baml:13:5 (string) len=12 "\"string key\"" +// config_dictionary.baml:13:18 (string) len=19 "\"value with spaces\"" +// config_dictionary.baml:14:5 (property) len=12 "booleanValue" +// config_dictionary.baml:14:18 (boolean) len=4 "true" +// config_dictionary.baml:15:5 (property) len=9 "stringKey" +// config_dictionary.baml:15:15 (string) len=6 "\"true\"" +// config_dictionary.baml:16:5 (property) len=6 "array1" +// config_dictionary.baml:17:7 (string) len=5 "\"one\"" +// config_dictionary.baml:18:7 (string) len=5 "\"two\"" +// config_dictionary.baml:20:5 (comment) len=32 "// a comment and new empty_lines" +// config_dictionary.baml:22:5 (property) len=6 "array2" +// config_dictionary.baml:22:14 (string) len=5 "\"one\"" +// config_dictionary.baml:22:21 (string) len=5 "\"two\"" +// config_dictionary.baml:23:5 (property) len=13 "array3Numbers" +// config_dictionary.baml:23:21 (number) len=1 "1" +// config_dictionary.baml:23:24 (number) len=1 "2" +// config_dictionary.baml:23:27 (number) len=1 "3" +// config_dictionary.baml:24:5 (property) len=9 "nestedKey" +// config_dictionary.baml:25:7 (property) len=3 "key" +// config_dictionary.baml:25:11 (string) len=7 "\"value\"" +// config_dictionary.baml:26:7 (property) len=4 "key2" +// config_dictionary.baml:26:12 (string) len=8 "\"value2\"" +// config_dictionary.baml:27:7 (property) len=11 "nestedArray" +// config_dictionary.baml:27:21 (string) len=5 "\"yes\"" +// config_dictionary.baml:27:28 (string) len=7 "\"queen\"" +// config_dictionary.baml:28:7 (property) len=6 "number" +// config_dictionary.baml:28:14 (number) len=2 "10" +// config_dictionary.baml:30:5 (property) len=28 "oneMoreValueToTestBrokenness" +// config_dictionary.baml:30:34 (string) len=7 "\"value\"" +// config_dictionary.baml:31:5 (property) len=9 "myInteger" +// config_dictionary.baml:31:15 (number) len=3 "100" +// config_dictionary.baml:32:5 (comment) len=57 "// array of objects with nested config blocks (no colons)" +// config_dictionary.baml:33:5 (property) len=5 "tools" +// config_dictionary.baml:35:9 (property) len=12 "server_label" +// config_dictionary.baml:35:22 (string) len=21 "\"parallel_web_search\"" +// config_dictionary.baml:36:9 (property) len=10 "server_url" +// config_dictionary.baml:36:20 (string) len=21 "\"https://example.com\"" +// config_dictionary.baml:37:9 (property) len=7 "headers" +// config_dictionary.baml:38:11 (string) len=11 "\"x-api-key\"" +// config_dictionary.baml:39:11 (property) len=13 "authorization" +// config_dictionary.baml:39:25 (string) len=14 "\"Bearer token\"" +// config_dictionary.baml:41:9 (property) len=4 "type" +// config_dictionary.baml:41:14 (string) len=5 "\"mcp\"" +// config_dictionary.baml:44:9 (property) len=12 "another_tool" +// config_dictionary.baml:44:22 (string) len=7 "\"value\"" +// config_dictionary.baml:47:5 (property) len=12 "block_string" +// config_dictionary.baml:47:18 (string) len=1 "#" +// config_dictionary.baml:47:19 (string) len=1 "\"" +// config_dictionary.baml:48:7 (string) len=5 "hello" +// config_dictionary.baml:48:13 (string) len=5 "there" +// config_dictionary.baml:48:19 (string) len=2 "my" +// config_dictionary.baml:48:22 (string) len=6 "friend" +// config_dictionary.baml:49:7 (string) len=1 "{" +// config_dictionary.baml:49:8 (string) len=1 "#" +// config_dictionary.baml:49:10 (string) len=1 "a" +// config_dictionary.baml:49:12 (string) len=7 "comment" +// config_dictionary.baml:49:20 (string) len=2 "in" +// config_dictionary.baml:49:23 (string) len=1 "a" +// config_dictionary.baml:49:25 (string) len=6 "prompt" +// config_dictionary.baml:49:32 (string) len=1 "#" +// config_dictionary.baml:49:33 (string) len=1 "}" +// config_dictionary.baml:50:5 (string) len=1 "\"" +// config_dictionary.baml:50:6 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_binding.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_binding.baml index 8565c04b80..4bc17a7fb3 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_binding.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_binding.baml @@ -27,13 +27,14 @@ function ConstToken() -> int { // //- semantic_tokens // const_binding.baml:1:1 (keyword) len=8 "function" -// const_binding.baml:1:10 (function) len=10 "ConstToken" -// const_binding.baml:1:26 (type) len=3 "int" +// const_binding.baml:1:10 (function) [declaration] len=10 "ConstToken" +// const_binding.baml:1:26 (type) [defaultLibrary] len=3 "int" // const_binding.baml:2:3 (keyword) len=5 "const" -// const_binding.baml:2:9 (variable) len=1 "x" +// const_binding.baml:2:9 (variable) [declaration] len=1 "x" // const_binding.baml:2:11 (operator) len=1 "=" // const_binding.baml:2:13 (number) len=1 "1" // const_binding.baml:3:3 (keyword) len=3 "let" -// const_binding.baml:3:7 (variable) len=5 "const" +// const_binding.baml:3:7 (variable) [declaration] len=5 "const" // const_binding.baml:3:13 (operator) len=1 "=" // const_binding.baml:3:15 (variable) len=1 "x" +// const_binding.baml:4:3 (variable) len=5 "const" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_let_else_defer.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_let_else_defer.baml new file mode 100644 index 0000000000..39d5432ad5 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_let_else_defer.baml @@ -0,0 +1,220 @@ +class User { + name string +} + +function BindingAndDeferForms(user: User, value: int | string, items: int[]) -> int { + const x = 1; + const y: int = x; + const _ = y; + + let v: int = value else { return 0; }; + + defer { + let cleanup = v; + cleanup; + } + + watch let observed = v; + + if const narrowed: int = value { + observed += narrowed; + } else { + observed += 0; + }; + + while const loop_value: int = value { + observed += loop_value; + break; + } + + for (const i = 0; i < 3; i += 1) { + observed += i; + } + + for (const item in items) { + observed += item; + } + + for const item in items { + observed += item; + } + + observed +} + +//---- +//- diagnostics +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:6:3 ] +// │ +// 6 │ const x = 1; +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ───╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:7:3 ] +// │ +// 7 │ const y: int = x; +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ───╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:8:3 ] +// │ +// 8 │ const _ = y; +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ───╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:19:6 ] +// │ +// 19 │ if const narrowed: int = value { +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ────╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:25:9 ] +// │ +// 25 │ while const loop_value: int = value { +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ────╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:30:8 ] +// │ +// 30 │ for (const i = 0; i < 3; i += 1) { +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ────╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:34:8 ] +// │ +// 34 │ for (const item in items) { +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ────╯ +// warning: `const` is currently treated like `let`; BAML does not enforce immutability yet. Use `let` for current BAML semantics. +// ╭─[ const_let_else_defer.baml:38:7 ] +// │ +// 38 │ for const item in items { +// │ ──┬── +// │ ╰──── `const` behaves like `let` for now +// │ +// │ Note: Error code: E0010 +// ────╯ +// +//- semantic_tokens +// const_let_else_defer.baml:1:1 (keyword) len=5 "class" +// const_let_else_defer.baml:1:7 (class) [declaration] len=4 "User" +// const_let_else_defer.baml:2:3 (property) [declaration] len=4 "name" +// const_let_else_defer.baml:2:8 (type) [defaultLibrary] len=6 "string" +// const_let_else_defer.baml:5:1 (keyword) len=8 "function" +// const_let_else_defer.baml:5:10 (function) [declaration] len=20 "BindingAndDeferForms" +// const_let_else_defer.baml:5:31 (parameter) [declaration] len=4 "user" +// const_let_else_defer.baml:5:37 (class) len=4 "User" +// const_let_else_defer.baml:5:43 (parameter) [declaration] len=5 "value" +// const_let_else_defer.baml:5:50 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:5:54 (operator) len=1 "|" +// const_let_else_defer.baml:5:56 (type) [defaultLibrary] len=6 "string" +// const_let_else_defer.baml:5:64 (parameter) [declaration] len=5 "items" +// const_let_else_defer.baml:5:71 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:5:81 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:6:3 (keyword) len=5 "const" +// const_let_else_defer.baml:6:9 (variable) [declaration] len=1 "x" +// const_let_else_defer.baml:6:11 (operator) len=1 "=" +// const_let_else_defer.baml:6:13 (number) len=1 "1" +// const_let_else_defer.baml:7:3 (keyword) len=5 "const" +// const_let_else_defer.baml:7:9 (variable) [declaration] len=1 "y" +// const_let_else_defer.baml:7:12 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:7:16 (operator) len=1 "=" +// const_let_else_defer.baml:7:18 (variable) len=1 "x" +// const_let_else_defer.baml:8:3 (keyword) len=5 "const" +// const_let_else_defer.baml:8:11 (operator) len=1 "=" +// const_let_else_defer.baml:8:13 (variable) len=1 "y" +// const_let_else_defer.baml:10:3 (keyword) len=3 "let" +// const_let_else_defer.baml:10:7 (variable) [declaration] len=1 "v" +// const_let_else_defer.baml:10:10 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:10:14 (operator) len=1 "=" +// const_let_else_defer.baml:10:16 (parameter) len=5 "value" +// const_let_else_defer.baml:10:22 (keyword) len=4 "else" +// const_let_else_defer.baml:10:29 (keyword) len=6 "return" +// const_let_else_defer.baml:10:36 (number) len=1 "0" +// const_let_else_defer.baml:12:3 (keyword) len=5 "defer" +// const_let_else_defer.baml:13:5 (keyword) len=3 "let" +// const_let_else_defer.baml:13:9 (variable) [declaration] len=7 "cleanup" +// const_let_else_defer.baml:13:17 (operator) len=1 "=" +// const_let_else_defer.baml:13:19 (variable) len=1 "v" +// const_let_else_defer.baml:14:5 (variable) len=7 "cleanup" +// const_let_else_defer.baml:17:3 (keyword) len=5 "watch" +// const_let_else_defer.baml:17:9 (keyword) len=3 "let" +// const_let_else_defer.baml:17:13 (variable) [declaration] len=8 "observed" +// const_let_else_defer.baml:17:22 (operator) len=1 "=" +// const_let_else_defer.baml:17:24 (variable) len=1 "v" +// const_let_else_defer.baml:19:3 (keyword) len=2 "if" +// const_let_else_defer.baml:19:6 (keyword) len=5 "const" +// const_let_else_defer.baml:19:12 (variable) [declaration] len=8 "narrowed" +// const_let_else_defer.baml:19:22 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:19:26 (operator) len=1 "=" +// const_let_else_defer.baml:19:28 (parameter) len=5 "value" +// const_let_else_defer.baml:20:5 (variable) len=8 "observed" +// const_let_else_defer.baml:20:14 (operator) len=2 "+=" +// const_let_else_defer.baml:20:17 (variable) len=8 "narrowed" +// const_let_else_defer.baml:21:5 (keyword) len=4 "else" +// const_let_else_defer.baml:22:5 (variable) len=8 "observed" +// const_let_else_defer.baml:22:14 (operator) len=2 "+=" +// const_let_else_defer.baml:22:17 (number) len=1 "0" +// const_let_else_defer.baml:25:3 (keyword) len=5 "while" +// const_let_else_defer.baml:25:9 (keyword) len=5 "const" +// const_let_else_defer.baml:25:15 (variable) [declaration] len=10 "loop_value" +// const_let_else_defer.baml:25:27 (type) [defaultLibrary] len=3 "int" +// const_let_else_defer.baml:25:31 (operator) len=1 "=" +// const_let_else_defer.baml:25:33 (parameter) len=5 "value" +// const_let_else_defer.baml:26:5 (variable) len=8 "observed" +// const_let_else_defer.baml:26:14 (operator) len=2 "+=" +// const_let_else_defer.baml:26:17 (variable) len=10 "loop_value" +// const_let_else_defer.baml:27:5 (keyword) len=5 "break" +// const_let_else_defer.baml:30:3 (keyword) len=3 "for" +// const_let_else_defer.baml:30:8 (keyword) len=5 "const" +// const_let_else_defer.baml:30:14 (variable) [declaration] len=1 "i" +// const_let_else_defer.baml:30:16 (operator) len=1 "=" +// const_let_else_defer.baml:30:18 (number) len=1 "0" +// const_let_else_defer.baml:30:21 (variable) len=1 "i" +// const_let_else_defer.baml:30:23 (operator) len=1 "<" +// const_let_else_defer.baml:30:25 (number) len=1 "3" +// const_let_else_defer.baml:30:28 (variable) len=1 "i" +// const_let_else_defer.baml:30:30 (operator) len=2 "+=" +// const_let_else_defer.baml:30:33 (number) len=1 "1" +// const_let_else_defer.baml:31:5 (variable) len=8 "observed" +// const_let_else_defer.baml:31:14 (operator) len=2 "+=" +// const_let_else_defer.baml:31:17 (variable) len=1 "i" +// const_let_else_defer.baml:34:3 (keyword) len=3 "for" +// const_let_else_defer.baml:34:8 (keyword) len=5 "const" +// const_let_else_defer.baml:34:14 (variable) [declaration] len=4 "item" +// const_let_else_defer.baml:34:19 (keyword) len=2 "in" +// const_let_else_defer.baml:34:22 (parameter) len=5 "items" +// const_let_else_defer.baml:35:5 (variable) len=8 "observed" +// const_let_else_defer.baml:35:14 (operator) len=2 "+=" +// const_let_else_defer.baml:35:17 (variable) len=4 "item" +// const_let_else_defer.baml:38:3 (keyword) len=3 "for" +// const_let_else_defer.baml:38:7 (keyword) len=5 "const" +// const_let_else_defer.baml:38:13 (variable) [declaration] len=4 "item" +// const_let_else_defer.baml:38:18 (keyword) len=2 "in" +// const_let_else_defer.baml:38:21 (parameter) len=5 "items" +// const_let_else_defer.baml:39:5 (variable) len=8 "observed" +// const_let_else_defer.baml:39:14 (operator) len=2 "+=" +// const_let_else_defer.baml:39:17 (variable) len=4 "item" +// const_let_else_defer.baml:42:3 (variable) len=8 "observed" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/constructor_spread.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/constructor_spread.baml new file mode 100644 index 0000000000..733b128309 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/constructor_spread.baml @@ -0,0 +1,66 @@ +class MyClass { + a int + b string +} + +let x = MyClass { a: 1, b: "2" }; + +let y = MyClass { a: 1, ...x }; + + +let default_person = Person { + name: "John Doe", + age: 20, + poem: "Never was there a man more plain." +}; + + +class Person { + name string + age int + poem string +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// constructor_spread.baml:1:1 (keyword) len=5 "class" +// constructor_spread.baml:1:7 (class) [declaration] len=7 "MyClass" +// constructor_spread.baml:2:5 (property) [declaration] len=1 "a" +// constructor_spread.baml:2:7 (type) [defaultLibrary] len=3 "int" +// constructor_spread.baml:3:5 (property) [declaration] len=1 "b" +// constructor_spread.baml:3:7 (type) [defaultLibrary] len=6 "string" +// constructor_spread.baml:6:1 (keyword) len=3 "let" +// constructor_spread.baml:6:5 (variable) [declaration] len=1 "x" +// constructor_spread.baml:6:7 (operator) len=1 "=" +// constructor_spread.baml:6:9 (class) len=7 "MyClass" +// constructor_spread.baml:6:19 (property) len=1 "a" +// constructor_spread.baml:6:22 (number) len=1 "1" +// constructor_spread.baml:6:25 (property) len=1 "b" +// constructor_spread.baml:6:28 (string) len=3 "\"2\"" +// constructor_spread.baml:8:1 (keyword) len=3 "let" +// constructor_spread.baml:8:5 (variable) [declaration] len=1 "y" +// constructor_spread.baml:8:7 (operator) len=1 "=" +// constructor_spread.baml:8:9 (class) len=7 "MyClass" +// constructor_spread.baml:8:19 (property) len=1 "a" +// constructor_spread.baml:8:22 (number) len=1 "1" +// constructor_spread.baml:11:1 (keyword) len=3 "let" +// constructor_spread.baml:11:5 (variable) [declaration] len=14 "default_person" +// constructor_spread.baml:11:20 (operator) len=1 "=" +// constructor_spread.baml:11:22 (class) len=6 "Person" +// constructor_spread.baml:12:5 (property) len=4 "name" +// constructor_spread.baml:12:11 (string) len=10 "\"John Doe\"" +// constructor_spread.baml:13:5 (property) len=3 "age" +// constructor_spread.baml:13:10 (number) len=2 "20" +// constructor_spread.baml:14:5 (property) len=4 "poem" +// constructor_spread.baml:14:11 (string) len=35 "\"Never was there a man more plain.\"" +// constructor_spread.baml:18:1 (keyword) len=5 "class" +// constructor_spread.baml:18:7 (class) [declaration] len=6 "Person" +// constructor_spread.baml:19:3 (property) [declaration] len=4 "name" +// constructor_spread.baml:19:8 (type) [defaultLibrary] len=6 "string" +// constructor_spread.baml:20:3 (property) [declaration] len=3 "age" +// constructor_spread.baml:20:7 (type) [defaultLibrary] len=3 "int" +// constructor_spread.baml:21:3 (property) [declaration] len=4 "poem" +// constructor_spread.baml:21:8 (type) [defaultLibrary] len=6 "string" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/deep_method_call.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/deep_method_call.baml new file mode 100644 index 0000000000..f39cd80a63 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/deep_method_call.baml @@ -0,0 +1,83 @@ +// Test: deep local-rooted method calls — throw target resolution. +// Issue #5: For `a.b.method()`, call_target_name reads segments[0]/segments[1] +// ("a"/"b") instead of using the receiver type and last segment ("B.method"). + +class B { + label string + + function greet(self) -> string { + self.label + } +} + +class A { + b B +} + +// Two-segment method call: a.b is the receiver, greet is the method. +// call_target_name should produce "B.greet", not "A.b". +function test_deep_method(a: A) -> string { + a.b.greet() +} + +// Three-segment chain: a.b.label is a field chain (not a method call). +// Should resolve correctly as field access. +function test_deep_field(a: A) -> string { + a.b.label +} + +// Method call on direct local — this is the 2-segment case that already works. +function test_direct_method(b: B) -> string { + b.greet() +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// deep_method_call.baml:1:1 (comment) len=68 "// Test: deep local-rooted method calls — throw target resolution." +// deep_method_call.baml:2:1 (comment) len=79 "// Issue #5: For `a.b.method()`, call_target_name reads segments[0]/segments[1]" +// deep_method_call.baml:3:1 (comment) len=78 "// (\"a\"/\"b\") instead of using the receiver type and last segment (\"B.method\")." +// deep_method_call.baml:5:1 (keyword) len=5 "class" +// deep_method_call.baml:5:7 (class) [declaration] len=1 "B" +// deep_method_call.baml:6:3 (property) [declaration] len=5 "label" +// deep_method_call.baml:6:9 (type) [defaultLibrary] len=6 "string" +// deep_method_call.baml:8:3 (keyword) len=8 "function" +// deep_method_call.baml:8:12 (method) [declaration] len=5 "greet" +// deep_method_call.baml:8:18 (parameter) [declaration] len=4 "self" +// deep_method_call.baml:8:27 (type) [defaultLibrary] len=6 "string" +// deep_method_call.baml:9:5 (parameter) len=4 "self" +// deep_method_call.baml:9:10 (property) len=5 "label" +// deep_method_call.baml:13:1 (keyword) len=5 "class" +// deep_method_call.baml:13:7 (class) [declaration] len=1 "A" +// deep_method_call.baml:14:3 (property) [declaration] len=1 "b" +// deep_method_call.baml:14:5 (class) len=1 "B" +// deep_method_call.baml:17:1 (comment) len=69 "// Two-segment method call: a.b is the receiver, greet is the method." +// deep_method_call.baml:18:1 (comment) len=56 "// call_target_name should produce \"B.greet\", not \"A.b\"." +// deep_method_call.baml:19:1 (keyword) len=8 "function" +// deep_method_call.baml:19:10 (function) [declaration] len=16 "test_deep_method" +// deep_method_call.baml:19:27 (parameter) [declaration] len=1 "a" +// deep_method_call.baml:19:30 (class) len=1 "A" +// deep_method_call.baml:19:36 (type) [defaultLibrary] len=6 "string" +// deep_method_call.baml:20:3 (parameter) len=1 "a" +// deep_method_call.baml:20:5 (property) len=1 "b" +// deep_method_call.baml:20:7 (method) len=5 "greet" +// deep_method_call.baml:23:1 (comment) len=71 "// Three-segment chain: a.b.label is a field chain (not a method call)." +// deep_method_call.baml:24:1 (comment) len=44 "// Should resolve correctly as field access." +// deep_method_call.baml:25:1 (keyword) len=8 "function" +// deep_method_call.baml:25:10 (function) [declaration] len=15 "test_deep_field" +// deep_method_call.baml:25:26 (parameter) [declaration] len=1 "a" +// deep_method_call.baml:25:29 (class) len=1 "A" +// deep_method_call.baml:25:35 (type) [defaultLibrary] len=6 "string" +// deep_method_call.baml:26:3 (parameter) len=1 "a" +// deep_method_call.baml:26:5 (property) len=1 "b" +// deep_method_call.baml:26:7 (property) len=5 "label" +// deep_method_call.baml:29:1 (comment) len=81 "// Method call on direct local — this is the 2-segment case that already works." +// deep_method_call.baml:30:1 (keyword) len=8 "function" +// deep_method_call.baml:30:10 (function) [declaration] len=18 "test_direct_method" +// deep_method_call.baml:30:29 (parameter) [declaration] len=1 "b" +// deep_method_call.baml:30:32 (class) len=1 "B" +// deep_method_call.baml:30:38 (type) [defaultLibrary] len=6 "string" +// deep_method_call.baml:31:3 (parameter) len=1 "b" +// deep_method_call.baml:31:5 (method) len=5 "greet" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/dynamic_type_builder.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/dynamic_type_builder.baml new file mode 100644 index 0000000000..b22c28b72e --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/dynamic_type_builder.baml @@ -0,0 +1,191 @@ +class Resume { + name string + education Education[] + skills string[] + @@dynamic // This class is marked as @@dynamic. +} + +class Education { + school string + degree string + year int +} + +enum Job { + SoftwareEngineer + DataScientist + @@dynamic +} + +// This function returns the dynamic class defined above. +function ExtractResume(from_text: string) -> Resume { + client "openai/gpt-4o-mini" + prompt #"Hello"# +} + +test ReturnDynamicClassTest { + functions [ExtractResume] + // New type_builder block used to define types and inject dynamic props. + type_builder { + // Defines a new type available only within this test block. + class Experience { + title string + company string + start_date string + end_date string + } + + enum Level { + Junior + Mid + Senior + } + + // This `dynamic` block is used to inject new properties into the + // `@@dynamic` part of the Resume class. + dynamic class Resume { + experience Experience[] + level Level + } + + dynamic enum Job { + ProductManager + } + } + args { + from_text #" + John Doe + + Education + - University of California, Berkeley, B.S. in Computer Science, 2020 + + Experience + - Software Engineer, Boundary, Sep 2022 - Sep 2023 + + Skills + - Python + - Java + "# + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// dynamic_type_builder.baml:1:1 (keyword) len=5 "class" +// dynamic_type_builder.baml:1:7 (class) [declaration] len=6 "Resume" +// dynamic_type_builder.baml:2:3 (property) [declaration] len=4 "name" +// dynamic_type_builder.baml:2:8 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:3:3 (property) [declaration] len=9 "education" +// dynamic_type_builder.baml:3:13 (class) len=9 "Education" +// dynamic_type_builder.baml:4:3 (property) [declaration] len=6 "skills" +// dynamic_type_builder.baml:4:10 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:5:3 (decorator) len=2 "@@" +// dynamic_type_builder.baml:5:5 (decorator) len=7 "dynamic" +// dynamic_type_builder.baml:5:13 (comment) len=37 "// This class is marked as @@dynamic." +// dynamic_type_builder.baml:8:1 (keyword) len=5 "class" +// dynamic_type_builder.baml:8:7 (class) [declaration] len=9 "Education" +// dynamic_type_builder.baml:9:3 (property) [declaration] len=6 "school" +// dynamic_type_builder.baml:9:10 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:10:3 (property) [declaration] len=6 "degree" +// dynamic_type_builder.baml:10:10 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:11:3 (property) [declaration] len=4 "year" +// dynamic_type_builder.baml:11:8 (type) [defaultLibrary] len=3 "int" +// dynamic_type_builder.baml:14:1 (keyword) len=4 "enum" +// dynamic_type_builder.baml:14:6 (enum) [declaration] len=3 "Job" +// dynamic_type_builder.baml:15:3 (enumMember) [declaration] len=16 "SoftwareEngineer" +// dynamic_type_builder.baml:16:3 (enumMember) [declaration] len=13 "DataScientist" +// dynamic_type_builder.baml:17:3 (decorator) len=2 "@@" +// dynamic_type_builder.baml:17:5 (decorator) len=7 "dynamic" +// dynamic_type_builder.baml:20:1 (comment) len=57 "// This function returns the dynamic class defined above." +// dynamic_type_builder.baml:21:1 (keyword) len=8 "function" +// dynamic_type_builder.baml:21:10 (function) [declaration] len=13 "ExtractResume" +// dynamic_type_builder.baml:21:24 (parameter) [declaration] len=9 "from_text" +// dynamic_type_builder.baml:21:35 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:21:46 (class) len=6 "Resume" +// dynamic_type_builder.baml:22:3 (property) len=6 "client" +// dynamic_type_builder.baml:22:10 (string) len=20 "\"openai/gpt-4o-mini\"" +// dynamic_type_builder.baml:23:3 (property) [declaration] len=6 "prompt" +// dynamic_type_builder.baml:23:10 (string) len=1 "#" +// dynamic_type_builder.baml:23:11 (string) len=1 "\"" +// dynamic_type_builder.baml:23:12 (string) len=5 "Hello" +// dynamic_type_builder.baml:23:17 (string) len=1 "\"" +// dynamic_type_builder.baml:23:18 (string) len=1 "#" +// dynamic_type_builder.baml:26:1 (keyword) len=4 "test" +// dynamic_type_builder.baml:26:6 (struct) [declaration] len=22 "ReturnDynamicClassTest" +// dynamic_type_builder.baml:27:3 (property) len=9 "functions" +// dynamic_type_builder.baml:28:3 (comment) len=72 "// New type_builder block used to define types and inject dynamic props." +// dynamic_type_builder.baml:29:3 (keyword) len=12 "type_builder" +// dynamic_type_builder.baml:30:5 (comment) len=60 "// Defines a new type available only within this test block." +// dynamic_type_builder.baml:31:5 (keyword) len=5 "class" +// dynamic_type_builder.baml:31:11 (class) [declaration] len=10 "Experience" +// dynamic_type_builder.baml:32:7 (property) [declaration] len=5 "title" +// dynamic_type_builder.baml:32:13 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:33:7 (property) [declaration] len=7 "company" +// dynamic_type_builder.baml:33:15 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:34:7 (property) [declaration] len=10 "start_date" +// dynamic_type_builder.baml:34:18 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:35:7 (property) [declaration] len=8 "end_date" +// dynamic_type_builder.baml:35:16 (type) [defaultLibrary] len=6 "string" +// dynamic_type_builder.baml:38:5 (keyword) len=4 "enum" +// dynamic_type_builder.baml:38:10 (enum) [declaration] len=5 "Level" +// dynamic_type_builder.baml:39:7 (enumMember) [declaration] len=6 "Junior" +// dynamic_type_builder.baml:40:7 (enumMember) [declaration] len=3 "Mid" +// dynamic_type_builder.baml:41:7 (enumMember) [declaration] len=6 "Senior" +// dynamic_type_builder.baml:44:5 (comment) len=65 "// This `dynamic` block is used to inject new properties into the" +// dynamic_type_builder.baml:45:5 (comment) len=40 "// `@@dynamic` part of the Resume class." +// dynamic_type_builder.baml:46:5 (keyword) len=7 "dynamic" +// dynamic_type_builder.baml:46:13 (keyword) len=5 "class" +// dynamic_type_builder.baml:46:19 (class) [declaration] len=6 "Resume" +// dynamic_type_builder.baml:47:7 (property) [declaration] len=10 "experience" +// dynamic_type_builder.baml:47:18 (type) len=10 "Experience" +// dynamic_type_builder.baml:48:7 (property) [declaration] len=5 "level" +// dynamic_type_builder.baml:48:13 (type) len=5 "Level" +// dynamic_type_builder.baml:51:5 (keyword) len=7 "dynamic" +// dynamic_type_builder.baml:51:13 (keyword) len=4 "enum" +// dynamic_type_builder.baml:51:18 (enum) [declaration] len=3 "Job" +// dynamic_type_builder.baml:52:7 (enumMember) [declaration] len=14 "ProductManager" +// dynamic_type_builder.baml:55:3 (property) len=4 "args" +// dynamic_type_builder.baml:56:5 (property) len=9 "from_text" +// dynamic_type_builder.baml:56:15 (string) len=1 "#" +// dynamic_type_builder.baml:56:16 (string) len=1 "\"" +// dynamic_type_builder.baml:57:7 (string) len=4 "John" +// dynamic_type_builder.baml:57:12 (string) len=3 "Doe" +// dynamic_type_builder.baml:59:7 (string) len=9 "Education" +// dynamic_type_builder.baml:60:7 (string) len=1 "-" +// dynamic_type_builder.baml:60:9 (string) len=10 "University" +// dynamic_type_builder.baml:60:20 (string) len=2 "of" +// dynamic_type_builder.baml:60:23 (string) len=10 "California" +// dynamic_type_builder.baml:60:33 (string) len=1 "," +// dynamic_type_builder.baml:60:35 (string) len=8 "Berkeley" +// dynamic_type_builder.baml:60:43 (string) len=1 "," +// dynamic_type_builder.baml:60:45 (string) len=1 "B" +// dynamic_type_builder.baml:60:46 (string) len=1 "." +// dynamic_type_builder.baml:60:47 (string) len=1 "S" +// dynamic_type_builder.baml:60:48 (string) len=1 "." +// dynamic_type_builder.baml:60:50 (string) len=2 "in" +// dynamic_type_builder.baml:60:53 (string) len=8 "Computer" +// dynamic_type_builder.baml:60:62 (string) len=7 "Science" +// dynamic_type_builder.baml:60:69 (string) len=1 "," +// dynamic_type_builder.baml:60:71 (string) len=4 "2020" +// dynamic_type_builder.baml:62:7 (string) len=10 "Experience" +// dynamic_type_builder.baml:63:7 (string) len=1 "-" +// dynamic_type_builder.baml:63:9 (string) len=8 "Software" +// dynamic_type_builder.baml:63:18 (string) len=8 "Engineer" +// dynamic_type_builder.baml:63:26 (string) len=1 "," +// dynamic_type_builder.baml:63:28 (string) len=8 "Boundary" +// dynamic_type_builder.baml:63:36 (string) len=1 "," +// dynamic_type_builder.baml:63:38 (string) len=3 "Sep" +// dynamic_type_builder.baml:63:42 (string) len=4 "2022" +// dynamic_type_builder.baml:63:47 (string) len=1 "-" +// dynamic_type_builder.baml:63:49 (string) len=3 "Sep" +// dynamic_type_builder.baml:63:53 (string) len=4 "2023" +// dynamic_type_builder.baml:65:7 (string) len=6 "Skills" +// dynamic_type_builder.baml:66:7 (string) len=1 "-" +// dynamic_type_builder.baml:66:9 (string) len=6 "Python" +// dynamic_type_builder.baml:67:7 (string) len=1 "-" +// dynamic_type_builder.baml:67:9 (string) len=4 "Java" +// dynamic_type_builder.baml:68:5 (string) len=1 "\"" +// dynamic_type_builder.baml:68:6 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_decls.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_decls.baml new file mode 100644 index 0000000000..749ec0ee32 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_decls.baml @@ -0,0 +1,525 @@ +// Testing all the formatter cases for enum declarations + +// ===== Minimal enum ===== +enum Minimal { + A +} + +// ===== Two variants ===== +enum TwoVariants { + Yes + No +} + +// ===== Multiple variants ===== +enum MultiVariant { + Red + Green + Blue + Yellow + Purple +} + +// ===== Variants with trailing commas ===== +enum WithCommas { + A, + B, + C, +} + +// ===== Variant with attribute ===== +enum WithAttr { + Active @description("Currently active") + Inactive @description("Not active") +} + +// ===== Variant with multiple attributes ===== +enum MultiAttr { + Success @description("Operation succeeded") @alias("ok") + Failure @description("Operation failed") @alias("err") +} + +// ===== Variant with long attribute exceeding limit ===== +enum LongAttr { + VeryImportantStatus @description("This is an extremely detailed description of the variant that pushes the line well past the default formatter line width of one hundred columns") +} + +// ===== Variant with many attributes exceeding limit ===== +enum ManyAttrsExceedingLimit { + ConfiguredVariant @description("A configured variant with many attributes") @alias("configured") @stream.done @stream.not_null @stream.with_state +} + +// ===== Long variant name + attributes exceeding limit ===== +enum LongVariantPlusAttrs { + ThisIsAnExtremelyLongVariantNameByItself @description("and it also has a description") @alias("long_variant") + AnotherVeryLongVariantNameThatNeedsWrapping @description("another long one") @alias("another") +} + +// ===== Block attribute on enum ===== +enum DynamicEnum { + X + Y + @@dynamic +} + +// ===== Trivia on enum declaration (line comments) ===== +// 1 enum keyword leading +enum // 2 enum keyword trailing +// 3 name leading +TriviaEnum // 4 name trailing +// 5 open brace leading +{ // 6 open brace trailing + // 7 first variant leading + A // 8 first variant trailing + // 9 second variant leading + B // 10 second variant trailing +// 11 close brace leading +} // 12 close brace trailing + +/////////////////// + +// ===== Trivia on enum declaration (block comments) ===== +/* 1 enum keyword leading */ +enum /* 2 enum keyword trailing */ +/* 3 name leading */ +TriviaEnumBlock /* 4 name trailing */ +/* 5 open brace leading */ +{ /* 6 open brace trailing */ + /* 7 first variant leading */ + A /* 8 first variant trailing */ + /* 9 second variant leading */ + B /* 10 second variant trailing */ +/* 11 close brace leading */ +} /* 12 close brace trailing */ + +/////////////////// + +// ===== Trivia on variant with attributes (line comments) ===== +enum TriviaVariantAttr { + // 1 variant leading + Active // 2 variant name trailing + // 3 attr leading + @description // 4 attr name trailing + // 5 open paren leading + ( // 6 open paren trailing + // 7 arg leading + "active" // 8 arg trailing + // 9 close paren leading + ) // 10 close paren trailing +} + +// ===== Trivia on variant with attributes (block comments) ===== +enum TriviaVariantAttrBlock { + /* 1 variant leading */ + Active /* 2 variant name trailing */ + /* 3 attr leading */ + @description /* 4 attr name trailing */ + /* 5 open paren leading */ + ( /* 6 open paren trailing */ + /* 7 arg leading */ + "active" /* 8 arg trailing */ + /* 9 close paren leading */ + ) /* 10 close paren trailing */ +} + +// ===== Trivia on wrapping variant with multiple attrs (line comments) ===== +enum TriviaWrapVariantAttrs { + // 1 variant leading + ConfiguredVariant // 2 variant name trailing + // 3 first attr leading + @description // 4 first attr name trailing + // 5 open paren leading + ( // 6 open paren trailing + // 7 arg leading + "a configured variant with many attributes" // 8 arg trailing + // 9 close paren leading + ) // 10 close paren trailing + // 11 second attr leading + @alias // 12 second attr name trailing + // 13 open paren leading + ( // 14 open paren trailing + // 15 arg leading + "configured" // 16 arg trailing + // 17 close paren leading + ) // 18 close paren trailing + // 19 third attr leading + @stream.done // 20 third attr trailing + // 21 fourth attr leading + @stream.not_null // 22 fourth attr trailing +} + +// ===== Trivia on wrapping variant with multiple attrs (block comments) ===== +enum TriviaWrapVariantAttrsBlock { + /* 1 variant leading */ + ConfiguredVariant /* 2 variant name trailing */ + /* 3 first attr leading */ + @description /* 4 first attr name trailing */ + /* 5 open paren leading */ + ( /* 6 open paren trailing */ + /* 7 arg leading */ + "a configured variant with many attributes" /* 8 arg trailing */ + /* 9 close paren leading */ + ) /* 10 close paren trailing */ + /* 11 second attr leading */ + @alias /* 12 second attr name trailing */ + /* 13 open paren leading */ + ( /* 14 open paren trailing */ + /* 15 arg leading */ + "configured" /* 16 arg trailing */ + /* 17 close paren leading */ + ) /* 18 close paren trailing */ + /* 19 third attr leading */ + @stream.done /* 20 third attr trailing */ + /* 21 fourth attr leading */ + @stream.not_null /* 22 fourth attr trailing */ +} + +// ===== Short enum name ===== +enum E { + V +} + +// ===== Long enum name exceeding limit ===== +enum ThisIsAnExtremelyLongEnumNameThatDefinitelyExceedsTheOneHundredCharacterLineLimitAllByItself { + Value +} + +// ===== Long variant names ===== +enum LongVariantNames { + ThisIsAVeryLongVariantNameThatByItselfExceedsTheOneHundredCharacterLineLimitAllByItselfEasily + AnotherExtremelyLongVariantNameForTestingLineWrappingBehaviorInTheFormatterOutputDefinitely + Short +} + +// ===== Many variants ===== +enum ManyVariants { + V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 + V10 + V11 + V12 +} + +// ===== Extraneous whitespace ===== +enum ExtraWhitespace { + A + B @description( "b" ) @alias( "bee" ) +} + +// ===== Variant with dotted attribute ===== +enum DottedAttrEnum { + X @stream.done + Y @stream.not_null +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// enum_decls.baml:1:1 (comment) len=56 "// Testing all the formatter cases for enum declarations" +// enum_decls.baml:3:1 (comment) len=27 "// ===== Minimal enum =====" +// enum_decls.baml:4:1 (keyword) len=4 "enum" +// enum_decls.baml:4:6 (enum) [declaration] len=7 "Minimal" +// enum_decls.baml:5:5 (enumMember) [declaration] len=1 "A" +// enum_decls.baml:8:1 (comment) len=27 "// ===== Two variants =====" +// enum_decls.baml:9:1 (keyword) len=4 "enum" +// enum_decls.baml:9:6 (enum) [declaration] len=11 "TwoVariants" +// enum_decls.baml:10:5 (enumMember) [declaration] len=3 "Yes" +// enum_decls.baml:11:5 (enumMember) [declaration] len=2 "No" +// enum_decls.baml:14:1 (comment) len=32 "// ===== Multiple variants =====" +// enum_decls.baml:15:1 (keyword) len=4 "enum" +// enum_decls.baml:15:6 (enum) [declaration] len=12 "MultiVariant" +// enum_decls.baml:16:5 (enumMember) [declaration] len=3 "Red" +// enum_decls.baml:17:5 (enumMember) [declaration] len=5 "Green" +// enum_decls.baml:18:5 (enumMember) [declaration] len=4 "Blue" +// enum_decls.baml:19:5 (enumMember) [declaration] len=6 "Yellow" +// enum_decls.baml:20:5 (enumMember) [declaration] len=6 "Purple" +// enum_decls.baml:23:1 (comment) len=44 "// ===== Variants with trailing commas =====" +// enum_decls.baml:24:1 (keyword) len=4 "enum" +// enum_decls.baml:24:6 (enum) [declaration] len=10 "WithCommas" +// enum_decls.baml:25:5 (enumMember) [declaration] len=1 "A" +// enum_decls.baml:26:5 (enumMember) [declaration] len=1 "B" +// enum_decls.baml:27:5 (enumMember) [declaration] len=1 "C" +// enum_decls.baml:30:1 (comment) len=37 "// ===== Variant with attribute =====" +// enum_decls.baml:31:1 (keyword) len=4 "enum" +// enum_decls.baml:31:6 (enum) [declaration] len=8 "WithAttr" +// enum_decls.baml:32:5 (enumMember) [declaration] len=6 "Active" +// enum_decls.baml:32:12 (decorator) len=1 "@" +// enum_decls.baml:32:13 (decorator) len=11 "description" +// enum_decls.baml:32:25 (string) len=18 "\"Currently active\"" +// enum_decls.baml:33:5 (enumMember) [declaration] len=8 "Inactive" +// enum_decls.baml:33:14 (decorator) len=1 "@" +// enum_decls.baml:33:15 (decorator) len=11 "description" +// enum_decls.baml:33:27 (string) len=12 "\"Not active\"" +// enum_decls.baml:36:1 (comment) len=47 "// ===== Variant with multiple attributes =====" +// enum_decls.baml:37:1 (keyword) len=4 "enum" +// enum_decls.baml:37:6 (enum) [declaration] len=9 "MultiAttr" +// enum_decls.baml:38:5 (enumMember) [declaration] len=7 "Success" +// enum_decls.baml:38:13 (decorator) len=1 "@" +// enum_decls.baml:38:14 (decorator) len=11 "description" +// enum_decls.baml:38:26 (string) len=21 "\"Operation succeeded\"" +// enum_decls.baml:38:49 (decorator) len=1 "@" +// enum_decls.baml:38:50 (decorator) len=5 "alias" +// enum_decls.baml:38:56 (string) len=4 "\"ok\"" +// enum_decls.baml:39:5 (enumMember) [declaration] len=7 "Failure" +// enum_decls.baml:39:13 (decorator) len=1 "@" +// enum_decls.baml:39:14 (decorator) len=11 "description" +// enum_decls.baml:39:26 (string) len=18 "\"Operation failed\"" +// enum_decls.baml:39:46 (decorator) len=1 "@" +// enum_decls.baml:39:47 (decorator) len=5 "alias" +// enum_decls.baml:39:53 (string) len=5 "\"err\"" +// enum_decls.baml:42:1 (comment) len=58 "// ===== Variant with long attribute exceeding limit =====" +// enum_decls.baml:43:1 (keyword) len=4 "enum" +// enum_decls.baml:43:6 (enum) [declaration] len=8 "LongAttr" +// enum_decls.baml:44:5 (enumMember) [declaration] len=19 "VeryImportantStatus" +// enum_decls.baml:44:25 (decorator) len=1 "@" +// enum_decls.baml:44:26 (decorator) len=11 "description" +// enum_decls.baml:44:38 (string) len=145 "\"This is an extremely detailed description of the variant that pushes the line well past the default formatter line width of one hundred columns\"" +// enum_decls.baml:47:1 (comment) len=59 "// ===== Variant with many attributes exceeding limit =====" +// enum_decls.baml:48:1 (keyword) len=4 "enum" +// enum_decls.baml:48:6 (enum) [declaration] len=23 "ManyAttrsExceedingLimit" +// enum_decls.baml:49:5 (enumMember) [declaration] len=17 "ConfiguredVariant" +// enum_decls.baml:49:23 (decorator) len=1 "@" +// enum_decls.baml:49:24 (decorator) len=11 "description" +// enum_decls.baml:49:36 (string) len=43 "\"A configured variant with many attributes\"" +// enum_decls.baml:49:81 (decorator) len=1 "@" +// enum_decls.baml:49:82 (decorator) len=5 "alias" +// enum_decls.baml:49:88 (string) len=12 "\"configured\"" +// enum_decls.baml:49:102 (decorator) len=1 "@" +// enum_decls.baml:49:103 (decorator) len=6 "stream" +// enum_decls.baml:49:110 (decorator) len=4 "done" +// enum_decls.baml:49:115 (decorator) len=1 "@" +// enum_decls.baml:49:116 (decorator) len=6 "stream" +// enum_decls.baml:49:123 (decorator) len=8 "not_null" +// enum_decls.baml:49:132 (decorator) len=1 "@" +// enum_decls.baml:49:133 (decorator) len=6 "stream" +// enum_decls.baml:49:140 (decorator) len=10 "with_state" +// enum_decls.baml:52:1 (comment) len=61 "// ===== Long variant name + attributes exceeding limit =====" +// enum_decls.baml:53:1 (keyword) len=4 "enum" +// enum_decls.baml:53:6 (enum) [declaration] len=20 "LongVariantPlusAttrs" +// enum_decls.baml:54:5 (enumMember) [declaration] len=40 "ThisIsAnExtremelyLongVariantNameByItself" +// enum_decls.baml:54:46 (decorator) len=1 "@" +// enum_decls.baml:54:47 (decorator) len=11 "description" +// enum_decls.baml:54:59 (string) len=31 "\"and it also has a description\"" +// enum_decls.baml:54:92 (decorator) len=1 "@" +// enum_decls.baml:54:93 (decorator) len=5 "alias" +// enum_decls.baml:54:99 (string) len=14 "\"long_variant\"" +// enum_decls.baml:55:5 (enumMember) [declaration] len=43 "AnotherVeryLongVariantNameThatNeedsWrapping" +// enum_decls.baml:55:49 (decorator) len=1 "@" +// enum_decls.baml:55:50 (decorator) len=11 "description" +// enum_decls.baml:55:62 (string) len=18 "\"another long one\"" +// enum_decls.baml:55:82 (decorator) len=1 "@" +// enum_decls.baml:55:83 (decorator) len=5 "alias" +// enum_decls.baml:55:89 (string) len=9 "\"another\"" +// enum_decls.baml:58:1 (comment) len=38 "// ===== Block attribute on enum =====" +// enum_decls.baml:59:1 (keyword) len=4 "enum" +// enum_decls.baml:59:6 (enum) [declaration] len=11 "DynamicEnum" +// enum_decls.baml:60:5 (enumMember) [declaration] len=1 "X" +// enum_decls.baml:61:5 (enumMember) [declaration] len=1 "Y" +// enum_decls.baml:62:5 (decorator) len=2 "@@" +// enum_decls.baml:62:7 (decorator) len=7 "dynamic" +// enum_decls.baml:65:1 (comment) len=57 "// ===== Trivia on enum declaration (line comments) =====" +// enum_decls.baml:66:1 (comment) len=25 "// 1 enum keyword leading" +// enum_decls.baml:67:1 (keyword) len=4 "enum" +// enum_decls.baml:67:6 (comment) len=26 "// 2 enum keyword trailing" +// enum_decls.baml:68:1 (comment) len=17 "// 3 name leading" +// enum_decls.baml:69:1 (enum) [declaration] len=10 "TriviaEnum" +// enum_decls.baml:69:12 (comment) len=18 "// 4 name trailing" +// enum_decls.baml:70:1 (comment) len=23 "// 5 open brace leading" +// enum_decls.baml:71:3 (comment) len=24 "// 6 open brace trailing" +// enum_decls.baml:72:5 (comment) len=26 "// 7 first variant leading" +// enum_decls.baml:73:5 (enumMember) [declaration] len=1 "A" +// enum_decls.baml:73:7 (comment) len=27 "// 8 first variant trailing" +// enum_decls.baml:74:5 (comment) len=27 "// 9 second variant leading" +// enum_decls.baml:75:5 (enumMember) [declaration] len=1 "B" +// enum_decls.baml:75:7 (comment) len=29 "// 10 second variant trailing" +// enum_decls.baml:76:1 (comment) len=25 "// 11 close brace leading" +// enum_decls.baml:77:3 (comment) len=26 "// 12 close brace trailing" +// enum_decls.baml:79:1 (comment) len=19 "///////////////////" +// enum_decls.baml:81:1 (comment) len=58 "// ===== Trivia on enum declaration (block comments) =====" +// enum_decls.baml:82:1 (comment) len=28 "/* 1 enum keyword leading */" +// enum_decls.baml:83:1 (keyword) len=4 "enum" +// enum_decls.baml:83:6 (comment) len=29 "/* 2 enum keyword trailing */" +// enum_decls.baml:84:1 (comment) len=20 "/* 3 name leading */" +// enum_decls.baml:85:1 (enum) [declaration] len=15 "TriviaEnumBlock" +// enum_decls.baml:85:17 (comment) len=21 "/* 4 name trailing */" +// enum_decls.baml:86:1 (comment) len=26 "/* 5 open brace leading */" +// enum_decls.baml:87:3 (comment) len=27 "/* 6 open brace trailing */" +// enum_decls.baml:88:5 (comment) len=29 "/* 7 first variant leading */" +// enum_decls.baml:89:5 (enumMember) [declaration] len=1 "A" +// enum_decls.baml:89:7 (comment) len=30 "/* 8 first variant trailing */" +// enum_decls.baml:90:5 (comment) len=30 "/* 9 second variant leading */" +// enum_decls.baml:91:5 (enumMember) [declaration] len=1 "B" +// enum_decls.baml:91:7 (comment) len=32 "/* 10 second variant trailing */" +// enum_decls.baml:92:1 (comment) len=28 "/* 11 close brace leading */" +// enum_decls.baml:93:3 (comment) len=29 "/* 12 close brace trailing */" +// enum_decls.baml:95:1 (comment) len=19 "///////////////////" +// enum_decls.baml:97:1 (comment) len=64 "// ===== Trivia on variant with attributes (line comments) =====" +// enum_decls.baml:98:1 (keyword) len=4 "enum" +// enum_decls.baml:98:6 (enum) [declaration] len=17 "TriviaVariantAttr" +// enum_decls.baml:99:5 (comment) len=20 "// 1 variant leading" +// enum_decls.baml:100:5 (enumMember) [declaration] len=6 "Active" +// enum_decls.baml:100:12 (comment) len=26 "// 2 variant name trailing" +// enum_decls.baml:101:5 (comment) len=17 "// 3 attr leading" +// enum_decls.baml:102:5 (decorator) len=1 "@" +// enum_decls.baml:102:6 (decorator) len=11 "description" +// enum_decls.baml:102:18 (comment) len=23 "// 4 attr name trailing" +// enum_decls.baml:103:5 (comment) len=23 "// 5 open paren leading" +// enum_decls.baml:104:7 (comment) len=24 "// 6 open paren trailing" +// enum_decls.baml:105:5 (comment) len=16 "// 7 arg leading" +// enum_decls.baml:106:5 (string) len=8 "\"active\"" +// enum_decls.baml:106:14 (comment) len=17 "// 8 arg trailing" +// enum_decls.baml:107:5 (comment) len=24 "// 9 close paren leading" +// enum_decls.baml:108:7 (comment) len=26 "// 10 close paren trailing" +// enum_decls.baml:111:1 (comment) len=65 "// ===== Trivia on variant with attributes (block comments) =====" +// enum_decls.baml:112:1 (keyword) len=4 "enum" +// enum_decls.baml:112:6 (enum) [declaration] len=22 "TriviaVariantAttrBlock" +// enum_decls.baml:113:5 (comment) len=23 "/* 1 variant leading */" +// enum_decls.baml:114:5 (enumMember) [declaration] len=6 "Active" +// enum_decls.baml:114:12 (comment) len=29 "/* 2 variant name trailing */" +// enum_decls.baml:115:5 (comment) len=20 "/* 3 attr leading */" +// enum_decls.baml:116:5 (decorator) len=1 "@" +// enum_decls.baml:116:6 (decorator) len=11 "description" +// enum_decls.baml:116:18 (comment) len=26 "/* 4 attr name trailing */" +// enum_decls.baml:117:5 (comment) len=26 "/* 5 open paren leading */" +// enum_decls.baml:118:7 (comment) len=27 "/* 6 open paren trailing */" +// enum_decls.baml:119:5 (comment) len=19 "/* 7 arg leading */" +// enum_decls.baml:120:5 (string) len=8 "\"active\"" +// enum_decls.baml:120:14 (comment) len=20 "/* 8 arg trailing */" +// enum_decls.baml:121:5 (comment) len=27 "/* 9 close paren leading */" +// enum_decls.baml:122:7 (comment) len=29 "/* 10 close paren trailing */" +// enum_decls.baml:125:1 (comment) len=77 "// ===== Trivia on wrapping variant with multiple attrs (line comments) =====" +// enum_decls.baml:126:1 (keyword) len=4 "enum" +// enum_decls.baml:126:6 (enum) [declaration] len=22 "TriviaWrapVariantAttrs" +// enum_decls.baml:127:5 (comment) len=20 "// 1 variant leading" +// enum_decls.baml:128:5 (enumMember) [declaration] len=17 "ConfiguredVariant" +// enum_decls.baml:128:23 (comment) len=26 "// 2 variant name trailing" +// enum_decls.baml:129:5 (comment) len=23 "// 3 first attr leading" +// enum_decls.baml:130:5 (decorator) len=1 "@" +// enum_decls.baml:130:6 (decorator) len=11 "description" +// enum_decls.baml:130:18 (comment) len=29 "// 4 first attr name trailing" +// enum_decls.baml:131:5 (comment) len=23 "// 5 open paren leading" +// enum_decls.baml:132:7 (comment) len=24 "// 6 open paren trailing" +// enum_decls.baml:133:5 (comment) len=16 "// 7 arg leading" +// enum_decls.baml:134:5 (string) len=43 "\"a configured variant with many attributes\"" +// enum_decls.baml:134:49 (comment) len=17 "// 8 arg trailing" +// enum_decls.baml:135:5 (comment) len=24 "// 9 close paren leading" +// enum_decls.baml:136:7 (comment) len=26 "// 10 close paren trailing" +// enum_decls.baml:137:5 (comment) len=25 "// 11 second attr leading" +// enum_decls.baml:138:5 (decorator) len=1 "@" +// enum_decls.baml:138:6 (decorator) len=5 "alias" +// enum_decls.baml:138:12 (comment) len=31 "// 12 second attr name trailing" +// enum_decls.baml:139:5 (comment) len=24 "// 13 open paren leading" +// enum_decls.baml:140:7 (comment) len=25 "// 14 open paren trailing" +// enum_decls.baml:141:5 (comment) len=17 "// 15 arg leading" +// enum_decls.baml:142:5 (string) len=12 "\"configured\"" +// enum_decls.baml:142:18 (comment) len=18 "// 16 arg trailing" +// enum_decls.baml:143:5 (comment) len=25 "// 17 close paren leading" +// enum_decls.baml:144:7 (comment) len=26 "// 18 close paren trailing" +// enum_decls.baml:145:5 (comment) len=24 "// 19 third attr leading" +// enum_decls.baml:146:5 (decorator) len=1 "@" +// enum_decls.baml:146:6 (decorator) len=6 "stream" +// enum_decls.baml:146:13 (decorator) len=4 "done" +// enum_decls.baml:146:18 (comment) len=25 "// 20 third attr trailing" +// enum_decls.baml:147:5 (comment) len=25 "// 21 fourth attr leading" +// enum_decls.baml:148:5 (decorator) len=1 "@" +// enum_decls.baml:148:6 (decorator) len=6 "stream" +// enum_decls.baml:148:13 (decorator) len=8 "not_null" +// enum_decls.baml:148:22 (comment) len=26 "// 22 fourth attr trailing" +// enum_decls.baml:151:1 (comment) len=78 "// ===== Trivia on wrapping variant with multiple attrs (block comments) =====" +// enum_decls.baml:152:1 (keyword) len=4 "enum" +// enum_decls.baml:152:6 (enum) [declaration] len=27 "TriviaWrapVariantAttrsBlock" +// enum_decls.baml:153:5 (comment) len=23 "/* 1 variant leading */" +// enum_decls.baml:154:5 (enumMember) [declaration] len=17 "ConfiguredVariant" +// enum_decls.baml:154:23 (comment) len=29 "/* 2 variant name trailing */" +// enum_decls.baml:155:5 (comment) len=26 "/* 3 first attr leading */" +// enum_decls.baml:156:5 (decorator) len=1 "@" +// enum_decls.baml:156:6 (decorator) len=11 "description" +// enum_decls.baml:156:18 (comment) len=32 "/* 4 first attr name trailing */" +// enum_decls.baml:157:5 (comment) len=26 "/* 5 open paren leading */" +// enum_decls.baml:158:7 (comment) len=27 "/* 6 open paren trailing */" +// enum_decls.baml:159:5 (comment) len=19 "/* 7 arg leading */" +// enum_decls.baml:160:5 (string) len=43 "\"a configured variant with many attributes\"" +// enum_decls.baml:160:49 (comment) len=20 "/* 8 arg trailing */" +// enum_decls.baml:161:5 (comment) len=27 "/* 9 close paren leading */" +// enum_decls.baml:162:7 (comment) len=29 "/* 10 close paren trailing */" +// enum_decls.baml:163:5 (comment) len=28 "/* 11 second attr leading */" +// enum_decls.baml:164:5 (decorator) len=1 "@" +// enum_decls.baml:164:6 (decorator) len=5 "alias" +// enum_decls.baml:164:12 (comment) len=34 "/* 12 second attr name trailing */" +// enum_decls.baml:165:5 (comment) len=27 "/* 13 open paren leading */" +// enum_decls.baml:166:7 (comment) len=28 "/* 14 open paren trailing */" +// enum_decls.baml:167:5 (comment) len=20 "/* 15 arg leading */" +// enum_decls.baml:168:5 (string) len=12 "\"configured\"" +// enum_decls.baml:168:18 (comment) len=21 "/* 16 arg trailing */" +// enum_decls.baml:169:5 (comment) len=28 "/* 17 close paren leading */" +// enum_decls.baml:170:7 (comment) len=29 "/* 18 close paren trailing */" +// enum_decls.baml:171:5 (comment) len=27 "/* 19 third attr leading */" +// enum_decls.baml:172:5 (decorator) len=1 "@" +// enum_decls.baml:172:6 (decorator) len=6 "stream" +// enum_decls.baml:172:13 (decorator) len=4 "done" +// enum_decls.baml:172:18 (comment) len=28 "/* 20 third attr trailing */" +// enum_decls.baml:173:5 (comment) len=28 "/* 21 fourth attr leading */" +// enum_decls.baml:174:5 (decorator) len=1 "@" +// enum_decls.baml:174:6 (decorator) len=6 "stream" +// enum_decls.baml:174:13 (decorator) len=8 "not_null" +// enum_decls.baml:174:22 (comment) len=29 "/* 22 fourth attr trailing */" +// enum_decls.baml:177:1 (comment) len=30 "// ===== Short enum name =====" +// enum_decls.baml:178:1 (keyword) len=4 "enum" +// enum_decls.baml:178:6 (enum) [declaration] len=1 "E" +// enum_decls.baml:179:5 (enumMember) [declaration] len=1 "V" +// enum_decls.baml:182:1 (comment) len=45 "// ===== Long enum name exceeding limit =====" +// enum_decls.baml:183:1 (keyword) len=4 "enum" +// enum_decls.baml:183:6 (enum) [declaration] len=92 "ThisIsAnExtremelyLongEnumNameThatDefinitelyExceedsTheOneHundredCharacterLineLimitAllByItself" +// enum_decls.baml:184:5 (enumMember) [declaration] len=5 "Value" +// enum_decls.baml:187:1 (comment) len=33 "// ===== Long variant names =====" +// enum_decls.baml:188:1 (keyword) len=4 "enum" +// enum_decls.baml:188:6 (enum) [declaration] len=16 "LongVariantNames" +// enum_decls.baml:189:5 (enumMember) [declaration] len=93 "ThisIsAVeryLongVariantNameThatByItselfExceedsTheOneHundredCharacterLineLimitAllByItselfEasily" +// enum_decls.baml:190:5 (enumMember) [declaration] len=91 "AnotherExtremelyLongVariantNameForTestingLineWrappingBehaviorInTheFormatterOutputDefinitely" +// enum_decls.baml:191:5 (enumMember) [declaration] len=5 "Short" +// enum_decls.baml:194:1 (comment) len=28 "// ===== Many variants =====" +// enum_decls.baml:195:1 (keyword) len=4 "enum" +// enum_decls.baml:195:6 (enum) [declaration] len=12 "ManyVariants" +// enum_decls.baml:196:5 (enumMember) [declaration] len=2 "V1" +// enum_decls.baml:197:5 (enumMember) [declaration] len=2 "V2" +// enum_decls.baml:198:5 (enumMember) [declaration] len=2 "V3" +// enum_decls.baml:199:5 (enumMember) [declaration] len=2 "V4" +// enum_decls.baml:200:5 (enumMember) [declaration] len=2 "V5" +// enum_decls.baml:201:5 (enumMember) [declaration] len=2 "V6" +// enum_decls.baml:202:5 (enumMember) [declaration] len=2 "V7" +// enum_decls.baml:203:5 (enumMember) [declaration] len=2 "V8" +// enum_decls.baml:204:5 (enumMember) [declaration] len=2 "V9" +// enum_decls.baml:205:5 (enumMember) [declaration] len=3 "V10" +// enum_decls.baml:206:5 (enumMember) [declaration] len=3 "V11" +// enum_decls.baml:207:5 (enumMember) [declaration] len=3 "V12" +// enum_decls.baml:210:1 (comment) len=36 "// ===== Extraneous whitespace =====" +// enum_decls.baml:211:1 (keyword) len=4 "enum" +// enum_decls.baml:211:9 (enum) [declaration] len=15 "ExtraWhitespace" +// enum_decls.baml:212:5 (enumMember) [declaration] len=1 "A" +// enum_decls.baml:213:5 (enumMember) [declaration] len=1 "B" +// enum_decls.baml:213:11 (decorator) len=1 "@" +// enum_decls.baml:213:12 (decorator) len=11 "description" +// enum_decls.baml:213:26 (string) len=3 "\"b\"" +// enum_decls.baml:213:37 (decorator) len=1 "@" +// enum_decls.baml:213:38 (decorator) len=5 "alias" +// enum_decls.baml:213:46 (string) len=5 "\"bee\"" +// enum_decls.baml:216:1 (comment) len=44 "// ===== Variant with dotted attribute =====" +// enum_decls.baml:217:1 (keyword) len=4 "enum" +// enum_decls.baml:217:6 (enum) [declaration] len=14 "DottedAttrEnum" +// enum_decls.baml:218:5 (enumMember) [declaration] len=1 "X" +// enum_decls.baml:218:7 (decorator) len=1 "@" +// enum_decls.baml:218:8 (decorator) len=6 "stream" +// enum_decls.baml:218:15 (decorator) len=4 "done" +// enum_decls.baml:219:5 (enumMember) [declaration] len=1 "Y" +// enum_decls.baml:219:7 (decorator) len=1 "@" +// enum_decls.baml:219:8 (decorator) len=6 "stream" +// enum_decls.baml:219:15 (decorator) len=8 "not_null" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_member_access.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_member_access.baml new file mode 100644 index 0000000000..376da2ebc4 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_member_access.baml @@ -0,0 +1,75 @@ +// Test: semantic tokens for multi-segment Path expressions. +// Issue #9: The final segment should get a type-aware token kind, +// not a generic "property" token for everything after the root. + +enum Status { + Active + Inactive +} + +class User { + name string + + function greet(self) -> string { + self.name + } +} + +function test_tokens() -> string { + // Status.Active — "Active" should be enumMember, not property + let s = Status.Active + + // user.greet() — "greet" should be function, not property + let u = User { name: "hi" } + let g = u.greet() + + // user.name — "name" should be property (this is correct already) + u.name +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// enum_member_access.baml:1:1 (comment) len=60 "// Test: semantic tokens for multi-segment Path expressions." +// enum_member_access.baml:2:1 (comment) len=66 "// Issue #9: The final segment should get a type-aware token kind," +// enum_member_access.baml:3:1 (comment) len=64 "// not a generic \"property\" token for everything after the root." +// enum_member_access.baml:5:1 (keyword) len=4 "enum" +// enum_member_access.baml:5:6 (enum) [declaration] len=6 "Status" +// enum_member_access.baml:6:3 (enumMember) [declaration] len=6 "Active" +// enum_member_access.baml:7:3 (enumMember) [declaration] len=8 "Inactive" +// enum_member_access.baml:10:1 (keyword) len=5 "class" +// enum_member_access.baml:10:7 (class) [declaration] len=4 "User" +// enum_member_access.baml:11:3 (property) [declaration] len=4 "name" +// enum_member_access.baml:11:8 (type) [defaultLibrary] len=6 "string" +// enum_member_access.baml:13:3 (keyword) len=8 "function" +// enum_member_access.baml:13:12 (method) [declaration] len=5 "greet" +// enum_member_access.baml:13:18 (parameter) [declaration] len=4 "self" +// enum_member_access.baml:13:27 (type) [defaultLibrary] len=6 "string" +// enum_member_access.baml:14:5 (parameter) len=4 "self" +// enum_member_access.baml:14:10 (property) len=4 "name" +// enum_member_access.baml:18:1 (keyword) len=8 "function" +// enum_member_access.baml:18:10 (function) [declaration] len=11 "test_tokens" +// enum_member_access.baml:18:27 (type) [defaultLibrary] len=6 "string" +// enum_member_access.baml:19:3 (comment) len=64 "// Status.Active — \"Active\" should be enumMember, not property" +// enum_member_access.baml:20:3 (keyword) len=3 "let" +// enum_member_access.baml:20:7 (variable) [declaration] len=1 "s" +// enum_member_access.baml:20:9 (operator) len=1 "=" +// enum_member_access.baml:20:11 (enum) len=6 "Status" +// enum_member_access.baml:20:18 (enumMember) len=6 "Active" +// enum_member_access.baml:22:3 (comment) len=60 "// user.greet() — \"greet\" should be function, not property" +// enum_member_access.baml:23:3 (keyword) len=3 "let" +// enum_member_access.baml:23:7 (variable) [declaration] len=1 "u" +// enum_member_access.baml:23:9 (operator) len=1 "=" +// enum_member_access.baml:23:11 (class) len=4 "User" +// enum_member_access.baml:23:18 (property) len=4 "name" +// enum_member_access.baml:23:24 (string) len=4 "\"hi\"" +// enum_member_access.baml:24:3 (keyword) len=3 "let" +// enum_member_access.baml:24:7 (variable) [declaration] len=1 "g" +// enum_member_access.baml:24:9 (operator) len=1 "=" +// enum_member_access.baml:24:11 (variable) len=1 "u" +// enum_member_access.baml:24:13 (method) len=5 "greet" +// enum_member_access.baml:26:3 (comment) len=68 "// user.name — \"name\" should be property (this is correct already)" +// enum_member_access.baml:27:3 (variable) len=1 "u" +// enum_member_access.baml:27:5 (property) len=4 "name" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/exhaustive.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/exhaustive.baml new file mode 100644 index 0000000000..b460c1c3d4 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/exhaustive.baml @@ -0,0 +1,188 @@ +// Exhaustive match patterns — no diagnostics expected +enum Direction { + North + South + East + West +} + +// All variants covered +function AllVariants(d: Direction) -> string { + match (d) { + Direction.North => "north", + Direction.South => "south", + Direction.East => "east", + Direction.West => "west" + } +} + +// Wildcard catch-all +function WildcardCatchAll(d: Direction) -> string { + match (d) { + Direction.North => "north", + _ => "other" + } +} + +// Named catch-all +function NamedCatchAll(d: Direction) -> string { + match (d) { + Direction.North => "north", + let other => "other" + } +} + +// Boolean exhaustive +function BoolExhaustive(b: bool) -> string { + match (b) { + true => "yes", + false => "no" + } +} + +// Optional with null +function OptionalExhaustive(x: int?) -> string { + match (x) { + let n: int => "has value", + null => "null" + } +} + +// Type alias union fully covered +class Ok { + value string +} +class Err { + message string +} +type MyResult = Ok | Err + +function TypeAliasExhaustive(r: MyResult) -> string { + match (r) { + let o: Ok => o.value, + let e: Err => e.message + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// exhaustive.baml:1:1 (comment) len=56 "// Exhaustive match patterns — no diagnostics expected" +// exhaustive.baml:2:1 (keyword) len=4 "enum" +// exhaustive.baml:2:6 (enum) [declaration] len=9 "Direction" +// exhaustive.baml:3:3 (enumMember) [declaration] len=5 "North" +// exhaustive.baml:4:3 (enumMember) [declaration] len=5 "South" +// exhaustive.baml:5:3 (enumMember) [declaration] len=4 "East" +// exhaustive.baml:6:3 (enumMember) [declaration] len=4 "West" +// exhaustive.baml:9:1 (comment) len=23 "// All variants covered" +// exhaustive.baml:10:1 (keyword) len=8 "function" +// exhaustive.baml:10:10 (function) [declaration] len=11 "AllVariants" +// exhaustive.baml:10:22 (parameter) [declaration] len=1 "d" +// exhaustive.baml:10:25 (enum) len=9 "Direction" +// exhaustive.baml:10:39 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:11:3 (keyword) len=5 "match" +// exhaustive.baml:11:10 (parameter) len=1 "d" +// exhaustive.baml:12:5 (enum) len=9 "Direction" +// exhaustive.baml:12:14 (operator) len=1 "." +// exhaustive.baml:12:15 (enumMember) len=5 "North" +// exhaustive.baml:12:24 (string) len=7 "\"north\"" +// exhaustive.baml:13:5 (enum) len=9 "Direction" +// exhaustive.baml:13:14 (operator) len=1 "." +// exhaustive.baml:13:15 (enumMember) len=5 "South" +// exhaustive.baml:13:24 (string) len=7 "\"south\"" +// exhaustive.baml:14:5 (enum) len=9 "Direction" +// exhaustive.baml:14:14 (operator) len=1 "." +// exhaustive.baml:14:15 (enumMember) len=4 "East" +// exhaustive.baml:14:23 (string) len=6 "\"east\"" +// exhaustive.baml:15:5 (enum) len=9 "Direction" +// exhaustive.baml:15:14 (operator) len=1 "." +// exhaustive.baml:15:15 (enumMember) len=4 "West" +// exhaustive.baml:15:23 (string) len=6 "\"west\"" +// exhaustive.baml:19:1 (comment) len=21 "// Wildcard catch-all" +// exhaustive.baml:20:1 (keyword) len=8 "function" +// exhaustive.baml:20:10 (function) [declaration] len=16 "WildcardCatchAll" +// exhaustive.baml:20:27 (parameter) [declaration] len=1 "d" +// exhaustive.baml:20:30 (enum) len=9 "Direction" +// exhaustive.baml:20:44 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:21:3 (keyword) len=5 "match" +// exhaustive.baml:21:10 (parameter) len=1 "d" +// exhaustive.baml:22:5 (enum) len=9 "Direction" +// exhaustive.baml:22:14 (operator) len=1 "." +// exhaustive.baml:22:15 (enumMember) len=5 "North" +// exhaustive.baml:22:24 (string) len=7 "\"north\"" +// exhaustive.baml:23:10 (string) len=7 "\"other\"" +// exhaustive.baml:27:1 (comment) len=18 "// Named catch-all" +// exhaustive.baml:28:1 (keyword) len=8 "function" +// exhaustive.baml:28:10 (function) [declaration] len=13 "NamedCatchAll" +// exhaustive.baml:28:24 (parameter) [declaration] len=1 "d" +// exhaustive.baml:28:27 (enum) len=9 "Direction" +// exhaustive.baml:28:41 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:29:3 (keyword) len=5 "match" +// exhaustive.baml:29:10 (parameter) len=1 "d" +// exhaustive.baml:30:5 (enum) len=9 "Direction" +// exhaustive.baml:30:14 (operator) len=1 "." +// exhaustive.baml:30:15 (enumMember) len=5 "North" +// exhaustive.baml:30:24 (string) len=7 "\"north\"" +// exhaustive.baml:31:5 (keyword) len=3 "let" +// exhaustive.baml:31:9 (variable) [declaration] len=5 "other" +// exhaustive.baml:31:18 (string) len=7 "\"other\"" +// exhaustive.baml:35:1 (comment) len=21 "// Boolean exhaustive" +// exhaustive.baml:36:1 (keyword) len=8 "function" +// exhaustive.baml:36:10 (function) [declaration] len=14 "BoolExhaustive" +// exhaustive.baml:36:25 (parameter) [declaration] len=1 "b" +// exhaustive.baml:36:28 (type) [defaultLibrary] len=4 "bool" +// exhaustive.baml:36:37 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:37:3 (keyword) len=5 "match" +// exhaustive.baml:37:10 (parameter) len=1 "b" +// exhaustive.baml:38:5 (type) len=4 "true" +// exhaustive.baml:38:13 (string) len=5 "\"yes\"" +// exhaustive.baml:39:5 (type) len=5 "false" +// exhaustive.baml:39:14 (string) len=4 "\"no\"" +// exhaustive.baml:43:1 (comment) len=21 "// Optional with null" +// exhaustive.baml:44:1 (keyword) len=8 "function" +// exhaustive.baml:44:10 (function) [declaration] len=18 "OptionalExhaustive" +// exhaustive.baml:44:29 (parameter) [declaration] len=1 "x" +// exhaustive.baml:44:32 (type) [defaultLibrary] len=3 "int" +// exhaustive.baml:44:41 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:45:3 (keyword) len=5 "match" +// exhaustive.baml:45:10 (parameter) len=1 "x" +// exhaustive.baml:46:5 (keyword) len=3 "let" +// exhaustive.baml:46:9 (variable) [declaration] len=1 "n" +// exhaustive.baml:46:12 (type) [defaultLibrary] len=3 "int" +// exhaustive.baml:46:19 (string) len=11 "\"has value\"" +// exhaustive.baml:47:5 (type) [defaultLibrary] len=4 "null" +// exhaustive.baml:47:13 (string) len=6 "\"null\"" +// exhaustive.baml:51:1 (comment) len=33 "// Type alias union fully covered" +// exhaustive.baml:52:1 (keyword) len=5 "class" +// exhaustive.baml:52:7 (class) [declaration] len=2 "Ok" +// exhaustive.baml:53:3 (property) [declaration] len=5 "value" +// exhaustive.baml:53:9 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:55:1 (keyword) len=5 "class" +// exhaustive.baml:55:7 (class) [declaration] len=3 "Err" +// exhaustive.baml:56:3 (property) [declaration] len=7 "message" +// exhaustive.baml:56:11 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:58:1 (keyword) len=4 "type" +// exhaustive.baml:58:6 (type) [declaration] len=8 "MyResult" +// exhaustive.baml:58:15 (operator) len=1 "=" +// exhaustive.baml:58:17 (class) len=2 "Ok" +// exhaustive.baml:58:20 (operator) len=1 "|" +// exhaustive.baml:58:22 (class) len=3 "Err" +// exhaustive.baml:60:1 (keyword) len=8 "function" +// exhaustive.baml:60:10 (function) [declaration] len=19 "TypeAliasExhaustive" +// exhaustive.baml:60:30 (parameter) [declaration] len=1 "r" +// exhaustive.baml:60:33 (type) len=8 "MyResult" +// exhaustive.baml:60:46 (type) [defaultLibrary] len=6 "string" +// exhaustive.baml:61:3 (keyword) len=5 "match" +// exhaustive.baml:61:10 (parameter) len=1 "r" +// exhaustive.baml:62:5 (keyword) len=3 "let" +// exhaustive.baml:62:9 (variable) [declaration] len=1 "o" +// exhaustive.baml:62:12 (class) len=2 "Ok" +// exhaustive.baml:62:18 (variable) len=1 "o" +// exhaustive.baml:62:20 (property) len=5 "value" +// exhaustive.baml:63:5 (keyword) len=3 "let" +// exhaustive.baml:63:9 (variable) [declaration] len=1 "e" +// exhaustive.baml:63:12 (class) len=3 "Err" +// exhaustive.baml:63:19 (variable) len=1 "e" +// exhaustive.baml:63:21 (property) len=7 "message" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/extends_chain.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/extends_chain.baml new file mode 100644 index 0000000000..56f158f094 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/extends_chain.baml @@ -0,0 +1,84 @@ +// BEP-044: a class implementing the leaf interface in a three-level requires +// chain should satisfy every contract in the chain. All fields and methods +// flow down transitively. + +interface HasName { + name: string +} + +interface Greeter requires HasName { + function greet(self) -> string throws never +} + +interface Polite requires Greeter { + function farewell(self) -> string throws never +} + +class Robot { + name: string + + implements HasName {} + + implements Greeter { + function greet(self) -> string { return "hello" } + } + + implements Polite { + function farewell(self) -> string { return "bye" } + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// extends_chain.baml:1:1 (comment) len=77 "// BEP-044: a class implementing the leaf interface in a three-level requires" +// extends_chain.baml:2:1 (comment) len=75 "// chain should satisfy every contract in the chain. All fields and methods" +// extends_chain.baml:3:1 (comment) len=26 "// flow down transitively." +// extends_chain.baml:5:1 (keyword) len=9 "interface" +// extends_chain.baml:5:11 (interface) [declaration] len=7 "HasName" +// extends_chain.baml:6:3 (property) [declaration] len=4 "name" +// extends_chain.baml:6:9 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:9:1 (keyword) len=9 "interface" +// extends_chain.baml:9:11 (interface) [declaration] len=7 "Greeter" +// extends_chain.baml:9:19 (keyword) len=8 "requires" +// extends_chain.baml:9:28 (interface) len=7 "HasName" +// extends_chain.baml:10:3 (keyword) len=8 "function" +// extends_chain.baml:10:12 (method) [declaration] len=5 "greet" +// extends_chain.baml:10:18 (parameter) [declaration] len=4 "self" +// extends_chain.baml:10:27 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:10:34 (keyword) len=6 "throws" +// extends_chain.baml:10:41 (type) [defaultLibrary] len=5 "never" +// extends_chain.baml:13:1 (keyword) len=9 "interface" +// extends_chain.baml:13:11 (interface) [declaration] len=6 "Polite" +// extends_chain.baml:13:18 (keyword) len=8 "requires" +// extends_chain.baml:13:27 (interface) len=7 "Greeter" +// extends_chain.baml:14:3 (keyword) len=8 "function" +// extends_chain.baml:14:12 (method) [declaration] len=8 "farewell" +// extends_chain.baml:14:21 (parameter) [declaration] len=4 "self" +// extends_chain.baml:14:30 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:14:37 (keyword) len=6 "throws" +// extends_chain.baml:14:44 (type) [defaultLibrary] len=5 "never" +// extends_chain.baml:17:1 (keyword) len=5 "class" +// extends_chain.baml:17:7 (class) [declaration] len=5 "Robot" +// extends_chain.baml:18:3 (property) [declaration] len=4 "name" +// extends_chain.baml:18:9 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:20:3 (keyword) len=10 "implements" +// extends_chain.baml:20:14 (interface) len=7 "HasName" +// extends_chain.baml:22:3 (keyword) len=10 "implements" +// extends_chain.baml:22:14 (interface) len=7 "Greeter" +// extends_chain.baml:23:5 (keyword) len=8 "function" +// extends_chain.baml:23:14 (method) [declaration] len=5 "greet" +// extends_chain.baml:23:20 (parameter) [declaration] len=4 "self" +// extends_chain.baml:23:29 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:23:38 (keyword) len=6 "return" +// extends_chain.baml:23:45 (string) len=7 "\"hello\"" +// extends_chain.baml:26:3 (keyword) len=10 "implements" +// extends_chain.baml:26:14 (interface) len=6 "Polite" +// extends_chain.baml:27:5 (keyword) len=8 "function" +// extends_chain.baml:27:14 (method) [declaration] len=8 "farewell" +// extends_chain.baml:27:23 (parameter) [declaration] len=4 "self" +// extends_chain.baml:27:32 (type) [defaultLibrary] len=6 "string" +// extends_chain.baml:27:41 (keyword) len=6 "return" +// extends_chain.baml:27:48 (string) len=5 "\"bye\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/field_alias.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/field_alias.baml new file mode 100644 index 0000000000..27b22226f0 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/field_alias.baml @@ -0,0 +1,51 @@ +// BEP-044: interface fields are linked to class-owned fields with +// `interface_field as class_field`. + +interface Named { + name: string +} + +class Person { + display_name: string + + implements Named { + name as display_name + } +} + +function read_name(p: Person) -> string { + return p.as.name +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// field_alias.baml:1:1 (comment) len=66 "// BEP-044: interface fields are linked to class-owned fields with" +// field_alias.baml:2:1 (comment) len=36 "// `interface_field as class_field`." +// field_alias.baml:4:1 (keyword) len=9 "interface" +// field_alias.baml:4:11 (interface) [declaration] len=5 "Named" +// field_alias.baml:5:3 (property) [declaration] len=4 "name" +// field_alias.baml:5:9 (type) [defaultLibrary] len=6 "string" +// field_alias.baml:8:1 (keyword) len=5 "class" +// field_alias.baml:8:7 (class) [declaration] len=6 "Person" +// field_alias.baml:9:3 (property) [declaration] len=12 "display_name" +// field_alias.baml:9:17 (type) [defaultLibrary] len=6 "string" +// field_alias.baml:11:3 (keyword) len=10 "implements" +// field_alias.baml:11:14 (interface) len=5 "Named" +// field_alias.baml:12:5 (property) len=4 "name" +// field_alias.baml:12:10 (keyword) len=2 "as" +// field_alias.baml:12:13 (property) len=12 "display_name" +// field_alias.baml:16:1 (keyword) len=8 "function" +// field_alias.baml:16:10 (function) [declaration] len=9 "read_name" +// field_alias.baml:16:20 (parameter) [declaration] len=1 "p" +// field_alias.baml:16:23 (class) len=6 "Person" +// field_alias.baml:16:34 (type) [defaultLibrary] len=6 "string" +// field_alias.baml:17:3 (keyword) len=6 "return" +// field_alias.baml:17:10 (parameter) len=1 "p" +// field_alias.baml:17:12 (keyword) len=2 "as" +// field_alias.baml:17:14 (operator) len=1 "<" +// field_alias.baml:17:15 (interface) len=5 "Named" +// field_alias.baml:17:20 (operator) len=1 ">" +// field_alias.baml:17:22 (property) len=4 "name" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/for_loops.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/for_loops.baml index 94b8ccc3ba..4448bc1071 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/for_loops.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/for_loops.baml @@ -20,34 +20,46 @@ function ForInLoop() -> int { // //- semantic_tokens // for_loops.baml:1:1 (keyword) len=8 "function" -// for_loops.baml:1:10 (function) len=10 "CStyleLoop" -// for_loops.baml:1:26 (type) len=3 "int" +// for_loops.baml:1:10 (function) [declaration] len=10 "CStyleLoop" +// for_loops.baml:1:26 (type) [defaultLibrary] len=3 "int" // for_loops.baml:2:3 (keyword) len=3 "let" -// for_loops.baml:2:7 (variable) len=3 "sum" +// for_loops.baml:2:7 (variable) [declaration] len=3 "sum" // for_loops.baml:2:11 (operator) len=1 "=" // for_loops.baml:2:13 (number) len=1 "0" // for_loops.baml:3:3 (keyword) len=3 "for" // for_loops.baml:3:8 (keyword) len=3 "let" -// for_loops.baml:3:12 (variable) len=1 "i" +// for_loops.baml:3:12 (variable) [declaration] len=1 "i" // for_loops.baml:3:14 (operator) len=1 "=" // for_loops.baml:3:16 (number) len=1 "0" +// for_loops.baml:3:19 (variable) len=1 "i" // for_loops.baml:3:21 (operator) len=1 "<" // for_loops.baml:3:23 (number) len=2 "10" +// for_loops.baml:3:27 (variable) len=1 "i" // for_loops.baml:3:29 (operator) len=2 "+=" // for_loops.baml:3:32 (number) len=1 "1" +// for_loops.baml:4:5 (variable) len=3 "sum" // for_loops.baml:4:9 (operator) len=1 "=" +// for_loops.baml:4:11 (variable) len=3 "sum" // for_loops.baml:4:15 (operator) len=1 "+" +// for_loops.baml:4:17 (variable) len=1 "i" +// for_loops.baml:6:3 (variable) len=3 "sum" // for_loops.baml:9:1 (keyword) len=8 "function" -// for_loops.baml:9:10 (function) len=9 "ForInLoop" -// for_loops.baml:9:25 (type) len=3 "int" +// for_loops.baml:9:10 (function) [declaration] len=9 "ForInLoop" +// for_loops.baml:9:25 (type) [defaultLibrary] len=3 "int" // for_loops.baml:10:3 (keyword) len=3 "let" +// for_loops.baml:10:7 (variable) [declaration] len=3 "sum" // for_loops.baml:10:11 (operator) len=1 "=" // for_loops.baml:10:13 (number) len=1 "0" // for_loops.baml:11:3 (keyword) len=3 "for" // for_loops.baml:11:8 (keyword) len=3 "let" +// for_loops.baml:11:12 (variable) [declaration] len=1 "x" // for_loops.baml:11:14 (keyword) len=2 "in" // for_loops.baml:11:18 (number) len=1 "1" // for_loops.baml:11:21 (number) len=1 "2" // for_loops.baml:11:24 (number) len=1 "3" +// for_loops.baml:12:5 (variable) len=3 "sum" // for_loops.baml:12:9 (operator) len=1 "=" +// for_loops.baml:12:11 (variable) len=3 "sum" // for_loops.baml:12:15 (operator) len=1 "+" +// for_loops.baml:12:17 (variable) len=1 "x" +// for_loops.baml:14:3 (variable) len=3 "sum" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/function.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/function.baml index 5a063c90e0..4e16d11d76 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/function.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/function.baml @@ -12,11 +12,13 @@ function classify(input: Input) -> string { // //- semantic_tokens // function.baml:1:1 (keyword) len=5 "class" -// function.baml:1:7 (class) len=5 "Input" -// function.baml:2:5 (property) len=4 "text" -// function.baml:2:10 (type) len=6 "string" +// function.baml:1:7 (class) [declaration] len=5 "Input" +// function.baml:2:5 (property) [declaration] len=4 "text" +// function.baml:2:10 (type) [defaultLibrary] len=6 "string" // function.baml:5:1 (keyword) len=8 "function" -// function.baml:5:10 (function) len=8 "classify" -// function.baml:5:19 (parameter) len=5 "input" +// function.baml:5:10 (function) [declaration] len=8 "classify" +// function.baml:5:19 (parameter) [declaration] len=5 "input" // function.baml:5:26 (class) len=5 "Input" -// function.baml:5:36 (type) len=6 "string" +// function.baml:5:36 (type) [defaultLibrary] len=6 "string" +// function.baml:6:5 (parameter) len=5 "input" +// function.baml:6:11 (property) len=4 "text" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generators.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generators.baml new file mode 100644 index 0000000000..82e419466c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generators.baml @@ -0,0 +1,99 @@ +// Codegen for the Python host: `baml generate` emits the typed `baml_sdk` +// package into python_demo/, next to the Python scripts that import it (so no +// sys.path tweaking). Re-run after changing any function or type that +// Python imports. NOTE: output_dir is relative to the project root (where +// baml.toml lives), not to baml_src/. +generator target { + output_type: "python/pydantic", + output_dir: "python_demo", + default_client_mode: "sync", + // the python/pydantic generator only supports preserve-case + naming_convention: "preserve-case", +} + +// Codegen for the Node/TypeScript host: emits the typed `baml_sdk` package +// into typescript_demo/, next to the TypeScript scripts that import it. The TS SDK +// always emits both sync and `_async` bindings, so there is no client-mode +// knob here. Generated code imports the `@boundaryml/baml-core-node` runtime. +// (Like the Python target, output_dir is relative to the project root and the +// `baml_sdk` package name is appended automatically.) Re-run `baml generate` +// after changing any function or type the TS side imports. +generator ts_target { + output_type: "typescript/node", + output_dir: "typescript_demo", + // the typescript/node generator only supports preserve-case + naming_convention: "preserve-case", +} + +//---- +//- diagnostics +// warning: `generator target` is ignored: code generators are configured in `baml.toml` now. Move it to a `[generator.]` section in baml.toml. +// ╭─[ generators.baml:6:1 ] +// │ +// 6 │ generator target { +// │ ────────┬─────── +// │ ╰───────── move this to baml.toml +// │ +// │ Note: Error code: E0017 +// ───╯ +// warning: `generator ts_target` is ignored: code generators are configured in `baml.toml` now. Move it to a `[generator.]` section in baml.toml. +// ╭─[ generators.baml:21:1 ] +// │ +// 21 │ generator ts_target { +// │ ─────────┬───────── +// │ ╰─────────── move this to baml.toml +// │ +// │ Note: Error code: E0017 +// ────╯ +// +//- semantic_tokens +// generators.baml:1:1 (comment) len=74 "// Codegen for the Python host: `baml generate` emits the typed `baml_sdk`" +// generators.baml:2:1 (comment) len=78 "// package into python_demo/, next to the Python scripts that import it (so no" +// generators.baml:3:1 (comment) len=70 "// sys.path tweaking). Re-run after changing any function or type that" +// generators.baml:4:1 (comment) len=74 "// Python imports. NOTE: output_dir is relative to the project root (where" +// generators.baml:5:1 (comment) len=38 "// baml.toml lives), not to baml_src/." +// generators.baml:6:1 (keyword) len=9 "generator" +// generators.baml:6:11 (struct) [declaration] len=6 "target" +// generators.baml:7:5 (property) len=11 "output_type" +// generators.baml:7:18 (string) len=1 "\"" +// generators.baml:7:19 (string) len=6 "python" +// generators.baml:7:25 (string) len=1 "/" +// generators.baml:7:26 (string) len=8 "pydantic" +// generators.baml:7:34 (string) len=1 "\"" +// generators.baml:8:5 (property) len=10 "output_dir" +// generators.baml:8:17 (string) len=1 "\"" +// generators.baml:8:18 (string) len=11 "python_demo" +// generators.baml:8:29 (string) len=1 "\"" +// generators.baml:9:5 (property) len=19 "default_client_mode" +// generators.baml:9:26 (string) len=1 "\"" +// generators.baml:9:27 (string) len=4 "sync" +// generators.baml:9:31 (string) len=1 "\"" +// generators.baml:10:5 (comment) len=60 "// the python/pydantic generator only supports preserve-case" +// generators.baml:11:5 (property) len=17 "naming_convention" +// generators.baml:11:24 (string) len=1 "\"" +// generators.baml:11:25 (string) len=13 "preserve-case" +// generators.baml:11:38 (string) len=1 "\"" +// generators.baml:14:1 (comment) len=75 "// Codegen for the Node/TypeScript host: emits the typed `baml_sdk` package" +// generators.baml:15:1 (comment) len=83 "// into typescript_demo/, next to the TypeScript scripts that import it. The TS SDK" +// generators.baml:16:1 (comment) len=75 "// always emits both sync and `_async` bindings, so there is no client-mode" +// generators.baml:17:1 (comment) len=78 "// knob here. Generated code imports the `@boundaryml/baml-core-node` runtime." +// generators.baml:18:1 (comment) len=78 "// (Like the Python target, output_dir is relative to the project root and the" +// generators.baml:19:1 (comment) len=77 "// `baml_sdk` package name is appended automatically.) Re-run `baml generate`" +// generators.baml:20:1 (comment) len=59 "// after changing any function or type the TS side imports." +// generators.baml:21:1 (keyword) len=9 "generator" +// generators.baml:21:11 (struct) [declaration] len=9 "ts_target" +// generators.baml:22:5 (property) len=11 "output_type" +// generators.baml:22:18 (string) len=1 "\"" +// generators.baml:22:19 (string) len=10 "typescript" +// generators.baml:22:29 (string) len=1 "/" +// generators.baml:22:30 (string) len=4 "node" +// generators.baml:22:34 (string) len=1 "\"" +// generators.baml:23:5 (property) len=10 "output_dir" +// generators.baml:23:17 (string) len=1 "\"" +// generators.baml:23:18 (string) len=15 "typescript_demo" +// generators.baml:23:33 (string) len=1 "\"" +// generators.baml:24:5 (comment) len=60 "// the typescript/node generator only supports preserve-case" +// generators.baml:25:5 (property) len=17 "naming_convention" +// generators.baml:25:24 (string) len=1 "\"" +// generators.baml:25:25 (string) len=13 "preserve-case" +// generators.baml:25:38 (string) len=1 "\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_field_chain.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_field_chain.baml new file mode 100644 index 0000000000..8ce1e0821b --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_field_chain.baml @@ -0,0 +1,97 @@ +// Test: generic type substitution preserved through chained field access. +// Issue #3: class_field_ty() should apply concrete type arguments, not return +// the raw unsubstituted type from the generic class definition. + +class Box { + value T +} + +class User { + name string + age int +} + +// box.value should be typed as User (not Unknown/type-var), +// so box.value.name should be typed as string. +function test_generic_chain(box: Box) -> string { + box.value.name +} + +// Nested generics: Box>.value.value.name +function test_nested_generic_chain(box: Box>) -> string { + box.value.value.name +} + +// Generic in lambda capture: lambda captures a Box and accesses value.name +function test_generic_capture(box: Box) -> string { + let get_name = () -> string { box.value.name } + get_name() +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// generic_field_chain.baml:1:1 (comment) len=74 "// Test: generic type substitution preserved through chained field access." +// generic_field_chain.baml:2:1 (comment) len=78 "// Issue #3: class_field_ty() should apply concrete type arguments, not return" +// generic_field_chain.baml:3:1 (comment) len=64 "// the raw unsubstituted type from the generic class definition." +// generic_field_chain.baml:5:1 (keyword) len=5 "class" +// generic_field_chain.baml:5:7 (class) [declaration] len=3 "Box" +// generic_field_chain.baml:5:10 (operator) len=1 "<" +// generic_field_chain.baml:5:11 (typeParameter) [declaration] len=1 "T" +// generic_field_chain.baml:5:12 (operator) len=1 ">" +// generic_field_chain.baml:6:3 (property) [declaration] len=5 "value" +// generic_field_chain.baml:6:9 (type) len=1 "T" +// generic_field_chain.baml:9:1 (keyword) len=5 "class" +// generic_field_chain.baml:9:7 (class) [declaration] len=4 "User" +// generic_field_chain.baml:10:3 (property) [declaration] len=4 "name" +// generic_field_chain.baml:10:8 (type) [defaultLibrary] len=6 "string" +// generic_field_chain.baml:11:3 (property) [declaration] len=3 "age" +// generic_field_chain.baml:11:7 (type) [defaultLibrary] len=3 "int" +// generic_field_chain.baml:14:1 (comment) len=60 "// box.value should be typed as User (not Unknown/type-var)," +// generic_field_chain.baml:15:1 (comment) len=47 "// so box.value.name should be typed as string." +// generic_field_chain.baml:16:1 (keyword) len=8 "function" +// generic_field_chain.baml:16:10 (function) [declaration] len=18 "test_generic_chain" +// generic_field_chain.baml:16:29 (parameter) [declaration] len=3 "box" +// generic_field_chain.baml:16:34 (class) len=3 "Box" +// generic_field_chain.baml:16:37 (operator) len=1 "<" +// generic_field_chain.baml:16:38 (class) len=4 "User" +// generic_field_chain.baml:16:42 (operator) len=1 ">" +// generic_field_chain.baml:16:48 (type) [defaultLibrary] len=6 "string" +// generic_field_chain.baml:17:3 (parameter) len=3 "box" +// generic_field_chain.baml:17:7 (property) len=5 "value" +// generic_field_chain.baml:17:13 (property) len=4 "name" +// generic_field_chain.baml:20:1 (comment) len=51 "// Nested generics: Box>.value.value.name" +// generic_field_chain.baml:21:1 (keyword) len=8 "function" +// generic_field_chain.baml:21:10 (function) [declaration] len=25 "test_nested_generic_chain" +// generic_field_chain.baml:21:36 (parameter) [declaration] len=3 "box" +// generic_field_chain.baml:21:41 (class) len=3 "Box" +// generic_field_chain.baml:21:44 (operator) len=1 "<" +// generic_field_chain.baml:21:45 (class) len=3 "Box" +// generic_field_chain.baml:21:48 (operator) len=1 "<" +// generic_field_chain.baml:21:49 (class) len=4 "User" +// generic_field_chain.baml:21:53 (operator) len=1 ">" +// generic_field_chain.baml:21:54 (operator) len=1 ">" +// generic_field_chain.baml:21:60 (type) [defaultLibrary] len=6 "string" +// generic_field_chain.baml:22:3 (parameter) len=3 "box" +// generic_field_chain.baml:22:7 (property) len=5 "value" +// generic_field_chain.baml:22:13 (property) len=5 "value" +// generic_field_chain.baml:22:19 (property) len=4 "name" +// generic_field_chain.baml:25:1 (comment) len=81 "// Generic in lambda capture: lambda captures a Box and accesses value.name" +// generic_field_chain.baml:26:1 (keyword) len=8 "function" +// generic_field_chain.baml:26:10 (function) [declaration] len=20 "test_generic_capture" +// generic_field_chain.baml:26:31 (parameter) [declaration] len=3 "box" +// generic_field_chain.baml:26:36 (class) len=3 "Box" +// generic_field_chain.baml:26:39 (operator) len=1 "<" +// generic_field_chain.baml:26:40 (class) len=4 "User" +// generic_field_chain.baml:26:44 (operator) len=1 ">" +// generic_field_chain.baml:26:50 (type) [defaultLibrary] len=6 "string" +// generic_field_chain.baml:27:3 (keyword) len=3 "let" +// generic_field_chain.baml:27:7 (variable) [declaration] len=8 "get_name" +// generic_field_chain.baml:27:16 (operator) len=1 "=" +// generic_field_chain.baml:27:24 (type) [defaultLibrary] len=6 "string" +// generic_field_chain.baml:27:33 (parameter) len=3 "box" +// generic_field_chain.baml:27:37 (property) len=5 "value" +// generic_field_chain.baml:27:43 (property) len=4 "name" +// generic_field_chain.baml:28:3 (variable) len=8 "get_name" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_function_call.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_function_call.baml new file mode 100644 index 0000000000..907287ddee --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_function_call.baml @@ -0,0 +1,43 @@ +// A free generic function called with explicit type args at the call site: +// `identity(5)`. The callee name (`identity`) sits in a `PATH_EXPR` whose +// segment span covers the whole `identity`, so the call-site name must be +// narrowed to match the WORD token; the `` arg resolves as a type. +function identity(x: T) -> T { + x +} + +function use_identity() -> int { + let a = identity(5); + a +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// generic_function_call.baml:1:1 (comment) len=75 "// A free generic function called with explicit type args at the call site:" +// generic_function_call.baml:2:1 (comment) len=79 "// `identity(5)`. The callee name (`identity`) sits in a `PATH_EXPR` whose" +// generic_function_call.baml:3:1 (comment) len=79 "// segment span covers the whole `identity`, so the call-site name must be" +// generic_function_call.baml:4:1 (comment) len=72 "// narrowed to match the WORD token; the `` arg resolves as a type." +// generic_function_call.baml:5:1 (keyword) len=8 "function" +// generic_function_call.baml:5:10 (function) [declaration] len=8 "identity" +// generic_function_call.baml:5:18 (operator) len=1 "<" +// generic_function_call.baml:5:19 (typeParameter) [declaration] len=1 "T" +// generic_function_call.baml:5:20 (operator) len=1 ">" +// generic_function_call.baml:5:22 (parameter) [declaration] len=1 "x" +// generic_function_call.baml:5:25 (type) len=1 "T" +// generic_function_call.baml:5:31 (type) len=1 "T" +// generic_function_call.baml:6:3 (parameter) len=1 "x" +// generic_function_call.baml:9:1 (keyword) len=8 "function" +// generic_function_call.baml:9:10 (function) [declaration] len=12 "use_identity" +// generic_function_call.baml:9:28 (type) [defaultLibrary] len=3 "int" +// generic_function_call.baml:10:3 (keyword) len=3 "let" +// generic_function_call.baml:10:7 (variable) [declaration] len=1 "a" +// generic_function_call.baml:10:9 (operator) len=1 "=" +// generic_function_call.baml:10:11 (function) len=8 "identity" +// generic_function_call.baml:10:19 (operator) len=1 "<" +// generic_function_call.baml:10:20 (type) [defaultLibrary] len=3 "int" +// generic_function_call.baml:10:23 (operator) len=1 ">" +// generic_function_call.baml:10:25 (number) len=1 "5" +// generic_function_call.baml:11:3 (variable) len=1 "a" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/header_comments.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/header_comments.baml new file mode 100644 index 0000000000..cee9a86e64 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/header_comments.baml @@ -0,0 +1,103 @@ +function ForLoopWithHeaders() -> int { + //# Loop Processing + let items = [1, 2, 3, 4, 5]; + let result = 0; + + //## Main Loop + for (let item in items) { + //### Item Processing + let processed = item * 2; + + //#### Accumulation + let result2 = result + processed; + + result2 + } + + //## Final Result + result +} + +// warning: Workflow functions are experimental, and will break in the future. +// --> headers/mdx_headers_for_loops.baml:1 +// | +// | +// 1 | function ForLoopWithHeaders() -> int { +// | + +//---- +//- diagnostics +// +// +//- semantic_tokens +// header_comments.baml:1:1 (keyword) len=8 "function" +// header_comments.baml:1:10 (function) [declaration] len=18 "ForLoopWithHeaders" +// header_comments.baml:1:34 (type) [defaultLibrary] len=3 "int" +// header_comments.baml:2:5 (comment) len=1 "/" +// header_comments.baml:2:6 (comment) len=1 "/" +// header_comments.baml:2:7 (comment) len=1 "#" +// header_comments.baml:2:9 (comment) len=4 "Loop" +// header_comments.baml:2:14 (comment) len=10 "Processing" +// header_comments.baml:3:5 (keyword) len=3 "let" +// header_comments.baml:3:9 (variable) [declaration] len=5 "items" +// header_comments.baml:3:15 (operator) len=1 "=" +// header_comments.baml:3:18 (number) len=1 "1" +// header_comments.baml:3:21 (number) len=1 "2" +// header_comments.baml:3:24 (number) len=1 "3" +// header_comments.baml:3:27 (number) len=1 "4" +// header_comments.baml:3:30 (number) len=1 "5" +// header_comments.baml:4:5 (keyword) len=3 "let" +// header_comments.baml:4:9 (variable) [declaration] len=6 "result" +// header_comments.baml:4:16 (operator) len=1 "=" +// header_comments.baml:4:18 (number) len=1 "0" +// header_comments.baml:6:5 (comment) len=1 "/" +// header_comments.baml:6:6 (comment) len=1 "/" +// header_comments.baml:6:7 (comment) len=1 "#" +// header_comments.baml:6:8 (comment) len=1 "#" +// header_comments.baml:6:10 (comment) len=4 "Main" +// header_comments.baml:6:15 (comment) len=4 "Loop" +// header_comments.baml:7:5 (keyword) len=3 "for" +// header_comments.baml:7:10 (keyword) len=3 "let" +// header_comments.baml:7:14 (variable) [declaration] len=4 "item" +// header_comments.baml:7:19 (keyword) len=2 "in" +// header_comments.baml:7:22 (variable) len=5 "items" +// header_comments.baml:8:9 (comment) len=1 "/" +// header_comments.baml:8:10 (comment) len=1 "/" +// header_comments.baml:8:11 (comment) len=1 "#" +// header_comments.baml:8:12 (comment) len=1 "#" +// header_comments.baml:8:13 (comment) len=1 "#" +// header_comments.baml:8:15 (comment) len=4 "Item" +// header_comments.baml:8:20 (comment) len=10 "Processing" +// header_comments.baml:9:9 (keyword) len=3 "let" +// header_comments.baml:9:13 (variable) [declaration] len=9 "processed" +// header_comments.baml:9:23 (operator) len=1 "=" +// header_comments.baml:9:25 (variable) len=4 "item" +// header_comments.baml:9:30 (operator) len=1 "*" +// header_comments.baml:9:32 (number) len=1 "2" +// header_comments.baml:11:9 (comment) len=1 "/" +// header_comments.baml:11:10 (comment) len=1 "/" +// header_comments.baml:11:11 (comment) len=1 "#" +// header_comments.baml:11:12 (comment) len=1 "#" +// header_comments.baml:11:13 (comment) len=1 "#" +// header_comments.baml:11:14 (comment) len=1 "#" +// header_comments.baml:11:16 (comment) len=12 "Accumulation" +// header_comments.baml:12:9 (keyword) len=3 "let" +// header_comments.baml:12:13 (variable) [declaration] len=7 "result2" +// header_comments.baml:12:21 (operator) len=1 "=" +// header_comments.baml:12:23 (variable) len=6 "result" +// header_comments.baml:12:30 (operator) len=1 "+" +// header_comments.baml:12:32 (variable) len=9 "processed" +// header_comments.baml:14:9 (variable) len=7 "result2" +// header_comments.baml:17:5 (comment) len=1 "/" +// header_comments.baml:17:6 (comment) len=1 "/" +// header_comments.baml:17:7 (comment) len=1 "#" +// header_comments.baml:17:8 (comment) len=1 "#" +// header_comments.baml:17:10 (comment) len=5 "Final" +// header_comments.baml:17:16 (comment) len=6 "Result" +// header_comments.baml:18:5 (variable) len=6 "result" +// header_comments.baml:21:1 (comment) len=78 "// warning: Workflow functions are experimental, and will break in the future." +// header_comments.baml:22:1 (comment) len=46 "// --> headers/mdx_headers_for_loops.baml:1" +// header_comments.baml:23:1 (comment) len=7 "// |" +// header_comments.baml:24:1 (comment) len=7 "// |" +// header_comments.baml:25:1 (comment) len=46 "// 1 | function ForLoopWithHeaders() -> int {" +// header_comments.baml:26:1 (comment) len=7 "// |" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/http_config.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/http_config.baml new file mode 100644 index 0000000000..e49a72e352 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/http_config.baml @@ -0,0 +1,106 @@ +// Valid HTTP configuration for regular clients +client ValidHttpClient { + provider openai + options { + model "gpt-4" + http { + connect_timeout_ms 5000 + request_timeout_ms 30000 + } + } +} + +// Valid streaming timeouts +client ValidStreamingClient { + provider anthropic + options { + model "claude-3" + http { + time_to_first_token_timeout_ms 15000 + idle_timeout_ms 10000 + } + } +} + +// Valid zero timeout (infinite) +client InfiniteTimeoutClient { + provider openai + options { + model "gpt-4" + http { + request_timeout_ms 0 + } + } +} + +// Valid composite client with total timeout +client ValidFallbackClient { + provider fallback + options { + strategy [ValidHttpClient, ValidStreamingClient] + http { + total_timeout_ms 60000 + } + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// http_config.baml:1:1 (comment) len=47 "// Valid HTTP configuration for regular clients" +// http_config.baml:2:1 (keyword) len=6 "client" +// http_config.baml:2:7 (operator) len=1 "<" +// http_config.baml:2:8 (type) len=3 "llm" +// http_config.baml:2:11 (operator) len=1 ">" +// http_config.baml:2:13 (struct) [declaration] len=15 "ValidHttpClient" +// http_config.baml:3:3 (property) len=8 "provider" +// http_config.baml:4:3 (property) len=7 "options" +// http_config.baml:5:5 (property) len=5 "model" +// http_config.baml:5:11 (string) len=7 "\"gpt-4\"" +// http_config.baml:6:5 (property) len=4 "http" +// http_config.baml:7:7 (property) len=18 "connect_timeout_ms" +// http_config.baml:7:26 (number) len=4 "5000" +// http_config.baml:8:7 (property) len=18 "request_timeout_ms" +// http_config.baml:8:26 (number) len=5 "30000" +// http_config.baml:13:1 (comment) len=27 "// Valid streaming timeouts" +// http_config.baml:14:1 (keyword) len=6 "client" +// http_config.baml:14:7 (operator) len=1 "<" +// http_config.baml:14:8 (type) len=3 "llm" +// http_config.baml:14:11 (operator) len=1 ">" +// http_config.baml:14:13 (struct) [declaration] len=20 "ValidStreamingClient" +// http_config.baml:15:3 (property) len=8 "provider" +// http_config.baml:16:3 (property) len=7 "options" +// http_config.baml:17:5 (property) len=5 "model" +// http_config.baml:17:11 (string) len=10 "\"claude-3\"" +// http_config.baml:18:5 (property) len=4 "http" +// http_config.baml:19:7 (property) len=30 "time_to_first_token_timeout_ms" +// http_config.baml:19:38 (number) len=5 "15000" +// http_config.baml:20:7 (property) len=15 "idle_timeout_ms" +// http_config.baml:20:23 (number) len=5 "10000" +// http_config.baml:25:1 (comment) len=32 "// Valid zero timeout (infinite)" +// http_config.baml:26:1 (keyword) len=6 "client" +// http_config.baml:26:7 (operator) len=1 "<" +// http_config.baml:26:8 (type) len=3 "llm" +// http_config.baml:26:11 (operator) len=1 ">" +// http_config.baml:26:13 (struct) [declaration] len=21 "InfiniteTimeoutClient" +// http_config.baml:27:3 (property) len=8 "provider" +// http_config.baml:28:3 (property) len=7 "options" +// http_config.baml:29:5 (property) len=5 "model" +// http_config.baml:29:11 (string) len=7 "\"gpt-4\"" +// http_config.baml:30:5 (property) len=4 "http" +// http_config.baml:31:7 (property) len=18 "request_timeout_ms" +// http_config.baml:31:26 (number) len=1 "0" +// http_config.baml:36:1 (comment) len=44 "// Valid composite client with total timeout" +// http_config.baml:37:1 (keyword) len=6 "client" +// http_config.baml:37:7 (operator) len=1 "<" +// http_config.baml:37:8 (type) len=3 "llm" +// http_config.baml:37:11 (operator) len=1 ">" +// http_config.baml:37:13 (struct) [declaration] len=19 "ValidFallbackClient" +// http_config.baml:38:3 (property) len=8 "provider" +// http_config.baml:39:3 (property) len=7 "options" +// http_config.baml:40:5 (property) len=8 "strategy" +// http_config.baml:41:5 (property) len=4 "http" +// http_config.baml:42:7 (property) len=16 "total_timeout_ms" +// http_config.baml:42:24 (number) len=5 "60000" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_else.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_else.baml index fca77973c8..581f606059 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_else.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_else.baml @@ -23,29 +23,37 @@ function Clamp(x: int) -> int { // //- semantic_tokens // if_else.baml:1:1 (keyword) len=8 "function" -// if_else.baml:1:10 (function) len=3 "Abs" -// if_else.baml:1:14 (parameter) len=1 "x" -// if_else.baml:1:17 (type) len=3 "int" -// if_else.baml:1:25 (type) len=3 "int" +// if_else.baml:1:10 (function) [declaration] len=3 "Abs" +// if_else.baml:1:14 (parameter) [declaration] len=1 "x" +// if_else.baml:1:17 (type) [defaultLibrary] len=3 "int" +// if_else.baml:1:25 (type) [defaultLibrary] len=3 "int" // if_else.baml:2:3 (keyword) len=2 "if" +// if_else.baml:2:7 (parameter) len=1 "x" // if_else.baml:2:9 (operator) len=1 "<" // if_else.baml:2:11 (number) len=1 "0" // if_else.baml:3:5 (operator) len=1 "-" +// if_else.baml:3:6 (parameter) len=1 "x" // if_else.baml:4:5 (keyword) len=4 "else" +// if_else.baml:5:5 (parameter) len=1 "x" // if_else.baml:9:1 (keyword) len=8 "function" -// if_else.baml:9:10 (function) len=5 "Clamp" -// if_else.baml:9:16 (parameter) len=1 "x" -// if_else.baml:9:19 (type) len=3 "int" -// if_else.baml:9:27 (type) len=3 "int" +// if_else.baml:9:10 (function) [declaration] len=5 "Clamp" +// if_else.baml:9:16 (parameter) [declaration] len=1 "x" +// if_else.baml:9:19 (type) [defaultLibrary] len=3 "int" +// if_else.baml:9:27 (type) [defaultLibrary] len=3 "int" // if_else.baml:10:3 (keyword) len=3 "let" +// if_else.baml:10:7 (variable) [declaration] len=6 "result" // if_else.baml:10:14 (operator) len=1 "=" // if_else.baml:10:16 (keyword) len=2 "if" +// if_else.baml:10:20 (parameter) len=1 "x" // if_else.baml:10:22 (operator) len=1 "<" // if_else.baml:10:24 (number) len=1 "0" // if_else.baml:11:5 (number) len=1 "0" // if_else.baml:12:5 (keyword) len=4 "else" // if_else.baml:12:10 (keyword) len=2 "if" +// if_else.baml:12:14 (parameter) len=1 "x" // if_else.baml:12:16 (operator) len=1 ">" // if_else.baml:12:18 (number) len=3 "100" // if_else.baml:13:5 (number) len=3 "100" // if_else.baml:14:5 (keyword) len=4 "else" +// if_else.baml:15:5 (parameter) len=1 "x" +// if_else.baml:17:3 (variable) len=6 "result" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_expression.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_expression.baml new file mode 100644 index 0000000000..b06aba7d7c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_expression.baml @@ -0,0 +1,59 @@ +function Abs(x: int) -> int { + if (x < 0) { + -x + } else { + x + } +} + +function Clamp(x: int) -> int { + let result = if (x < 0) { + 0 + } else if (x > 100) { + 100 + } else { + x + }; + result +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// if_expression.baml:1:1 (keyword) len=8 "function" +// if_expression.baml:1:10 (function) [declaration] len=3 "Abs" +// if_expression.baml:1:14 (parameter) [declaration] len=1 "x" +// if_expression.baml:1:17 (type) [defaultLibrary] len=3 "int" +// if_expression.baml:1:25 (type) [defaultLibrary] len=3 "int" +// if_expression.baml:2:3 (keyword) len=2 "if" +// if_expression.baml:2:7 (parameter) len=1 "x" +// if_expression.baml:2:9 (operator) len=1 "<" +// if_expression.baml:2:11 (number) len=1 "0" +// if_expression.baml:3:5 (operator) len=1 "-" +// if_expression.baml:3:6 (parameter) len=1 "x" +// if_expression.baml:4:5 (keyword) len=4 "else" +// if_expression.baml:5:5 (parameter) len=1 "x" +// if_expression.baml:9:1 (keyword) len=8 "function" +// if_expression.baml:9:10 (function) [declaration] len=5 "Clamp" +// if_expression.baml:9:16 (parameter) [declaration] len=1 "x" +// if_expression.baml:9:19 (type) [defaultLibrary] len=3 "int" +// if_expression.baml:9:27 (type) [defaultLibrary] len=3 "int" +// if_expression.baml:10:3 (keyword) len=3 "let" +// if_expression.baml:10:7 (variable) [declaration] len=6 "result" +// if_expression.baml:10:14 (operator) len=1 "=" +// if_expression.baml:10:16 (keyword) len=2 "if" +// if_expression.baml:10:20 (parameter) len=1 "x" +// if_expression.baml:10:22 (operator) len=1 "<" +// if_expression.baml:10:24 (number) len=1 "0" +// if_expression.baml:11:5 (number) len=1 "0" +// if_expression.baml:12:5 (keyword) len=4 "else" +// if_expression.baml:12:10 (keyword) len=2 "if" +// if_expression.baml:12:14 (parameter) len=1 "x" +// if_expression.baml:12:16 (operator) len=1 ">" +// if_expression.baml:12:18 (number) len=3 "100" +// if_expression.baml:13:5 (number) len=3 "100" +// if_expression.baml:14:5 (keyword) len=4 "else" +// if_expression.baml:15:5 (parameter) len=1 "x" +// if_expression.baml:17:3 (variable) len=6 "result" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_let_chain.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_let_chain.baml new file mode 100644 index 0000000000..76bc3061fc --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_let_chain.baml @@ -0,0 +1,152 @@ +// `else if let` and `else if` chains. +class Ok { + value string +} +class Err { + message string +} +class Empty {} + +// Plain `else if` after `if let`. The `is Empty { ... }` form is no +// longer ambiguous with the then-block in condition position — the +// parser suppresses destructure patterns there (Rust-style restriction). +function MixedChainPlain(r: Ok | Err | Empty) -> string { + if let o: Ok = r { + o.value + } else if r is Empty { + "empty" + } else { + "other" + } +} + +// `else if let` chain — each branch binds its own name. +function IfLetChain(r: Ok | Err | Empty) -> string { + if let o: Ok = r { + o.value + } else if let e: Err = r { + e.message + } else { + "empty" + } +} + +// `else if let` without a final else. +function IfLetChainNoElse(r: Ok | Err) -> string { + if let o: Ok = r { + return o.value; + } else if let e: Err = r { + return e.message; + } + "unreachable" +} + +//---- +//- diagnostics +// warning: irrefutable `if let` pattern; the `else` branch is unreachable — use a plain `let` binding instead +// ╭─[ if_let_chain.baml:38:13 ] +// │ +// 38 │ } else if let e: Err = r { +// │ ─────┬──── +// │ ╰────── irrefutable `if let` pattern; the `else` branch is unreachable — use a plain `let` binding instead +// │ +// │ Note: Error code: E0112 +// ────╯ +// +//- semantic_tokens +// if_let_chain.baml:1:1 (comment) len=38 "// `else if let` and `else if` chains." +// if_let_chain.baml:2:1 (keyword) len=5 "class" +// if_let_chain.baml:2:7 (class) [declaration] len=2 "Ok" +// if_let_chain.baml:3:3 (property) [declaration] len=5 "value" +// if_let_chain.baml:3:9 (type) [defaultLibrary] len=6 "string" +// if_let_chain.baml:5:1 (keyword) len=5 "class" +// if_let_chain.baml:5:7 (class) [declaration] len=3 "Err" +// if_let_chain.baml:6:3 (property) [declaration] len=7 "message" +// if_let_chain.baml:6:11 (type) [defaultLibrary] len=6 "string" +// if_let_chain.baml:8:1 (keyword) len=5 "class" +// if_let_chain.baml:8:7 (class) [declaration] len=5 "Empty" +// if_let_chain.baml:10:1 (comment) len=68 "// Plain `else if` after `if let`. The `is Empty { ... }` form is no" +// if_let_chain.baml:11:1 (comment) len=69 "// longer ambiguous with the then-block in condition position — the" +// if_let_chain.baml:12:1 (comment) len=73 "// parser suppresses destructure patterns there (Rust-style restriction)." +// if_let_chain.baml:13:1 (keyword) len=8 "function" +// if_let_chain.baml:13:10 (function) [declaration] len=15 "MixedChainPlain" +// if_let_chain.baml:13:26 (parameter) [declaration] len=1 "r" +// if_let_chain.baml:13:29 (class) len=2 "Ok" +// if_let_chain.baml:13:32 (operator) len=1 "|" +// if_let_chain.baml:13:34 (class) len=3 "Err" +// if_let_chain.baml:13:38 (operator) len=1 "|" +// if_let_chain.baml:13:40 (class) len=5 "Empty" +// if_let_chain.baml:13:50 (type) [defaultLibrary] len=6 "string" +// if_let_chain.baml:14:3 (keyword) len=2 "if" +// if_let_chain.baml:14:6 (keyword) len=3 "let" +// if_let_chain.baml:14:10 (variable) [declaration] len=1 "o" +// if_let_chain.baml:14:13 (class) len=2 "Ok" +// if_let_chain.baml:14:16 (operator) len=1 "=" +// if_let_chain.baml:14:18 (parameter) len=1 "r" +// if_let_chain.baml:15:5 (variable) len=1 "o" +// if_let_chain.baml:15:7 (property) len=5 "value" +// if_let_chain.baml:16:5 (keyword) len=4 "else" +// if_let_chain.baml:16:10 (keyword) len=2 "if" +// if_let_chain.baml:16:13 (parameter) len=1 "r" +// if_let_chain.baml:16:15 (keyword) len=2 "is" +// if_let_chain.baml:16:18 (class) len=5 "Empty" +// if_let_chain.baml:17:5 (string) len=7 "\"empty\"" +// if_let_chain.baml:18:5 (keyword) len=4 "else" +// if_let_chain.baml:19:5 (string) len=7 "\"other\"" +// if_let_chain.baml:23:1 (comment) len=58 "// `else if let` chain — each branch binds its own name." +// if_let_chain.baml:24:1 (keyword) len=8 "function" +// if_let_chain.baml:24:10 (function) [declaration] len=10 "IfLetChain" +// if_let_chain.baml:24:21 (parameter) [declaration] len=1 "r" +// if_let_chain.baml:24:24 (class) len=2 "Ok" +// if_let_chain.baml:24:27 (operator) len=1 "|" +// if_let_chain.baml:24:29 (class) len=3 "Err" +// if_let_chain.baml:24:33 (operator) len=1 "|" +// if_let_chain.baml:24:35 (class) len=5 "Empty" +// if_let_chain.baml:24:45 (type) [defaultLibrary] len=6 "string" +// if_let_chain.baml:25:3 (keyword) len=2 "if" +// if_let_chain.baml:25:6 (keyword) len=3 "let" +// if_let_chain.baml:25:10 (variable) [declaration] len=1 "o" +// if_let_chain.baml:25:13 (class) len=2 "Ok" +// if_let_chain.baml:25:16 (operator) len=1 "=" +// if_let_chain.baml:25:18 (parameter) len=1 "r" +// if_let_chain.baml:26:5 (variable) len=1 "o" +// if_let_chain.baml:26:7 (property) len=5 "value" +// if_let_chain.baml:27:5 (keyword) len=4 "else" +// if_let_chain.baml:27:10 (keyword) len=2 "if" +// if_let_chain.baml:27:13 (keyword) len=3 "let" +// if_let_chain.baml:27:17 (variable) [declaration] len=1 "e" +// if_let_chain.baml:27:20 (class) len=3 "Err" +// if_let_chain.baml:27:24 (operator) len=1 "=" +// if_let_chain.baml:27:26 (parameter) len=1 "r" +// if_let_chain.baml:28:5 (variable) len=1 "e" +// if_let_chain.baml:28:7 (property) len=7 "message" +// if_let_chain.baml:29:5 (keyword) len=4 "else" +// if_let_chain.baml:30:5 (string) len=7 "\"empty\"" +// if_let_chain.baml:34:1 (comment) len=38 "// `else if let` without a final else." +// if_let_chain.baml:35:1 (keyword) len=8 "function" +// if_let_chain.baml:35:10 (function) [declaration] len=16 "IfLetChainNoElse" +// if_let_chain.baml:35:27 (parameter) [declaration] len=1 "r" +// if_let_chain.baml:35:30 (class) len=2 "Ok" +// if_let_chain.baml:35:33 (operator) len=1 "|" +// if_let_chain.baml:35:35 (class) len=3 "Err" +// if_let_chain.baml:35:43 (type) [defaultLibrary] len=6 "string" +// if_let_chain.baml:36:3 (keyword) len=2 "if" +// if_let_chain.baml:36:6 (keyword) len=3 "let" +// if_let_chain.baml:36:10 (variable) [declaration] len=1 "o" +// if_let_chain.baml:36:13 (class) len=2 "Ok" +// if_let_chain.baml:36:16 (operator) len=1 "=" +// if_let_chain.baml:36:18 (parameter) len=1 "r" +// if_let_chain.baml:37:5 (keyword) len=6 "return" +// if_let_chain.baml:37:12 (variable) len=1 "o" +// if_let_chain.baml:37:14 (property) len=5 "value" +// if_let_chain.baml:38:5 (keyword) len=4 "else" +// if_let_chain.baml:38:10 (keyword) len=2 "if" +// if_let_chain.baml:38:13 (keyword) len=3 "let" +// if_let_chain.baml:38:17 (variable) [declaration] len=1 "e" +// if_let_chain.baml:38:20 (class) len=3 "Err" +// if_let_chain.baml:38:24 (operator) len=1 "=" +// if_let_chain.baml:38:26 (parameter) len=1 "r" +// if_let_chain.baml:39:5 (keyword) len=6 "return" +// if_let_chain.baml:39:12 (variable) len=1 "e" +// if_let_chain.baml:39:14 (property) len=7 "message" +// if_let_chain.baml:41:3 (string) len=13 "\"unreachable\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/implements_for.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/implements_for.baml new file mode 100644 index 0000000000..fb6575535a --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/implements_for.baml @@ -0,0 +1,45 @@ +// Out-of-body implements: top-level `implements I for T { ... }` + +interface ToJson { + function to_json(self) -> string throws never +} + +class Dog { + breed: string +} + +implements ToJson for Dog { + function to_json(self) -> string { + return self.breed + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// implements_for.baml:1:1 (comment) len=65 "// Out-of-body implements: top-level `implements I for T { ... }`" +// implements_for.baml:3:1 (keyword) len=9 "interface" +// implements_for.baml:3:11 (interface) [declaration] len=6 "ToJson" +// implements_for.baml:4:5 (keyword) len=8 "function" +// implements_for.baml:4:14 (method) [declaration] len=7 "to_json" +// implements_for.baml:4:22 (parameter) [declaration] len=4 "self" +// implements_for.baml:4:31 (type) [defaultLibrary] len=6 "string" +// implements_for.baml:4:38 (keyword) len=6 "throws" +// implements_for.baml:4:45 (type) [defaultLibrary] len=5 "never" +// implements_for.baml:7:1 (keyword) len=5 "class" +// implements_for.baml:7:7 (class) [declaration] len=3 "Dog" +// implements_for.baml:8:5 (property) [declaration] len=5 "breed" +// implements_for.baml:8:12 (type) [defaultLibrary] len=6 "string" +// implements_for.baml:11:1 (keyword) len=10 "implements" +// implements_for.baml:11:12 (interface) len=6 "ToJson" +// implements_for.baml:11:19 (keyword) len=3 "for" +// implements_for.baml:11:23 (class) len=3 "Dog" +// implements_for.baml:12:5 (keyword) len=8 "function" +// implements_for.baml:12:14 (method) [declaration] len=7 "to_json" +// implements_for.baml:12:22 (parameter) [declaration] len=4 "self" +// implements_for.baml:12:31 (type) [defaultLibrary] len=6 "string" +// implements_for.baml:13:9 (keyword) len=6 "return" +// implements_for.baml:13:16 (parameter) len=4 "self" +// implements_for.baml:13:21 (property) len=5 "breed" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/index_access.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/index_access.baml new file mode 100644 index 0000000000..eee4d07c26 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/index_access.baml @@ -0,0 +1,121 @@ +class Foo { + name string + age int +} + +let foo = Foo { + name: "John", + age: 2, +}; +let name = foo.name; +let misspelling = foo.names; +let nonsense = foo.name.field; + +let array_access_1 = [1, 2, 3][0]; +let array_access_2 = [1,2, 3]["hi"]; +let array_access_3 = [1,2, 3][foo.age]; +let array_access_4 = [1,2, 3][foo.name]; + +// error: Error validating: Class Foo has no field names +// --> expr/access.baml:11 +// | +// 10 | let name = foo.name; +// 11 | let misspelling = foo.names; +// | +// error: Error validating: Can only access fields on class instances +// --> expr/access.baml:12 +// | +// 11 | let misspelling = foo.names; +// 12 | let nonsense = foo.name.field; +// | +// error: Error validating: Array index must be integer +// --> expr/access.baml:15 +// | +// 14 | let array_access_1 = [1, 2, 3][0]; +// 15 | let array_access_2 = [1,2, 3]["hi"]; +// | +// error: Error validating: Array index must be integer +// --> expr/access.baml:17 +// | +// 16 | let array_access_3 = [1,2, 3][foo.age]; +// 17 | let array_access_4 = [1,2, 3][foo.name]; +// | + +//---- +//- diagnostics +// +// +//- semantic_tokens +// index_access.baml:1:1 (keyword) len=5 "class" +// index_access.baml:1:7 (class) [declaration] len=3 "Foo" +// index_access.baml:2:5 (property) [declaration] len=4 "name" +// index_access.baml:2:10 (type) [defaultLibrary] len=6 "string" +// index_access.baml:3:5 (property) [declaration] len=3 "age" +// index_access.baml:3:9 (type) [defaultLibrary] len=3 "int" +// index_access.baml:6:1 (keyword) len=3 "let" +// index_access.baml:6:5 (variable) [declaration] len=3 "foo" +// index_access.baml:6:9 (operator) len=1 "=" +// index_access.baml:6:11 (class) len=3 "Foo" +// index_access.baml:7:5 (property) len=4 "name" +// index_access.baml:7:11 (string) len=6 "\"John\"" +// index_access.baml:8:5 (property) len=3 "age" +// index_access.baml:8:10 (number) len=1 "2" +// index_access.baml:10:1 (keyword) len=3 "let" +// index_access.baml:10:5 (variable) [declaration] len=4 "name" +// index_access.baml:10:10 (operator) len=1 "=" +// index_access.baml:11:1 (keyword) len=3 "let" +// index_access.baml:11:5 (variable) [declaration] len=11 "misspelling" +// index_access.baml:11:17 (operator) len=1 "=" +// index_access.baml:12:1 (keyword) len=3 "let" +// index_access.baml:12:5 (variable) [declaration] len=8 "nonsense" +// index_access.baml:12:14 (operator) len=1 "=" +// index_access.baml:14:1 (keyword) len=3 "let" +// index_access.baml:14:5 (variable) [declaration] len=14 "array_access_1" +// index_access.baml:14:20 (operator) len=1 "=" +// index_access.baml:14:23 (number) len=1 "1" +// index_access.baml:14:26 (number) len=1 "2" +// index_access.baml:14:29 (number) len=1 "3" +// index_access.baml:14:32 (number) len=1 "0" +// index_access.baml:15:1 (keyword) len=3 "let" +// index_access.baml:15:5 (variable) [declaration] len=14 "array_access_2" +// index_access.baml:15:20 (operator) len=1 "=" +// index_access.baml:15:23 (number) len=1 "1" +// index_access.baml:15:25 (number) len=1 "2" +// index_access.baml:15:28 (number) len=1 "3" +// index_access.baml:15:31 (string) len=4 "\"hi\"" +// index_access.baml:16:1 (keyword) len=3 "let" +// index_access.baml:16:5 (variable) [declaration] len=14 "array_access_3" +// index_access.baml:16:20 (operator) len=1 "=" +// index_access.baml:16:23 (number) len=1 "1" +// index_access.baml:16:25 (number) len=1 "2" +// index_access.baml:16:28 (number) len=1 "3" +// index_access.baml:17:1 (keyword) len=3 "let" +// index_access.baml:17:5 (variable) [declaration] len=14 "array_access_4" +// index_access.baml:17:20 (operator) len=1 "=" +// index_access.baml:17:23 (number) len=1 "1" +// index_access.baml:17:25 (number) len=1 "2" +// index_access.baml:17:28 (number) len=1 "3" +// index_access.baml:19:1 (comment) len=56 "// error: Error validating: Class Foo has no field names" +// index_access.baml:20:1 (comment) len=29 "// --> expr/access.baml:11" +// index_access.baml:21:1 (comment) len=7 "// |" +// index_access.baml:22:1 (comment) len=28 "// 10 | let name = foo.name;" +// index_access.baml:23:1 (comment) len=36 "// 11 | let misspelling = foo.names;" +// index_access.baml:24:1 (comment) len=7 "// |" +// index_access.baml:25:1 (comment) len=69 "// error: Error validating: Can only access fields on class instances" +// index_access.baml:26:1 (comment) len=29 "// --> expr/access.baml:12" +// index_access.baml:27:1 (comment) len=7 "// |" +// index_access.baml:28:1 (comment) len=36 "// 11 | let misspelling = foo.names;" +// index_access.baml:29:1 (comment) len=38 "// 12 | let nonsense = foo.name.field;" +// index_access.baml:30:1 (comment) len=7 "// |" +// index_access.baml:31:1 (comment) len=55 "// error: Error validating: Array index must be integer" +// index_access.baml:32:1 (comment) len=29 "// --> expr/access.baml:15" +// index_access.baml:33:1 (comment) len=7 "// |" +// index_access.baml:34:1 (comment) len=42 "// 14 | let array_access_1 = [1, 2, 3][0];" +// index_access.baml:35:1 (comment) len=44 "// 15 | let array_access_2 = [1,2, 3][\"hi\"];" +// index_access.baml:36:1 (comment) len=7 "// |" +// index_access.baml:37:1 (comment) len=55 "// error: Error validating: Array index must be integer" +// index_access.baml:38:1 (comment) len=29 "// --> expr/access.baml:17" +// index_access.baml:39:1 (comment) len=7 "// |" +// index_access.baml:40:1 (comment) len=47 "// 16 | let array_access_3 = [1,2, 3][foo.age];" +// index_access.baml:41:1 (comment) len=48 "// 17 | let array_access_4 = [1,2, 3][foo.name];" +// index_access.baml:42:1 (comment) len=7 "// |" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interface_impl.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interface_impl.baml new file mode 100644 index 0000000000..6d38c34157 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interface_impl.baml @@ -0,0 +1,45 @@ +// Out-of-body implements: top-level `implements I for T { ... }` + +interface ToJson { + function to_json(self) -> string throws never +} + +class Dog { + breed: string +} + +implements ToJson for Dog { + function to_json(self) -> string { + return self.breed + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// interface_impl.baml:1:1 (comment) len=65 "// Out-of-body implements: top-level `implements I for T { ... }`" +// interface_impl.baml:3:1 (keyword) len=9 "interface" +// interface_impl.baml:3:11 (interface) [declaration] len=6 "ToJson" +// interface_impl.baml:4:5 (keyword) len=8 "function" +// interface_impl.baml:4:14 (method) [declaration] len=7 "to_json" +// interface_impl.baml:4:22 (parameter) [declaration] len=4 "self" +// interface_impl.baml:4:31 (type) [defaultLibrary] len=6 "string" +// interface_impl.baml:4:38 (keyword) len=6 "throws" +// interface_impl.baml:4:45 (type) [defaultLibrary] len=5 "never" +// interface_impl.baml:7:1 (keyword) len=5 "class" +// interface_impl.baml:7:7 (class) [declaration] len=3 "Dog" +// interface_impl.baml:8:5 (property) [declaration] len=5 "breed" +// interface_impl.baml:8:12 (type) [defaultLibrary] len=6 "string" +// interface_impl.baml:11:1 (keyword) len=10 "implements" +// interface_impl.baml:11:12 (interface) len=6 "ToJson" +// interface_impl.baml:11:19 (keyword) len=3 "for" +// interface_impl.baml:11:23 (class) len=3 "Dog" +// interface_impl.baml:12:5 (keyword) len=8 "function" +// interface_impl.baml:12:14 (method) [declaration] len=7 "to_json" +// interface_impl.baml:12:22 (parameter) [declaration] len=4 "self" +// interface_impl.baml:12:31 (type) [defaultLibrary] len=6 "string" +// interface_impl.baml:13:9 (keyword) len=6 "return" +// interface_impl.baml:13:16 (parameter) len=4 "self" +// interface_impl.baml:13:21 (property) len=5 "breed" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_inferred_generic_type_args.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_inferred_generic_type_args.baml new file mode 100644 index 0000000000..a215bcbb8c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_inferred_generic_type_args.baml @@ -0,0 +1,1672 @@ +// End-to-end tests for the generic-type-arg dispatch fix. +// +// A generic class whose `` is *inferred* (rather than written explicitly) +// must carry the correct runtime `class_type_args`, and a method dispatched +// through a multi-implementor interface must receive the resolved +// class/interface type args in its frame. Without this, a method body that +// reads its enclosing `T` at runtime — `reflect.type_of()`, or constructing +// `Other{}` — resolves `T` to `unknown`; the new instance gets empty +// `class_type_args`; and the runtime `IsType` dispatch guard falls through to +// the WRONG implementor (a silent wrong answer, or a field-access panic when +// the sibling has a different field layout). +// +// Fixed in `baml_compiler2_mir::lower`: the interface-dispatch switch now seeds +// the callee frame's `type_args` per candidate — a class-owned method gets the +// implementor's class args (statically when the guard pins them, otherwise from +// the matched runtime instance via a `BoundMethod`, which covers `Any`/partial +// guards); an inherited default gets the interface's args. `default.()` +// forwarding seeds the same way, and `enclosing_generic_params` includes +// interface params for default methods. +// +// NOTE: test bodies live in top-level helper functions — locals holding class +// instances misbehave when compared/passed inside `test { ... }` blocks (the +// same VM local-boxing caveat documented in `ns_class_type_args_at_runtime`). + +// ═══════════════════════════════════════════════════════════════════════════ +// Showcase: a lazy cursor protocol — the exact shape `baml.iter` needs. +// +// `Cursor` is a generic interface with a default `take_one(self)` that builds +// a *new* generic adapter (`SingleCursor`) from the interface's element type +// `T`. The two leaf implementors have different field layouts, so a mis-dispatch +// doesn't merely return a wrong value — it reads the wrong field and panics. +// +// The whole pipeline runs through the `Cursor` interface, and the `` +// is never written after the first annotation: `ArrayCursor.of([...])` infers +// it, and the default method must propagate it into the `SingleCursor` it +// constructs. Correctness depends entirely on the inferred `` reaching +// each dispatched frame. +// ═══════════════════════════════════════════════════════════════════════════ + +interface Cursor { + function head(self) -> T throws unknown + + // Default method, inherited by every implementor. It constructs a generic + // `SingleCursor` from the interface's own `T`. The resulting instance MUST + // carry `class_type_args = [T]`; otherwise the `single.head()` dispatch in + // `take_one_then_head` resolves to `ArrayCursor.head` — which indexes an + // `arr` field that `SingleCursor` does not have — instead of + // `SingleCursor.head`. + function take_one(self) -> Cursor throws unknown { + return SingleCursor { value: self.head() } + } +} + +class ArrayCursor { + arr: T[], + idx: int, + + // Static constructor: `T` is INFERRED from the argument, never written. + function of(items: T[]) -> ArrayCursor { + return ArrayCursor { arr: items, idx: 0 }; + } + + implements Cursor { + function head(self) -> T throws unknown { + return self.arr[0]; + } + } +} + +class SingleCursor { + value: T, + + implements Cursor { + function head(self) -> T throws unknown { + return self.value; + } + } +} + +// Build an `ArrayCursor` with an inferred ``, narrow it to a single +// element via the inherited default method, then read the head back — entirely +// through the `Cursor` interface. Exercises inferred static-ctor type args +// AND a default method that builds a generic from the interface's `T`. +function take_one_then_head() -> int throws unknown { + let cursor: Cursor = ArrayCursor.of([10, 20, 30]); + let single: Cursor = cursor.take_one(); + single.head() +} + +test "showcase_lazy_cursor_pipeline" { + assert.equal(take_one_then_head(), 10) +} + +// ═══════════════════════════════════════════════════════════════════════════ +// Focused regression cases +// ═══════════════════════════════════════════════════════════════════════════ + +// ─── Inferred static constructor + non-generic interface, two implementors ─── + +interface Animal { + function speak(self) -> string throws never +} + +class Dog { + value: T, + + function make(v: T) -> Dog { + return Dog { value: v }; + } + + implements Animal { + function speak(self) -> string { + return "woof"; + } + } +} + +class Cat { + meow_count: int, + + implements Animal { + function speak(self) -> string { + return "meow"; + } + } +} + +// `Dog.make(42)` infers `Dog`; dispatched through `Animal` (which `Cat` +// also implements) it must still pick `Dog`'s method. +function inferred_static_ctor_speak() -> string { + let d: Animal = Dog.make(42); + d.speak() +} + +test "inferred_static_ctor_dispatches_to_correct_implementor" { + assert.equal(inferred_static_ctor_speak(), "woof") +} + +// ─── Inferred static constructor + generic interface, mismatched shapes ─── + +interface Bag { + function first(self) -> T throws unknown +} + +class ArrBag { + arr: T[], + idx: int, + + function make(a: T[]) -> ArrBag { + return ArrBag { arr: a, idx: 0 }; + } + + implements Bag { + function first(self) -> T throws unknown { + return self.arr[0]; + } + } +} + +class OneBag { + only: T, + + implements Bag { + function first(self) -> T throws unknown { + return self.only; + } + } +} + +// A mis-dispatch would read `only` off an `ArrBag` (or index `arr` on a +// `OneBag`) — different layouts, so the wrong arm panics rather than silently +// returning a bad value. +function inferred_static_ctor_first() -> int throws unknown { + let s: Bag = ArrBag.make([5, 6, 7]); + s.first() +} + +test "inferred_static_ctor_dispatches_through_generic_interface" { + assert.equal(inferred_static_ctor_first(), 5) +} + +// ─── Interface default method can read the interface's type var at runtime ─── + +interface Named { + function first(self) -> T throws unknown + function tname(self) -> string throws never { + return reflect.type_of().to_string() + } +} + +class ArrNamed { + arr: T[], + idx: int, + implements Named { + function first(self) -> T throws unknown { + return self.arr[0]; + } + } +} + +class OneNamed { + only: T, + implements Named { + function first(self) -> T throws unknown { + return self.only; + } + } +} + +// `tname` is a default method dispatched through `Named`; it must see +// `T == int`, not `unknown`/`void`. +function default_method_typevar_name() -> string throws unknown { + let s: Named = ArrNamed { arr: [5, 6, 7], idx: 0 }; + s.tname() +} + +test "interface_default_method_sees_interface_type_var" { + assert.equal(default_method_typevar_name(), "int") +} + +// ─── Class-owned (non-default) method that builds a generic from class `T` ─── + +interface Wrap { + function first(self) -> T throws unknown +} + +class SrcWrap { + arr: T[], + idx: int, + + // A regular class method (not an interface default) that constructs a + // generic `Boxed` from the class-level `T`. + function boxed(self) -> Wrap throws unknown { + return Boxed { val: self.arr[0] }; + } + + implements Wrap { + function first(self) -> T throws unknown { + return self.arr[0]; + } + } +} + +class Boxed { + val: T, + implements Wrap { + function first(self) -> T throws unknown { + return self.val; + } + } +} + +function class_method_builds_generic() -> int throws unknown { + let s: SrcWrap = SrcWrap { arr: [5, 6, 7], idx: 0 }; + let w: Wrap = s.boxed(); + w.first() +} + +test "class_method_builds_generic_via_class_type_var" { + assert.equal(class_method_builds_generic(), 5) +} + +// ─── `default.()` forwards into a generic interface default ─── +// +// Calling the interface's default implementation explicitly (the `super`-like +// `default.()` form) from inside an override must seed the default +// body's frame with the interface's type args, so a generic default that reads +// `T` at runtime resolves it instead of seeing `unknown`. + +interface Counter { + function element_type(self) -> string throws never { + return reflect.type_of().to_string() + } + function describe(self) -> string throws never +} + +class IntCounter { + value: T, + implements Counter { + // Override `describe` but delegate to the generic default `element_type`. + function describe(self) -> string { + return default.element_type(); + } + } +} + +class StrCounter { + label: T, + implements Counter { + function describe(self) -> string { + return "str"; + } + } +} + +function default_forward_reads_type_var() -> string { + let c: Counter = IntCounter { value: 7 }; + c.describe() +} + +test "default_method_forward_reads_interface_type_var" { + assert.equal(default_forward_reads_type_var(), "int") +} + +// ─── Generic class behind a NON-generic interface reads its class `T` ─── +// +// The interface request pins no type args (it has none), so the dispatch guard +// is `Any` and can't name the implementor's class args statically. The matched +// runtime instance still carries them, so the dispatched class-owned method +// must resolve its class `T` (here via `reflect.type_of()`). + +interface Describable { + function describe(self) -> string throws never +} + +class TypedBox { + value: T, + implements Describable { + function describe(self) -> string { + return reflect.type_of().to_string(); + } + } +} + +class PlainThing { + n: int, + implements Describable { + function describe(self) -> string { + return "plain"; + } + } +} + +function generic_behind_nongeneric_iface() -> string { + let d: Describable = TypedBox { value: 42 }; + d.describe() +} + +test "generic_class_behind_nongeneric_interface_reads_type_var" { + assert.equal(generic_behind_nongeneric_iface(), "int") +} + +// ═══════════════════════════════════════════════════════════════════════════ +// Inferred call-site type args reach the callee frame at runtime. +// +// The cases above dispatch correctly, but dispatch alone can pass "by luck" +// of arm order even when the instantiation is lost (the unguarded last arm of +// the candidate switch happens to be the right implementor). The cases below +// pin the instantiation itself, so they cannot pass by dispatch luck: +// • a free generic function must see its inferred `T` via reflect; +// • an instance built by an inferred static ctor must carry +// `class_type_args = [int]` — observable through a user-level +// `match`/IsType test, which consults the args directly. +// Both were broken before TIR began persisting inferred call bindings in +// `CallPlan.type_args` for MIR to seed the callee frame. +// ═══════════════════════════════════════════════════════════════════════════ + +function free_fn_tname(a: T[]) -> string { + return reflect.type_of().to_string(); +} + +function free_fn_inferred_t() -> string { + return free_fn_tname([1, 2, 3]); +} + +test "free_function_sees_inferred_type_arg" { + assert.equal(free_fn_inferred_t(), "int") +} + +// The inferred-ctor instance must pass a runtime `IsType ArrBag` test — +// NOT fall through to the wildcard arm. +function inferred_ctor_instance_is_typed() -> int throws unknown { + let s: Bag = ArrBag.make([5, 6, 7]); + match (s) { + let a: ArrBag => 1, + let o: OneBag => 2, + _ => 9, + } +} + +test "inferred_static_ctor_instance_carries_class_type_args" { + assert.equal(inferred_ctor_instance_is_typed(), 1) +} + +// Lazy-iterator shape end-to-end: inferred static ctor, consumption through +// an inherited default method that drives `self.next()` in a loop, with a +// second implementor present. Returns the COLLECTED COUNT, so a mis-dispatch +// (e.g. `next` resolving to `Lone.next` against an `ArrIter` receiver) +// yields 0 or 1 instead of 3. +interface NextIter { + function next2(self) -> T | IterDone throws E + + function collect2(self) -> T[] throws E { + let out: T[] = []; + while (true) { + match (self.next2()) { + IterDone => { break; }, + let x: T => { out.push(x); } + } + } + out + } +} + +class IterDone { +} + +class ArrIter { + arr: T[], + idx: int, + + function of(a: T[]) -> ArrIter throws never { + return ArrIter { arr: a, idx: 0 }; + } + + implements NextIter { + function next2(self) -> T | IterDone throws never { + match (self.arr.at(self.idx)) { + null => IterDone { }, + let x: T => { + self.idx += 1; + x + }, + } + } + } +} + +class LoneIter { + v: T, + used: bool, + + implements NextIter { + function next2(self) -> T | IterDone throws never { + if (self.used) { + IterDone { } + } else { + self.used = true; + self.v + } + } + } +} + +function inferred_ctor_collect_count() -> int throws unknown { + let it: NextIter = ArrIter.of([1, 2, 3]); + it.collect2().length() +} + +test "inferred_ctor_default_method_collects_all" { + assert.equal(inferred_ctor_collect_count(), 3) +} + +// ─── Inferred binding nesting a rigid `Self` must NOT seed `void` ─── +// +// Inside an interface default method, `self` has the rigid pinned type `Self`, +// which is never among the caller frame's generic params. An inferred generic +// call whose binding NESTS it (here `T := Self[]` via `echo_type([self])`) +// cannot be resolved to a frame index — the seeding must demote that binding +// to `unknown` (the unseeded status quo), not lower `Self` to `void`. + +function echo_type(a: T) -> string { + return reflect.type_of().to_string(); +} + +interface SelfEcho { + function tag(self) -> string throws never + function nested_self_type(self) -> string throws never { + return echo_type([self]) + } +} + +class EchoA { + n: int, + implements SelfEcho { + function tag(self) -> string { + return "a"; + } + } +} + +class EchoB { + s: string, + implements SelfEcho { + function tag(self) -> string { + return "b"; + } + } +} + +function nested_self_inferred_binding() -> string throws unknown { + let e: SelfEcho = EchoA { n: 1 }; + e.nested_self_type() +} + +// `unknown` (the whole binding demoted) is the pre-existing status quo for an +// unresolvable binding — the regression this guards against is `void[]`, which +// a naive lowering of the nested rigid `Self` produces. +test "nested_self_inferred_binding_not_voided" { + assert.equal(nested_self_inferred_binding(), "unknown") +} + +// Interface dispatch must also carry inferred method-level type args. The +// dispatch arm itself seeds the receiver/interface frame; `CallPlan.type_args` +// supplies the method's inferred `U`. +interface TypeProbe { + function seen(self, value: U) -> string throws never +} + +class ProbeA { + implements TypeProbe { + function seen(self, value: U) -> string { + return reflect.type_of().to_string(); + } + } +} + +class ProbeB { + implements TypeProbe { + function seen(self, value: U) -> string { + return "wrong"; + } + } +} + +function interface_dispatch_inferred_method_type_arg() -> string { + let p: TypeProbe = ProbeA { }; + let x: int = 1; + p.seen(x) +} + +test "interface_dispatch_sees_inferred_method_type_arg" { + assert.equal(interface_dispatch_inferred_method_type_arg(), "int") +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// interfaces_inferred_generic_type_args.baml:1:1 (comment) len=58 "// End-to-end tests for the generic-type-arg dispatch fix." +// interfaces_inferred_generic_type_args.baml:2:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:3:1 (comment) len=77 "// A generic class whose `` is *inferred* (rather than written explicitly)" +// interfaces_inferred_generic_type_args.baml:4:1 (comment) len=76 "// must carry the correct runtime `class_type_args`, and a method dispatched" +// interfaces_inferred_generic_type_args.baml:5:1 (comment) len=66 "// through a multi-implementor interface must receive the resolved" +// interfaces_inferred_generic_type_args.baml:6:1 (comment) len=75 "// class/interface type args in its frame. Without this, a method body that" +// interfaces_inferred_generic_type_args.baml:7:1 (comment) len=81 "// reads its enclosing `T` at runtime — `reflect.type_of()`, or constructing" +// interfaces_inferred_generic_type_args.baml:8:1 (comment) len=74 "// `Other{}` — resolves `T` to `unknown`; the new instance gets empty" +// interfaces_inferred_generic_type_args.baml:9:1 (comment) len=78 "// `class_type_args`; and the runtime `IsType` dispatch guard falls through to" +// interfaces_inferred_generic_type_args.baml:10:1 (comment) len=77 "// the WRONG implementor (a silent wrong answer, or a field-access panic when" +// interfaces_inferred_generic_type_args.baml:11:1 (comment) len=45 "// the sibling has a different field layout)." +// interfaces_inferred_generic_type_args.baml:12:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:13:1 (comment) len=80 "// Fixed in `baml_compiler2_mir::lower`: the interface-dispatch switch now seeds" +// interfaces_inferred_generic_type_args.baml:14:1 (comment) len=81 "// the callee frame's `type_args` per candidate — a class-owned method gets the" +// interfaces_inferred_generic_type_args.baml:15:1 (comment) len=80 "// implementor's class args (statically when the guard pins them, otherwise from" +// interfaces_inferred_generic_type_args.baml:16:1 (comment) len=79 "// the matched runtime instance via a `BoundMethod`, which covers `Any`/partial" +// interfaces_inferred_generic_type_args.baml:17:1 (comment) len=80 "// guards); an inherited default gets the interface's args. `default.()`" +// interfaces_inferred_generic_type_args.baml:18:1 (comment) len=73 "// forwarding seeds the same way, and `enclosing_generic_params` includes" +// interfaces_inferred_generic_type_args.baml:19:1 (comment) len=40 "// interface params for default methods." +// interfaces_inferred_generic_type_args.baml:20:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:21:1 (comment) len=80 "// NOTE: test bodies live in top-level helper functions — locals holding class" +// interfaces_inferred_generic_type_args.baml:22:1 (comment) len=77 "// instances misbehave when compared/passed inside `test { ... }` blocks (the" +// interfaces_inferred_generic_type_args.baml:23:1 (comment) len=78 "// same VM local-boxing caveat documented in `ns_class_type_args_at_runtime`)." +// interfaces_inferred_generic_type_args.baml:25:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:26:1 (comment) len=74 "// Showcase: a lazy cursor protocol — the exact shape `baml.iter` needs." +// interfaces_inferred_generic_type_args.baml:27:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:28:1 (comment) len=81 "// `Cursor` is a generic interface with a default `take_one(self)` that builds" +// interfaces_inferred_generic_type_args.baml:29:1 (comment) len=80 "// a *new* generic adapter (`SingleCursor`) from the interface's element type" +// interfaces_inferred_generic_type_args.baml:30:1 (comment) len=81 "// `T`. The two leaf implementors have different field layouts, so a mis-dispatch" +// interfaces_inferred_generic_type_args.baml:31:1 (comment) len=79 "// doesn't merely return a wrong value — it reads the wrong field and panics." +// interfaces_inferred_generic_type_args.baml:32:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:33:1 (comment) len=79 "// The whole pipeline runs through the `Cursor` interface, and the ``" +// interfaces_inferred_generic_type_args.baml:34:1 (comment) len=78 "// is never written after the first annotation: `ArrayCursor.of([...])` infers" +// interfaces_inferred_generic_type_args.baml:35:1 (comment) len=79 "// it, and the default method must propagate it into the `SingleCursor` it" +// interfaces_inferred_generic_type_args.baml:36:1 (comment) len=76 "// constructs. Correctness depends entirely on the inferred `` reaching" +// interfaces_inferred_generic_type_args.baml:37:1 (comment) len=25 "// each dispatched frame." +// interfaces_inferred_generic_type_args.baml:38:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:40:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:40:11 (interface) [declaration] len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:40:17 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:40:18 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:40:19 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:41:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:41:12 (method) [declaration] len=4 "head" +// interfaces_inferred_generic_type_args.baml:41:17 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:41:26 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:41:28 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:41:35 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:43:3 (comment) len=74 "// Default method, inherited by every implementor. It constructs a generic" +// interfaces_inferred_generic_type_args.baml:44:3 (comment) len=78 "// `SingleCursor` from the interface's own `T`. The resulting instance MUST" +// interfaces_inferred_generic_type_args.baml:45:3 (comment) len=75 "// carry `class_type_args = [T]`; otherwise the `single.head()` dispatch in" +// interfaces_inferred_generic_type_args.baml:46:3 (comment) len=75 "// `take_one_then_head` resolves to `ArrayCursor.head` — which indexes an" +// interfaces_inferred_generic_type_args.baml:47:3 (comment) len=63 "// `arr` field that `SingleCursor` does not have — instead of" +// interfaces_inferred_generic_type_args.baml:48:3 (comment) len=23 "// `SingleCursor.head`." +// interfaces_inferred_generic_type_args.baml:49:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:49:12 (method) [declaration] len=8 "take_one" +// interfaces_inferred_generic_type_args.baml:49:21 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:49:30 (interface) len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:49:36 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:49:37 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:49:38 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:49:40 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:49:47 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:50:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:50:12 (class) len=12 "SingleCursor" +// interfaces_inferred_generic_type_args.baml:50:24 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:50:25 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:50:26 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:50:30 (property) len=5 "value" +// interfaces_inferred_generic_type_args.baml:50:37 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:50:42 (method) len=4 "head" +// interfaces_inferred_generic_type_args.baml:54:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:54:7 (class) [declaration] len=11 "ArrayCursor" +// interfaces_inferred_generic_type_args.baml:54:18 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:54:19 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:54:20 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:55:5 (property) [declaration] len=3 "arr" +// interfaces_inferred_generic_type_args.baml:55:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:56:5 (property) [declaration] len=3 "idx" +// interfaces_inferred_generic_type_args.baml:56:10 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:58:5 (comment) len=72 "// Static constructor: `T` is INFERRED from the argument, never written." +// interfaces_inferred_generic_type_args.baml:59:5 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:59:14 (method) [declaration] len=2 "of" +// interfaces_inferred_generic_type_args.baml:59:17 (parameter) [declaration] len=5 "items" +// interfaces_inferred_generic_type_args.baml:59:24 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:59:32 (class) len=11 "ArrayCursor" +// interfaces_inferred_generic_type_args.baml:59:43 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:59:44 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:59:45 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:60:9 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:60:16 (class) len=11 "ArrayCursor" +// interfaces_inferred_generic_type_args.baml:60:27 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:60:28 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:60:29 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:60:33 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:60:38 (parameter) len=5 "items" +// interfaces_inferred_generic_type_args.baml:60:45 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:60:50 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:63:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:63:16 (interface) len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:63:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:63:23 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:63:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:64:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:64:18 (method) [declaration] len=4 "head" +// interfaces_inferred_generic_type_args.baml:64:23 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:64:32 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:64:34 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:64:41 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:65:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:65:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:65:25 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:65:29 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:70:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:70:7 (class) [declaration] len=12 "SingleCursor" +// interfaces_inferred_generic_type_args.baml:70:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:70:20 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:70:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:71:5 (property) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:71:12 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:73:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:73:16 (interface) len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:73:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:73:23 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:73:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:74:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:74:18 (method) [declaration] len=4 "head" +// interfaces_inferred_generic_type_args.baml:74:23 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:74:32 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:74:34 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:74:41 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:75:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:75:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:75:25 (property) len=5 "value" +// interfaces_inferred_generic_type_args.baml:80:1 (comment) len=78 "// Build an `ArrayCursor` with an inferred ``, narrow it to a single" +// interfaces_inferred_generic_type_args.baml:81:1 (comment) len=81 "// element via the inherited default method, then read the head back — entirely" +// interfaces_inferred_generic_type_args.baml:82:1 (comment) len=80 "// through the `Cursor` interface. Exercises inferred static-ctor type args" +// interfaces_inferred_generic_type_args.baml:83:1 (comment) len=71 "// AND a default method that builds a generic from the interface's `T`." +// interfaces_inferred_generic_type_args.baml:84:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:84:10 (function) [declaration] len=18 "take_one_then_head" +// interfaces_inferred_generic_type_args.baml:84:34 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:84:38 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:84:45 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:85:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:85:9 (variable) [declaration] len=6 "cursor" +// interfaces_inferred_generic_type_args.baml:85:17 (interface) len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:85:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:85:24 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:85:27 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:85:29 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:85:31 (class) len=11 "ArrayCursor" +// interfaces_inferred_generic_type_args.baml:85:43 (method) len=2 "of" +// interfaces_inferred_generic_type_args.baml:85:47 (number) len=2 "10" +// interfaces_inferred_generic_type_args.baml:85:51 (number) len=2 "20" +// interfaces_inferred_generic_type_args.baml:85:55 (number) len=2 "30" +// interfaces_inferred_generic_type_args.baml:86:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:86:9 (variable) [declaration] len=6 "single" +// interfaces_inferred_generic_type_args.baml:86:17 (interface) len=6 "Cursor" +// interfaces_inferred_generic_type_args.baml:86:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:86:24 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:86:27 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:86:29 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:86:31 (variable) len=6 "cursor" +// interfaces_inferred_generic_type_args.baml:86:38 (method) len=8 "take_one" +// interfaces_inferred_generic_type_args.baml:87:5 (variable) len=6 "single" +// interfaces_inferred_generic_type_args.baml:87:12 (method) len=4 "head" +// interfaces_inferred_generic_type_args.baml:90:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:90:6 (string) len=31 "\"showcase_lazy_cursor_pipeline\"" +// interfaces_inferred_generic_type_args.baml:91:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:91:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:91:18 (function) len=18 "take_one_then_head" +// interfaces_inferred_generic_type_args.baml:91:40 (number) len=2 "10" +// interfaces_inferred_generic_type_args.baml:94:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:95:1 (comment) len=27 "// Focused regression cases" +// interfaces_inferred_generic_type_args.baml:96:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:98:1 (comment) len=92 "// ─── Inferred static constructor + non-generic interface, two implementors ───" +// interfaces_inferred_generic_type_args.baml:100:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:100:11 (interface) [declaration] len=6 "Animal" +// interfaces_inferred_generic_type_args.baml:101:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:101:12 (method) [declaration] len=5 "speak" +// interfaces_inferred_generic_type_args.baml:101:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:101:27 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:101:34 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:101:41 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:104:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:104:7 (class) [declaration] len=3 "Dog" +// interfaces_inferred_generic_type_args.baml:104:10 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:104:11 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:104:12 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:105:5 (property) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:105:12 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:107:5 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:107:14 (method) [declaration] len=4 "make" +// interfaces_inferred_generic_type_args.baml:107:19 (parameter) [declaration] len=1 "v" +// interfaces_inferred_generic_type_args.baml:107:22 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:107:28 (class) len=3 "Dog" +// interfaces_inferred_generic_type_args.baml:107:31 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:107:32 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:107:33 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:108:9 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:108:16 (class) len=3 "Dog" +// interfaces_inferred_generic_type_args.baml:108:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:108:20 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:108:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:108:25 (property) len=5 "value" +// interfaces_inferred_generic_type_args.baml:108:32 (parameter) len=1 "v" +// interfaces_inferred_generic_type_args.baml:111:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:111:16 (interface) len=6 "Animal" +// interfaces_inferred_generic_type_args.baml:112:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:112:18 (method) [declaration] len=5 "speak" +// interfaces_inferred_generic_type_args.baml:112:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:112:33 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:113:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:113:20 (string) len=6 "\"woof\"" +// interfaces_inferred_generic_type_args.baml:118:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:118:7 (class) [declaration] len=3 "Cat" +// interfaces_inferred_generic_type_args.baml:119:5 (property) [declaration] len=10 "meow_count" +// interfaces_inferred_generic_type_args.baml:119:17 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:121:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:121:16 (interface) len=6 "Animal" +// interfaces_inferred_generic_type_args.baml:122:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:122:18 (method) [declaration] len=5 "speak" +// interfaces_inferred_generic_type_args.baml:122:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:122:33 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:123:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:123:20 (string) len=6 "\"meow\"" +// interfaces_inferred_generic_type_args.baml:128:1 (comment) len=77 "// `Dog.make(42)` infers `Dog`; dispatched through `Animal` (which `Cat`" +// interfaces_inferred_generic_type_args.baml:129:1 (comment) len=54 "// also implements) it must still pick `Dog`'s method." +// interfaces_inferred_generic_type_args.baml:130:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:130:10 (function) [declaration] len=26 "inferred_static_ctor_speak" +// interfaces_inferred_generic_type_args.baml:130:42 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:131:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:131:9 (variable) [declaration] len=1 "d" +// interfaces_inferred_generic_type_args.baml:131:12 (interface) len=6 "Animal" +// interfaces_inferred_generic_type_args.baml:131:19 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:131:21 (class) len=3 "Dog" +// interfaces_inferred_generic_type_args.baml:131:25 (method) len=4 "make" +// interfaces_inferred_generic_type_args.baml:131:30 (number) len=2 "42" +// interfaces_inferred_generic_type_args.baml:132:5 (variable) len=1 "d" +// interfaces_inferred_generic_type_args.baml:132:7 (method) len=5 "speak" +// interfaces_inferred_generic_type_args.baml:135:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:135:6 (string) len=56 "\"inferred_static_ctor_dispatches_to_correct_implementor\"" +// interfaces_inferred_generic_type_args.baml:136:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:136:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:136:18 (function) len=26 "inferred_static_ctor_speak" +// interfaces_inferred_generic_type_args.baml:136:48 (string) len=6 "\"woof\"" +// interfaces_inferred_generic_type_args.baml:139:1 (comment) len=89 "// ─── Inferred static constructor + generic interface, mismatched shapes ───" +// interfaces_inferred_generic_type_args.baml:141:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:141:11 (interface) [declaration] len=3 "Bag" +// interfaces_inferred_generic_type_args.baml:141:14 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:141:15 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:141:16 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:142:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:142:12 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:142:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:142:27 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:142:29 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:142:36 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:145:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:145:7 (class) [declaration] len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:145:13 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:145:14 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:145:15 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:146:5 (property) [declaration] len=3 "arr" +// interfaces_inferred_generic_type_args.baml:146:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:147:5 (property) [declaration] len=3 "idx" +// interfaces_inferred_generic_type_args.baml:147:10 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:149:5 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:149:14 (method) [declaration] len=4 "make" +// interfaces_inferred_generic_type_args.baml:149:19 (parameter) [declaration] len=1 "a" +// interfaces_inferred_generic_type_args.baml:149:22 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:149:30 (class) len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:149:36 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:149:37 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:149:38 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:150:9 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:150:16 (class) len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:150:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:150:23 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:150:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:150:28 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:150:33 (parameter) len=1 "a" +// interfaces_inferred_generic_type_args.baml:150:36 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:150:41 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:153:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:153:16 (interface) len=3 "Bag" +// interfaces_inferred_generic_type_args.baml:153:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:153:20 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:153:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:154:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:154:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:154:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:154:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:154:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:154:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:155:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:155:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:155:25 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:155:29 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:160:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:160:7 (class) [declaration] len=6 "OneBag" +// interfaces_inferred_generic_type_args.baml:160:13 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:160:14 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:160:15 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:161:5 (property) [declaration] len=4 "only" +// interfaces_inferred_generic_type_args.baml:161:11 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:163:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:163:16 (interface) len=3 "Bag" +// interfaces_inferred_generic_type_args.baml:163:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:163:20 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:163:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:164:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:164:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:164:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:164:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:164:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:164:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:165:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:165:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:165:25 (property) len=4 "only" +// interfaces_inferred_generic_type_args.baml:170:1 (comment) len=72 "// A mis-dispatch would read `only` off an `ArrBag` (or index `arr` on a" +// interfaces_inferred_generic_type_args.baml:171:1 (comment) len=80 "// `OneBag`) — different layouts, so the wrong arm panics rather than silently" +// interfaces_inferred_generic_type_args.baml:172:1 (comment) len=25 "// returning a bad value." +// interfaces_inferred_generic_type_args.baml:173:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:173:10 (function) [declaration] len=26 "inferred_static_ctor_first" +// interfaces_inferred_generic_type_args.baml:173:42 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:173:46 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:173:53 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:174:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:174:9 (variable) [declaration] len=1 "s" +// interfaces_inferred_generic_type_args.baml:174:12 (interface) len=3 "Bag" +// interfaces_inferred_generic_type_args.baml:174:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:174:16 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:174:19 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:174:21 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:174:23 (class) len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:174:30 (method) len=4 "make" +// interfaces_inferred_generic_type_args.baml:174:36 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:174:39 (number) len=1 "6" +// interfaces_inferred_generic_type_args.baml:174:42 (number) len=1 "7" +// interfaces_inferred_generic_type_args.baml:175:5 (variable) len=1 "s" +// interfaces_inferred_generic_type_args.baml:175:7 (method) len=5 "first" +// interfaces_inferred_generic_type_args.baml:178:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:178:6 (string) len=59 "\"inferred_static_ctor_dispatches_through_generic_interface\"" +// interfaces_inferred_generic_type_args.baml:179:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:179:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:179:18 (function) len=26 "inferred_static_ctor_first" +// interfaces_inferred_generic_type_args.baml:179:48 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:182:1 (comment) len=92 "// ─── Interface default method can read the interface's type var at runtime ───" +// interfaces_inferred_generic_type_args.baml:184:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:184:11 (interface) [declaration] len=5 "Named" +// interfaces_inferred_generic_type_args.baml:184:16 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:184:17 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:184:18 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:185:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:185:12 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:185:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:185:27 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:185:29 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:185:36 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:186:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:186:12 (method) [declaration] len=5 "tname" +// interfaces_inferred_generic_type_args.baml:186:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:186:27 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:186:34 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:186:41 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:187:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:187:12 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:187:20 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:187:27 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:187:28 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:187:29 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:187:33 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:191:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:191:7 (class) [declaration] len=8 "ArrNamed" +// interfaces_inferred_generic_type_args.baml:191:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:191:16 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:191:17 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:192:5 (property) [declaration] len=3 "arr" +// interfaces_inferred_generic_type_args.baml:192:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:193:5 (property) [declaration] len=3 "idx" +// interfaces_inferred_generic_type_args.baml:193:10 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:194:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:194:16 (interface) len=5 "Named" +// interfaces_inferred_generic_type_args.baml:194:21 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:194:22 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:194:23 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:195:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:195:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:195:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:195:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:195:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:195:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:196:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:196:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:196:25 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:196:29 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:201:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:201:7 (class) [declaration] len=8 "OneNamed" +// interfaces_inferred_generic_type_args.baml:201:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:201:16 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:201:17 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:202:5 (property) [declaration] len=4 "only" +// interfaces_inferred_generic_type_args.baml:202:11 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:203:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:203:16 (interface) len=5 "Named" +// interfaces_inferred_generic_type_args.baml:203:21 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:203:22 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:203:23 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:204:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:204:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:204:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:204:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:204:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:204:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:205:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:205:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:205:25 (property) len=4 "only" +// interfaces_inferred_generic_type_args.baml:210:1 (comment) len=75 "// `tname` is a default method dispatched through `Named`; it must see" +// interfaces_inferred_generic_type_args.baml:211:1 (comment) len=36 "// `T == int`, not `unknown`/`void`." +// interfaces_inferred_generic_type_args.baml:212:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:212:10 (function) [declaration] len=27 "default_method_typevar_name" +// interfaces_inferred_generic_type_args.baml:212:43 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:212:50 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:212:57 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:213:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:213:9 (variable) [declaration] len=1 "s" +// interfaces_inferred_generic_type_args.baml:213:12 (interface) len=5 "Named" +// interfaces_inferred_generic_type_args.baml:213:17 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:213:18 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:213:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:213:23 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:213:25 (class) len=8 "ArrNamed" +// interfaces_inferred_generic_type_args.baml:213:33 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:213:34 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:213:37 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:213:41 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:213:47 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:213:50 (number) len=1 "6" +// interfaces_inferred_generic_type_args.baml:213:53 (number) len=1 "7" +// interfaces_inferred_generic_type_args.baml:213:57 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:213:62 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:214:5 (variable) len=1 "s" +// interfaces_inferred_generic_type_args.baml:214:7 (method) len=5 "tname" +// interfaces_inferred_generic_type_args.baml:217:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:217:6 (string) len=50 "\"interface_default_method_sees_interface_type_var\"" +// interfaces_inferred_generic_type_args.baml:218:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:218:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:218:18 (function) len=27 "default_method_typevar_name" +// interfaces_inferred_generic_type_args.baml:218:49 (string) len=5 "\"int\"" +// interfaces_inferred_generic_type_args.baml:221:1 (comment) len=92 "// ─── Class-owned (non-default) method that builds a generic from class `T` ───" +// interfaces_inferred_generic_type_args.baml:223:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:223:11 (interface) [declaration] len=4 "Wrap" +// interfaces_inferred_generic_type_args.baml:223:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:223:16 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:223:17 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:224:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:224:12 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:224:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:224:27 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:224:29 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:224:36 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:227:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:227:7 (class) [declaration] len=7 "SrcWrap" +// interfaces_inferred_generic_type_args.baml:227:14 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:227:15 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:227:16 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:228:5 (property) [declaration] len=3 "arr" +// interfaces_inferred_generic_type_args.baml:228:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:229:5 (property) [declaration] len=3 "idx" +// interfaces_inferred_generic_type_args.baml:229:10 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:231:5 (comment) len=70 "// A regular class method (not an interface default) that constructs a" +// interfaces_inferred_generic_type_args.baml:232:5 (comment) len=47 "// generic `Boxed` from the class-level `T`." +// interfaces_inferred_generic_type_args.baml:233:5 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:233:14 (method) [declaration] len=5 "boxed" +// interfaces_inferred_generic_type_args.baml:233:20 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:233:29 (interface) len=4 "Wrap" +// interfaces_inferred_generic_type_args.baml:233:33 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:233:34 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:233:35 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:233:37 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:233:44 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:234:9 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:234:16 (class) len=5 "Boxed" +// interfaces_inferred_generic_type_args.baml:234:21 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:234:22 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:234:23 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:234:27 (property) len=3 "val" +// interfaces_inferred_generic_type_args.baml:234:32 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:234:37 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:234:41 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:237:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:237:16 (interface) len=4 "Wrap" +// interfaces_inferred_generic_type_args.baml:237:20 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:237:21 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:237:22 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:238:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:238:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:238:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:238:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:238:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:238:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:239:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:239:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:239:25 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:239:29 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:244:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:244:7 (class) [declaration] len=5 "Boxed" +// interfaces_inferred_generic_type_args.baml:244:12 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:244:13 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:244:14 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:245:5 (property) [declaration] len=3 "val" +// interfaces_inferred_generic_type_args.baml:245:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:246:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:246:16 (interface) len=4 "Wrap" +// interfaces_inferred_generic_type_args.baml:246:20 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:246:21 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:246:22 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:247:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:247:18 (method) [declaration] len=5 "first" +// interfaces_inferred_generic_type_args.baml:247:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:247:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:247:35 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:247:42 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:248:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:248:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:248:25 (property) len=3 "val" +// interfaces_inferred_generic_type_args.baml:253:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:253:10 (function) [declaration] len=27 "class_method_builds_generic" +// interfaces_inferred_generic_type_args.baml:253:43 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:253:47 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:253:54 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:254:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:254:9 (variable) [declaration] len=1 "s" +// interfaces_inferred_generic_type_args.baml:254:12 (class) len=7 "SrcWrap" +// interfaces_inferred_generic_type_args.baml:254:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:254:20 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:254:23 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:254:25 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:254:27 (class) len=7 "SrcWrap" +// interfaces_inferred_generic_type_args.baml:254:34 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:254:35 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:254:38 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:254:42 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:254:48 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:254:51 (number) len=1 "6" +// interfaces_inferred_generic_type_args.baml:254:54 (number) len=1 "7" +// interfaces_inferred_generic_type_args.baml:254:58 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:254:63 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:255:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:255:9 (variable) [declaration] len=1 "w" +// interfaces_inferred_generic_type_args.baml:255:12 (interface) len=4 "Wrap" +// interfaces_inferred_generic_type_args.baml:255:16 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:255:17 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:255:20 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:255:22 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:255:24 (variable) len=1 "s" +// interfaces_inferred_generic_type_args.baml:255:26 (method) len=5 "boxed" +// interfaces_inferred_generic_type_args.baml:256:5 (variable) len=1 "w" +// interfaces_inferred_generic_type_args.baml:256:7 (method) len=5 "first" +// interfaces_inferred_generic_type_args.baml:259:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:259:6 (string) len=48 "\"class_method_builds_generic_via_class_type_var\"" +// interfaces_inferred_generic_type_args.baml:260:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:260:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:260:18 (function) len=27 "class_method_builds_generic" +// interfaces_inferred_generic_type_args.baml:260:49 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:263:1 (comment) len=85 "// ─── `default.()` forwards into a generic interface default ───" +// interfaces_inferred_generic_type_args.baml:264:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:265:1 (comment) len=78 "// Calling the interface's default implementation explicitly (the `super`-like" +// interfaces_inferred_generic_type_args.baml:266:1 (comment) len=75 "// `default.()` form) from inside an override must seed the default" +// interfaces_inferred_generic_type_args.baml:267:1 (comment) len=79 "// body's frame with the interface's type args, so a generic default that reads" +// interfaces_inferred_generic_type_args.baml:268:1 (comment) len=58 "// `T` at runtime resolves it instead of seeing `unknown`." +// interfaces_inferred_generic_type_args.baml:270:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:270:11 (interface) [declaration] len=7 "Counter" +// interfaces_inferred_generic_type_args.baml:270:18 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:270:19 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:270:20 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:271:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:271:12 (method) [declaration] len=12 "element_type" +// interfaces_inferred_generic_type_args.baml:271:25 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:271:34 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:271:41 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:271:48 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:272:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:272:12 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:272:20 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:272:27 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:272:28 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:272:29 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:272:33 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:274:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:274:12 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:274:21 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:274:30 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:274:37 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:274:44 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:277:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:277:7 (class) [declaration] len=10 "IntCounter" +// interfaces_inferred_generic_type_args.baml:277:17 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:277:18 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:277:19 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:278:5 (property) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:278:12 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:279:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:279:16 (interface) len=7 "Counter" +// interfaces_inferred_generic_type_args.baml:279:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:279:24 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:279:25 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:280:9 (comment) len=74 "// Override `describe` but delegate to the generic default `element_type`." +// interfaces_inferred_generic_type_args.baml:281:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:281:18 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:281:27 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:281:36 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:282:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:282:28 (method) len=12 "element_type" +// interfaces_inferred_generic_type_args.baml:287:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:287:7 (class) [declaration] len=10 "StrCounter" +// interfaces_inferred_generic_type_args.baml:287:17 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:287:18 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:287:19 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:288:5 (property) [declaration] len=5 "label" +// interfaces_inferred_generic_type_args.baml:288:12 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:289:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:289:16 (interface) len=7 "Counter" +// interfaces_inferred_generic_type_args.baml:289:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:289:24 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:289:25 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:290:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:290:18 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:290:27 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:290:36 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:291:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:291:20 (string) len=5 "\"str\"" +// interfaces_inferred_generic_type_args.baml:296:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:296:10 (function) [declaration] len=30 "default_forward_reads_type_var" +// interfaces_inferred_generic_type_args.baml:296:46 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:297:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:297:9 (variable) [declaration] len=1 "c" +// interfaces_inferred_generic_type_args.baml:297:12 (interface) len=7 "Counter" +// interfaces_inferred_generic_type_args.baml:297:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:297:20 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:297:23 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:297:25 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:297:27 (class) len=10 "IntCounter" +// interfaces_inferred_generic_type_args.baml:297:37 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:297:38 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:297:41 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:297:45 (property) len=5 "value" +// interfaces_inferred_generic_type_args.baml:297:52 (number) len=1 "7" +// interfaces_inferred_generic_type_args.baml:298:5 (variable) len=1 "c" +// interfaces_inferred_generic_type_args.baml:298:7 (method) len=8 "describe" +// interfaces_inferred_generic_type_args.baml:301:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:301:6 (string) len=49 "\"default_method_forward_reads_interface_type_var\"" +// interfaces_inferred_generic_type_args.baml:302:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:302:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:302:18 (function) len=30 "default_forward_reads_type_var" +// interfaces_inferred_generic_type_args.baml:302:52 (string) len=5 "\"int\"" +// interfaces_inferred_generic_type_args.baml:305:1 (comment) len=87 "// ─── Generic class behind a NON-generic interface reads its class `T` ───" +// interfaces_inferred_generic_type_args.baml:306:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:307:1 (comment) len=79 "// The interface request pins no type args (it has none), so the dispatch guard" +// interfaces_inferred_generic_type_args.baml:308:1 (comment) len=79 "// is `Any` and can't name the implementor's class args statically. The matched" +// interfaces_inferred_generic_type_args.baml:309:1 (comment) len=76 "// runtime instance still carries them, so the dispatched class-owned method" +// interfaces_inferred_generic_type_args.baml:310:1 (comment) len=64 "// must resolve its class `T` (here via `reflect.type_of()`)." +// interfaces_inferred_generic_type_args.baml:312:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:312:11 (interface) [declaration] len=11 "Describable" +// interfaces_inferred_generic_type_args.baml:313:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:313:12 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:313:21 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:313:30 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:313:37 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:313:44 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:316:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:316:7 (class) [declaration] len=8 "TypedBox" +// interfaces_inferred_generic_type_args.baml:316:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:316:16 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:316:17 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:317:5 (property) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:317:12 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:318:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:318:16 (interface) len=11 "Describable" +// interfaces_inferred_generic_type_args.baml:319:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:319:18 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:319:27 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:319:36 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:320:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:320:20 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:320:28 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:320:35 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:320:36 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:320:37 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:320:41 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:325:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:325:7 (class) [declaration] len=10 "PlainThing" +// interfaces_inferred_generic_type_args.baml:326:5 (property) [declaration] len=1 "n" +// interfaces_inferred_generic_type_args.baml:326:8 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:327:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:327:16 (interface) len=11 "Describable" +// interfaces_inferred_generic_type_args.baml:328:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:328:18 (method) [declaration] len=8 "describe" +// interfaces_inferred_generic_type_args.baml:328:27 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:328:36 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:329:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:329:20 (string) len=7 "\"plain\"" +// interfaces_inferred_generic_type_args.baml:334:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:334:10 (function) [declaration] len=31 "generic_behind_nongeneric_iface" +// interfaces_inferred_generic_type_args.baml:334:47 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:335:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:335:9 (variable) [declaration] len=1 "d" +// interfaces_inferred_generic_type_args.baml:335:12 (interface) len=11 "Describable" +// interfaces_inferred_generic_type_args.baml:335:24 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:335:26 (class) len=8 "TypedBox" +// interfaces_inferred_generic_type_args.baml:335:34 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:335:35 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:335:38 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:335:42 (property) len=5 "value" +// interfaces_inferred_generic_type_args.baml:335:49 (number) len=2 "42" +// interfaces_inferred_generic_type_args.baml:336:5 (variable) len=1 "d" +// interfaces_inferred_generic_type_args.baml:336:7 (method) len=8 "describe" +// interfaces_inferred_generic_type_args.baml:339:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:339:6 (string) len=58 "\"generic_class_behind_nongeneric_interface_reads_type_var\"" +// interfaces_inferred_generic_type_args.baml:340:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:340:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:340:18 (function) len=31 "generic_behind_nongeneric_iface" +// interfaces_inferred_generic_type_args.baml:340:53 (string) len=5 "\"int\"" +// interfaces_inferred_generic_type_args.baml:343:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:344:1 (comment) len=66 "// Inferred call-site type args reach the callee frame at runtime." +// interfaces_inferred_generic_type_args.baml:345:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:346:1 (comment) len=76 "// The cases above dispatch correctly, but dispatch alone can pass \"by luck\"" +// interfaces_inferred_generic_type_args.baml:347:1 (comment) len=78 "// of arm order even when the instantiation is lost (the unguarded last arm of" +// interfaces_inferred_generic_type_args.baml:348:1 (comment) len=77 "// the candidate switch happens to be the right implementor). The cases below" +// interfaces_inferred_generic_type_args.baml:349:1 (comment) len=70 "// pin the instantiation itself, so they cannot pass by dispatch luck:" +// interfaces_inferred_generic_type_args.baml:350:1 (comment) len=71 "// • a free generic function must see its inferred `T` via reflect;" +// interfaces_inferred_generic_type_args.baml:351:1 (comment) len=64 "// • an instance built by an inferred static ctor must carry" +// interfaces_inferred_generic_type_args.baml:352:1 (comment) len=68 "// `class_type_args = [int]` — observable through a user-level" +// interfaces_inferred_generic_type_args.baml:353:1 (comment) len=61 "// `match`/IsType test, which consults the args directly." +// interfaces_inferred_generic_type_args.baml:354:1 (comment) len=73 "// Both were broken before TIR began persisting inferred call bindings in" +// interfaces_inferred_generic_type_args.baml:355:1 (comment) len=57 "// `CallPlan.type_args` for MIR to seed the callee frame." +// interfaces_inferred_generic_type_args.baml:356:1 (comment) len=228 "// ═══════════════════════════════════════════════════════════════════════════" +// interfaces_inferred_generic_type_args.baml:358:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:358:10 (function) [declaration] len=13 "free_fn_tname" +// interfaces_inferred_generic_type_args.baml:358:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:358:24 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:358:25 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:358:27 (parameter) [declaration] len=1 "a" +// interfaces_inferred_generic_type_args.baml:358:30 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:358:38 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:359:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:359:12 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:359:20 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:359:27 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:359:28 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:359:29 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:359:33 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:362:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:362:10 (function) [declaration] len=18 "free_fn_inferred_t" +// interfaces_inferred_generic_type_args.baml:362:34 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:363:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:363:12 (function) len=13 "free_fn_tname" +// interfaces_inferred_generic_type_args.baml:363:27 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:363:30 (number) len=1 "2" +// interfaces_inferred_generic_type_args.baml:363:33 (number) len=1 "3" +// interfaces_inferred_generic_type_args.baml:366:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:366:6 (string) len=38 "\"free_function_sees_inferred_type_arg\"" +// interfaces_inferred_generic_type_args.baml:367:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:367:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:367:18 (function) len=18 "free_fn_inferred_t" +// interfaces_inferred_generic_type_args.baml:367:40 (string) len=5 "\"int\"" +// interfaces_inferred_generic_type_args.baml:370:1 (comment) len=79 "// The inferred-ctor instance must pass a runtime `IsType ArrBag` test —" +// interfaces_inferred_generic_type_args.baml:371:1 (comment) len=40 "// NOT fall through to the wildcard arm." +// interfaces_inferred_generic_type_args.baml:372:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:372:10 (function) [declaration] len=31 "inferred_ctor_instance_is_typed" +// interfaces_inferred_generic_type_args.baml:372:47 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:372:51 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:372:58 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:373:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:373:9 (variable) [declaration] len=1 "s" +// interfaces_inferred_generic_type_args.baml:373:12 (interface) len=3 "Bag" +// interfaces_inferred_generic_type_args.baml:373:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:373:16 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:373:19 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:373:21 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:373:23 (class) len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:373:30 (method) len=4 "make" +// interfaces_inferred_generic_type_args.baml:373:36 (number) len=1 "5" +// interfaces_inferred_generic_type_args.baml:373:39 (number) len=1 "6" +// interfaces_inferred_generic_type_args.baml:373:42 (number) len=1 "7" +// interfaces_inferred_generic_type_args.baml:374:5 (keyword) len=5 "match" +// interfaces_inferred_generic_type_args.baml:374:12 (variable) len=1 "s" +// interfaces_inferred_generic_type_args.baml:375:9 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:375:13 (variable) [declaration] len=1 "a" +// interfaces_inferred_generic_type_args.baml:375:16 (class) len=6 "ArrBag" +// interfaces_inferred_generic_type_args.baml:375:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:375:23 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:375:26 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:375:31 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:376:9 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:376:13 (variable) [declaration] len=1 "o" +// interfaces_inferred_generic_type_args.baml:376:16 (class) len=6 "OneBag" +// interfaces_inferred_generic_type_args.baml:376:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:376:23 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:376:26 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:376:31 (number) len=1 "2" +// interfaces_inferred_generic_type_args.baml:377:14 (number) len=1 "9" +// interfaces_inferred_generic_type_args.baml:381:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:381:6 (string) len=55 "\"inferred_static_ctor_instance_carries_class_type_args\"" +// interfaces_inferred_generic_type_args.baml:382:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:382:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:382:18 (function) len=31 "inferred_ctor_instance_is_typed" +// interfaces_inferred_generic_type_args.baml:382:53 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:385:1 (comment) len=76 "// Lazy-iterator shape end-to-end: inferred static ctor, consumption through" +// interfaces_inferred_generic_type_args.baml:386:1 (comment) len=74 "// an inherited default method that drives `self.next()` in a loop, with a" +// interfaces_inferred_generic_type_args.baml:387:1 (comment) len=77 "// second implementor present. Returns the COLLECTED COUNT, so a mis-dispatch" +// interfaces_inferred_generic_type_args.baml:388:1 (comment) len=71 "// (e.g. `next` resolving to `Lone.next` against an `ArrIter` receiver)" +// interfaces_inferred_generic_type_args.baml:389:1 (comment) len=30 "// yields 0 or 1 instead of 3." +// interfaces_inferred_generic_type_args.baml:390:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:390:11 (interface) [declaration] len=8 "NextIter" +// interfaces_inferred_generic_type_args.baml:390:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:390:20 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:390:23 (typeParameter) [declaration] len=1 "E" +// interfaces_inferred_generic_type_args.baml:390:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:391:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:391:12 (method) [declaration] len=5 "next2" +// interfaces_inferred_generic_type_args.baml:391:18 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:391:27 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:391:29 (operator) len=1 "|" +// interfaces_inferred_generic_type_args.baml:391:31 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:391:40 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:391:47 (type) len=1 "E" +// interfaces_inferred_generic_type_args.baml:393:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:393:12 (method) [declaration] len=8 "collect2" +// interfaces_inferred_generic_type_args.baml:393:21 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:393:30 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:393:34 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:393:41 (type) len=1 "E" +// interfaces_inferred_generic_type_args.baml:394:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:394:9 (variable) [declaration] len=3 "out" +// interfaces_inferred_generic_type_args.baml:394:14 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:394:18 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:395:5 (keyword) len=5 "while" +// interfaces_inferred_generic_type_args.baml:395:12 (boolean) len=4 "true" +// interfaces_inferred_generic_type_args.baml:396:7 (keyword) len=5 "match" +// interfaces_inferred_generic_type_args.baml:396:14 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:396:19 (method) len=5 "next2" +// interfaces_inferred_generic_type_args.baml:397:9 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:397:23 (keyword) len=5 "break" +// interfaces_inferred_generic_type_args.baml:398:9 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:398:13 (variable) [declaration] len=1 "x" +// interfaces_inferred_generic_type_args.baml:398:16 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:398:23 (variable) len=3 "out" +// interfaces_inferred_generic_type_args.baml:398:27 (method) len=4 "push" +// interfaces_inferred_generic_type_args.baml:398:32 (variable) len=1 "x" +// interfaces_inferred_generic_type_args.baml:401:5 (variable) len=3 "out" +// interfaces_inferred_generic_type_args.baml:405:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:405:7 (class) [declaration] len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:408:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:408:7 (class) [declaration] len=7 "ArrIter" +// interfaces_inferred_generic_type_args.baml:408:14 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:408:15 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:408:16 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:409:5 (property) [declaration] len=3 "arr" +// interfaces_inferred_generic_type_args.baml:409:10 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:410:5 (property) [declaration] len=3 "idx" +// interfaces_inferred_generic_type_args.baml:410:10 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:412:5 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:412:14 (method) [declaration] len=2 "of" +// interfaces_inferred_generic_type_args.baml:412:17 (parameter) [declaration] len=1 "a" +// interfaces_inferred_generic_type_args.baml:412:20 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:412:28 (class) len=7 "ArrIter" +// interfaces_inferred_generic_type_args.baml:412:35 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:412:36 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:412:37 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:412:39 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:412:46 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:413:9 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:413:16 (class) len=7 "ArrIter" +// interfaces_inferred_generic_type_args.baml:413:23 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:413:24 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:413:25 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:413:29 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:413:34 (parameter) len=1 "a" +// interfaces_inferred_generic_type_args.baml:413:37 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:413:42 (number) len=1 "0" +// interfaces_inferred_generic_type_args.baml:416:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:416:16 (interface) len=8 "NextIter" +// interfaces_inferred_generic_type_args.baml:416:24 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:416:25 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:416:28 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:416:33 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:417:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:417:18 (method) [declaration] len=5 "next2" +// interfaces_inferred_generic_type_args.baml:417:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:417:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:417:35 (operator) len=1 "|" +// interfaces_inferred_generic_type_args.baml:417:37 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:417:46 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:417:53 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:418:13 (keyword) len=5 "match" +// interfaces_inferred_generic_type_args.baml:418:20 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:418:25 (property) len=3 "arr" +// interfaces_inferred_generic_type_args.baml:418:29 (method) len=2 "at" +// interfaces_inferred_generic_type_args.baml:418:32 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:418:37 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:419:17 (type) [defaultLibrary] len=4 "null" +// interfaces_inferred_generic_type_args.baml:419:25 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:420:17 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:420:21 (variable) [declaration] len=1 "x" +// interfaces_inferred_generic_type_args.baml:420:24 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:421:21 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:421:26 (property) len=3 "idx" +// interfaces_inferred_generic_type_args.baml:421:30 (operator) len=2 "+=" +// interfaces_inferred_generic_type_args.baml:421:33 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:422:21 (variable) len=1 "x" +// interfaces_inferred_generic_type_args.baml:429:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:429:7 (class) [declaration] len=8 "LoneIter" +// interfaces_inferred_generic_type_args.baml:429:15 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:429:16 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:429:17 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:430:5 (property) [declaration] len=1 "v" +// interfaces_inferred_generic_type_args.baml:430:8 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:431:5 (property) [declaration] len=4 "used" +// interfaces_inferred_generic_type_args.baml:431:11 (type) [defaultLibrary] len=4 "bool" +// interfaces_inferred_generic_type_args.baml:433:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:433:16 (interface) len=8 "NextIter" +// interfaces_inferred_generic_type_args.baml:433:24 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:433:25 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:433:28 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:433:33 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:434:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:434:18 (method) [declaration] len=5 "next2" +// interfaces_inferred_generic_type_args.baml:434:24 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:434:33 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:434:35 (operator) len=1 "|" +// interfaces_inferred_generic_type_args.baml:434:37 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:434:46 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:434:53 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:435:13 (keyword) len=2 "if" +// interfaces_inferred_generic_type_args.baml:435:17 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:435:22 (property) len=4 "used" +// interfaces_inferred_generic_type_args.baml:436:17 (class) len=8 "IterDone" +// interfaces_inferred_generic_type_args.baml:437:15 (keyword) len=4 "else" +// interfaces_inferred_generic_type_args.baml:438:17 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:438:22 (property) len=4 "used" +// interfaces_inferred_generic_type_args.baml:438:27 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:438:29 (boolean) len=4 "true" +// interfaces_inferred_generic_type_args.baml:439:17 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:439:22 (property) len=1 "v" +// interfaces_inferred_generic_type_args.baml:445:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:445:10 (function) [declaration] len=27 "inferred_ctor_collect_count" +// interfaces_inferred_generic_type_args.baml:445:43 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:445:47 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:445:54 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:446:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:446:9 (variable) [declaration] len=2 "it" +// interfaces_inferred_generic_type_args.baml:446:13 (interface) len=8 "NextIter" +// interfaces_inferred_generic_type_args.baml:446:21 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:446:22 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:446:27 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:446:32 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:446:34 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:446:36 (class) len=7 "ArrIter" +// interfaces_inferred_generic_type_args.baml:446:44 (method) len=2 "of" +// interfaces_inferred_generic_type_args.baml:446:48 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:446:51 (number) len=1 "2" +// interfaces_inferred_generic_type_args.baml:446:54 (number) len=1 "3" +// interfaces_inferred_generic_type_args.baml:447:5 (variable) len=2 "it" +// interfaces_inferred_generic_type_args.baml:447:8 (method) len=8 "collect2" +// interfaces_inferred_generic_type_args.baml:447:19 (method) len=6 "length" +// interfaces_inferred_generic_type_args.baml:450:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:450:6 (string) len=43 "\"inferred_ctor_default_method_collects_all\"" +// interfaces_inferred_generic_type_args.baml:451:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:451:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:451:18 (function) len=27 "inferred_ctor_collect_count" +// interfaces_inferred_generic_type_args.baml:451:49 (number) len=1 "3" +// interfaces_inferred_generic_type_args.baml:454:1 (comment) len=83 "// ─── Inferred binding nesting a rigid `Self` must NOT seed `void` ───" +// interfaces_inferred_generic_type_args.baml:455:1 (comment) len=2 "//" +// interfaces_inferred_generic_type_args.baml:456:1 (comment) len=79 "// Inside an interface default method, `self` has the rigid pinned type `Self`," +// interfaces_inferred_generic_type_args.baml:457:1 (comment) len=78 "// which is never among the caller frame's generic params. An inferred generic" +// interfaces_inferred_generic_type_args.baml:458:1 (comment) len=75 "// call whose binding NESTS it (here `T := Self[]` via `echo_type([self])`)" +// interfaces_inferred_generic_type_args.baml:459:1 (comment) len=79 "// cannot be resolved to a frame index — the seeding must demote that binding" +// interfaces_inferred_generic_type_args.baml:460:1 (comment) len=70 "// to `unknown` (the unseeded status quo), not lower `Self` to `void`." +// interfaces_inferred_generic_type_args.baml:462:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:462:10 (function) [declaration] len=9 "echo_type" +// interfaces_inferred_generic_type_args.baml:462:19 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:462:20 (typeParameter) [declaration] len=1 "T" +// interfaces_inferred_generic_type_args.baml:462:21 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:462:23 (parameter) [declaration] len=1 "a" +// interfaces_inferred_generic_type_args.baml:462:26 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:462:32 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:463:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:463:12 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:463:20 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:463:27 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:463:28 (type) len=1 "T" +// interfaces_inferred_generic_type_args.baml:463:29 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:463:33 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:466:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:466:11 (interface) [declaration] len=8 "SelfEcho" +// interfaces_inferred_generic_type_args.baml:467:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:467:12 (method) [declaration] len=3 "tag" +// interfaces_inferred_generic_type_args.baml:467:16 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:467:25 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:467:32 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:467:39 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:468:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:468:12 (method) [declaration] len=16 "nested_self_type" +// interfaces_inferred_generic_type_args.baml:468:29 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:468:38 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:468:45 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:468:52 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:469:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:469:12 (function) len=9 "echo_type" +// interfaces_inferred_generic_type_args.baml:469:23 (parameter) len=4 "self" +// interfaces_inferred_generic_type_args.baml:473:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:473:7 (class) [declaration] len=5 "EchoA" +// interfaces_inferred_generic_type_args.baml:474:5 (property) [declaration] len=1 "n" +// interfaces_inferred_generic_type_args.baml:474:8 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:475:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:475:16 (interface) len=8 "SelfEcho" +// interfaces_inferred_generic_type_args.baml:476:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:476:18 (method) [declaration] len=3 "tag" +// interfaces_inferred_generic_type_args.baml:476:22 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:476:31 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:477:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:477:20 (string) len=3 "\"a\"" +// interfaces_inferred_generic_type_args.baml:482:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:482:7 (class) [declaration] len=5 "EchoB" +// interfaces_inferred_generic_type_args.baml:483:5 (property) [declaration] len=1 "s" +// interfaces_inferred_generic_type_args.baml:483:8 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:484:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:484:16 (interface) len=8 "SelfEcho" +// interfaces_inferred_generic_type_args.baml:485:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:485:18 (method) [declaration] len=3 "tag" +// interfaces_inferred_generic_type_args.baml:485:22 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:485:31 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:486:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:486:20 (string) len=3 "\"b\"" +// interfaces_inferred_generic_type_args.baml:491:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:491:10 (function) [declaration] len=28 "nested_self_inferred_binding" +// interfaces_inferred_generic_type_args.baml:491:44 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:491:51 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:491:58 (type) [defaultLibrary] len=7 "unknown" +// interfaces_inferred_generic_type_args.baml:492:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:492:9 (variable) [declaration] len=1 "e" +// interfaces_inferred_generic_type_args.baml:492:12 (interface) len=8 "SelfEcho" +// interfaces_inferred_generic_type_args.baml:492:21 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:492:23 (class) len=5 "EchoA" +// interfaces_inferred_generic_type_args.baml:492:31 (property) len=1 "n" +// interfaces_inferred_generic_type_args.baml:492:34 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:493:5 (variable) len=1 "e" +// interfaces_inferred_generic_type_args.baml:493:7 (method) len=16 "nested_self_type" +// interfaces_inferred_generic_type_args.baml:496:1 (comment) len=78 "// `unknown` (the whole binding demoted) is the pre-existing status quo for an" +// interfaces_inferred_generic_type_args.baml:497:1 (comment) len=81 "// unresolvable binding — the regression this guards against is `void[]`, which" +// interfaces_inferred_generic_type_args.baml:498:1 (comment) len=56 "// a naive lowering of the nested rigid `Self` produces." +// interfaces_inferred_generic_type_args.baml:499:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:499:6 (string) len=41 "\"nested_self_inferred_binding_not_voided\"" +// interfaces_inferred_generic_type_args.baml:500:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:500:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:500:18 (function) len=28 "nested_self_inferred_binding" +// interfaces_inferred_generic_type_args.baml:500:50 (string) len=9 "\"unknown\"" +// interfaces_inferred_generic_type_args.baml:503:1 (comment) len=74 "// Interface dispatch must also carry inferred method-level type args. The" +// interfaces_inferred_generic_type_args.baml:504:1 (comment) len=79 "// dispatch arm itself seeds the receiver/interface frame; `CallPlan.type_args`" +// interfaces_inferred_generic_type_args.baml:505:1 (comment) len=38 "// supplies the method's inferred `U`." +// interfaces_inferred_generic_type_args.baml:506:1 (keyword) len=9 "interface" +// interfaces_inferred_generic_type_args.baml:506:11 (interface) [declaration] len=9 "TypeProbe" +// interfaces_inferred_generic_type_args.baml:507:3 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:507:12 (method) [declaration] len=4 "seen" +// interfaces_inferred_generic_type_args.baml:507:16 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:507:17 (typeParameter) [declaration] len=1 "U" +// interfaces_inferred_generic_type_args.baml:507:18 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:507:20 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:507:26 (parameter) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:507:33 (type) len=1 "U" +// interfaces_inferred_generic_type_args.baml:507:39 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:507:46 (keyword) len=6 "throws" +// interfaces_inferred_generic_type_args.baml:507:53 (type) [defaultLibrary] len=5 "never" +// interfaces_inferred_generic_type_args.baml:510:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:510:7 (class) [declaration] len=6 "ProbeA" +// interfaces_inferred_generic_type_args.baml:511:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:511:16 (interface) len=9 "TypeProbe" +// interfaces_inferred_generic_type_args.baml:512:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:512:18 (method) [declaration] len=4 "seen" +// interfaces_inferred_generic_type_args.baml:512:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:512:23 (typeParameter) [declaration] len=1 "U" +// interfaces_inferred_generic_type_args.baml:512:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:512:26 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:512:32 (parameter) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:512:39 (type) len=1 "U" +// interfaces_inferred_generic_type_args.baml:512:45 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:513:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:513:20 (namespace) [defaultLibrary] len=7 "reflect" +// interfaces_inferred_generic_type_args.baml:513:28 (function) len=7 "type_of" +// interfaces_inferred_generic_type_args.baml:513:35 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:513:36 (type) len=1 "U" +// interfaces_inferred_generic_type_args.baml:513:37 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:513:41 (method) len=9 "to_string" +// interfaces_inferred_generic_type_args.baml:518:1 (keyword) len=5 "class" +// interfaces_inferred_generic_type_args.baml:518:7 (class) [declaration] len=6 "ProbeB" +// interfaces_inferred_generic_type_args.baml:519:5 (keyword) len=10 "implements" +// interfaces_inferred_generic_type_args.baml:519:16 (interface) len=9 "TypeProbe" +// interfaces_inferred_generic_type_args.baml:520:9 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:520:18 (method) [declaration] len=4 "seen" +// interfaces_inferred_generic_type_args.baml:520:22 (operator) len=1 "<" +// interfaces_inferred_generic_type_args.baml:520:23 (typeParameter) [declaration] len=1 "U" +// interfaces_inferred_generic_type_args.baml:520:24 (operator) len=1 ">" +// interfaces_inferred_generic_type_args.baml:520:26 (parameter) [declaration] len=4 "self" +// interfaces_inferred_generic_type_args.baml:520:32 (parameter) [declaration] len=5 "value" +// interfaces_inferred_generic_type_args.baml:520:39 (type) len=1 "U" +// interfaces_inferred_generic_type_args.baml:520:45 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:521:13 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:521:20 (string) len=7 "\"wrong\"" +// interfaces_inferred_generic_type_args.baml:526:1 (keyword) len=8 "function" +// interfaces_inferred_generic_type_args.baml:526:10 (function) [declaration] len=43 "interface_dispatch_inferred_method_type_arg" +// interfaces_inferred_generic_type_args.baml:526:59 (type) [defaultLibrary] len=6 "string" +// interfaces_inferred_generic_type_args.baml:527:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:527:9 (variable) [declaration] len=1 "p" +// interfaces_inferred_generic_type_args.baml:527:12 (interface) len=9 "TypeProbe" +// interfaces_inferred_generic_type_args.baml:527:22 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:527:24 (class) len=6 "ProbeA" +// interfaces_inferred_generic_type_args.baml:528:5 (keyword) len=3 "let" +// interfaces_inferred_generic_type_args.baml:528:9 (variable) [declaration] len=1 "x" +// interfaces_inferred_generic_type_args.baml:528:12 (type) [defaultLibrary] len=3 "int" +// interfaces_inferred_generic_type_args.baml:528:16 (operator) len=1 "=" +// interfaces_inferred_generic_type_args.baml:528:18 (number) len=1 "1" +// interfaces_inferred_generic_type_args.baml:529:5 (variable) len=1 "p" +// interfaces_inferred_generic_type_args.baml:529:7 (method) len=4 "seen" +// interfaces_inferred_generic_type_args.baml:529:12 (variable) len=1 "x" +// interfaces_inferred_generic_type_args.baml:532:1 (keyword) len=4 "test" +// interfaces_inferred_generic_type_args.baml:532:6 (string) len=50 "\"interface_dispatch_sees_inferred_method_type_arg\"" +// interfaces_inferred_generic_type_args.baml:533:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_inferred_generic_type_args.baml:533:12 (function) len=5 "equal" +// interfaces_inferred_generic_type_args.baml:533:18 (function) len=43 "interface_dispatch_inferred_method_type_arg" +// interfaces_inferred_generic_type_args.baml:533:65 (string) len=5 "\"int\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_iter_core.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_iter_core.baml new file mode 100644 index 0000000000..20d0408511 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_iter_core.baml @@ -0,0 +1,1929 @@ +// Iterator protocol and concrete sources for the native BAML iterator tests. +// The tests live one namespace up, in `user.iter_impl_generics_only`, so they exercise qualified +// generic interface types across nested namespaces. + +class Done {} + +interface Iterable { + function iter(self) -> Iterator throws never +} + +interface Iterator requires Iterable { + function next(self) -> T | Done throws E + + function map(self, fn: (T) -> R throws E2) -> Iterator throws never { + Map { iter: self, func: fn } + } + + function filter(self, predicate: (T) -> bool throws E2) -> Iterator throws never { + Filter { iter: self, predicate: predicate } + } + + function filter_map(self, fn: (T) -> R? throws E2) -> Iterator throws never { + FilterMap { iter: self, func: fn } + } + + function flat_map(self, fn: (T) -> Iterable throws E2) -> Iterator throws never { + FlatMap { iter: self, func: fn, inner: Done {} } + } + + function step_by(self, n: int) -> Iterator throws never { + StepBy { iter: self, n: n, first: true } + } + + function chain(self, other: Iterator) -> Iterator throws never { + Chain { iter: self, other: other, first_done: false } + } + + function peekable(self) -> Peekable throws never { + Peekable { iter: self, buffer: Done {}, has_buffer: false } + } + + function collect(self) -> T[] throws E { + let r: T[] = []; + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => r.push(x), + } + } + r + } + + function reduce(self, fn: (A, T) -> A throws E2, initial: A) -> A throws E | E2 { + let acc: A = initial; + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => { acc = fn(acc, x); }, + } + } + acc + } + + function count(self) -> int throws E { + let n: int = 0; + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => { n += 1; }, + } + } + n + } + + function some(self, predicate: (T) -> bool throws E2) -> bool throws E | E2 { + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => { + if (predicate(x)) { + return true; + } + }, + } + } + false + } + + function every(self, predicate: (T) -> bool throws E2) -> bool throws E | E2 { + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => { + if (!predicate(x)) { + return false; + } + }, + } + } + true + } + + function find(self, predicate: (T) -> bool throws E2) -> T? throws E | E2 { + while (true) { + match (self.next()) { + Done => { break; }, + let x: T => { + if (predicate(x)) { + return x; + } + }, + } + } + null + } +} + +function flatten(src: Iterator, E>) -> Iterator throws never { + Flatten { iter: src, inner: Done {} } +} + +class ArrayIterator { + arr: T[] + idx: int + + function new(arr: T[]) -> ArrayIterator throws never { + ArrayIterator { arr: arr.slice(0, arr.length()), idx: 0 } + } + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws never { + match (self.arr.at(self.idx)) { + null => Done {}, + let item: T => { + self.idx += 1; + item + }, + } + } + } +} + +class Range { + i: int + max: int + step: int + + function new(min: int, max: int, step: int = 1) -> Range throws never { + Range { i: min, max: max, step: step } + } + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> int | Done throws never { + if (self.i < self.max) { + let cur = self.i; + self.i += self.step; + cur + } else { + Done {} + } + } + } +} + +class Repeat { + value: T + count: int + + function new(value: T, count: int = -1) -> Repeat throws never { + Repeat { value: value, count: count } + } + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws never { + if (self.count < 0) { + self.value + } else if (self.count > 0) { + self.count -= 1; + self.value + } else { + Done {} + } + } + } +} + +interface OutOfBodyValue { + function get(self) -> T throws unknown +} + +class OutOfBodyBox { + value: T + + function new(value: T) -> OutOfBodyBox throws never { + OutOfBodyBox { value: value } + } +} + +implements OutOfBodyValue for OutOfBodyBox { + function get(self) -> T throws unknown { + self.value + } +} + +class Map { + iter: Iterator + func: (T) -> R throws E2 + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> R | Done throws E | E2 { + match (self.iter.next()) { + Done => Done {}, + let x: T => self.func(x), + } + } + } +} + +class Filter { + iter: Iterator + predicate: (T) -> bool throws E2 + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws E | E2 { + while (true) { + match (self.iter.next()) { + Done => { return Done {}; }, + let x: T => { + if (self.predicate(x)) { + return x; + } + }, + } + } + Done {} + } + } +} + +class FilterMap { + iter: Iterator + func: (T) -> R? throws E2 + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> R | Done throws E | E2 { + while (true) { + match (self.iter.next()) { + Done => { return Done {}; }, + let x: T => { + match (self.func(x)) { + null => {}, + let y: R => { return y; }, + } + }, + } + } + Done {} + } + } +} + +class FlatMap { + iter: Iterator + func: (T) -> Iterable throws E2 + inner: Iterator | Done + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> R | Done throws E | E2 | E3 { + while (true) { + match (self.inner) { + let cur: Iterator => { + match (cur.next()) { + Done => { self.inner = Done {}; }, + let y: R => { return y; }, + } + }, + Done => { + match (self.iter.next()) { + Done => { return Done {}; }, + let x: T => { + let it = self.func(x).iter(); + self.inner = it; + }, + } + }, + } + } + Done {} + } + } +} + +class Flatten { + iter: Iterator, E> + inner: Iterator | Done + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> R | Done throws E | E3 { + while (true) { + match (self.inner) { + let cur: Iterator => { + match (cur.next()) { + Done => { self.inner = Done {}; }, + let y: R => { return y; }, + } + }, + Done => { + match (self.iter.next()) { + Done => { return Done {}; }, + let x: Iterable => { + let it = x.iter(); + self.inner = it; + }, + } + }, + } + } + Done {} + } + } +} + +class Peekable { + iter: Iterator + buffer: T | Done + has_buffer: bool + + function peek(self) -> T | Done throws E { + if (self.has_buffer) { + return self.buffer; + } + let v = self.iter.next(); + self.buffer = v; + self.has_buffer = true; + v + } + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws E { + if (self.has_buffer) { + let v = self.buffer; + self.buffer = Done {}; + self.has_buffer = false; + return v; + } + self.iter.next() + } + } +} + +class StepBy { + iter: Iterator + n: int + first: bool + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws E { + if (self.first) { + self.first = false; + return self.iter.next(); + } + for (let i = 0; i < self.n - 1; i += 1) { + match (self.iter.next()) { + Done => { return Done {}; }, + let x: T => {}, + } + } + self.iter.next() + } + } +} + +class Chain { + iter: Iterator + other: Iterator + first_done: bool + + implements Iterable { + function iter(self) -> Iterator throws never { self } + } + + implements Iterator { + function next(self) -> T | Done throws E { + if (!self.first_done) { + match (self.iter.next()) { + Done => { self.first_done = true; }, + let x: T => { return x; }, + } + } + self.other.next() + } + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// interfaces_iter_core.baml:1:1 (comment) len=77 "// Iterator protocol and concrete sources for the native BAML iterator tests." +// interfaces_iter_core.baml:2:1 (comment) len=97 "// The tests live one namespace up, in `user.iter_impl_generics_only`, so they exercise qualified" +// interfaces_iter_core.baml:3:1 (comment) len=52 "// generic interface types across nested namespaces." +// interfaces_iter_core.baml:5:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:5:7 (class) [declaration] len=4 "Done" +// interfaces_iter_core.baml:7:1 (keyword) len=9 "interface" +// interfaces_iter_core.baml:7:11 (interface) [declaration] len=8 "Iterable" +// interfaces_iter_core.baml:7:19 (operator) len=1 "<" +// interfaces_iter_core.baml:7:20 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:7:23 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:7:24 (operator) len=1 ">" +// interfaces_iter_core.baml:8:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:8:12 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:8:17 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:8:26 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:8:34 (operator) len=1 "<" +// interfaces_iter_core.baml:8:35 (type) len=1 "T" +// interfaces_iter_core.baml:8:38 (type) len=1 "E" +// interfaces_iter_core.baml:8:39 (operator) len=1 ">" +// interfaces_iter_core.baml:8:41 (keyword) len=6 "throws" +// interfaces_iter_core.baml:8:48 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:11:1 (keyword) len=9 "interface" +// interfaces_iter_core.baml:11:11 (interface) [declaration] len=8 "Iterator" +// interfaces_iter_core.baml:11:19 (operator) len=1 "<" +// interfaces_iter_core.baml:11:20 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:11:23 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:11:24 (operator) len=1 ">" +// interfaces_iter_core.baml:11:26 (keyword) len=8 "requires" +// interfaces_iter_core.baml:11:35 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:11:43 (operator) len=1 "<" +// interfaces_iter_core.baml:11:44 (type) len=1 "T" +// interfaces_iter_core.baml:11:47 (type) len=1 "E" +// interfaces_iter_core.baml:11:48 (operator) len=1 ">" +// interfaces_iter_core.baml:12:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:12:12 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:12:17 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:12:26 (type) len=1 "T" +// interfaces_iter_core.baml:12:28 (operator) len=1 "|" +// interfaces_iter_core.baml:12:30 (class) len=4 "Done" +// interfaces_iter_core.baml:12:35 (keyword) len=6 "throws" +// interfaces_iter_core.baml:12:42 (type) len=1 "E" +// interfaces_iter_core.baml:14:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:14:12 (method) [declaration] len=3 "map" +// interfaces_iter_core.baml:14:15 (operator) len=1 "<" +// interfaces_iter_core.baml:14:16 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:14:19 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:14:21 (operator) len=1 ">" +// interfaces_iter_core.baml:14:23 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:14:29 (parameter) [declaration] len=2 "fn" +// interfaces_iter_core.baml:14:34 (type) len=1 "T" +// interfaces_iter_core.baml:14:40 (type) len=1 "R" +// interfaces_iter_core.baml:14:42 (keyword) len=6 "throws" +// interfaces_iter_core.baml:14:49 (type) len=2 "E2" +// interfaces_iter_core.baml:14:56 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:14:64 (operator) len=1 "<" +// interfaces_iter_core.baml:14:65 (type) len=1 "R" +// interfaces_iter_core.baml:14:68 (type) len=1 "E" +// interfaces_iter_core.baml:14:70 (operator) len=1 "|" +// interfaces_iter_core.baml:14:72 (type) len=2 "E2" +// interfaces_iter_core.baml:14:74 (operator) len=1 ">" +// interfaces_iter_core.baml:14:76 (keyword) len=6 "throws" +// interfaces_iter_core.baml:14:83 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:15:5 (class) len=3 "Map" +// interfaces_iter_core.baml:15:8 (operator) len=1 "<" +// interfaces_iter_core.baml:15:9 (type) len=1 "T" +// interfaces_iter_core.baml:15:12 (type) len=1 "R" +// interfaces_iter_core.baml:15:15 (type) len=1 "E" +// interfaces_iter_core.baml:15:18 (type) len=2 "E2" +// interfaces_iter_core.baml:15:20 (operator) len=1 ">" +// interfaces_iter_core.baml:15:24 (property) len=4 "iter" +// interfaces_iter_core.baml:15:30 (parameter) len=4 "self" +// interfaces_iter_core.baml:15:36 (property) len=4 "func" +// interfaces_iter_core.baml:15:42 (parameter) len=2 "fn" +// interfaces_iter_core.baml:18:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:18:12 (method) [declaration] len=6 "filter" +// interfaces_iter_core.baml:18:18 (operator) len=1 "<" +// interfaces_iter_core.baml:18:19 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:18:21 (operator) len=1 ">" +// interfaces_iter_core.baml:18:23 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:18:29 (parameter) [declaration] len=9 "predicate" +// interfaces_iter_core.baml:18:41 (type) len=1 "T" +// interfaces_iter_core.baml:18:47 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:18:52 (keyword) len=6 "throws" +// interfaces_iter_core.baml:18:59 (type) len=2 "E2" +// interfaces_iter_core.baml:18:66 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:18:74 (operator) len=1 "<" +// interfaces_iter_core.baml:18:75 (type) len=1 "T" +// interfaces_iter_core.baml:18:78 (type) len=1 "E" +// interfaces_iter_core.baml:18:80 (operator) len=1 "|" +// interfaces_iter_core.baml:18:82 (type) len=2 "E2" +// interfaces_iter_core.baml:18:84 (operator) len=1 ">" +// interfaces_iter_core.baml:18:86 (keyword) len=6 "throws" +// interfaces_iter_core.baml:18:93 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:19:5 (class) len=6 "Filter" +// interfaces_iter_core.baml:19:11 (operator) len=1 "<" +// interfaces_iter_core.baml:19:12 (type) len=1 "T" +// interfaces_iter_core.baml:19:15 (type) len=1 "E" +// interfaces_iter_core.baml:19:18 (type) len=2 "E2" +// interfaces_iter_core.baml:19:20 (operator) len=1 ">" +// interfaces_iter_core.baml:19:24 (property) len=4 "iter" +// interfaces_iter_core.baml:19:30 (parameter) len=4 "self" +// interfaces_iter_core.baml:19:36 (property) len=9 "predicate" +// interfaces_iter_core.baml:19:47 (parameter) len=9 "predicate" +// interfaces_iter_core.baml:22:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:22:12 (method) [declaration] len=10 "filter_map" +// interfaces_iter_core.baml:22:22 (operator) len=1 "<" +// interfaces_iter_core.baml:22:23 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:22:26 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:22:28 (operator) len=1 ">" +// interfaces_iter_core.baml:22:30 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:22:36 (parameter) [declaration] len=2 "fn" +// interfaces_iter_core.baml:22:41 (type) len=1 "T" +// interfaces_iter_core.baml:22:47 (type) len=1 "R" +// interfaces_iter_core.baml:22:50 (keyword) len=6 "throws" +// interfaces_iter_core.baml:22:57 (type) len=2 "E2" +// interfaces_iter_core.baml:22:64 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:22:72 (operator) len=1 "<" +// interfaces_iter_core.baml:22:73 (type) len=1 "R" +// interfaces_iter_core.baml:22:76 (type) len=1 "E" +// interfaces_iter_core.baml:22:78 (operator) len=1 "|" +// interfaces_iter_core.baml:22:80 (type) len=2 "E2" +// interfaces_iter_core.baml:22:82 (operator) len=1 ">" +// interfaces_iter_core.baml:22:84 (keyword) len=6 "throws" +// interfaces_iter_core.baml:22:91 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:23:5 (class) len=9 "FilterMap" +// interfaces_iter_core.baml:23:14 (operator) len=1 "<" +// interfaces_iter_core.baml:23:15 (type) len=1 "T" +// interfaces_iter_core.baml:23:18 (type) len=1 "R" +// interfaces_iter_core.baml:23:21 (type) len=1 "E" +// interfaces_iter_core.baml:23:24 (type) len=2 "E2" +// interfaces_iter_core.baml:23:26 (operator) len=1 ">" +// interfaces_iter_core.baml:23:30 (property) len=4 "iter" +// interfaces_iter_core.baml:23:36 (parameter) len=4 "self" +// interfaces_iter_core.baml:23:42 (property) len=4 "func" +// interfaces_iter_core.baml:23:48 (parameter) len=2 "fn" +// interfaces_iter_core.baml:26:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:26:12 (method) [declaration] len=8 "flat_map" +// interfaces_iter_core.baml:26:20 (operator) len=1 "<" +// interfaces_iter_core.baml:26:21 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:26:24 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:26:28 (typeParameter) [declaration] len=2 "E3" +// interfaces_iter_core.baml:26:30 (operator) len=1 ">" +// interfaces_iter_core.baml:26:32 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:26:38 (parameter) [declaration] len=2 "fn" +// interfaces_iter_core.baml:26:43 (type) len=1 "T" +// interfaces_iter_core.baml:26:49 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:26:57 (operator) len=1 "<" +// interfaces_iter_core.baml:26:58 (type) len=1 "R" +// interfaces_iter_core.baml:26:61 (type) len=2 "E3" +// interfaces_iter_core.baml:26:63 (operator) len=1 ">" +// interfaces_iter_core.baml:26:65 (keyword) len=6 "throws" +// interfaces_iter_core.baml:26:72 (type) len=2 "E2" +// interfaces_iter_core.baml:26:79 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:26:87 (operator) len=1 "<" +// interfaces_iter_core.baml:26:88 (type) len=1 "R" +// interfaces_iter_core.baml:26:91 (type) len=1 "E" +// interfaces_iter_core.baml:26:93 (operator) len=1 "|" +// interfaces_iter_core.baml:26:95 (type) len=2 "E2" +// interfaces_iter_core.baml:26:98 (operator) len=1 "|" +// interfaces_iter_core.baml:26:100 (type) len=2 "E3" +// interfaces_iter_core.baml:26:102 (operator) len=1 ">" +// interfaces_iter_core.baml:26:104 (keyword) len=6 "throws" +// interfaces_iter_core.baml:26:111 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:27:5 (class) len=7 "FlatMap" +// interfaces_iter_core.baml:27:12 (operator) len=1 "<" +// interfaces_iter_core.baml:27:13 (type) len=1 "T" +// interfaces_iter_core.baml:27:16 (type) len=1 "R" +// interfaces_iter_core.baml:27:19 (type) len=1 "E" +// interfaces_iter_core.baml:27:22 (type) len=2 "E2" +// interfaces_iter_core.baml:27:26 (type) len=2 "E3" +// interfaces_iter_core.baml:27:28 (operator) len=1 ">" +// interfaces_iter_core.baml:27:32 (property) len=4 "iter" +// interfaces_iter_core.baml:27:38 (parameter) len=4 "self" +// interfaces_iter_core.baml:27:44 (property) len=4 "func" +// interfaces_iter_core.baml:27:50 (parameter) len=2 "fn" +// interfaces_iter_core.baml:27:54 (property) len=5 "inner" +// interfaces_iter_core.baml:27:61 (class) len=4 "Done" +// interfaces_iter_core.baml:30:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:30:12 (method) [declaration] len=7 "step_by" +// interfaces_iter_core.baml:30:20 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:30:26 (parameter) [declaration] len=1 "n" +// interfaces_iter_core.baml:30:29 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:30:37 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:30:45 (operator) len=1 "<" +// interfaces_iter_core.baml:30:46 (type) len=1 "T" +// interfaces_iter_core.baml:30:49 (type) len=1 "E" +// interfaces_iter_core.baml:30:50 (operator) len=1 ">" +// interfaces_iter_core.baml:30:52 (keyword) len=6 "throws" +// interfaces_iter_core.baml:30:59 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:31:5 (class) len=6 "StepBy" +// interfaces_iter_core.baml:31:11 (operator) len=1 "<" +// interfaces_iter_core.baml:31:12 (type) len=1 "T" +// interfaces_iter_core.baml:31:15 (type) len=1 "E" +// interfaces_iter_core.baml:31:16 (operator) len=1 ">" +// interfaces_iter_core.baml:31:20 (property) len=4 "iter" +// interfaces_iter_core.baml:31:26 (parameter) len=4 "self" +// interfaces_iter_core.baml:31:32 (property) len=1 "n" +// interfaces_iter_core.baml:31:35 (parameter) len=1 "n" +// interfaces_iter_core.baml:31:38 (property) len=5 "first" +// interfaces_iter_core.baml:31:45 (boolean) len=4 "true" +// interfaces_iter_core.baml:34:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:34:12 (method) [declaration] len=5 "chain" +// interfaces_iter_core.baml:34:18 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:34:24 (parameter) [declaration] len=5 "other" +// interfaces_iter_core.baml:34:31 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:34:39 (operator) len=1 "<" +// interfaces_iter_core.baml:34:40 (type) len=1 "T" +// interfaces_iter_core.baml:34:43 (type) len=1 "E" +// interfaces_iter_core.baml:34:44 (operator) len=1 ">" +// interfaces_iter_core.baml:34:50 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:34:58 (operator) len=1 "<" +// interfaces_iter_core.baml:34:59 (type) len=1 "T" +// interfaces_iter_core.baml:34:62 (type) len=1 "E" +// interfaces_iter_core.baml:34:63 (operator) len=1 ">" +// interfaces_iter_core.baml:34:65 (keyword) len=6 "throws" +// interfaces_iter_core.baml:34:72 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:35:5 (class) len=5 "Chain" +// interfaces_iter_core.baml:35:10 (operator) len=1 "<" +// interfaces_iter_core.baml:35:11 (type) len=1 "T" +// interfaces_iter_core.baml:35:14 (type) len=1 "E" +// interfaces_iter_core.baml:35:15 (operator) len=1 ">" +// interfaces_iter_core.baml:35:19 (property) len=4 "iter" +// interfaces_iter_core.baml:35:25 (parameter) len=4 "self" +// interfaces_iter_core.baml:35:31 (property) len=5 "other" +// interfaces_iter_core.baml:35:38 (parameter) len=5 "other" +// interfaces_iter_core.baml:35:45 (property) len=10 "first_done" +// interfaces_iter_core.baml:35:57 (boolean) len=5 "false" +// interfaces_iter_core.baml:38:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:38:12 (method) [declaration] len=8 "peekable" +// interfaces_iter_core.baml:38:21 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:38:30 (class) len=8 "Peekable" +// interfaces_iter_core.baml:38:38 (operator) len=1 "<" +// interfaces_iter_core.baml:38:39 (type) len=1 "T" +// interfaces_iter_core.baml:38:42 (type) len=1 "E" +// interfaces_iter_core.baml:38:43 (operator) len=1 ">" +// interfaces_iter_core.baml:38:45 (keyword) len=6 "throws" +// interfaces_iter_core.baml:38:52 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:39:5 (class) len=8 "Peekable" +// interfaces_iter_core.baml:39:13 (operator) len=1 "<" +// interfaces_iter_core.baml:39:14 (type) len=1 "T" +// interfaces_iter_core.baml:39:17 (type) len=1 "E" +// interfaces_iter_core.baml:39:18 (operator) len=1 ">" +// interfaces_iter_core.baml:39:22 (property) len=4 "iter" +// interfaces_iter_core.baml:39:28 (parameter) len=4 "self" +// interfaces_iter_core.baml:39:34 (property) len=6 "buffer" +// interfaces_iter_core.baml:39:42 (class) len=4 "Done" +// interfaces_iter_core.baml:39:51 (property) len=10 "has_buffer" +// interfaces_iter_core.baml:39:63 (boolean) len=5 "false" +// interfaces_iter_core.baml:42:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:42:12 (method) [declaration] len=7 "collect" +// interfaces_iter_core.baml:42:20 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:42:29 (type) len=1 "T" +// interfaces_iter_core.baml:42:33 (keyword) len=6 "throws" +// interfaces_iter_core.baml:42:40 (type) len=1 "E" +// interfaces_iter_core.baml:43:5 (keyword) len=3 "let" +// interfaces_iter_core.baml:43:9 (variable) [declaration] len=1 "r" +// interfaces_iter_core.baml:43:12 (type) len=1 "T" +// interfaces_iter_core.baml:43:16 (operator) len=1 "=" +// interfaces_iter_core.baml:44:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:44:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:45:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:45:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:45:19 (method) len=4 "next" +// interfaces_iter_core.baml:46:9 (class) len=4 "Done" +// interfaces_iter_core.baml:46:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:47:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:47:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:47:16 (type) len=1 "T" +// interfaces_iter_core.baml:47:21 (variable) len=1 "r" +// interfaces_iter_core.baml:47:23 (method) len=4 "push" +// interfaces_iter_core.baml:47:28 (variable) len=1 "x" +// interfaces_iter_core.baml:50:5 (variable) len=1 "r" +// interfaces_iter_core.baml:53:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:53:12 (method) [declaration] len=6 "reduce" +// interfaces_iter_core.baml:53:18 (operator) len=1 "<" +// interfaces_iter_core.baml:53:19 (typeParameter) [declaration] len=1 "A" +// interfaces_iter_core.baml:53:22 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:53:24 (operator) len=1 ">" +// interfaces_iter_core.baml:53:26 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:53:32 (parameter) [declaration] len=2 "fn" +// interfaces_iter_core.baml:53:37 (type) len=1 "A" +// interfaces_iter_core.baml:53:40 (type) len=1 "T" +// interfaces_iter_core.baml:53:46 (type) len=1 "A" +// interfaces_iter_core.baml:53:48 (keyword) len=6 "throws" +// interfaces_iter_core.baml:53:55 (type) len=2 "E2" +// interfaces_iter_core.baml:53:59 (parameter) [declaration] len=7 "initial" +// interfaces_iter_core.baml:53:68 (type) len=1 "A" +// interfaces_iter_core.baml:53:74 (type) len=1 "A" +// interfaces_iter_core.baml:53:76 (keyword) len=6 "throws" +// interfaces_iter_core.baml:53:83 (type) len=1 "E" +// interfaces_iter_core.baml:53:85 (operator) len=1 "|" +// interfaces_iter_core.baml:53:87 (type) len=2 "E2" +// interfaces_iter_core.baml:54:5 (keyword) len=3 "let" +// interfaces_iter_core.baml:54:9 (variable) [declaration] len=3 "acc" +// interfaces_iter_core.baml:54:14 (type) len=1 "A" +// interfaces_iter_core.baml:54:16 (operator) len=1 "=" +// interfaces_iter_core.baml:54:18 (parameter) len=7 "initial" +// interfaces_iter_core.baml:55:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:55:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:56:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:56:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:56:19 (method) len=4 "next" +// interfaces_iter_core.baml:57:9 (class) len=4 "Done" +// interfaces_iter_core.baml:57:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:58:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:58:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:58:16 (type) len=1 "T" +// interfaces_iter_core.baml:58:23 (variable) len=3 "acc" +// interfaces_iter_core.baml:58:27 (operator) len=1 "=" +// interfaces_iter_core.baml:58:29 (parameter) len=2 "fn" +// interfaces_iter_core.baml:58:32 (variable) len=3 "acc" +// interfaces_iter_core.baml:58:37 (variable) len=1 "x" +// interfaces_iter_core.baml:61:5 (variable) len=3 "acc" +// interfaces_iter_core.baml:64:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:64:12 (method) [declaration] len=5 "count" +// interfaces_iter_core.baml:64:18 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:64:27 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:64:31 (keyword) len=6 "throws" +// interfaces_iter_core.baml:64:38 (type) len=1 "E" +// interfaces_iter_core.baml:65:5 (keyword) len=3 "let" +// interfaces_iter_core.baml:65:9 (variable) [declaration] len=1 "n" +// interfaces_iter_core.baml:65:12 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:65:16 (operator) len=1 "=" +// interfaces_iter_core.baml:65:18 (number) len=1 "0" +// interfaces_iter_core.baml:66:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:66:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:67:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:67:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:67:19 (method) len=4 "next" +// interfaces_iter_core.baml:68:9 (class) len=4 "Done" +// interfaces_iter_core.baml:68:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:69:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:69:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:69:16 (type) len=1 "T" +// interfaces_iter_core.baml:69:23 (variable) len=1 "n" +// interfaces_iter_core.baml:69:25 (operator) len=2 "+=" +// interfaces_iter_core.baml:69:28 (number) len=1 "1" +// interfaces_iter_core.baml:72:5 (variable) len=1 "n" +// interfaces_iter_core.baml:75:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:75:12 (method) [declaration] len=4 "some" +// interfaces_iter_core.baml:75:16 (operator) len=1 "<" +// interfaces_iter_core.baml:75:17 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:75:19 (operator) len=1 ">" +// interfaces_iter_core.baml:75:21 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:75:27 (parameter) [declaration] len=9 "predicate" +// interfaces_iter_core.baml:75:39 (type) len=1 "T" +// interfaces_iter_core.baml:75:45 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:75:50 (keyword) len=6 "throws" +// interfaces_iter_core.baml:75:57 (type) len=2 "E2" +// interfaces_iter_core.baml:75:64 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:75:69 (keyword) len=6 "throws" +// interfaces_iter_core.baml:75:76 (type) len=1 "E" +// interfaces_iter_core.baml:75:78 (operator) len=1 "|" +// interfaces_iter_core.baml:75:80 (type) len=2 "E2" +// interfaces_iter_core.baml:76:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:76:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:77:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:77:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:77:19 (method) len=4 "next" +// interfaces_iter_core.baml:78:9 (class) len=4 "Done" +// interfaces_iter_core.baml:78:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:79:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:79:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:79:16 (type) len=1 "T" +// interfaces_iter_core.baml:80:11 (keyword) len=2 "if" +// interfaces_iter_core.baml:80:15 (parameter) len=9 "predicate" +// interfaces_iter_core.baml:80:25 (variable) len=1 "x" +// interfaces_iter_core.baml:81:13 (keyword) len=6 "return" +// interfaces_iter_core.baml:81:20 (boolean) len=4 "true" +// interfaces_iter_core.baml:86:5 (boolean) len=5 "false" +// interfaces_iter_core.baml:89:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:89:12 (method) [declaration] len=5 "every" +// interfaces_iter_core.baml:89:17 (operator) len=1 "<" +// interfaces_iter_core.baml:89:18 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:89:20 (operator) len=1 ">" +// interfaces_iter_core.baml:89:22 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:89:28 (parameter) [declaration] len=9 "predicate" +// interfaces_iter_core.baml:89:40 (type) len=1 "T" +// interfaces_iter_core.baml:89:46 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:89:51 (keyword) len=6 "throws" +// interfaces_iter_core.baml:89:58 (type) len=2 "E2" +// interfaces_iter_core.baml:89:65 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:89:70 (keyword) len=6 "throws" +// interfaces_iter_core.baml:89:77 (type) len=1 "E" +// interfaces_iter_core.baml:89:79 (operator) len=1 "|" +// interfaces_iter_core.baml:89:81 (type) len=2 "E2" +// interfaces_iter_core.baml:90:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:90:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:91:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:91:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:91:19 (method) len=4 "next" +// interfaces_iter_core.baml:92:9 (class) len=4 "Done" +// interfaces_iter_core.baml:92:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:93:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:93:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:93:16 (type) len=1 "T" +// interfaces_iter_core.baml:94:11 (keyword) len=2 "if" +// interfaces_iter_core.baml:94:15 (operator) len=1 "!" +// interfaces_iter_core.baml:94:16 (parameter) len=9 "predicate" +// interfaces_iter_core.baml:94:26 (variable) len=1 "x" +// interfaces_iter_core.baml:95:13 (keyword) len=6 "return" +// interfaces_iter_core.baml:95:20 (boolean) len=5 "false" +// interfaces_iter_core.baml:100:5 (boolean) len=4 "true" +// interfaces_iter_core.baml:103:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:103:12 (method) [declaration] len=4 "find" +// interfaces_iter_core.baml:103:16 (operator) len=1 "<" +// interfaces_iter_core.baml:103:17 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:103:19 (operator) len=1 ">" +// interfaces_iter_core.baml:103:21 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:103:27 (parameter) [declaration] len=9 "predicate" +// interfaces_iter_core.baml:103:39 (type) len=1 "T" +// interfaces_iter_core.baml:103:45 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:103:50 (keyword) len=6 "throws" +// interfaces_iter_core.baml:103:57 (type) len=2 "E2" +// interfaces_iter_core.baml:103:64 (type) len=1 "T" +// interfaces_iter_core.baml:103:67 (keyword) len=6 "throws" +// interfaces_iter_core.baml:103:74 (type) len=1 "E" +// interfaces_iter_core.baml:103:76 (operator) len=1 "|" +// interfaces_iter_core.baml:103:78 (type) len=2 "E2" +// interfaces_iter_core.baml:104:5 (keyword) len=5 "while" +// interfaces_iter_core.baml:104:12 (boolean) len=4 "true" +// interfaces_iter_core.baml:105:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:105:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:105:19 (method) len=4 "next" +// interfaces_iter_core.baml:106:9 (class) len=4 "Done" +// interfaces_iter_core.baml:106:19 (keyword) len=5 "break" +// interfaces_iter_core.baml:107:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:107:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:107:16 (type) len=1 "T" +// interfaces_iter_core.baml:108:11 (keyword) len=2 "if" +// interfaces_iter_core.baml:108:15 (parameter) len=9 "predicate" +// interfaces_iter_core.baml:108:25 (variable) len=1 "x" +// interfaces_iter_core.baml:109:13 (keyword) len=6 "return" +// interfaces_iter_core.baml:109:20 (variable) len=1 "x" +// interfaces_iter_core.baml:114:5 (type) [defaultLibrary] len=4 "null" +// interfaces_iter_core.baml:118:1 (keyword) len=8 "function" +// interfaces_iter_core.baml:118:10 (function) [declaration] len=7 "flatten" +// interfaces_iter_core.baml:118:17 (operator) len=1 "<" +// interfaces_iter_core.baml:118:18 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:118:21 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:118:24 (typeParameter) [declaration] len=2 "E3" +// interfaces_iter_core.baml:118:26 (operator) len=1 ">" +// interfaces_iter_core.baml:118:28 (parameter) [declaration] len=3 "src" +// interfaces_iter_core.baml:118:33 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:118:41 (operator) len=1 "<" +// interfaces_iter_core.baml:118:42 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:118:50 (operator) len=1 "<" +// interfaces_iter_core.baml:118:51 (type) len=1 "R" +// interfaces_iter_core.baml:118:54 (type) len=2 "E3" +// interfaces_iter_core.baml:118:56 (operator) len=1 ">" +// interfaces_iter_core.baml:118:59 (type) len=1 "E" +// interfaces_iter_core.baml:118:60 (operator) len=1 ">" +// interfaces_iter_core.baml:118:66 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:118:74 (operator) len=1 "<" +// interfaces_iter_core.baml:118:75 (type) len=1 "R" +// interfaces_iter_core.baml:118:78 (type) len=1 "E" +// interfaces_iter_core.baml:118:80 (operator) len=1 "|" +// interfaces_iter_core.baml:118:82 (type) len=2 "E3" +// interfaces_iter_core.baml:118:84 (operator) len=1 ">" +// interfaces_iter_core.baml:118:86 (keyword) len=6 "throws" +// interfaces_iter_core.baml:118:93 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:119:3 (class) len=7 "Flatten" +// interfaces_iter_core.baml:119:10 (operator) len=1 "<" +// interfaces_iter_core.baml:119:11 (type) len=1 "R" +// interfaces_iter_core.baml:119:14 (type) len=1 "E" +// interfaces_iter_core.baml:119:17 (type) len=2 "E3" +// interfaces_iter_core.baml:119:19 (operator) len=1 ">" +// interfaces_iter_core.baml:119:23 (property) len=4 "iter" +// interfaces_iter_core.baml:119:29 (parameter) len=3 "src" +// interfaces_iter_core.baml:119:34 (property) len=5 "inner" +// interfaces_iter_core.baml:119:41 (class) len=4 "Done" +// interfaces_iter_core.baml:122:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:122:7 (class) [declaration] len=13 "ArrayIterator" +// interfaces_iter_core.baml:122:20 (operator) len=1 "<" +// interfaces_iter_core.baml:122:21 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:122:22 (operator) len=1 ">" +// interfaces_iter_core.baml:123:3 (property) [declaration] len=3 "arr" +// interfaces_iter_core.baml:123:8 (type) len=1 "T" +// interfaces_iter_core.baml:124:3 (property) [declaration] len=3 "idx" +// interfaces_iter_core.baml:124:8 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:126:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:126:12 (method) [declaration] len=3 "new" +// interfaces_iter_core.baml:126:16 (parameter) [declaration] len=3 "arr" +// interfaces_iter_core.baml:126:21 (type) len=1 "T" +// interfaces_iter_core.baml:126:29 (class) len=13 "ArrayIterator" +// interfaces_iter_core.baml:126:42 (operator) len=1 "<" +// interfaces_iter_core.baml:126:43 (type) len=1 "T" +// interfaces_iter_core.baml:126:44 (operator) len=1 ">" +// interfaces_iter_core.baml:126:46 (keyword) len=6 "throws" +// interfaces_iter_core.baml:126:53 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:127:5 (class) len=13 "ArrayIterator" +// interfaces_iter_core.baml:127:18 (operator) len=1 "<" +// interfaces_iter_core.baml:127:19 (type) len=1 "T" +// interfaces_iter_core.baml:127:20 (operator) len=1 ">" +// interfaces_iter_core.baml:127:24 (property) len=3 "arr" +// interfaces_iter_core.baml:127:29 (parameter) len=3 "arr" +// interfaces_iter_core.baml:127:33 (method) len=5 "slice" +// interfaces_iter_core.baml:127:39 (number) len=1 "0" +// interfaces_iter_core.baml:127:42 (parameter) len=3 "arr" +// interfaces_iter_core.baml:127:46 (method) len=6 "length" +// interfaces_iter_core.baml:127:57 (property) len=3 "idx" +// interfaces_iter_core.baml:127:62 (number) len=1 "0" +// interfaces_iter_core.baml:130:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:130:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:130:22 (operator) len=1 "<" +// interfaces_iter_core.baml:130:23 (type) len=1 "T" +// interfaces_iter_core.baml:130:26 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:130:31 (operator) len=1 ">" +// interfaces_iter_core.baml:131:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:131:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:131:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:131:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:131:36 (operator) len=1 "<" +// interfaces_iter_core.baml:131:37 (type) len=1 "T" +// interfaces_iter_core.baml:131:40 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:131:45 (operator) len=1 ">" +// interfaces_iter_core.baml:131:47 (keyword) len=6 "throws" +// interfaces_iter_core.baml:131:54 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:131:62 (parameter) len=4 "self" +// interfaces_iter_core.baml:134:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:134:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:134:22 (operator) len=1 "<" +// interfaces_iter_core.baml:134:23 (type) len=1 "T" +// interfaces_iter_core.baml:134:26 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:134:31 (operator) len=1 ">" +// interfaces_iter_core.baml:135:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:135:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:135:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:135:28 (type) len=1 "T" +// interfaces_iter_core.baml:135:30 (operator) len=1 "|" +// interfaces_iter_core.baml:135:32 (class) len=4 "Done" +// interfaces_iter_core.baml:135:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:135:44 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:136:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:136:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:136:19 (property) len=3 "arr" +// interfaces_iter_core.baml:136:23 (method) len=2 "at" +// interfaces_iter_core.baml:136:26 (parameter) len=4 "self" +// interfaces_iter_core.baml:136:31 (property) len=3 "idx" +// interfaces_iter_core.baml:137:9 (type) [defaultLibrary] len=4 "null" +// interfaces_iter_core.baml:137:17 (class) len=4 "Done" +// interfaces_iter_core.baml:138:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:138:13 (variable) [declaration] len=4 "item" +// interfaces_iter_core.baml:138:19 (type) len=1 "T" +// interfaces_iter_core.baml:139:11 (parameter) len=4 "self" +// interfaces_iter_core.baml:139:16 (property) len=3 "idx" +// interfaces_iter_core.baml:139:20 (operator) len=2 "+=" +// interfaces_iter_core.baml:139:23 (number) len=1 "1" +// interfaces_iter_core.baml:140:11 (variable) len=4 "item" +// interfaces_iter_core.baml:147:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:147:7 (class) [declaration] len=5 "Range" +// interfaces_iter_core.baml:148:3 (property) [declaration] len=1 "i" +// interfaces_iter_core.baml:148:6 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:149:3 (property) [declaration] len=3 "max" +// interfaces_iter_core.baml:149:8 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:150:3 (property) [declaration] len=4 "step" +// interfaces_iter_core.baml:150:9 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:152:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:152:12 (method) [declaration] len=3 "new" +// interfaces_iter_core.baml:152:16 (parameter) [declaration] len=3 "min" +// interfaces_iter_core.baml:152:21 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:152:26 (parameter) [declaration] len=3 "max" +// interfaces_iter_core.baml:152:31 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:152:36 (parameter) [declaration] len=4 "step" +// interfaces_iter_core.baml:152:42 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:152:46 (operator) len=1 "=" +// interfaces_iter_core.baml:152:48 (number) len=1 "1" +// interfaces_iter_core.baml:152:54 (class) len=5 "Range" +// interfaces_iter_core.baml:152:60 (keyword) len=6 "throws" +// interfaces_iter_core.baml:152:67 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:153:5 (class) len=5 "Range" +// interfaces_iter_core.baml:153:13 (property) len=1 "i" +// interfaces_iter_core.baml:153:16 (parameter) len=3 "min" +// interfaces_iter_core.baml:153:21 (property) len=3 "max" +// interfaces_iter_core.baml:153:26 (parameter) len=3 "max" +// interfaces_iter_core.baml:153:31 (property) len=4 "step" +// interfaces_iter_core.baml:153:37 (parameter) len=4 "step" +// interfaces_iter_core.baml:156:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:156:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:156:22 (operator) len=1 "<" +// interfaces_iter_core.baml:156:23 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:156:28 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:156:33 (operator) len=1 ">" +// interfaces_iter_core.baml:157:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:157:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:157:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:157:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:157:36 (operator) len=1 "<" +// interfaces_iter_core.baml:157:37 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:157:42 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:157:47 (operator) len=1 ">" +// interfaces_iter_core.baml:157:49 (keyword) len=6 "throws" +// interfaces_iter_core.baml:157:56 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:157:64 (parameter) len=4 "self" +// interfaces_iter_core.baml:160:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:160:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:160:22 (operator) len=1 "<" +// interfaces_iter_core.baml:160:23 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:160:28 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:160:33 (operator) len=1 ">" +// interfaces_iter_core.baml:161:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:161:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:161:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:161:28 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:161:32 (operator) len=1 "|" +// interfaces_iter_core.baml:161:34 (class) len=4 "Done" +// interfaces_iter_core.baml:161:39 (keyword) len=6 "throws" +// interfaces_iter_core.baml:161:46 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:162:7 (keyword) len=2 "if" +// interfaces_iter_core.baml:162:11 (parameter) len=4 "self" +// interfaces_iter_core.baml:162:16 (property) len=1 "i" +// interfaces_iter_core.baml:162:18 (operator) len=1 "<" +// interfaces_iter_core.baml:162:20 (parameter) len=4 "self" +// interfaces_iter_core.baml:162:25 (property) len=3 "max" +// interfaces_iter_core.baml:163:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:163:13 (variable) [declaration] len=3 "cur" +// interfaces_iter_core.baml:163:17 (operator) len=1 "=" +// interfaces_iter_core.baml:163:19 (parameter) len=4 "self" +// interfaces_iter_core.baml:163:24 (property) len=1 "i" +// interfaces_iter_core.baml:164:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:164:14 (property) len=1 "i" +// interfaces_iter_core.baml:164:16 (operator) len=2 "+=" +// interfaces_iter_core.baml:164:19 (parameter) len=4 "self" +// interfaces_iter_core.baml:164:24 (property) len=4 "step" +// interfaces_iter_core.baml:165:9 (variable) len=3 "cur" +// interfaces_iter_core.baml:166:9 (keyword) len=4 "else" +// interfaces_iter_core.baml:167:9 (class) len=4 "Done" +// interfaces_iter_core.baml:173:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:173:7 (class) [declaration] len=6 "Repeat" +// interfaces_iter_core.baml:173:13 (operator) len=1 "<" +// interfaces_iter_core.baml:173:14 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:173:15 (operator) len=1 ">" +// interfaces_iter_core.baml:174:3 (property) [declaration] len=5 "value" +// interfaces_iter_core.baml:174:10 (type) len=1 "T" +// interfaces_iter_core.baml:175:3 (property) [declaration] len=5 "count" +// interfaces_iter_core.baml:175:10 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:177:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:177:12 (method) [declaration] len=3 "new" +// interfaces_iter_core.baml:177:16 (parameter) [declaration] len=5 "value" +// interfaces_iter_core.baml:177:23 (type) len=1 "T" +// interfaces_iter_core.baml:177:26 (parameter) [declaration] len=5 "count" +// interfaces_iter_core.baml:177:33 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:177:37 (operator) len=1 "=" +// interfaces_iter_core.baml:177:39 (operator) len=1 "-" +// interfaces_iter_core.baml:177:40 (number) len=1 "1" +// interfaces_iter_core.baml:177:46 (class) len=6 "Repeat" +// interfaces_iter_core.baml:177:52 (operator) len=1 "<" +// interfaces_iter_core.baml:177:53 (type) len=1 "T" +// interfaces_iter_core.baml:177:54 (operator) len=1 ">" +// interfaces_iter_core.baml:177:56 (keyword) len=6 "throws" +// interfaces_iter_core.baml:177:63 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:178:5 (class) len=6 "Repeat" +// interfaces_iter_core.baml:178:11 (operator) len=1 "<" +// interfaces_iter_core.baml:178:12 (type) len=1 "T" +// interfaces_iter_core.baml:178:13 (operator) len=1 ">" +// interfaces_iter_core.baml:178:17 (property) len=5 "value" +// interfaces_iter_core.baml:178:24 (parameter) len=5 "value" +// interfaces_iter_core.baml:178:31 (property) len=5 "count" +// interfaces_iter_core.baml:178:38 (parameter) len=5 "count" +// interfaces_iter_core.baml:181:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:181:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:181:22 (operator) len=1 "<" +// interfaces_iter_core.baml:181:23 (type) len=1 "T" +// interfaces_iter_core.baml:181:26 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:181:31 (operator) len=1 ">" +// interfaces_iter_core.baml:182:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:182:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:182:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:182:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:182:36 (operator) len=1 "<" +// interfaces_iter_core.baml:182:37 (type) len=1 "T" +// interfaces_iter_core.baml:182:40 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:182:45 (operator) len=1 ">" +// interfaces_iter_core.baml:182:47 (keyword) len=6 "throws" +// interfaces_iter_core.baml:182:54 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:182:62 (parameter) len=4 "self" +// interfaces_iter_core.baml:185:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:185:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:185:22 (operator) len=1 "<" +// interfaces_iter_core.baml:185:23 (type) len=1 "T" +// interfaces_iter_core.baml:185:26 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:185:31 (operator) len=1 ">" +// interfaces_iter_core.baml:186:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:186:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:186:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:186:28 (type) len=1 "T" +// interfaces_iter_core.baml:186:30 (operator) len=1 "|" +// interfaces_iter_core.baml:186:32 (class) len=4 "Done" +// interfaces_iter_core.baml:186:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:186:44 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:187:7 (keyword) len=2 "if" +// interfaces_iter_core.baml:187:11 (parameter) len=4 "self" +// interfaces_iter_core.baml:187:16 (property) len=5 "count" +// interfaces_iter_core.baml:187:22 (operator) len=1 "<" +// interfaces_iter_core.baml:187:24 (number) len=1 "0" +// interfaces_iter_core.baml:188:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:188:14 (property) len=5 "value" +// interfaces_iter_core.baml:189:9 (keyword) len=4 "else" +// interfaces_iter_core.baml:189:14 (keyword) len=2 "if" +// interfaces_iter_core.baml:189:18 (parameter) len=4 "self" +// interfaces_iter_core.baml:189:23 (property) len=5 "count" +// interfaces_iter_core.baml:189:29 (operator) len=1 ">" +// interfaces_iter_core.baml:189:31 (number) len=1 "0" +// interfaces_iter_core.baml:190:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:190:14 (property) len=5 "count" +// interfaces_iter_core.baml:190:20 (operator) len=2 "-=" +// interfaces_iter_core.baml:190:23 (number) len=1 "1" +// interfaces_iter_core.baml:191:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:191:14 (property) len=5 "value" +// interfaces_iter_core.baml:192:9 (keyword) len=4 "else" +// interfaces_iter_core.baml:193:9 (class) len=4 "Done" +// interfaces_iter_core.baml:199:1 (keyword) len=9 "interface" +// interfaces_iter_core.baml:199:11 (interface) [declaration] len=14 "OutOfBodyValue" +// interfaces_iter_core.baml:199:25 (operator) len=1 "<" +// interfaces_iter_core.baml:199:26 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:199:27 (operator) len=1 ">" +// interfaces_iter_core.baml:200:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:200:12 (method) [declaration] len=3 "get" +// interfaces_iter_core.baml:200:16 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:200:25 (type) len=1 "T" +// interfaces_iter_core.baml:200:27 (keyword) len=6 "throws" +// interfaces_iter_core.baml:200:34 (type) [defaultLibrary] len=7 "unknown" +// interfaces_iter_core.baml:203:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:203:7 (class) [declaration] len=12 "OutOfBodyBox" +// interfaces_iter_core.baml:203:19 (operator) len=1 "<" +// interfaces_iter_core.baml:203:20 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:203:21 (operator) len=1 ">" +// interfaces_iter_core.baml:204:3 (property) [declaration] len=5 "value" +// interfaces_iter_core.baml:204:10 (type) len=1 "T" +// interfaces_iter_core.baml:206:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:206:12 (method) [declaration] len=3 "new" +// interfaces_iter_core.baml:206:16 (parameter) [declaration] len=5 "value" +// interfaces_iter_core.baml:206:23 (type) len=1 "T" +// interfaces_iter_core.baml:206:29 (class) len=12 "OutOfBodyBox" +// interfaces_iter_core.baml:206:41 (operator) len=1 "<" +// interfaces_iter_core.baml:206:42 (type) len=1 "T" +// interfaces_iter_core.baml:206:43 (operator) len=1 ">" +// interfaces_iter_core.baml:206:45 (keyword) len=6 "throws" +// interfaces_iter_core.baml:206:52 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:207:5 (class) len=12 "OutOfBodyBox" +// interfaces_iter_core.baml:207:17 (operator) len=1 "<" +// interfaces_iter_core.baml:207:18 (type) len=1 "T" +// interfaces_iter_core.baml:207:19 (operator) len=1 ">" +// interfaces_iter_core.baml:207:23 (property) len=5 "value" +// interfaces_iter_core.baml:207:30 (parameter) len=5 "value" +// interfaces_iter_core.baml:211:1 (keyword) len=10 "implements" +// interfaces_iter_core.baml:211:11 (operator) len=1 "<" +// interfaces_iter_core.baml:211:12 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:211:13 (operator) len=1 ">" +// interfaces_iter_core.baml:211:15 (interface) len=14 "OutOfBodyValue" +// interfaces_iter_core.baml:211:29 (operator) len=1 "<" +// interfaces_iter_core.baml:211:30 (type) len=1 "T" +// interfaces_iter_core.baml:211:31 (operator) len=1 ">" +// interfaces_iter_core.baml:211:33 (keyword) len=3 "for" +// interfaces_iter_core.baml:211:37 (class) len=12 "OutOfBodyBox" +// interfaces_iter_core.baml:211:49 (operator) len=1 "<" +// interfaces_iter_core.baml:211:50 (type) len=1 "T" +// interfaces_iter_core.baml:211:51 (operator) len=1 ">" +// interfaces_iter_core.baml:212:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:212:12 (method) [declaration] len=3 "get" +// interfaces_iter_core.baml:212:16 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:212:25 (type) len=1 "T" +// interfaces_iter_core.baml:212:27 (keyword) len=6 "throws" +// interfaces_iter_core.baml:212:34 (type) [defaultLibrary] len=7 "unknown" +// interfaces_iter_core.baml:213:5 (parameter) len=4 "self" +// interfaces_iter_core.baml:213:10 (property) len=5 "value" +// interfaces_iter_core.baml:217:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:217:7 (class) [declaration] len=3 "Map" +// interfaces_iter_core.baml:217:10 (operator) len=1 "<" +// interfaces_iter_core.baml:217:11 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:217:14 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:217:17 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:217:20 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:217:22 (operator) len=1 ">" +// interfaces_iter_core.baml:218:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:218:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:218:17 (operator) len=1 "<" +// interfaces_iter_core.baml:218:18 (type) len=1 "T" +// interfaces_iter_core.baml:218:21 (type) len=1 "E" +// interfaces_iter_core.baml:218:22 (operator) len=1 ">" +// interfaces_iter_core.baml:219:3 (property) [declaration] len=4 "func" +// interfaces_iter_core.baml:219:10 (type) len=1 "T" +// interfaces_iter_core.baml:219:16 (type) len=1 "R" +// interfaces_iter_core.baml:219:18 (keyword) len=6 "throws" +// interfaces_iter_core.baml:219:25 (type) len=2 "E2" +// interfaces_iter_core.baml:221:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:221:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:221:22 (operator) len=1 "<" +// interfaces_iter_core.baml:221:23 (type) len=1 "R" +// interfaces_iter_core.baml:221:26 (type) len=1 "E" +// interfaces_iter_core.baml:221:28 (operator) len=1 "|" +// interfaces_iter_core.baml:221:30 (type) len=2 "E2" +// interfaces_iter_core.baml:221:32 (operator) len=1 ">" +// interfaces_iter_core.baml:222:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:222:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:222:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:222:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:222:36 (operator) len=1 "<" +// interfaces_iter_core.baml:222:37 (type) len=1 "R" +// interfaces_iter_core.baml:222:40 (type) len=1 "E" +// interfaces_iter_core.baml:222:42 (operator) len=1 "|" +// interfaces_iter_core.baml:222:44 (type) len=2 "E2" +// interfaces_iter_core.baml:222:46 (operator) len=1 ">" +// interfaces_iter_core.baml:222:48 (keyword) len=6 "throws" +// interfaces_iter_core.baml:222:55 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:222:63 (parameter) len=4 "self" +// interfaces_iter_core.baml:225:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:225:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:225:22 (operator) len=1 "<" +// interfaces_iter_core.baml:225:23 (type) len=1 "R" +// interfaces_iter_core.baml:225:26 (type) len=1 "E" +// interfaces_iter_core.baml:225:28 (operator) len=1 "|" +// interfaces_iter_core.baml:225:30 (type) len=2 "E2" +// interfaces_iter_core.baml:225:32 (operator) len=1 ">" +// interfaces_iter_core.baml:226:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:226:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:226:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:226:28 (type) len=1 "R" +// interfaces_iter_core.baml:226:30 (operator) len=1 "|" +// interfaces_iter_core.baml:226:32 (class) len=4 "Done" +// interfaces_iter_core.baml:226:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:226:44 (type) len=1 "E" +// interfaces_iter_core.baml:226:46 (operator) len=1 "|" +// interfaces_iter_core.baml:226:48 (type) len=2 "E2" +// interfaces_iter_core.baml:227:7 (keyword) len=5 "match" +// interfaces_iter_core.baml:227:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:227:19 (property) len=4 "iter" +// interfaces_iter_core.baml:227:24 (method) len=4 "next" +// interfaces_iter_core.baml:228:9 (class) len=4 "Done" +// interfaces_iter_core.baml:228:17 (class) len=4 "Done" +// interfaces_iter_core.baml:229:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:229:13 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:229:16 (type) len=1 "T" +// interfaces_iter_core.baml:229:21 (parameter) len=4 "self" +// interfaces_iter_core.baml:229:26 (property) len=4 "func" +// interfaces_iter_core.baml:229:31 (variable) len=1 "x" +// interfaces_iter_core.baml:235:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:235:7 (class) [declaration] len=6 "Filter" +// interfaces_iter_core.baml:235:13 (operator) len=1 "<" +// interfaces_iter_core.baml:235:14 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:235:17 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:235:20 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:235:22 (operator) len=1 ">" +// interfaces_iter_core.baml:236:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:236:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:236:17 (operator) len=1 "<" +// interfaces_iter_core.baml:236:18 (type) len=1 "T" +// interfaces_iter_core.baml:236:21 (type) len=1 "E" +// interfaces_iter_core.baml:236:22 (operator) len=1 ">" +// interfaces_iter_core.baml:237:3 (property) [declaration] len=9 "predicate" +// interfaces_iter_core.baml:237:15 (type) len=1 "T" +// interfaces_iter_core.baml:237:21 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:237:26 (keyword) len=6 "throws" +// interfaces_iter_core.baml:237:33 (type) len=2 "E2" +// interfaces_iter_core.baml:239:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:239:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:239:22 (operator) len=1 "<" +// interfaces_iter_core.baml:239:23 (type) len=1 "T" +// interfaces_iter_core.baml:239:26 (type) len=1 "E" +// interfaces_iter_core.baml:239:28 (operator) len=1 "|" +// interfaces_iter_core.baml:239:30 (type) len=2 "E2" +// interfaces_iter_core.baml:239:32 (operator) len=1 ">" +// interfaces_iter_core.baml:240:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:240:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:240:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:240:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:240:36 (operator) len=1 "<" +// interfaces_iter_core.baml:240:37 (type) len=1 "T" +// interfaces_iter_core.baml:240:40 (type) len=1 "E" +// interfaces_iter_core.baml:240:42 (operator) len=1 "|" +// interfaces_iter_core.baml:240:44 (type) len=2 "E2" +// interfaces_iter_core.baml:240:46 (operator) len=1 ">" +// interfaces_iter_core.baml:240:48 (keyword) len=6 "throws" +// interfaces_iter_core.baml:240:55 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:240:63 (parameter) len=4 "self" +// interfaces_iter_core.baml:243:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:243:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:243:22 (operator) len=1 "<" +// interfaces_iter_core.baml:243:23 (type) len=1 "T" +// interfaces_iter_core.baml:243:26 (type) len=1 "E" +// interfaces_iter_core.baml:243:28 (operator) len=1 "|" +// interfaces_iter_core.baml:243:30 (type) len=2 "E2" +// interfaces_iter_core.baml:243:32 (operator) len=1 ">" +// interfaces_iter_core.baml:244:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:244:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:244:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:244:28 (type) len=1 "T" +// interfaces_iter_core.baml:244:30 (operator) len=1 "|" +// interfaces_iter_core.baml:244:32 (class) len=4 "Done" +// interfaces_iter_core.baml:244:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:244:44 (type) len=1 "E" +// interfaces_iter_core.baml:244:46 (operator) len=1 "|" +// interfaces_iter_core.baml:244:48 (type) len=2 "E2" +// interfaces_iter_core.baml:245:7 (keyword) len=5 "while" +// interfaces_iter_core.baml:245:14 (boolean) len=4 "true" +// interfaces_iter_core.baml:246:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:246:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:246:21 (property) len=4 "iter" +// interfaces_iter_core.baml:246:26 (method) len=4 "next" +// interfaces_iter_core.baml:247:11 (class) len=4 "Done" +// interfaces_iter_core.baml:247:21 (keyword) len=6 "return" +// interfaces_iter_core.baml:247:28 (class) len=4 "Done" +// interfaces_iter_core.baml:248:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:248:15 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:248:18 (type) len=1 "T" +// interfaces_iter_core.baml:249:13 (keyword) len=2 "if" +// interfaces_iter_core.baml:249:17 (parameter) len=4 "self" +// interfaces_iter_core.baml:249:22 (property) len=9 "predicate" +// interfaces_iter_core.baml:249:32 (variable) len=1 "x" +// interfaces_iter_core.baml:250:15 (keyword) len=6 "return" +// interfaces_iter_core.baml:250:22 (variable) len=1 "x" +// interfaces_iter_core.baml:255:7 (class) len=4 "Done" +// interfaces_iter_core.baml:260:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:260:7 (class) [declaration] len=9 "FilterMap" +// interfaces_iter_core.baml:260:16 (operator) len=1 "<" +// interfaces_iter_core.baml:260:17 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:260:20 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:260:23 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:260:26 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:260:28 (operator) len=1 ">" +// interfaces_iter_core.baml:261:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:261:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:261:17 (operator) len=1 "<" +// interfaces_iter_core.baml:261:18 (type) len=1 "T" +// interfaces_iter_core.baml:261:21 (type) len=1 "E" +// interfaces_iter_core.baml:261:22 (operator) len=1 ">" +// interfaces_iter_core.baml:262:3 (property) [declaration] len=4 "func" +// interfaces_iter_core.baml:262:10 (type) len=1 "T" +// interfaces_iter_core.baml:262:16 (type) len=1 "R" +// interfaces_iter_core.baml:262:19 (keyword) len=6 "throws" +// interfaces_iter_core.baml:262:26 (type) len=2 "E2" +// interfaces_iter_core.baml:264:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:264:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:264:22 (operator) len=1 "<" +// interfaces_iter_core.baml:264:23 (type) len=1 "R" +// interfaces_iter_core.baml:264:26 (type) len=1 "E" +// interfaces_iter_core.baml:264:28 (operator) len=1 "|" +// interfaces_iter_core.baml:264:30 (type) len=2 "E2" +// interfaces_iter_core.baml:264:32 (operator) len=1 ">" +// interfaces_iter_core.baml:265:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:265:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:265:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:265:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:265:36 (operator) len=1 "<" +// interfaces_iter_core.baml:265:37 (type) len=1 "R" +// interfaces_iter_core.baml:265:40 (type) len=1 "E" +// interfaces_iter_core.baml:265:42 (operator) len=1 "|" +// interfaces_iter_core.baml:265:44 (type) len=2 "E2" +// interfaces_iter_core.baml:265:46 (operator) len=1 ">" +// interfaces_iter_core.baml:265:48 (keyword) len=6 "throws" +// interfaces_iter_core.baml:265:55 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:265:63 (parameter) len=4 "self" +// interfaces_iter_core.baml:268:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:268:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:268:22 (operator) len=1 "<" +// interfaces_iter_core.baml:268:23 (type) len=1 "R" +// interfaces_iter_core.baml:268:26 (type) len=1 "E" +// interfaces_iter_core.baml:268:28 (operator) len=1 "|" +// interfaces_iter_core.baml:268:30 (type) len=2 "E2" +// interfaces_iter_core.baml:268:32 (operator) len=1 ">" +// interfaces_iter_core.baml:269:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:269:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:269:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:269:28 (type) len=1 "R" +// interfaces_iter_core.baml:269:30 (operator) len=1 "|" +// interfaces_iter_core.baml:269:32 (class) len=4 "Done" +// interfaces_iter_core.baml:269:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:269:44 (type) len=1 "E" +// interfaces_iter_core.baml:269:46 (operator) len=1 "|" +// interfaces_iter_core.baml:269:48 (type) len=2 "E2" +// interfaces_iter_core.baml:270:7 (keyword) len=5 "while" +// interfaces_iter_core.baml:270:14 (boolean) len=4 "true" +// interfaces_iter_core.baml:271:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:271:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:271:21 (property) len=4 "iter" +// interfaces_iter_core.baml:271:26 (method) len=4 "next" +// interfaces_iter_core.baml:272:11 (class) len=4 "Done" +// interfaces_iter_core.baml:272:21 (keyword) len=6 "return" +// interfaces_iter_core.baml:272:28 (class) len=4 "Done" +// interfaces_iter_core.baml:273:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:273:15 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:273:18 (type) len=1 "T" +// interfaces_iter_core.baml:274:13 (keyword) len=5 "match" +// interfaces_iter_core.baml:274:20 (parameter) len=4 "self" +// interfaces_iter_core.baml:274:25 (property) len=4 "func" +// interfaces_iter_core.baml:274:30 (variable) len=1 "x" +// interfaces_iter_core.baml:275:15 (type) [defaultLibrary] len=4 "null" +// interfaces_iter_core.baml:276:15 (keyword) len=3 "let" +// interfaces_iter_core.baml:276:19 (variable) [declaration] len=1 "y" +// interfaces_iter_core.baml:276:22 (type) len=1 "R" +// interfaces_iter_core.baml:276:29 (keyword) len=6 "return" +// interfaces_iter_core.baml:276:36 (variable) len=1 "y" +// interfaces_iter_core.baml:281:7 (class) len=4 "Done" +// interfaces_iter_core.baml:286:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:286:7 (class) [declaration] len=7 "FlatMap" +// interfaces_iter_core.baml:286:14 (operator) len=1 "<" +// interfaces_iter_core.baml:286:15 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:286:18 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:286:21 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:286:24 (typeParameter) [declaration] len=2 "E2" +// interfaces_iter_core.baml:286:28 (typeParameter) [declaration] len=2 "E3" +// interfaces_iter_core.baml:286:30 (operator) len=1 ">" +// interfaces_iter_core.baml:287:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:287:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:287:17 (operator) len=1 "<" +// interfaces_iter_core.baml:287:18 (type) len=1 "T" +// interfaces_iter_core.baml:287:21 (type) len=1 "E" +// interfaces_iter_core.baml:287:22 (operator) len=1 ">" +// interfaces_iter_core.baml:288:3 (property) [declaration] len=4 "func" +// interfaces_iter_core.baml:288:10 (type) len=1 "T" +// interfaces_iter_core.baml:288:16 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:288:24 (operator) len=1 "<" +// interfaces_iter_core.baml:288:25 (type) len=1 "R" +// interfaces_iter_core.baml:288:28 (type) len=2 "E3" +// interfaces_iter_core.baml:288:30 (operator) len=1 ">" +// interfaces_iter_core.baml:288:32 (keyword) len=6 "throws" +// interfaces_iter_core.baml:288:39 (type) len=2 "E2" +// interfaces_iter_core.baml:289:3 (property) [declaration] len=5 "inner" +// interfaces_iter_core.baml:289:10 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:289:18 (operator) len=1 "<" +// interfaces_iter_core.baml:289:19 (type) len=1 "R" +// interfaces_iter_core.baml:289:22 (type) len=2 "E3" +// interfaces_iter_core.baml:289:24 (operator) len=1 ">" +// interfaces_iter_core.baml:289:26 (operator) len=1 "|" +// interfaces_iter_core.baml:289:28 (class) len=4 "Done" +// interfaces_iter_core.baml:291:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:291:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:291:22 (operator) len=1 "<" +// interfaces_iter_core.baml:291:23 (type) len=1 "R" +// interfaces_iter_core.baml:291:26 (type) len=1 "E" +// interfaces_iter_core.baml:291:28 (operator) len=1 "|" +// interfaces_iter_core.baml:291:30 (type) len=2 "E2" +// interfaces_iter_core.baml:291:33 (operator) len=1 "|" +// interfaces_iter_core.baml:291:35 (type) len=2 "E3" +// interfaces_iter_core.baml:291:37 (operator) len=1 ">" +// interfaces_iter_core.baml:292:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:292:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:292:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:292:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:292:36 (operator) len=1 "<" +// interfaces_iter_core.baml:292:37 (type) len=1 "R" +// interfaces_iter_core.baml:292:40 (type) len=1 "E" +// interfaces_iter_core.baml:292:42 (operator) len=1 "|" +// interfaces_iter_core.baml:292:44 (type) len=2 "E2" +// interfaces_iter_core.baml:292:47 (operator) len=1 "|" +// interfaces_iter_core.baml:292:49 (type) len=2 "E3" +// interfaces_iter_core.baml:292:51 (operator) len=1 ">" +// interfaces_iter_core.baml:292:53 (keyword) len=6 "throws" +// interfaces_iter_core.baml:292:60 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:292:68 (parameter) len=4 "self" +// interfaces_iter_core.baml:295:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:295:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:295:22 (operator) len=1 "<" +// interfaces_iter_core.baml:295:23 (type) len=1 "R" +// interfaces_iter_core.baml:295:26 (type) len=1 "E" +// interfaces_iter_core.baml:295:28 (operator) len=1 "|" +// interfaces_iter_core.baml:295:30 (type) len=2 "E2" +// interfaces_iter_core.baml:295:33 (operator) len=1 "|" +// interfaces_iter_core.baml:295:35 (type) len=2 "E3" +// interfaces_iter_core.baml:295:37 (operator) len=1 ">" +// interfaces_iter_core.baml:296:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:296:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:296:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:296:28 (type) len=1 "R" +// interfaces_iter_core.baml:296:30 (operator) len=1 "|" +// interfaces_iter_core.baml:296:32 (class) len=4 "Done" +// interfaces_iter_core.baml:296:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:296:44 (type) len=1 "E" +// interfaces_iter_core.baml:296:46 (operator) len=1 "|" +// interfaces_iter_core.baml:296:48 (type) len=2 "E2" +// interfaces_iter_core.baml:296:51 (operator) len=1 "|" +// interfaces_iter_core.baml:296:53 (type) len=2 "E3" +// interfaces_iter_core.baml:297:7 (keyword) len=5 "while" +// interfaces_iter_core.baml:297:14 (boolean) len=4 "true" +// interfaces_iter_core.baml:298:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:298:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:298:21 (property) len=5 "inner" +// interfaces_iter_core.baml:299:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:299:15 (variable) [declaration] len=3 "cur" +// interfaces_iter_core.baml:299:20 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:299:28 (operator) len=1 "<" +// interfaces_iter_core.baml:299:29 (type) len=1 "R" +// interfaces_iter_core.baml:299:32 (type) len=2 "E3" +// interfaces_iter_core.baml:299:34 (operator) len=1 ">" +// interfaces_iter_core.baml:300:13 (keyword) len=5 "match" +// interfaces_iter_core.baml:300:20 (variable) len=3 "cur" +// interfaces_iter_core.baml:300:24 (method) len=4 "next" +// interfaces_iter_core.baml:301:15 (class) len=4 "Done" +// interfaces_iter_core.baml:301:25 (parameter) len=4 "self" +// interfaces_iter_core.baml:301:30 (property) len=5 "inner" +// interfaces_iter_core.baml:301:36 (operator) len=1 "=" +// interfaces_iter_core.baml:301:38 (class) len=4 "Done" +// interfaces_iter_core.baml:302:15 (keyword) len=3 "let" +// interfaces_iter_core.baml:302:19 (variable) [declaration] len=1 "y" +// interfaces_iter_core.baml:302:22 (type) len=1 "R" +// interfaces_iter_core.baml:302:29 (keyword) len=6 "return" +// interfaces_iter_core.baml:302:36 (variable) len=1 "y" +// interfaces_iter_core.baml:305:11 (class) len=4 "Done" +// interfaces_iter_core.baml:306:13 (keyword) len=5 "match" +// interfaces_iter_core.baml:306:20 (parameter) len=4 "self" +// interfaces_iter_core.baml:306:25 (property) len=4 "iter" +// interfaces_iter_core.baml:306:30 (method) len=4 "next" +// interfaces_iter_core.baml:307:15 (class) len=4 "Done" +// interfaces_iter_core.baml:307:25 (keyword) len=6 "return" +// interfaces_iter_core.baml:307:32 (class) len=4 "Done" +// interfaces_iter_core.baml:308:15 (keyword) len=3 "let" +// interfaces_iter_core.baml:308:19 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:308:22 (type) len=1 "T" +// interfaces_iter_core.baml:309:17 (keyword) len=3 "let" +// interfaces_iter_core.baml:309:21 (variable) [declaration] len=2 "it" +// interfaces_iter_core.baml:309:24 (operator) len=1 "=" +// interfaces_iter_core.baml:309:26 (parameter) len=4 "self" +// interfaces_iter_core.baml:309:31 (property) len=4 "func" +// interfaces_iter_core.baml:309:36 (variable) len=1 "x" +// interfaces_iter_core.baml:309:39 (method) len=4 "iter" +// interfaces_iter_core.baml:310:17 (parameter) len=4 "self" +// interfaces_iter_core.baml:310:22 (property) len=5 "inner" +// interfaces_iter_core.baml:310:28 (operator) len=1 "=" +// interfaces_iter_core.baml:310:30 (variable) len=2 "it" +// interfaces_iter_core.baml:316:7 (class) len=4 "Done" +// interfaces_iter_core.baml:321:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:321:7 (class) [declaration] len=7 "Flatten" +// interfaces_iter_core.baml:321:14 (operator) len=1 "<" +// interfaces_iter_core.baml:321:15 (typeParameter) [declaration] len=1 "R" +// interfaces_iter_core.baml:321:18 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:321:21 (typeParameter) [declaration] len=2 "E3" +// interfaces_iter_core.baml:321:23 (operator) len=1 ">" +// interfaces_iter_core.baml:322:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:322:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:322:17 (operator) len=1 "<" +// interfaces_iter_core.baml:322:18 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:322:26 (operator) len=1 "<" +// interfaces_iter_core.baml:322:27 (type) len=1 "R" +// interfaces_iter_core.baml:322:30 (type) len=2 "E3" +// interfaces_iter_core.baml:322:32 (operator) len=1 ">" +// interfaces_iter_core.baml:322:35 (type) len=1 "E" +// interfaces_iter_core.baml:322:36 (operator) len=1 ">" +// interfaces_iter_core.baml:323:3 (property) [declaration] len=5 "inner" +// interfaces_iter_core.baml:323:10 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:323:18 (operator) len=1 "<" +// interfaces_iter_core.baml:323:19 (type) len=1 "R" +// interfaces_iter_core.baml:323:22 (type) len=2 "E3" +// interfaces_iter_core.baml:323:24 (operator) len=1 ">" +// interfaces_iter_core.baml:323:26 (operator) len=1 "|" +// interfaces_iter_core.baml:323:28 (class) len=4 "Done" +// interfaces_iter_core.baml:325:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:325:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:325:22 (operator) len=1 "<" +// interfaces_iter_core.baml:325:23 (type) len=1 "R" +// interfaces_iter_core.baml:325:26 (type) len=1 "E" +// interfaces_iter_core.baml:325:28 (operator) len=1 "|" +// interfaces_iter_core.baml:325:30 (type) len=2 "E3" +// interfaces_iter_core.baml:325:32 (operator) len=1 ">" +// interfaces_iter_core.baml:326:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:326:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:326:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:326:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:326:36 (operator) len=1 "<" +// interfaces_iter_core.baml:326:37 (type) len=1 "R" +// interfaces_iter_core.baml:326:40 (type) len=1 "E" +// interfaces_iter_core.baml:326:42 (operator) len=1 "|" +// interfaces_iter_core.baml:326:44 (type) len=2 "E3" +// interfaces_iter_core.baml:326:46 (operator) len=1 ">" +// interfaces_iter_core.baml:326:48 (keyword) len=6 "throws" +// interfaces_iter_core.baml:326:55 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:326:63 (parameter) len=4 "self" +// interfaces_iter_core.baml:329:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:329:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:329:22 (operator) len=1 "<" +// interfaces_iter_core.baml:329:23 (type) len=1 "R" +// interfaces_iter_core.baml:329:26 (type) len=1 "E" +// interfaces_iter_core.baml:329:28 (operator) len=1 "|" +// interfaces_iter_core.baml:329:30 (type) len=2 "E3" +// interfaces_iter_core.baml:329:32 (operator) len=1 ">" +// interfaces_iter_core.baml:330:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:330:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:330:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:330:28 (type) len=1 "R" +// interfaces_iter_core.baml:330:30 (operator) len=1 "|" +// interfaces_iter_core.baml:330:32 (class) len=4 "Done" +// interfaces_iter_core.baml:330:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:330:44 (type) len=1 "E" +// interfaces_iter_core.baml:330:46 (operator) len=1 "|" +// interfaces_iter_core.baml:330:48 (type) len=2 "E3" +// interfaces_iter_core.baml:331:7 (keyword) len=5 "while" +// interfaces_iter_core.baml:331:14 (boolean) len=4 "true" +// interfaces_iter_core.baml:332:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:332:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:332:21 (property) len=5 "inner" +// interfaces_iter_core.baml:333:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:333:15 (variable) [declaration] len=3 "cur" +// interfaces_iter_core.baml:333:20 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:333:28 (operator) len=1 "<" +// interfaces_iter_core.baml:333:29 (type) len=1 "R" +// interfaces_iter_core.baml:333:32 (type) len=2 "E3" +// interfaces_iter_core.baml:333:34 (operator) len=1 ">" +// interfaces_iter_core.baml:334:13 (keyword) len=5 "match" +// interfaces_iter_core.baml:334:20 (variable) len=3 "cur" +// interfaces_iter_core.baml:334:24 (method) len=4 "next" +// interfaces_iter_core.baml:335:15 (class) len=4 "Done" +// interfaces_iter_core.baml:335:25 (parameter) len=4 "self" +// interfaces_iter_core.baml:335:30 (property) len=5 "inner" +// interfaces_iter_core.baml:335:36 (operator) len=1 "=" +// interfaces_iter_core.baml:335:38 (class) len=4 "Done" +// interfaces_iter_core.baml:336:15 (keyword) len=3 "let" +// interfaces_iter_core.baml:336:19 (variable) [declaration] len=1 "y" +// interfaces_iter_core.baml:336:22 (type) len=1 "R" +// interfaces_iter_core.baml:336:29 (keyword) len=6 "return" +// interfaces_iter_core.baml:336:36 (variable) len=1 "y" +// interfaces_iter_core.baml:339:11 (class) len=4 "Done" +// interfaces_iter_core.baml:340:13 (keyword) len=5 "match" +// interfaces_iter_core.baml:340:20 (parameter) len=4 "self" +// interfaces_iter_core.baml:340:25 (property) len=4 "iter" +// interfaces_iter_core.baml:340:30 (method) len=4 "next" +// interfaces_iter_core.baml:341:15 (class) len=4 "Done" +// interfaces_iter_core.baml:341:25 (keyword) len=6 "return" +// interfaces_iter_core.baml:341:32 (class) len=4 "Done" +// interfaces_iter_core.baml:342:15 (keyword) len=3 "let" +// interfaces_iter_core.baml:342:19 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:342:22 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:342:30 (operator) len=1 "<" +// interfaces_iter_core.baml:342:31 (type) len=1 "R" +// interfaces_iter_core.baml:342:34 (type) len=2 "E3" +// interfaces_iter_core.baml:342:36 (operator) len=1 ">" +// interfaces_iter_core.baml:343:17 (keyword) len=3 "let" +// interfaces_iter_core.baml:343:21 (variable) [declaration] len=2 "it" +// interfaces_iter_core.baml:343:24 (operator) len=1 "=" +// interfaces_iter_core.baml:343:26 (variable) len=1 "x" +// interfaces_iter_core.baml:343:28 (method) len=4 "iter" +// interfaces_iter_core.baml:344:17 (parameter) len=4 "self" +// interfaces_iter_core.baml:344:22 (property) len=5 "inner" +// interfaces_iter_core.baml:344:28 (operator) len=1 "=" +// interfaces_iter_core.baml:344:30 (variable) len=2 "it" +// interfaces_iter_core.baml:350:7 (class) len=4 "Done" +// interfaces_iter_core.baml:355:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:355:7 (class) [declaration] len=8 "Peekable" +// interfaces_iter_core.baml:355:15 (operator) len=1 "<" +// interfaces_iter_core.baml:355:16 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:355:19 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:355:20 (operator) len=1 ">" +// interfaces_iter_core.baml:356:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:356:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:356:17 (operator) len=1 "<" +// interfaces_iter_core.baml:356:18 (type) len=1 "T" +// interfaces_iter_core.baml:356:21 (type) len=1 "E" +// interfaces_iter_core.baml:356:22 (operator) len=1 ">" +// interfaces_iter_core.baml:357:3 (property) [declaration] len=6 "buffer" +// interfaces_iter_core.baml:357:11 (type) len=1 "T" +// interfaces_iter_core.baml:357:13 (operator) len=1 "|" +// interfaces_iter_core.baml:357:15 (class) len=4 "Done" +// interfaces_iter_core.baml:358:3 (property) [declaration] len=10 "has_buffer" +// interfaces_iter_core.baml:358:15 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:360:3 (keyword) len=8 "function" +// interfaces_iter_core.baml:360:12 (method) [declaration] len=4 "peek" +// interfaces_iter_core.baml:360:17 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:360:26 (type) len=1 "T" +// interfaces_iter_core.baml:360:28 (operator) len=1 "|" +// interfaces_iter_core.baml:360:30 (class) len=4 "Done" +// interfaces_iter_core.baml:360:35 (keyword) len=6 "throws" +// interfaces_iter_core.baml:360:42 (type) len=1 "E" +// interfaces_iter_core.baml:361:5 (keyword) len=2 "if" +// interfaces_iter_core.baml:361:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:361:14 (property) len=10 "has_buffer" +// interfaces_iter_core.baml:362:7 (keyword) len=6 "return" +// interfaces_iter_core.baml:362:14 (parameter) len=4 "self" +// interfaces_iter_core.baml:362:19 (property) len=6 "buffer" +// interfaces_iter_core.baml:364:5 (keyword) len=3 "let" +// interfaces_iter_core.baml:364:9 (variable) [declaration] len=1 "v" +// interfaces_iter_core.baml:364:11 (operator) len=1 "=" +// interfaces_iter_core.baml:364:13 (parameter) len=4 "self" +// interfaces_iter_core.baml:364:18 (property) len=4 "iter" +// interfaces_iter_core.baml:364:23 (method) len=4 "next" +// interfaces_iter_core.baml:365:5 (parameter) len=4 "self" +// interfaces_iter_core.baml:365:10 (property) len=6 "buffer" +// interfaces_iter_core.baml:365:17 (operator) len=1 "=" +// interfaces_iter_core.baml:365:19 (variable) len=1 "v" +// interfaces_iter_core.baml:366:5 (parameter) len=4 "self" +// interfaces_iter_core.baml:366:10 (property) len=10 "has_buffer" +// interfaces_iter_core.baml:366:21 (operator) len=1 "=" +// interfaces_iter_core.baml:366:23 (boolean) len=4 "true" +// interfaces_iter_core.baml:367:5 (variable) len=1 "v" +// interfaces_iter_core.baml:370:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:370:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:370:22 (operator) len=1 "<" +// interfaces_iter_core.baml:370:23 (type) len=1 "T" +// interfaces_iter_core.baml:370:26 (type) len=1 "E" +// interfaces_iter_core.baml:370:27 (operator) len=1 ">" +// interfaces_iter_core.baml:371:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:371:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:371:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:371:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:371:36 (operator) len=1 "<" +// interfaces_iter_core.baml:371:37 (type) len=1 "T" +// interfaces_iter_core.baml:371:40 (type) len=1 "E" +// interfaces_iter_core.baml:371:41 (operator) len=1 ">" +// interfaces_iter_core.baml:371:43 (keyword) len=6 "throws" +// interfaces_iter_core.baml:371:50 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:371:58 (parameter) len=4 "self" +// interfaces_iter_core.baml:374:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:374:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:374:22 (operator) len=1 "<" +// interfaces_iter_core.baml:374:23 (type) len=1 "T" +// interfaces_iter_core.baml:374:26 (type) len=1 "E" +// interfaces_iter_core.baml:374:27 (operator) len=1 ">" +// interfaces_iter_core.baml:375:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:375:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:375:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:375:28 (type) len=1 "T" +// interfaces_iter_core.baml:375:30 (operator) len=1 "|" +// interfaces_iter_core.baml:375:32 (class) len=4 "Done" +// interfaces_iter_core.baml:375:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:375:44 (type) len=1 "E" +// interfaces_iter_core.baml:376:7 (keyword) len=2 "if" +// interfaces_iter_core.baml:376:11 (parameter) len=4 "self" +// interfaces_iter_core.baml:376:16 (property) len=10 "has_buffer" +// interfaces_iter_core.baml:377:9 (keyword) len=3 "let" +// interfaces_iter_core.baml:377:13 (variable) [declaration] len=1 "v" +// interfaces_iter_core.baml:377:15 (operator) len=1 "=" +// interfaces_iter_core.baml:377:17 (parameter) len=4 "self" +// interfaces_iter_core.baml:377:22 (property) len=6 "buffer" +// interfaces_iter_core.baml:378:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:378:14 (property) len=6 "buffer" +// interfaces_iter_core.baml:378:21 (operator) len=1 "=" +// interfaces_iter_core.baml:378:23 (class) len=4 "Done" +// interfaces_iter_core.baml:379:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:379:14 (property) len=10 "has_buffer" +// interfaces_iter_core.baml:379:25 (operator) len=1 "=" +// interfaces_iter_core.baml:379:27 (boolean) len=5 "false" +// interfaces_iter_core.baml:380:9 (keyword) len=6 "return" +// interfaces_iter_core.baml:380:16 (variable) len=1 "v" +// interfaces_iter_core.baml:382:7 (parameter) len=4 "self" +// interfaces_iter_core.baml:382:12 (property) len=4 "iter" +// interfaces_iter_core.baml:382:17 (method) len=4 "next" +// interfaces_iter_core.baml:387:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:387:7 (class) [declaration] len=6 "StepBy" +// interfaces_iter_core.baml:387:13 (operator) len=1 "<" +// interfaces_iter_core.baml:387:14 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:387:17 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:387:18 (operator) len=1 ">" +// interfaces_iter_core.baml:388:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:388:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:388:17 (operator) len=1 "<" +// interfaces_iter_core.baml:388:18 (type) len=1 "T" +// interfaces_iter_core.baml:388:21 (type) len=1 "E" +// interfaces_iter_core.baml:388:22 (operator) len=1 ">" +// interfaces_iter_core.baml:389:3 (property) [declaration] len=1 "n" +// interfaces_iter_core.baml:389:6 (type) [defaultLibrary] len=3 "int" +// interfaces_iter_core.baml:390:3 (property) [declaration] len=5 "first" +// interfaces_iter_core.baml:390:10 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:392:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:392:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:392:22 (operator) len=1 "<" +// interfaces_iter_core.baml:392:23 (type) len=1 "T" +// interfaces_iter_core.baml:392:26 (type) len=1 "E" +// interfaces_iter_core.baml:392:27 (operator) len=1 ">" +// interfaces_iter_core.baml:393:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:393:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:393:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:393:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:393:36 (operator) len=1 "<" +// interfaces_iter_core.baml:393:37 (type) len=1 "T" +// interfaces_iter_core.baml:393:40 (type) len=1 "E" +// interfaces_iter_core.baml:393:41 (operator) len=1 ">" +// interfaces_iter_core.baml:393:43 (keyword) len=6 "throws" +// interfaces_iter_core.baml:393:50 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:393:58 (parameter) len=4 "self" +// interfaces_iter_core.baml:396:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:396:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:396:22 (operator) len=1 "<" +// interfaces_iter_core.baml:396:23 (type) len=1 "T" +// interfaces_iter_core.baml:396:26 (type) len=1 "E" +// interfaces_iter_core.baml:396:27 (operator) len=1 ">" +// interfaces_iter_core.baml:397:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:397:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:397:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:397:28 (type) len=1 "T" +// interfaces_iter_core.baml:397:30 (operator) len=1 "|" +// interfaces_iter_core.baml:397:32 (class) len=4 "Done" +// interfaces_iter_core.baml:397:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:397:44 (type) len=1 "E" +// interfaces_iter_core.baml:398:7 (keyword) len=2 "if" +// interfaces_iter_core.baml:398:11 (parameter) len=4 "self" +// interfaces_iter_core.baml:398:16 (property) len=5 "first" +// interfaces_iter_core.baml:399:9 (parameter) len=4 "self" +// interfaces_iter_core.baml:399:14 (property) len=5 "first" +// interfaces_iter_core.baml:399:20 (operator) len=1 "=" +// interfaces_iter_core.baml:399:22 (boolean) len=5 "false" +// interfaces_iter_core.baml:400:9 (keyword) len=6 "return" +// interfaces_iter_core.baml:400:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:400:21 (property) len=4 "iter" +// interfaces_iter_core.baml:400:26 (method) len=4 "next" +// interfaces_iter_core.baml:402:7 (keyword) len=3 "for" +// interfaces_iter_core.baml:402:12 (keyword) len=3 "let" +// interfaces_iter_core.baml:402:16 (variable) [declaration] len=1 "i" +// interfaces_iter_core.baml:402:18 (operator) len=1 "=" +// interfaces_iter_core.baml:402:20 (number) len=1 "0" +// interfaces_iter_core.baml:402:23 (variable) len=1 "i" +// interfaces_iter_core.baml:402:25 (operator) len=1 "<" +// interfaces_iter_core.baml:402:27 (parameter) len=4 "self" +// interfaces_iter_core.baml:402:32 (property) len=1 "n" +// interfaces_iter_core.baml:402:34 (operator) len=1 "-" +// interfaces_iter_core.baml:402:36 (number) len=1 "1" +// interfaces_iter_core.baml:402:39 (variable) len=1 "i" +// interfaces_iter_core.baml:402:41 (operator) len=2 "+=" +// interfaces_iter_core.baml:402:44 (number) len=1 "1" +// interfaces_iter_core.baml:403:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:403:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:403:21 (property) len=4 "iter" +// interfaces_iter_core.baml:403:26 (method) len=4 "next" +// interfaces_iter_core.baml:404:11 (class) len=4 "Done" +// interfaces_iter_core.baml:404:21 (keyword) len=6 "return" +// interfaces_iter_core.baml:404:28 (class) len=4 "Done" +// interfaces_iter_core.baml:405:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:405:15 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:405:18 (type) len=1 "T" +// interfaces_iter_core.baml:408:7 (parameter) len=4 "self" +// interfaces_iter_core.baml:408:12 (property) len=4 "iter" +// interfaces_iter_core.baml:408:17 (method) len=4 "next" +// interfaces_iter_core.baml:413:1 (keyword) len=5 "class" +// interfaces_iter_core.baml:413:7 (class) [declaration] len=5 "Chain" +// interfaces_iter_core.baml:413:12 (operator) len=1 "<" +// interfaces_iter_core.baml:413:13 (typeParameter) [declaration] len=1 "T" +// interfaces_iter_core.baml:413:16 (typeParameter) [declaration] len=1 "E" +// interfaces_iter_core.baml:413:17 (operator) len=1 ">" +// interfaces_iter_core.baml:414:3 (property) [declaration] len=4 "iter" +// interfaces_iter_core.baml:414:9 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:414:17 (operator) len=1 "<" +// interfaces_iter_core.baml:414:18 (type) len=1 "T" +// interfaces_iter_core.baml:414:21 (type) len=1 "E" +// interfaces_iter_core.baml:414:22 (operator) len=1 ">" +// interfaces_iter_core.baml:415:3 (property) [declaration] len=5 "other" +// interfaces_iter_core.baml:415:10 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:415:18 (operator) len=1 "<" +// interfaces_iter_core.baml:415:19 (type) len=1 "T" +// interfaces_iter_core.baml:415:22 (type) len=1 "E" +// interfaces_iter_core.baml:415:23 (operator) len=1 ">" +// interfaces_iter_core.baml:416:3 (property) [declaration] len=10 "first_done" +// interfaces_iter_core.baml:416:15 (type) [defaultLibrary] len=4 "bool" +// interfaces_iter_core.baml:418:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:418:14 (interface) len=8 "Iterable" +// interfaces_iter_core.baml:418:22 (operator) len=1 "<" +// interfaces_iter_core.baml:418:23 (type) len=1 "T" +// interfaces_iter_core.baml:418:26 (type) len=1 "E" +// interfaces_iter_core.baml:418:27 (operator) len=1 ">" +// interfaces_iter_core.baml:419:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:419:14 (method) [declaration] len=4 "iter" +// interfaces_iter_core.baml:419:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:419:28 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:419:36 (operator) len=1 "<" +// interfaces_iter_core.baml:419:37 (type) len=1 "T" +// interfaces_iter_core.baml:419:40 (type) len=1 "E" +// interfaces_iter_core.baml:419:41 (operator) len=1 ">" +// interfaces_iter_core.baml:419:43 (keyword) len=6 "throws" +// interfaces_iter_core.baml:419:50 (type) [defaultLibrary] len=5 "never" +// interfaces_iter_core.baml:419:58 (parameter) len=4 "self" +// interfaces_iter_core.baml:422:3 (keyword) len=10 "implements" +// interfaces_iter_core.baml:422:14 (interface) len=8 "Iterator" +// interfaces_iter_core.baml:422:22 (operator) len=1 "<" +// interfaces_iter_core.baml:422:23 (type) len=1 "T" +// interfaces_iter_core.baml:422:26 (type) len=1 "E" +// interfaces_iter_core.baml:422:27 (operator) len=1 ">" +// interfaces_iter_core.baml:423:5 (keyword) len=8 "function" +// interfaces_iter_core.baml:423:14 (method) [declaration] len=4 "next" +// interfaces_iter_core.baml:423:19 (parameter) [declaration] len=4 "self" +// interfaces_iter_core.baml:423:28 (type) len=1 "T" +// interfaces_iter_core.baml:423:30 (operator) len=1 "|" +// interfaces_iter_core.baml:423:32 (class) len=4 "Done" +// interfaces_iter_core.baml:423:37 (keyword) len=6 "throws" +// interfaces_iter_core.baml:423:44 (type) len=1 "E" +// interfaces_iter_core.baml:424:7 (keyword) len=2 "if" +// interfaces_iter_core.baml:424:11 (operator) len=1 "!" +// interfaces_iter_core.baml:424:12 (parameter) len=4 "self" +// interfaces_iter_core.baml:424:17 (property) len=10 "first_done" +// interfaces_iter_core.baml:425:9 (keyword) len=5 "match" +// interfaces_iter_core.baml:425:16 (parameter) len=4 "self" +// interfaces_iter_core.baml:425:21 (property) len=4 "iter" +// interfaces_iter_core.baml:425:26 (method) len=4 "next" +// interfaces_iter_core.baml:426:11 (class) len=4 "Done" +// interfaces_iter_core.baml:426:21 (parameter) len=4 "self" +// interfaces_iter_core.baml:426:26 (property) len=10 "first_done" +// interfaces_iter_core.baml:426:37 (operator) len=1 "=" +// interfaces_iter_core.baml:426:39 (boolean) len=4 "true" +// interfaces_iter_core.baml:427:11 (keyword) len=3 "let" +// interfaces_iter_core.baml:427:15 (variable) [declaration] len=1 "x" +// interfaces_iter_core.baml:427:18 (type) len=1 "T" +// interfaces_iter_core.baml:427:25 (keyword) len=6 "return" +// interfaces_iter_core.baml:427:32 (variable) len=1 "x" +// interfaces_iter_core.baml:430:7 (parameter) len=4 "self" +// interfaces_iter_core.baml:430:12 (property) len=5 "other" +// interfaces_iter_core.baml:430:18 (method) len=4 "next" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml new file mode 100644 index 0000000000..b0505d2473 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml @@ -0,0 +1,1392 @@ +// Tests for the `Comparable` interface (stdlib `comparable.baml`) and the +// `Sortable`-based array sort built on top of it. +// +// Phase 2 of thoughts/sam-projects/array-sort/01b-option-5-tdd-plan.md +// (float semantics updated by the 02 follow-up): builtin impls for +// int/float/bigint/string, `type CompareError = never` for all four — float +// orders by IEEE 754 totalOrder (`f64::total_cmp`), so NaN has a defined +// position and `compare` never throws. + +// NB on shape: receivers are *annotated* test-block locals and arguments are +// literals (or inline calls). The annotation widens the receiver's literal +// type — `(5).compare(3)` would bind `Self` to the literal type `5` and +// reject `3` — and literal arguments widen into `Self` fine. Arguments must +// not be test-block locals: a local passed as the `other` argument of a +// two-`Self` interface method arrives boxed in a `test` block (pre-existing +// VM quirk, see the user-class section note below) and the comparison op +// rejects the box. Receiver-position locals unbox fine. + +test "comparable_int_compare" { + let five: int = 5; + let three: int = 3; + assert.is_true(five.compare(3) > 0); + assert.is_true(three.compare(5) < 0); + assert.is_true(three.compare(3) == 0) +} + +test "comparable_string_compare" { + // Annotated receivers widen the literal types ("a".compare("b") would + // bind `Self` to the literal type "a" and reject "b"); literal arguments + // widen into `Self` fine. + let a: string = "a"; + let b: string = "b"; + let aa: string = "aa"; + assert.is_true(a.compare("b") < 0); + assert.is_true(b.compare("a") > 0); + assert.is_true(aa.compare("a") > 0); + assert.is_true(a.compare("a") == 0) +} + +test "comparable_bigint_compare" { + let one: bigint = 1n; + let two: bigint = 2n; + assert.is_true(two.compare(1n) > 0); + assert.is_true(one.compare(2n) < 0); + assert.is_true(two.compare(2n) == 0) +} + +test "comparable_float_compare" { + // Same literal-type widening dance as the string test above. + let lo: float = 1.5; + let hi: float = 2.5; + assert.is_true(hi.compare(1.5) > 0); + assert.is_true(lo.compare(2.5) < 0); + assert.is_true(lo.compare(1.5) == 0) +} + +// DECISION TEST (02-plan Phase 3, reverses the 01b NaN decision): float +// comparison no longer throws on NaN — `total_cmp` orders NaN after +inf +// (`… < +inf < +NaN`) and equal to itself. +test "comparable_float_nan_total_order" { + let one: float = 1.0; + assert.is_true(one.compare(float.nan()) < 0); + assert.is_true(float.nan().compare(1.0) > 0); + assert.is_true(float.nan().compare(float.inf()) > 0); + assert.is_true(float.nan().compare(float.nan()) == 0) +} + +// ─── user classes opting in ────────────────────────────────────────────────── +// +// KNOWN VM BUG (pre-existing, not Comparable-specific): a class instance read +// back from a *test-block local* stays boxed, and passing a boxed value to a +// two-`Self`-param interface method (`compare(self, other: Self)`) panics the +// VM with "unreachable code executed". The same calls work from ordinary +// functions. Workaround used throughout: construct instances at the call +// boundary (inline arguments), never via test-block `let`. + +// Total-order user type: binds `type CompareError = never` and writes the +// matching `throws never` (an omitted `throws` is inferred, not `never`, and +// fails conformance E0120). +class ComparableScore { + points int + implements baml.Comparable { + type CompareError = never + function compare(self, other: Self) -> int throws never { + self.points.compare(other.points) + } + } +} + +test "comparable_user_class_default_cmperror_is_never" { + assert.is_true(ComparableScore { points: 9 }.compare(ComparableScore { points: 1 }) > 0); + assert.is_true(ComparableScore { points: 1 }.compare(ComparableScore { points: 9 }) < 0); + assert.is_true(ComparableScore { points: 1 }.compare(ComparableScore { points: 1 }) == 0) +} + +// Fallible comparator: binds `type CompareError = ComparableCompareError` and throws. +class ComparableCompareError { + message string +} + +class ComparableFlaky { + value int? + implements baml.Comparable { + type CompareError = ComparableCompareError + + function compare(self, other: Self) -> int throws ComparableCompareError { + if let a: int = self.value { + if let b: int = other.value { + return a.compare(b) + } + } + throw ComparableCompareError { message: "cannot compare null" } + } + } +} + +// The fallible comparator's happy path: both values present, delegates to +// the builtin `int.compare` from inside the impl body. The catch value is +// compared inline (a catch result stored in a test-block `let` stays boxed). +test "comparable_user_class_fallible_happy_path" { + assert.is_true((ComparableFlaky { value: 1 }.compare(ComparableFlaky { value: 2 }) catch (e) { + ComparableCompareError => 99 + }) < 0) +} + +test "comparable_user_class_custom_cmperror_propagates" { + let msg = { + let v = ComparableFlaky { value: 1 }.compare(ComparableFlaky { value: null }); + "no throw" + } catch (e) { + ComparableCompareError => e.message + }; + assert.is_true(msg.matches("cannot compare null")) +} + +// ─── Sortable: `sort` (Phase 3 — new path alongside the old `sort`) ───────── +// +// Parity with the Phase 0 `sort()` corpus. These exercise `sort()` on *local* +// array receivers (`xs.sort()`). +// +// NB: these run the sort on a *local* receiver rather than through a +// `sort_ints(xs)` helper. Passing a test-block `let` local to a function +// delivers it as `Null` inside the callee — a pre-existing VM quirk of `test` +// blocks (see the `arrays.baml` header note), unrelated to sort. Param-receiver +// dispatch itself works in real functions (Rust `phase3_*` tests). The helper +// functions below are still *declared* (and compile) to pin the `throws never` +// normalization for parameter receivers at compile time. + +function sort_ints(xs: int[]) -> int[] throws never { xs.sort() } +function sort_strings(xs: string[]) -> string[] throws never { xs.sort() } +function sort_bigints(xs: bigint[]) -> bigint[] throws never { xs.sort() } + +test "sort_ints_in_place_returns_self" { + let xs = [3, 1, 2]; + let result = xs.sort(); + let expected = [1, 2, 3]; + assert.is_true(result == xs); + assert.is_true(baml.deep_equals(xs, expected)) +} + +test "sort_empty_is_noop" { + let xs: int[] = []; + let result = xs.sort(); + let expected: int[] = []; + assert.is_true(result == xs); + assert.is_true(baml.deep_equals(xs, expected)) +} + +test "sort_duplicates" { + let xs = [3, 1, 2, 1, 3]; + xs.sort(); + let expected = [1, 1, 2, 3, 3]; + assert.is_true(baml.deep_equals(xs, expected)) +} + +test "sort_strings_match_sort" { + let xs = ["b", "a", "aa"]; + xs.sort(); + let expected = ["a", "aa", "b"]; + assert.is_true(baml.deep_equals(xs, expected)) +} + +test "sort_bigints_match_sort" { + let xs = [3n, 1n, 2n]; + xs.sort(); + let expected = [1n, 2n, 3n]; + assert.is_true(baml.deep_equals(xs, expected)) +} + +// float's SortError is `never` (total_cmp decision) — infallible like int. +function sort_floats(xs: float[]) -> float[] throws never { + xs.sort() +} + +test "sort_floats_match_sort" { + let xs = [2.5, 0.5, 1.5]; + xs.sort(); + let expected = [0.5, 1.5, 2.5]; + assert.is_true(baml.deep_equals(xs, expected)) +} + +// DECISION TEST (02-plan Phase 3): NaN no longer throws — `total_cmp` is a +// total order over all doubles, so NaN sorts deterministically after +inf. +test "sort_floats_nan_sorts_last" { + let xs = [1.0, float.nan(), 0.5]; + xs.sort(); + assert.is_true(baml.deep_equals(xs.length(), 3)); + assert.equal(xs.at(0), 0.5); + assert.equal(xs.at(1), 1.0); + // NaN != NaN under `==`; assert positionally via is_nan. + let last = xs.at(2); + match (last) { + null => assert.is_true(false) + let f: float => assert.is_true(f.is_nan()) + } +} + +// User class with an infallible (`never`) CompareError sorts by its compare — +// stably, in place, returning self. +class SortableItem { + rank int + label string + implements baml.Comparable { + type CompareError = never + function compare(self, other: Self) -> int throws never { + self.rank.compare(other.rank) + } + } +} + +// `sort_items` is declared (and compiles) to pin the `throws never` +// normalization for an infallible user `Comparable` at compile time; the +// runtime tests below dispatch on local receivers (see the param-receiver +// limitation note above). +function sort_items(xs: SortableItem[]) -> SortableItem[] throws never { + xs.sort() +} + +test "sort_user_class_sorts_by_compare" { + let xs = [ + SortableItem { rank: 3, label: "c" }, + SortableItem { rank: 1, label: "a" }, + SortableItem { rank: 2, label: "b" } + ]; + let result = xs.sort(); + assert.is_true(result == xs); + let labels = xs.map((x: SortableItem) -> string { x.label }); + let expected = ["a", "b", "c"]; + assert.is_true(baml.deep_equals(labels, expected)) +} + +test "sort_user_class_is_stable" { + let xs = [ + SortableItem { rank: 2, label: "a" }, + SortableItem { rank: 1, label: "b" }, + SortableItem { rank: 2, label: "c" }, + SortableItem { rank: 1, label: "d" } + ]; + xs.sort(); + let labels = xs.map((x: SortableItem) -> string { x.label }); + let expected = ["b", "d", "a", "c"]; + assert.is_true(baml.deep_equals(labels, expected)) +} + +// Fallible comparator (CompareError = ComparableCompareError): the call site must +// handle it, and a throw mid-sort leaves the array in pre-sort state. +function sort_flaky(xs: ComparableFlaky[]) -> ComparableFlaky[] throws ComparableCompareError { + xs.sort() +} + +test "sort_fallible_comparator_throw_rolls_back" { + let xs = [ + ComparableFlaky { value: 3 }, + ComparableFlaky { value: null }, + ComparableFlaky { value: 1 } + ]; + let msg = { + sort_flaky(xs); + "no throw" + } catch (e) { + ComparableCompareError => e.message + }; + assert.is_true(msg.matches("cannot compare null")); + // rollback: original order intact + let vals = xs.map((x: ComparableFlaky) -> int { + if let v: int = x.value { v } else { -1 } + }); + let expected = [3, -1, 1]; + assert.is_true(baml.deep_equals(vals, expected)) +} + +test "sort_fallible_comparator_happy_path" { + let xs = [ + ComparableFlaky { value: 3 }, + ComparableFlaky { value: 1 }, + ComparableFlaky { value: 2 } + ]; + // No-throw contract: all values present, so the comparator never fails. + // Asserted inline — a catch result stored in a test-block `let` stays + // boxed (same VM quirk as above) and `== false` would reject the box. + assert.is_true(({ + sort_flaky(xs); + false + } catch (e) { + ComparableCompareError => true + }) == false); + let vals = xs.map((x: ComparableFlaky) -> int { + if let v: int = x.value { v } else { -1 } + }); + let expected = [1, 2, 3]; + assert.is_true(baml.deep_equals(vals, expected)) +} + +// Generic propagation: a function over `U extends Comparable` may call +// `xs.sort()`, propagating `U.CompareError` symbolically; the test routes +// through it to pin the runtime instantiation too. The array is built in a +// wrapper *function* — a test-block local passed to a generic function +// arrives boxed (the VM quirk above) and the native sort rejects the box. +function sort_generic(xs: U[]) -> U[] throws U.CompareError { + xs.sort() +} + +function run_sort_generic_ints() -> int[] throws never { + let xs = [3, 1, 2]; + sort_generic(xs) +} + +test "sort_generic_propagation" { + let result = run_sort_generic_ints(); + let expected = [1, 2, 3]; + assert.is_true(baml.deep_equals(result, expected)) +} + +// ─── out-of-body `implements baml.Comparable for ` ─────────────────── +// +// The impl methods register under the synthetic `Comparable$for$` +// name (as spelled at the impl site), in this file's namespace. Pins that +// `_compare_shim`'s runtime dispatch finds them for class elements — the +// namespaced complement to the flat-package Rust test +// (`sort_user_class_with_out_of_body_comparable_impl`). +class OutOfBodyScore { + points int +} + +implements baml.Comparable for OutOfBodyScore { + type CompareError = never + function compare(self, other: Self) -> int throws never { + self.points.compare(other.points) + } +} + +test "sort_user_class_out_of_body_impl" { + let xs = [ + OutOfBodyScore { points: 3 }, + OutOfBodyScore { points: 1 }, + OutOfBodyScore { points: 2 } + ]; + xs.sort(); + let pts = xs.map((x: OutOfBodyScore) -> int { x.points }); + let expected = [1, 2, 3]; + assert.is_true(baml.deep_equals(pts, expected)) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// interfaces_sort_comparable.baml:1:1 (comment) len=74 "// Tests for the `Comparable` interface (stdlib `comparable.baml`) and the" +// interfaces_sort_comparable.baml:2:1 (comment) len=50 "// `Sortable`-based array sort built on top of it." +// interfaces_sort_comparable.baml:3:1 (comment) len=2 "//" +// interfaces_sort_comparable.baml:4:1 (comment) len=71 "// Phase 2 of thoughts/sam-projects/array-sort/01b-option-5-tdd-plan.md" +// interfaces_sort_comparable.baml:5:1 (comment) len=67 "// (float semantics updated by the 02 follow-up): builtin impls for" +// interfaces_sort_comparable.baml:6:1 (comment) len=78 "// int/float/bigint/string, `type CompareError = never` for all four — float" +// interfaces_sort_comparable.baml:7:1 (comment) len=73 "// orders by IEEE 754 totalOrder (`f64::total_cmp`), so NaN has a defined" +// interfaces_sort_comparable.baml:8:1 (comment) len=39 "// position and `compare` never throws." +// interfaces_sort_comparable.baml:10:1 (comment) len=77 "// NB on shape: receivers are *annotated* test-block locals and arguments are" +// interfaces_sort_comparable.baml:11:1 (comment) len=75 "// literals (or inline calls). The annotation widens the receiver's literal" +// interfaces_sort_comparable.baml:12:1 (comment) len=74 "// type — `(5).compare(3)` would bind `Self` to the literal type `5` and" +// interfaces_sort_comparable.baml:13:1 (comment) len=78 "// reject `3` — and literal arguments widen into `Self` fine. Arguments must" +// interfaces_sort_comparable.baml:14:1 (comment) len=72 "// not be test-block locals: a local passed as the `other` argument of a" +// interfaces_sort_comparable.baml:15:1 (comment) len=76 "// two-`Self` interface method arrives boxed in a `test` block (pre-existing" +// interfaces_sort_comparable.baml:16:1 (comment) len=73 "// VM quirk, see the user-class section note below) and the comparison op" +// interfaces_sort_comparable.baml:17:1 (comment) len=56 "// rejects the box. Receiver-position locals unbox fine." +// interfaces_sort_comparable.baml:19:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:19:6 (string) len=24 "\"comparable_int_compare\"" +// interfaces_sort_comparable.baml:20:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:20:9 (variable) [declaration] len=4 "five" +// interfaces_sort_comparable.baml:20:15 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:20:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:20:21 (number) len=1 "5" +// interfaces_sort_comparable.baml:21:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:21:9 (variable) [declaration] len=5 "three" +// interfaces_sort_comparable.baml:21:16 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:21:20 (operator) len=1 "=" +// interfaces_sort_comparable.baml:21:22 (number) len=1 "3" +// interfaces_sort_comparable.baml:22:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:22:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:22:20 (variable) len=4 "five" +// interfaces_sort_comparable.baml:22:25 (method) len=7 "compare" +// interfaces_sort_comparable.baml:22:33 (number) len=1 "3" +// interfaces_sort_comparable.baml:22:36 (operator) len=1 ">" +// interfaces_sort_comparable.baml:22:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:23:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:23:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:23:20 (variable) len=5 "three" +// interfaces_sort_comparable.baml:23:26 (method) len=7 "compare" +// interfaces_sort_comparable.baml:23:34 (number) len=1 "5" +// interfaces_sort_comparable.baml:23:37 (operator) len=1 "<" +// interfaces_sort_comparable.baml:23:39 (number) len=1 "0" +// interfaces_sort_comparable.baml:24:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:24:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:24:20 (variable) len=5 "three" +// interfaces_sort_comparable.baml:24:26 (method) len=7 "compare" +// interfaces_sort_comparable.baml:24:34 (number) len=1 "3" +// interfaces_sort_comparable.baml:24:37 (operator) len=2 "==" +// interfaces_sort_comparable.baml:24:40 (number) len=1 "0" +// interfaces_sort_comparable.baml:27:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:27:6 (string) len=27 "\"comparable_string_compare\"" +// interfaces_sort_comparable.baml:28:5 (comment) len=70 "// Annotated receivers widen the literal types (\"a\".compare(\"b\") would" +// interfaces_sort_comparable.baml:29:5 (comment) len=73 "// bind `Self` to the literal type \"a\" and reject \"b\"); literal arguments" +// interfaces_sort_comparable.baml:30:5 (comment) len=26 "// widen into `Self` fine." +// interfaces_sort_comparable.baml:31:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:31:9 (variable) [declaration] len=1 "a" +// interfaces_sort_comparable.baml:31:12 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:31:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:31:21 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:32:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:32:9 (variable) [declaration] len=1 "b" +// interfaces_sort_comparable.baml:32:12 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:32:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:32:21 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:33:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:33:9 (variable) [declaration] len=2 "aa" +// interfaces_sort_comparable.baml:33:13 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:33:20 (operator) len=1 "=" +// interfaces_sort_comparable.baml:33:22 (string) len=4 "\"aa\"" +// interfaces_sort_comparable.baml:34:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:34:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:34:20 (variable) len=1 "a" +// interfaces_sort_comparable.baml:34:22 (method) len=7 "compare" +// interfaces_sort_comparable.baml:34:30 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:34:35 (operator) len=1 "<" +// interfaces_sort_comparable.baml:34:37 (number) len=1 "0" +// interfaces_sort_comparable.baml:35:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:35:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:35:20 (variable) len=1 "b" +// interfaces_sort_comparable.baml:35:22 (method) len=7 "compare" +// interfaces_sort_comparable.baml:35:30 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:35:35 (operator) len=1 ">" +// interfaces_sort_comparable.baml:35:37 (number) len=1 "0" +// interfaces_sort_comparable.baml:36:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:36:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:36:20 (variable) len=2 "aa" +// interfaces_sort_comparable.baml:36:23 (method) len=7 "compare" +// interfaces_sort_comparable.baml:36:31 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:36:36 (operator) len=1 ">" +// interfaces_sort_comparable.baml:36:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:37:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:37:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:37:20 (variable) len=1 "a" +// interfaces_sort_comparable.baml:37:22 (method) len=7 "compare" +// interfaces_sort_comparable.baml:37:30 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:37:35 (operator) len=2 "==" +// interfaces_sort_comparable.baml:37:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:40:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:40:6 (string) len=27 "\"comparable_bigint_compare\"" +// interfaces_sort_comparable.baml:41:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:41:9 (variable) [declaration] len=3 "one" +// interfaces_sort_comparable.baml:41:14 (type) [defaultLibrary] len=6 "bigint" +// interfaces_sort_comparable.baml:41:21 (operator) len=1 "=" +// interfaces_sort_comparable.baml:41:23 (number) len=2 "1n" +// interfaces_sort_comparable.baml:42:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:42:9 (variable) [declaration] len=3 "two" +// interfaces_sort_comparable.baml:42:14 (type) [defaultLibrary] len=6 "bigint" +// interfaces_sort_comparable.baml:42:21 (operator) len=1 "=" +// interfaces_sort_comparable.baml:42:23 (number) len=2 "2n" +// interfaces_sort_comparable.baml:43:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:43:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:43:20 (variable) len=3 "two" +// interfaces_sort_comparable.baml:43:24 (method) len=7 "compare" +// interfaces_sort_comparable.baml:43:32 (number) len=2 "1n" +// interfaces_sort_comparable.baml:43:36 (operator) len=1 ">" +// interfaces_sort_comparable.baml:43:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:44:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:44:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:44:20 (variable) len=3 "one" +// interfaces_sort_comparable.baml:44:24 (method) len=7 "compare" +// interfaces_sort_comparable.baml:44:32 (number) len=2 "2n" +// interfaces_sort_comparable.baml:44:36 (operator) len=1 "<" +// interfaces_sort_comparable.baml:44:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:45:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:45:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:45:20 (variable) len=3 "two" +// interfaces_sort_comparable.baml:45:24 (method) len=7 "compare" +// interfaces_sort_comparable.baml:45:32 (number) len=2 "2n" +// interfaces_sort_comparable.baml:45:36 (operator) len=2 "==" +// interfaces_sort_comparable.baml:45:39 (number) len=1 "0" +// interfaces_sort_comparable.baml:48:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:48:6 (string) len=26 "\"comparable_float_compare\"" +// interfaces_sort_comparable.baml:49:5 (comment) len=61 "// Same literal-type widening dance as the string test above." +// interfaces_sort_comparable.baml:50:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:50:9 (variable) [declaration] len=2 "lo" +// interfaces_sort_comparable.baml:50:13 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:50:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:50:21 (number) len=3 "1.5" +// interfaces_sort_comparable.baml:51:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:51:9 (variable) [declaration] len=2 "hi" +// interfaces_sort_comparable.baml:51:13 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:51:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:51:21 (number) len=3 "2.5" +// interfaces_sort_comparable.baml:52:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:52:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:52:20 (variable) len=2 "hi" +// interfaces_sort_comparable.baml:52:23 (method) len=7 "compare" +// interfaces_sort_comparable.baml:52:31 (number) len=3 "1.5" +// interfaces_sort_comparable.baml:52:36 (operator) len=1 ">" +// interfaces_sort_comparable.baml:52:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:53:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:53:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:53:20 (variable) len=2 "lo" +// interfaces_sort_comparable.baml:53:23 (method) len=7 "compare" +// interfaces_sort_comparable.baml:53:31 (number) len=3 "2.5" +// interfaces_sort_comparable.baml:53:36 (operator) len=1 "<" +// interfaces_sort_comparable.baml:53:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:54:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:54:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:54:20 (variable) len=2 "lo" +// interfaces_sort_comparable.baml:54:23 (method) len=7 "compare" +// interfaces_sort_comparable.baml:54:31 (number) len=3 "1.5" +// interfaces_sort_comparable.baml:54:36 (operator) len=2 "==" +// interfaces_sort_comparable.baml:54:39 (number) len=1 "0" +// interfaces_sort_comparable.baml:57:1 (comment) len=72 "// DECISION TEST (02-plan Phase 3, reverses the 01b NaN decision): float" +// interfaces_sort_comparable.baml:58:1 (comment) len=75 "// comparison no longer throws on NaN — `total_cmp` orders NaN after +inf" +// interfaces_sort_comparable.baml:59:1 (comment) len=45 "// (`… < +inf < +NaN`) and equal to itself." +// interfaces_sort_comparable.baml:60:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:60:6 (string) len=34 "\"comparable_float_nan_total_order\"" +// interfaces_sort_comparable.baml:61:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:61:9 (variable) [declaration] len=3 "one" +// interfaces_sort_comparable.baml:61:14 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:61:20 (operator) len=1 "=" +// interfaces_sort_comparable.baml:61:22 (number) len=3 "1.0" +// interfaces_sort_comparable.baml:62:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:62:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:62:20 (variable) len=3 "one" +// interfaces_sort_comparable.baml:62:24 (method) len=7 "compare" +// interfaces_sort_comparable.baml:62:32 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:62:38 (method) len=3 "nan" +// interfaces_sort_comparable.baml:62:45 (operator) len=1 "<" +// interfaces_sort_comparable.baml:62:47 (number) len=1 "0" +// interfaces_sort_comparable.baml:63:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:63:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:63:20 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:63:26 (method) len=3 "nan" +// interfaces_sort_comparable.baml:63:32 (method) len=7 "compare" +// interfaces_sort_comparable.baml:63:40 (number) len=3 "1.0" +// interfaces_sort_comparable.baml:63:45 (operator) len=1 ">" +// interfaces_sort_comparable.baml:63:47 (number) len=1 "0" +// interfaces_sort_comparable.baml:64:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:64:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:64:20 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:64:26 (method) len=3 "nan" +// interfaces_sort_comparable.baml:64:32 (method) len=7 "compare" +// interfaces_sort_comparable.baml:64:40 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:64:46 (method) len=3 "inf" +// interfaces_sort_comparable.baml:64:53 (operator) len=1 ">" +// interfaces_sort_comparable.baml:64:55 (number) len=1 "0" +// interfaces_sort_comparable.baml:65:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:65:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:65:20 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:65:26 (method) len=3 "nan" +// interfaces_sort_comparable.baml:65:32 (method) len=7 "compare" +// interfaces_sort_comparable.baml:65:40 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:65:46 (method) len=3 "nan" +// interfaces_sort_comparable.baml:65:53 (operator) len=2 "==" +// interfaces_sort_comparable.baml:65:56 (number) len=1 "0" +// interfaces_sort_comparable.baml:68:1 (comment) len=186 "// ─── user classes opting in ──────────────────────────────────────────────────" +// interfaces_sort_comparable.baml:69:1 (comment) len=2 "//" +// interfaces_sort_comparable.baml:70:1 (comment) len=78 "// KNOWN VM BUG (pre-existing, not Comparable-specific): a class instance read" +// interfaces_sort_comparable.baml:71:1 (comment) len=77 "// back from a *test-block local* stays boxed, and passing a boxed value to a" +// interfaces_sort_comparable.baml:72:1 (comment) len=78 "// two-`Self`-param interface method (`compare(self, other: Self)`) panics the" +// interfaces_sort_comparable.baml:73:1 (comment) len=73 "// VM with \"unreachable code executed\". The same calls work from ordinary" +// interfaces_sort_comparable.baml:74:1 (comment) len=73 "// functions. Workaround used throughout: construct instances at the call" +// interfaces_sort_comparable.baml:75:1 (comment) len=59 "// boundary (inline arguments), never via test-block `let`." +// interfaces_sort_comparable.baml:77:1 (comment) len=74 "// Total-order user type: binds `type CompareError = never` and writes the" +// interfaces_sort_comparable.baml:78:1 (comment) len=77 "// matching `throws never` (an omitted `throws` is inferred, not `never`, and" +// interfaces_sort_comparable.baml:79:1 (comment) len=28 "// fails conformance E0120)." +// interfaces_sort_comparable.baml:80:1 (keyword) len=5 "class" +// interfaces_sort_comparable.baml:80:7 (class) [declaration] len=15 "ComparableScore" +// interfaces_sort_comparable.baml:81:5 (property) [declaration] len=6 "points" +// interfaces_sort_comparable.baml:81:12 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:82:5 (keyword) len=10 "implements" +// interfaces_sort_comparable.baml:82:16 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:82:20 (operator) len=1 "." +// interfaces_sort_comparable.baml:82:21 (interface) [defaultLibrary] len=10 "Comparable" +// interfaces_sort_comparable.baml:83:9 (keyword) len=4 "type" +// interfaces_sort_comparable.baml:83:14 (type) [declaration] len=12 "CompareError" +// interfaces_sort_comparable.baml:83:27 (operator) len=1 "=" +// interfaces_sort_comparable.baml:83:29 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:84:9 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:84:18 (method) [declaration] len=7 "compare" +// interfaces_sort_comparable.baml:84:26 (parameter) [declaration] len=4 "self" +// interfaces_sort_comparable.baml:84:32 (parameter) [declaration] len=5 "other" +// interfaces_sort_comparable.baml:84:39 (type) len=4 "Self" +// interfaces_sort_comparable.baml:84:48 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:84:52 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:84:59 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:85:13 (parameter) len=4 "self" +// interfaces_sort_comparable.baml:85:18 (property) len=6 "points" +// interfaces_sort_comparable.baml:85:25 (method) len=7 "compare" +// interfaces_sort_comparable.baml:85:33 (parameter) len=5 "other" +// interfaces_sort_comparable.baml:85:39 (property) len=6 "points" +// interfaces_sort_comparable.baml:90:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:90:6 (string) len=49 "\"comparable_user_class_default_cmperror_is_never\"" +// interfaces_sort_comparable.baml:91:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:91:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:91:20 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:91:38 (property) len=6 "points" +// interfaces_sort_comparable.baml:91:46 (number) len=1 "9" +// interfaces_sort_comparable.baml:91:50 (method) len=7 "compare" +// interfaces_sort_comparable.baml:91:58 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:91:76 (property) len=6 "points" +// interfaces_sort_comparable.baml:91:84 (number) len=1 "1" +// interfaces_sort_comparable.baml:91:89 (operator) len=1 ">" +// interfaces_sort_comparable.baml:91:91 (number) len=1 "0" +// interfaces_sort_comparable.baml:92:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:92:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:92:20 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:92:38 (property) len=6 "points" +// interfaces_sort_comparable.baml:92:46 (number) len=1 "1" +// interfaces_sort_comparable.baml:92:50 (method) len=7 "compare" +// interfaces_sort_comparable.baml:92:58 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:92:76 (property) len=6 "points" +// interfaces_sort_comparable.baml:92:84 (number) len=1 "9" +// interfaces_sort_comparable.baml:92:89 (operator) len=1 "<" +// interfaces_sort_comparable.baml:92:91 (number) len=1 "0" +// interfaces_sort_comparable.baml:93:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:93:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:93:20 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:93:38 (property) len=6 "points" +// interfaces_sort_comparable.baml:93:46 (number) len=1 "1" +// interfaces_sort_comparable.baml:93:50 (method) len=7 "compare" +// interfaces_sort_comparable.baml:93:58 (class) len=15 "ComparableScore" +// interfaces_sort_comparable.baml:93:76 (property) len=6 "points" +// interfaces_sort_comparable.baml:93:84 (number) len=1 "1" +// interfaces_sort_comparable.baml:93:89 (operator) len=2 "==" +// interfaces_sort_comparable.baml:93:92 (number) len=1 "0" +// interfaces_sort_comparable.baml:96:1 (comment) len=86 "// Fallible comparator: binds `type CompareError = ComparableCompareError` and throws." +// interfaces_sort_comparable.baml:97:1 (keyword) len=5 "class" +// interfaces_sort_comparable.baml:97:7 (class) [declaration] len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:98:5 (property) [declaration] len=7 "message" +// interfaces_sort_comparable.baml:98:13 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:101:1 (keyword) len=5 "class" +// interfaces_sort_comparable.baml:101:7 (class) [declaration] len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:102:5 (property) [declaration] len=5 "value" +// interfaces_sort_comparable.baml:102:11 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:103:5 (keyword) len=10 "implements" +// interfaces_sort_comparable.baml:103:16 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:103:20 (operator) len=1 "." +// interfaces_sort_comparable.baml:103:21 (interface) [defaultLibrary] len=10 "Comparable" +// interfaces_sort_comparable.baml:104:9 (keyword) len=4 "type" +// interfaces_sort_comparable.baml:104:14 (type) [declaration] len=12 "CompareError" +// interfaces_sort_comparable.baml:104:27 (operator) len=1 "=" +// interfaces_sort_comparable.baml:104:29 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:106:9 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:106:18 (method) [declaration] len=7 "compare" +// interfaces_sort_comparable.baml:106:26 (parameter) [declaration] len=4 "self" +// interfaces_sort_comparable.baml:106:32 (parameter) [declaration] len=5 "other" +// interfaces_sort_comparable.baml:106:39 (type) len=4 "Self" +// interfaces_sort_comparable.baml:106:48 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:106:52 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:106:59 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:107:13 (keyword) len=2 "if" +// interfaces_sort_comparable.baml:107:16 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:107:20 (variable) [declaration] len=1 "a" +// interfaces_sort_comparable.baml:107:23 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:107:27 (operator) len=1 "=" +// interfaces_sort_comparable.baml:107:29 (parameter) len=4 "self" +// interfaces_sort_comparable.baml:107:34 (property) len=5 "value" +// interfaces_sort_comparable.baml:108:17 (keyword) len=2 "if" +// interfaces_sort_comparable.baml:108:20 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:108:24 (variable) [declaration] len=1 "b" +// interfaces_sort_comparable.baml:108:27 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:108:31 (operator) len=1 "=" +// interfaces_sort_comparable.baml:108:33 (parameter) len=5 "other" +// interfaces_sort_comparable.baml:108:39 (property) len=5 "value" +// interfaces_sort_comparable.baml:109:21 (keyword) len=6 "return" +// interfaces_sort_comparable.baml:109:28 (variable) len=1 "a" +// interfaces_sort_comparable.baml:109:30 (method) len=7 "compare" +// interfaces_sort_comparable.baml:109:38 (variable) len=1 "b" +// interfaces_sort_comparable.baml:112:13 (keyword) len=5 "throw" +// interfaces_sort_comparable.baml:112:19 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:112:44 (property) len=7 "message" +// interfaces_sort_comparable.baml:112:53 (string) len=21 "\"cannot compare null\"" +// interfaces_sort_comparable.baml:117:1 (comment) len=74 "// The fallible comparator's happy path: both values present, delegates to" +// interfaces_sort_comparable.baml:118:1 (comment) len=74 "// the builtin `int.compare` from inside the impl body. The catch value is" +// interfaces_sort_comparable.baml:119:1 (comment) len=77 "// compared inline (a catch result stored in a test-block `let` stays boxed)." +// interfaces_sort_comparable.baml:120:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:120:6 (string) len=43 "\"comparable_user_class_fallible_happy_path\"" +// interfaces_sort_comparable.baml:121:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:121:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:121:21 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:121:39 (property) len=5 "value" +// interfaces_sort_comparable.baml:121:46 (number) len=1 "1" +// interfaces_sort_comparable.baml:121:50 (method) len=7 "compare" +// interfaces_sort_comparable.baml:121:58 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:121:76 (property) len=5 "value" +// interfaces_sort_comparable.baml:121:83 (number) len=1 "2" +// interfaces_sort_comparable.baml:121:88 (keyword) len=5 "catch" +// interfaces_sort_comparable.baml:121:95 (parameter) [declaration] len=1 "e" +// interfaces_sort_comparable.baml:122:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:122:35 (number) len=2 "99" +// interfaces_sort_comparable.baml:123:8 (operator) len=1 "<" +// interfaces_sort_comparable.baml:123:10 (number) len=1 "0" +// interfaces_sort_comparable.baml:126:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:126:6 (string) len=50 "\"comparable_user_class_custom_cmperror_propagates\"" +// interfaces_sort_comparable.baml:127:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:127:9 (variable) [declaration] len=3 "msg" +// interfaces_sort_comparable.baml:127:13 (operator) len=1 "=" +// interfaces_sort_comparable.baml:128:9 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:128:13 (variable) [declaration] len=1 "v" +// interfaces_sort_comparable.baml:128:15 (operator) len=1 "=" +// interfaces_sort_comparable.baml:128:17 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:128:35 (property) len=5 "value" +// interfaces_sort_comparable.baml:128:42 (number) len=1 "1" +// interfaces_sort_comparable.baml:128:46 (method) len=7 "compare" +// interfaces_sort_comparable.baml:128:54 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:128:72 (property) len=5 "value" +// interfaces_sort_comparable.baml:128:79 (type) [defaultLibrary] len=4 "null" +// interfaces_sort_comparable.baml:129:9 (string) len=10 "\"no throw\"" +// interfaces_sort_comparable.baml:130:7 (keyword) len=5 "catch" +// interfaces_sort_comparable.baml:130:14 (parameter) [declaration] len=1 "e" +// interfaces_sort_comparable.baml:131:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:131:35 (parameter) len=1 "e" +// interfaces_sort_comparable.baml:131:37 (property) len=7 "message" +// interfaces_sort_comparable.baml:133:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:133:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:133:20 (variable) len=3 "msg" +// interfaces_sort_comparable.baml:133:24 (method) len=7 "matches" +// interfaces_sort_comparable.baml:133:32 (string) len=21 "\"cannot compare null\"" +// interfaces_sort_comparable.baml:136:1 (comment) len=105 "// ─── Sortable: `sort` (Phase 3 — new path alongside the old `sort`) ─────────" +// interfaces_sort_comparable.baml:137:1 (comment) len=2 "//" +// interfaces_sort_comparable.baml:138:1 (comment) len=78 "// Parity with the Phase 0 `sort()` corpus. These exercise `sort()` on *local*" +// interfaces_sort_comparable.baml:139:1 (comment) len=33 "// array receivers (`xs.sort()`)." +// interfaces_sort_comparable.baml:140:1 (comment) len=2 "//" +// interfaces_sort_comparable.baml:141:1 (comment) len=69 "// NB: these run the sort on a *local* receiver rather than through a" +// interfaces_sort_comparable.baml:142:1 (comment) len=73 "// `sort_ints(xs)` helper. Passing a test-block `let` local to a function" +// interfaces_sort_comparable.baml:143:1 (comment) len=80 "// delivers it as `Null` inside the callee — a pre-existing VM quirk of `test`" +// interfaces_sort_comparable.baml:144:1 (comment) len=80 "// blocks (see the `arrays.baml` header note), unrelated to sort. Param-receiver" +// interfaces_sort_comparable.baml:145:1 (comment) len=78 "// dispatch itself works in real functions (Rust `phase3_*` tests). The helper" +// interfaces_sort_comparable.baml:146:1 (comment) len=79 "// functions below are still *declared* (and compile) to pin the `throws never`" +// interfaces_sort_comparable.baml:147:1 (comment) len=57 "// normalization for parameter receivers at compile time." +// interfaces_sort_comparable.baml:149:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:149:10 (function) [declaration] len=9 "sort_ints" +// interfaces_sort_comparable.baml:149:20 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:149:24 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:149:34 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:149:40 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:149:47 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:149:55 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:149:58 (method) len=4 "sort" +// interfaces_sort_comparable.baml:150:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:150:10 (function) [declaration] len=12 "sort_strings" +// interfaces_sort_comparable.baml:150:23 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:150:27 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:150:40 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:150:49 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:150:56 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:150:64 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:150:67 (method) len=4 "sort" +// interfaces_sort_comparable.baml:151:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:151:10 (function) [declaration] len=12 "sort_bigints" +// interfaces_sort_comparable.baml:151:23 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:151:27 (type) [defaultLibrary] len=6 "bigint" +// interfaces_sort_comparable.baml:151:40 (type) [defaultLibrary] len=6 "bigint" +// interfaces_sort_comparable.baml:151:49 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:151:56 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:151:64 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:151:67 (method) len=4 "sort" +// interfaces_sort_comparable.baml:153:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:153:6 (string) len=33 "\"sort_ints_in_place_returns_self\"" +// interfaces_sort_comparable.baml:154:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:154:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:154:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:154:15 (number) len=1 "3" +// interfaces_sort_comparable.baml:154:18 (number) len=1 "1" +// interfaces_sort_comparable.baml:154:21 (number) len=1 "2" +// interfaces_sort_comparable.baml:155:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:155:9 (variable) [declaration] len=6 "result" +// interfaces_sort_comparable.baml:155:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:155:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:155:21 (method) len=4 "sort" +// interfaces_sort_comparable.baml:156:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:156:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:156:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:156:21 (number) len=1 "1" +// interfaces_sort_comparable.baml:156:24 (number) len=1 "2" +// interfaces_sort_comparable.baml:156:27 (number) len=1 "3" +// interfaces_sort_comparable.baml:157:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:157:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:157:20 (variable) len=6 "result" +// interfaces_sort_comparable.baml:157:27 (operator) len=2 "==" +// interfaces_sort_comparable.baml:157:30 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:158:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:158:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:158:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:158:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:158:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:158:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:161:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:161:6 (string) len=20 "\"sort_empty_is_noop\"" +// interfaces_sort_comparable.baml:162:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:162:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:162:13 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:162:19 (operator) len=1 "=" +// interfaces_sort_comparable.baml:163:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:163:9 (variable) [declaration] len=6 "result" +// interfaces_sort_comparable.baml:163:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:163:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:163:21 (method) len=4 "sort" +// interfaces_sort_comparable.baml:164:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:164:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:164:19 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:164:25 (operator) len=1 "=" +// interfaces_sort_comparable.baml:165:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:165:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:165:20 (variable) len=6 "result" +// interfaces_sort_comparable.baml:165:27 (operator) len=2 "==" +// interfaces_sort_comparable.baml:165:30 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:166:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:166:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:166:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:166:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:166:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:166:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:169:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:169:6 (string) len=17 "\"sort_duplicates\"" +// interfaces_sort_comparable.baml:170:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:170:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:170:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:170:15 (number) len=1 "3" +// interfaces_sort_comparable.baml:170:18 (number) len=1 "1" +// interfaces_sort_comparable.baml:170:21 (number) len=1 "2" +// interfaces_sort_comparable.baml:170:24 (number) len=1 "1" +// interfaces_sort_comparable.baml:170:27 (number) len=1 "3" +// interfaces_sort_comparable.baml:171:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:171:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:172:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:172:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:172:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:172:21 (number) len=1 "1" +// interfaces_sort_comparable.baml:172:24 (number) len=1 "1" +// interfaces_sort_comparable.baml:172:27 (number) len=1 "2" +// interfaces_sort_comparable.baml:172:30 (number) len=1 "3" +// interfaces_sort_comparable.baml:172:33 (number) len=1 "3" +// interfaces_sort_comparable.baml:173:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:173:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:173:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:173:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:173:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:173:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:176:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:176:6 (string) len=25 "\"sort_strings_match_sort\"" +// interfaces_sort_comparable.baml:177:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:177:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:177:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:177:15 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:177:20 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:177:25 (string) len=4 "\"aa\"" +// interfaces_sort_comparable.baml:178:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:178:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:179:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:179:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:179:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:179:21 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:179:26 (string) len=4 "\"aa\"" +// interfaces_sort_comparable.baml:179:32 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:180:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:180:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:180:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:180:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:180:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:180:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:183:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:183:6 (string) len=25 "\"sort_bigints_match_sort\"" +// interfaces_sort_comparable.baml:184:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:184:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:184:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:184:15 (number) len=2 "3n" +// interfaces_sort_comparable.baml:184:19 (number) len=2 "1n" +// interfaces_sort_comparable.baml:184:23 (number) len=2 "2n" +// interfaces_sort_comparable.baml:185:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:185:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:186:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:186:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:186:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:186:21 (number) len=2 "1n" +// interfaces_sort_comparable.baml:186:25 (number) len=2 "2n" +// interfaces_sort_comparable.baml:186:29 (number) len=2 "3n" +// interfaces_sort_comparable.baml:187:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:187:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:187:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:187:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:187:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:187:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:190:1 (comment) len=77 "// float's SortError is `never` (total_cmp decision) — infallible like int." +// interfaces_sort_comparable.baml:191:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:191:10 (function) [declaration] len=11 "sort_floats" +// interfaces_sort_comparable.baml:191:22 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:191:26 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:191:38 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:191:46 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:191:53 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:192:5 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:192:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:195:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:195:6 (string) len=24 "\"sort_floats_match_sort\"" +// interfaces_sort_comparable.baml:196:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:196:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:196:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:196:15 (number) len=3 "2.5" +// interfaces_sort_comparable.baml:196:20 (number) len=3 "0.5" +// interfaces_sort_comparable.baml:196:25 (number) len=3 "1.5" +// interfaces_sort_comparable.baml:197:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:197:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:198:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:198:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:198:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:198:21 (number) len=3 "0.5" +// interfaces_sort_comparable.baml:198:26 (number) len=3 "1.5" +// interfaces_sort_comparable.baml:198:31 (number) len=3 "2.5" +// interfaces_sort_comparable.baml:199:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:199:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:199:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:199:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:199:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:199:41 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:202:1 (comment) len=77 "// DECISION TEST (02-plan Phase 3): NaN no longer throws — `total_cmp` is a" +// interfaces_sort_comparable.baml:203:1 (comment) len=75 "// total order over all doubles, so NaN sorts deterministically after +inf." +// interfaces_sort_comparable.baml:204:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:204:6 (string) len=28 "\"sort_floats_nan_sorts_last\"" +// interfaces_sort_comparable.baml:205:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:205:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:205:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:205:15 (number) len=3 "1.0" +// interfaces_sort_comparable.baml:205:20 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:205:26 (method) len=3 "nan" +// interfaces_sort_comparable.baml:205:33 (number) len=3 "0.5" +// interfaces_sort_comparable.baml:206:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:206:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:207:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:207:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:207:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:207:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:207:37 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:207:40 (method) len=6 "length" +// interfaces_sort_comparable.baml:207:50 (number) len=1 "3" +// interfaces_sort_comparable.baml:208:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:208:12 (function) len=5 "equal" +// interfaces_sort_comparable.baml:208:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:208:21 (method) len=2 "at" +// interfaces_sort_comparable.baml:208:24 (number) len=1 "0" +// interfaces_sort_comparable.baml:208:28 (number) len=3 "0.5" +// interfaces_sort_comparable.baml:209:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:209:12 (function) len=5 "equal" +// interfaces_sort_comparable.baml:209:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:209:21 (method) len=2 "at" +// interfaces_sort_comparable.baml:209:24 (number) len=1 "1" +// interfaces_sort_comparable.baml:209:28 (number) len=3 "1.0" +// interfaces_sort_comparable.baml:210:5 (comment) len=57 "// NaN != NaN under `==`; assert positionally via is_nan." +// interfaces_sort_comparable.baml:211:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:211:9 (variable) [declaration] len=4 "last" +// interfaces_sort_comparable.baml:211:14 (operator) len=1 "=" +// interfaces_sort_comparable.baml:211:16 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:211:19 (method) len=2 "at" +// interfaces_sort_comparable.baml:211:22 (number) len=1 "2" +// interfaces_sort_comparable.baml:212:5 (keyword) len=5 "match" +// interfaces_sort_comparable.baml:212:12 (variable) len=4 "last" +// interfaces_sort_comparable.baml:213:9 (type) [defaultLibrary] len=4 "null" +// interfaces_sort_comparable.baml:213:17 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:213:24 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:213:32 (boolean) len=5 "false" +// interfaces_sort_comparable.baml:214:9 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:214:13 (variable) [declaration] len=1 "f" +// interfaces_sort_comparable.baml:214:16 (type) [defaultLibrary] len=5 "float" +// interfaces_sort_comparable.baml:214:25 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:214:32 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:214:40 (variable) len=1 "f" +// interfaces_sort_comparable.baml:214:42 (method) len=6 "is_nan" +// interfaces_sort_comparable.baml:218:1 (comment) len=80 "// User class with an infallible (`never`) CompareError sorts by its compare —" +// interfaces_sort_comparable.baml:219:1 (comment) len=36 "// stably, in place, returning self." +// interfaces_sort_comparable.baml:220:1 (keyword) len=5 "class" +// interfaces_sort_comparable.baml:220:7 (class) [declaration] len=12 "SortableItem" +// interfaces_sort_comparable.baml:221:5 (property) [declaration] len=4 "rank" +// interfaces_sort_comparable.baml:221:10 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:222:5 (property) [declaration] len=5 "label" +// interfaces_sort_comparable.baml:222:11 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:223:5 (keyword) len=10 "implements" +// interfaces_sort_comparable.baml:223:16 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:223:20 (operator) len=1 "." +// interfaces_sort_comparable.baml:223:21 (interface) [defaultLibrary] len=10 "Comparable" +// interfaces_sort_comparable.baml:224:9 (keyword) len=4 "type" +// interfaces_sort_comparable.baml:224:14 (type) [declaration] len=12 "CompareError" +// interfaces_sort_comparable.baml:224:27 (operator) len=1 "=" +// interfaces_sort_comparable.baml:224:29 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:225:9 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:225:18 (method) [declaration] len=7 "compare" +// interfaces_sort_comparable.baml:225:26 (parameter) [declaration] len=4 "self" +// interfaces_sort_comparable.baml:225:32 (parameter) [declaration] len=5 "other" +// interfaces_sort_comparable.baml:225:39 (type) len=4 "Self" +// interfaces_sort_comparable.baml:225:48 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:225:52 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:225:59 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:226:13 (parameter) len=4 "self" +// interfaces_sort_comparable.baml:226:18 (property) len=4 "rank" +// interfaces_sort_comparable.baml:226:23 (method) len=7 "compare" +// interfaces_sort_comparable.baml:226:31 (parameter) len=5 "other" +// interfaces_sort_comparable.baml:226:37 (property) len=4 "rank" +// interfaces_sort_comparable.baml:231:1 (comment) len=68 "// `sort_items` is declared (and compiles) to pin the `throws never`" +// interfaces_sort_comparable.baml:232:1 (comment) len=73 "// normalization for an infallible user `Comparable` at compile time; the" +// interfaces_sort_comparable.baml:233:1 (comment) len=74 "// runtime tests below dispatch on local receivers (see the param-receiver" +// interfaces_sort_comparable.baml:234:1 (comment) len=26 "// limitation note above)." +// interfaces_sort_comparable.baml:235:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:235:10 (function) [declaration] len=10 "sort_items" +// interfaces_sort_comparable.baml:235:21 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:235:25 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:235:44 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:235:59 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:235:66 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:236:5 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:236:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:239:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:239:6 (string) len=34 "\"sort_user_class_sorts_by_compare\"" +// interfaces_sort_comparable.baml:240:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:240:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:240:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:241:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:241:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:241:30 (number) len=1 "3" +// interfaces_sort_comparable.baml:241:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:241:40 (string) len=3 "\"c\"" +// interfaces_sort_comparable.baml:242:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:242:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:242:30 (number) len=1 "1" +// interfaces_sort_comparable.baml:242:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:242:40 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:243:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:243:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:243:30 (number) len=1 "2" +// interfaces_sort_comparable.baml:243:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:243:40 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:245:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:245:9 (variable) [declaration] len=6 "result" +// interfaces_sort_comparable.baml:245:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:245:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:245:21 (method) len=4 "sort" +// interfaces_sort_comparable.baml:246:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:246:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:246:20 (variable) len=6 "result" +// interfaces_sort_comparable.baml:246:27 (operator) len=2 "==" +// interfaces_sort_comparable.baml:246:30 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:247:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:247:9 (variable) [declaration] len=6 "labels" +// interfaces_sort_comparable.baml:247:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:247:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:247:21 (method) len=3 "map" +// interfaces_sort_comparable.baml:247:26 (parameter) [declaration] len=1 "x" +// interfaces_sort_comparable.baml:247:29 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:247:46 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:247:55 (parameter) len=1 "x" +// interfaces_sort_comparable.baml:247:57 (property) len=5 "label" +// interfaces_sort_comparable.baml:248:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:248:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:248:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:248:21 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:248:26 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:248:31 (string) len=3 "\"c\"" +// interfaces_sort_comparable.baml:249:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:249:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:249:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:249:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:249:37 (variable) len=6 "labels" +// interfaces_sort_comparable.baml:249:45 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:252:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:252:6 (string) len=27 "\"sort_user_class_is_stable\"" +// interfaces_sort_comparable.baml:253:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:253:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:253:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:254:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:254:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:254:30 (number) len=1 "2" +// interfaces_sort_comparable.baml:254:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:254:40 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:255:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:255:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:255:30 (number) len=1 "1" +// interfaces_sort_comparable.baml:255:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:255:40 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:256:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:256:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:256:30 (number) len=1 "2" +// interfaces_sort_comparable.baml:256:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:256:40 (string) len=3 "\"c\"" +// interfaces_sort_comparable.baml:257:9 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:257:24 (property) len=4 "rank" +// interfaces_sort_comparable.baml:257:30 (number) len=1 "1" +// interfaces_sort_comparable.baml:257:33 (property) len=5 "label" +// interfaces_sort_comparable.baml:257:40 (string) len=3 "\"d\"" +// interfaces_sort_comparable.baml:259:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:259:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:260:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:260:9 (variable) [declaration] len=6 "labels" +// interfaces_sort_comparable.baml:260:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:260:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:260:21 (method) len=3 "map" +// interfaces_sort_comparable.baml:260:26 (parameter) [declaration] len=1 "x" +// interfaces_sort_comparable.baml:260:29 (class) len=12 "SortableItem" +// interfaces_sort_comparable.baml:260:46 (type) [defaultLibrary] len=6 "string" +// interfaces_sort_comparable.baml:260:55 (parameter) len=1 "x" +// interfaces_sort_comparable.baml:260:57 (property) len=5 "label" +// interfaces_sort_comparable.baml:261:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:261:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:261:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:261:21 (string) len=3 "\"b\"" +// interfaces_sort_comparable.baml:261:26 (string) len=3 "\"d\"" +// interfaces_sort_comparable.baml:261:31 (string) len=3 "\"a\"" +// interfaces_sort_comparable.baml:261:36 (string) len=3 "\"c\"" +// interfaces_sort_comparable.baml:262:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:262:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:262:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:262:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:262:37 (variable) len=6 "labels" +// interfaces_sort_comparable.baml:262:45 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:265:1 (comment) len=82 "// Fallible comparator (CompareError = ComparableCompareError): the call site must" +// interfaces_sort_comparable.baml:266:1 (comment) len=70 "// handle it, and a throw mid-sort leaves the array in pre-sort state." +// interfaces_sort_comparable.baml:267:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:267:10 (function) [declaration] len=10 "sort_flaky" +// interfaces_sort_comparable.baml:267:21 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:267:25 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:267:47 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:267:65 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:267:72 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:268:5 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:268:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:271:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:271:6 (string) len=43 "\"sort_fallible_comparator_throw_rolls_back\"" +// interfaces_sort_comparable.baml:272:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:272:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:272:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:273:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:273:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:273:34 (number) len=1 "3" +// interfaces_sort_comparable.baml:274:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:274:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:274:34 (type) [defaultLibrary] len=4 "null" +// interfaces_sort_comparable.baml:275:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:275:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:275:34 (number) len=1 "1" +// interfaces_sort_comparable.baml:277:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:277:9 (variable) [declaration] len=3 "msg" +// interfaces_sort_comparable.baml:277:13 (operator) len=1 "=" +// interfaces_sort_comparable.baml:278:9 (function) len=10 "sort_flaky" +// interfaces_sort_comparable.baml:278:20 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:279:9 (string) len=10 "\"no throw\"" +// interfaces_sort_comparable.baml:280:7 (keyword) len=5 "catch" +// interfaces_sort_comparable.baml:280:14 (parameter) [declaration] len=1 "e" +// interfaces_sort_comparable.baml:281:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:281:35 (parameter) len=1 "e" +// interfaces_sort_comparable.baml:281:37 (property) len=7 "message" +// interfaces_sort_comparable.baml:283:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:283:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:283:20 (variable) len=3 "msg" +// interfaces_sort_comparable.baml:283:24 (method) len=7 "matches" +// interfaces_sort_comparable.baml:283:32 (string) len=21 "\"cannot compare null\"" +// interfaces_sort_comparable.baml:284:5 (comment) len=34 "// rollback: original order intact" +// interfaces_sort_comparable.baml:285:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:285:9 (variable) [declaration] len=4 "vals" +// interfaces_sort_comparable.baml:285:14 (operator) len=1 "=" +// interfaces_sort_comparable.baml:285:16 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:285:19 (method) len=3 "map" +// interfaces_sort_comparable.baml:285:24 (parameter) [declaration] len=1 "x" +// interfaces_sort_comparable.baml:285:27 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:285:47 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:286:9 (keyword) len=2 "if" +// interfaces_sort_comparable.baml:286:12 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:286:16 (variable) [declaration] len=1 "v" +// interfaces_sort_comparable.baml:286:19 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:286:23 (operator) len=1 "=" +// interfaces_sort_comparable.baml:286:25 (parameter) len=1 "x" +// interfaces_sort_comparable.baml:286:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:286:35 (variable) len=1 "v" +// interfaces_sort_comparable.baml:286:39 (keyword) len=4 "else" +// interfaces_sort_comparable.baml:286:46 (operator) len=1 "-" +// interfaces_sort_comparable.baml:286:47 (number) len=1 "1" +// interfaces_sort_comparable.baml:288:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:288:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:288:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:288:21 (number) len=1 "3" +// interfaces_sort_comparable.baml:288:24 (operator) len=1 "-" +// interfaces_sort_comparable.baml:288:25 (number) len=1 "1" +// interfaces_sort_comparable.baml:288:28 (number) len=1 "1" +// interfaces_sort_comparable.baml:289:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:289:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:289:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:289:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:289:37 (variable) len=4 "vals" +// interfaces_sort_comparable.baml:289:43 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:292:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:292:6 (string) len=37 "\"sort_fallible_comparator_happy_path\"" +// interfaces_sort_comparable.baml:293:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:293:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:293:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:294:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:294:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:294:34 (number) len=1 "3" +// interfaces_sort_comparable.baml:295:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:295:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:295:34 (number) len=1 "1" +// interfaces_sort_comparable.baml:296:9 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:296:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:296:34 (number) len=1 "2" +// interfaces_sort_comparable.baml:298:5 (comment) len=72 "// No-throw contract: all values present, so the comparator never fails." +// interfaces_sort_comparable.baml:299:5 (comment) len=72 "// Asserted inline — a catch result stored in a test-block `let` stays" +// interfaces_sort_comparable.baml:300:5 (comment) len=70 "// boxed (same VM quirk as above) and `== false` would reject the box." +// interfaces_sort_comparable.baml:301:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:301:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:302:9 (function) len=10 "sort_flaky" +// interfaces_sort_comparable.baml:302:20 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:303:9 (boolean) len=5 "false" +// interfaces_sort_comparable.baml:304:7 (keyword) len=5 "catch" +// interfaces_sort_comparable.baml:304:14 (parameter) [declaration] len=1 "e" +// interfaces_sort_comparable.baml:305:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:305:35 (boolean) len=4 "true" +// interfaces_sort_comparable.baml:306:8 (operator) len=2 "==" +// interfaces_sort_comparable.baml:306:11 (boolean) len=5 "false" +// interfaces_sort_comparable.baml:307:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:307:9 (variable) [declaration] len=4 "vals" +// interfaces_sort_comparable.baml:307:14 (operator) len=1 "=" +// interfaces_sort_comparable.baml:307:16 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:307:19 (method) len=3 "map" +// interfaces_sort_comparable.baml:307:24 (parameter) [declaration] len=1 "x" +// interfaces_sort_comparable.baml:307:27 (class) len=15 "ComparableFlaky" +// interfaces_sort_comparable.baml:307:47 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:308:9 (keyword) len=2 "if" +// interfaces_sort_comparable.baml:308:12 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:308:16 (variable) [declaration] len=1 "v" +// interfaces_sort_comparable.baml:308:19 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:308:23 (operator) len=1 "=" +// interfaces_sort_comparable.baml:308:25 (parameter) len=1 "x" +// interfaces_sort_comparable.baml:308:27 (property) len=5 "value" +// interfaces_sort_comparable.baml:308:35 (variable) len=1 "v" +// interfaces_sort_comparable.baml:308:39 (keyword) len=4 "else" +// interfaces_sort_comparable.baml:308:46 (operator) len=1 "-" +// interfaces_sort_comparable.baml:308:47 (number) len=1 "1" +// interfaces_sort_comparable.baml:310:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:310:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:310:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:310:21 (number) len=1 "1" +// interfaces_sort_comparable.baml:310:24 (number) len=1 "2" +// interfaces_sort_comparable.baml:310:27 (number) len=1 "3" +// interfaces_sort_comparable.baml:311:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:311:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:311:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:311:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:311:37 (variable) len=4 "vals" +// interfaces_sort_comparable.baml:311:43 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:314:1 (comment) len=71 "// Generic propagation: a function over `U extends Comparable` may call" +// interfaces_sort_comparable.baml:315:1 (comment) len=74 "// `xs.sort()`, propagating `U.CompareError` symbolically; the test routes" +// interfaces_sort_comparable.baml:316:1 (comment) len=75 "// through it to pin the runtime instantiation too. The array is built in a" +// interfaces_sort_comparable.baml:317:1 (comment) len=73 "// wrapper *function* — a test-block local passed to a generic function" +// interfaces_sort_comparable.baml:318:1 (comment) len=74 "// arrives boxed (the VM quirk above) and the native sort rejects the box." +// interfaces_sort_comparable.baml:319:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:319:10 (function) [declaration] len=12 "sort_generic" +// interfaces_sort_comparable.baml:319:22 (operator) len=1 "<" +// interfaces_sort_comparable.baml:319:23 (typeParameter) [declaration] len=1 "U" +// interfaces_sort_comparable.baml:319:25 (keyword) len=7 "extends" +// interfaces_sort_comparable.baml:319:33 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:319:37 (operator) len=1 "." +// interfaces_sort_comparable.baml:319:38 (interface) [defaultLibrary] len=10 "Comparable" +// interfaces_sort_comparable.baml:319:48 (operator) len=1 ">" +// interfaces_sort_comparable.baml:319:50 (parameter) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:319:54 (type) len=1 "U" +// interfaces_sort_comparable.baml:319:62 (type) len=1 "U" +// interfaces_sort_comparable.baml:319:66 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:319:73 (type) len=1 "U" +// interfaces_sort_comparable.baml:319:74 (operator) len=1 "." +// interfaces_sort_comparable.baml:319:75 (type) len=12 "CompareError" +// interfaces_sort_comparable.baml:320:5 (parameter) len=2 "xs" +// interfaces_sort_comparable.baml:320:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:323:1 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:323:10 (function) [declaration] len=21 "run_sort_generic_ints" +// interfaces_sort_comparable.baml:323:37 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:323:43 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:323:50 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:324:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:324:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:324:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:324:15 (number) len=1 "3" +// interfaces_sort_comparable.baml:324:18 (number) len=1 "1" +// interfaces_sort_comparable.baml:324:21 (number) len=1 "2" +// interfaces_sort_comparable.baml:325:5 (function) len=12 "sort_generic" +// interfaces_sort_comparable.baml:325:18 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:328:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:328:6 (string) len=26 "\"sort_generic_propagation\"" +// interfaces_sort_comparable.baml:329:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:329:9 (variable) [declaration] len=6 "result" +// interfaces_sort_comparable.baml:329:16 (operator) len=1 "=" +// interfaces_sort_comparable.baml:329:18 (function) len=21 "run_sort_generic_ints" +// interfaces_sort_comparable.baml:330:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:330:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:330:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:330:21 (number) len=1 "1" +// interfaces_sort_comparable.baml:330:24 (number) len=1 "2" +// interfaces_sort_comparable.baml:330:27 (number) len=1 "3" +// interfaces_sort_comparable.baml:331:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:331:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:331:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:331:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:331:37 (variable) len=6 "result" +// interfaces_sort_comparable.baml:331:45 (variable) len=8 "expected" +// interfaces_sort_comparable.baml:334:1 (comment) len=123 "// ─── out-of-body `implements baml.Comparable for ` ───────────────────" +// interfaces_sort_comparable.baml:335:1 (comment) len=2 "//" +// interfaces_sort_comparable.baml:336:1 (comment) len=73 "// The impl methods register under the synthetic `Comparable$for$`" +// interfaces_sort_comparable.baml:337:1 (comment) len=74 "// name (as spelled at the impl site), in this file's namespace. Pins that" +// interfaces_sort_comparable.baml:338:1 (comment) len=75 "// `_compare_shim`'s runtime dispatch finds them for class elements — the" +// interfaces_sort_comparable.baml:339:1 (comment) len=54 "// namespaced complement to the flat-package Rust test" +// interfaces_sort_comparable.baml:340:1 (comment) len=56 "// (`sort_user_class_with_out_of_body_comparable_impl`)." +// interfaces_sort_comparable.baml:341:1 (keyword) len=5 "class" +// interfaces_sort_comparable.baml:341:7 (class) [declaration] len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:342:5 (property) [declaration] len=6 "points" +// interfaces_sort_comparable.baml:342:12 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:345:1 (keyword) len=10 "implements" +// interfaces_sort_comparable.baml:345:12 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:345:16 (operator) len=1 "." +// interfaces_sort_comparable.baml:345:17 (interface) [defaultLibrary] len=10 "Comparable" +// interfaces_sort_comparable.baml:345:28 (keyword) len=3 "for" +// interfaces_sort_comparable.baml:345:32 (class) len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:346:5 (keyword) len=4 "type" +// interfaces_sort_comparable.baml:346:10 (type) [declaration] len=12 "CompareError" +// interfaces_sort_comparable.baml:346:23 (operator) len=1 "=" +// interfaces_sort_comparable.baml:346:25 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:347:5 (keyword) len=8 "function" +// interfaces_sort_comparable.baml:347:14 (method) [declaration] len=7 "compare" +// interfaces_sort_comparable.baml:347:22 (parameter) [declaration] len=4 "self" +// interfaces_sort_comparable.baml:347:28 (parameter) [declaration] len=5 "other" +// interfaces_sort_comparable.baml:347:35 (type) len=4 "Self" +// interfaces_sort_comparable.baml:347:44 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:347:48 (keyword) len=6 "throws" +// interfaces_sort_comparable.baml:347:55 (type) [defaultLibrary] len=5 "never" +// interfaces_sort_comparable.baml:348:9 (parameter) len=4 "self" +// interfaces_sort_comparable.baml:348:14 (property) len=6 "points" +// interfaces_sort_comparable.baml:348:21 (method) len=7 "compare" +// interfaces_sort_comparable.baml:348:29 (parameter) len=5 "other" +// interfaces_sort_comparable.baml:348:35 (property) len=6 "points" +// interfaces_sort_comparable.baml:352:1 (keyword) len=4 "test" +// interfaces_sort_comparable.baml:352:6 (string) len=34 "\"sort_user_class_out_of_body_impl\"" +// interfaces_sort_comparable.baml:353:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:353:9 (variable) [declaration] len=2 "xs" +// interfaces_sort_comparable.baml:353:12 (operator) len=1 "=" +// interfaces_sort_comparable.baml:354:9 (class) len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:354:26 (property) len=6 "points" +// interfaces_sort_comparable.baml:354:34 (number) len=1 "3" +// interfaces_sort_comparable.baml:355:9 (class) len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:355:26 (property) len=6 "points" +// interfaces_sort_comparable.baml:355:34 (number) len=1 "1" +// interfaces_sort_comparable.baml:356:9 (class) len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:356:26 (property) len=6 "points" +// interfaces_sort_comparable.baml:356:34 (number) len=1 "2" +// interfaces_sort_comparable.baml:358:5 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:358:8 (method) len=4 "sort" +// interfaces_sort_comparable.baml:359:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:359:9 (variable) [declaration] len=3 "pts" +// interfaces_sort_comparable.baml:359:13 (operator) len=1 "=" +// interfaces_sort_comparable.baml:359:15 (variable) len=2 "xs" +// interfaces_sort_comparable.baml:359:18 (method) len=3 "map" +// interfaces_sort_comparable.baml:359:23 (parameter) [declaration] len=1 "x" +// interfaces_sort_comparable.baml:359:26 (class) len=14 "OutOfBodyScore" +// interfaces_sort_comparable.baml:359:45 (type) [defaultLibrary] len=3 "int" +// interfaces_sort_comparable.baml:359:51 (parameter) len=1 "x" +// interfaces_sort_comparable.baml:359:53 (property) len=6 "points" +// interfaces_sort_comparable.baml:360:5 (keyword) len=3 "let" +// interfaces_sort_comparable.baml:360:9 (variable) [declaration] len=8 "expected" +// interfaces_sort_comparable.baml:360:18 (operator) len=1 "=" +// interfaces_sort_comparable.baml:360:21 (number) len=1 "1" +// interfaces_sort_comparable.baml:360:24 (number) len=1 "2" +// interfaces_sort_comparable.baml:360:27 (number) len=1 "3" +// interfaces_sort_comparable.baml:361:5 (namespace) [defaultLibrary] len=6 "assert" +// interfaces_sort_comparable.baml:361:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:361:20 (namespace) [defaultLibrary] len=4 "baml" +// interfaces_sort_comparable.baml:361:25 (function) len=11 "deep_equals" +// interfaces_sort_comparable.baml:361:37 (variable) len=3 "pts" +// interfaces_sort_comparable.baml:361:42 (variable) len=8 "expected" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/is_operator.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/is_operator.baml new file mode 100644 index 0000000000..07efc1fabc --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/is_operator.baml @@ -0,0 +1,122 @@ +// ` is ` — Rust `matches!`-style pattern test. +// Returns true if the scrutinee matches the pattern, false otherwise. + +// Simple type check on a union. +function is_int(v: int | string) -> bool { + v is int +} + +// Negation by composing with `!`. +function is_not_string(v: int | string) -> bool { + !(v is string) +} + +// Or-pattern on the RHS. +function is_int_or_bool(v: int | string | bool) -> bool { + v is int | bool +} + +// Use inside an `if` condition. +function classify(v: int | string) -> string { + if (v is int) { "number" } + else { "text" } +} + +// Chain into a boolean expression with `&&`. +function both_ints(a: int | string, b: int | string) -> bool { + a is int && b is int +} + +// Literal pattern. +function is_zero(n: int) -> bool { + n is 0 +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// is_operator.baml:1:1 (comment) len=64 "// ` is ` — Rust `matches!`-style pattern test." +// is_operator.baml:2:1 (comment) len=70 "// Returns true if the scrutinee matches the pattern, false otherwise." +// is_operator.baml:4:1 (comment) len=32 "// Simple type check on a union." +// is_operator.baml:5:1 (keyword) len=8 "function" +// is_operator.baml:5:10 (function) [declaration] len=6 "is_int" +// is_operator.baml:5:17 (parameter) [declaration] len=1 "v" +// is_operator.baml:5:20 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:5:24 (operator) len=1 "|" +// is_operator.baml:5:26 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:5:37 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:6:5 (parameter) len=1 "v" +// is_operator.baml:6:7 (keyword) len=2 "is" +// is_operator.baml:6:10 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:9:1 (comment) len=34 "// Negation by composing with `!`." +// is_operator.baml:10:1 (keyword) len=8 "function" +// is_operator.baml:10:10 (function) [declaration] len=13 "is_not_string" +// is_operator.baml:10:24 (parameter) [declaration] len=1 "v" +// is_operator.baml:10:27 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:10:31 (operator) len=1 "|" +// is_operator.baml:10:33 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:10:44 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:11:5 (operator) len=1 "!" +// is_operator.baml:11:7 (parameter) len=1 "v" +// is_operator.baml:11:9 (keyword) len=2 "is" +// is_operator.baml:11:12 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:14:1 (comment) len=25 "// Or-pattern on the RHS." +// is_operator.baml:15:1 (keyword) len=8 "function" +// is_operator.baml:15:10 (function) [declaration] len=14 "is_int_or_bool" +// is_operator.baml:15:25 (parameter) [declaration] len=1 "v" +// is_operator.baml:15:28 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:15:32 (operator) len=1 "|" +// is_operator.baml:15:34 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:15:41 (operator) len=1 "|" +// is_operator.baml:15:43 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:15:52 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:16:5 (parameter) len=1 "v" +// is_operator.baml:16:7 (keyword) len=2 "is" +// is_operator.baml:16:10 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:16:14 (operator) len=1 "|" +// is_operator.baml:16:16 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:19:1 (comment) len=32 "// Use inside an `if` condition." +// is_operator.baml:20:1 (keyword) len=8 "function" +// is_operator.baml:20:10 (function) [declaration] len=8 "classify" +// is_operator.baml:20:19 (parameter) [declaration] len=1 "v" +// is_operator.baml:20:22 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:20:26 (operator) len=1 "|" +// is_operator.baml:20:28 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:20:39 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:21:5 (keyword) len=2 "if" +// is_operator.baml:21:9 (parameter) len=1 "v" +// is_operator.baml:21:11 (keyword) len=2 "is" +// is_operator.baml:21:14 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:21:21 (string) len=8 "\"number\"" +// is_operator.baml:22:5 (keyword) len=4 "else" +// is_operator.baml:22:12 (string) len=6 "\"text\"" +// is_operator.baml:25:1 (comment) len=45 "// Chain into a boolean expression with `&&`." +// is_operator.baml:26:1 (keyword) len=8 "function" +// is_operator.baml:26:10 (function) [declaration] len=9 "both_ints" +// is_operator.baml:26:20 (parameter) [declaration] len=1 "a" +// is_operator.baml:26:23 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:26:27 (operator) len=1 "|" +// is_operator.baml:26:29 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:26:37 (parameter) [declaration] len=1 "b" +// is_operator.baml:26:40 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:26:44 (operator) len=1 "|" +// is_operator.baml:26:46 (type) [defaultLibrary] len=6 "string" +// is_operator.baml:26:57 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:27:5 (parameter) len=1 "a" +// is_operator.baml:27:7 (keyword) len=2 "is" +// is_operator.baml:27:10 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:27:14 (operator) len=2 "&&" +// is_operator.baml:27:17 (parameter) len=1 "b" +// is_operator.baml:27:19 (keyword) len=2 "is" +// is_operator.baml:27:22 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:30:1 (comment) len=19 "// Literal pattern." +// is_operator.baml:31:1 (keyword) len=8 "function" +// is_operator.baml:31:10 (function) [declaration] len=7 "is_zero" +// is_operator.baml:31:18 (parameter) [declaration] len=1 "n" +// is_operator.baml:31:21 (type) [defaultLibrary] len=3 "int" +// is_operator.baml:31:29 (type) [defaultLibrary] len=4 "bool" +// is_operator.baml:32:5 (parameter) len=1 "n" +// is_operator.baml:32:7 (keyword) len=2 "is" +// is_operator.baml:32:10 (number) len=1 "0" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/iterator.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/iterator.baml new file mode 100644 index 0000000000..acea5406be --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/iterator.baml @@ -0,0 +1,67 @@ +// Generic stdlib iterators (`baml.iter`), named type args, lambdas, `throws`. +function CollectStrings(it: baml.iter.Iterator) -> string[] throws never { + it.collect() +} + +function DoubleAll() -> baml.iter.Iterator throws never { + baml.iter.ArrayIterator.new([1, 2, 3]).map((x: int) -> int { x * 2 }) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// iterator.baml:1:1 (comment) len=78 "// Generic stdlib iterators (`baml.iter`), named type args, lambdas, `throws`." +// iterator.baml:2:1 (keyword) len=8 "function" +// iterator.baml:2:10 (function) [declaration] len=14 "CollectStrings" +// iterator.baml:2:25 (parameter) [declaration] len=2 "it" +// iterator.baml:2:29 (namespace) [defaultLibrary] len=4 "baml" +// iterator.baml:2:33 (operator) len=1 "." +// iterator.baml:2:34 (namespace) [defaultLibrary] len=4 "iter" +// iterator.baml:2:38 (operator) len=1 "." +// iterator.baml:2:39 (interface) [defaultLibrary] len=8 "Iterator" +// iterator.baml:2:47 (operator) len=1 "<" +// iterator.baml:2:48 (type) len=4 "Item" +// iterator.baml:2:53 (operator) len=1 "=" +// iterator.baml:2:55 (type) [defaultLibrary] len=6 "string" +// iterator.baml:2:63 (type) len=5 "Error" +// iterator.baml:2:69 (operator) len=1 "=" +// iterator.baml:2:71 (type) [defaultLibrary] len=5 "never" +// iterator.baml:2:76 (operator) len=1 ">" +// iterator.baml:2:82 (type) [defaultLibrary] len=6 "string" +// iterator.baml:2:91 (keyword) len=6 "throws" +// iterator.baml:2:98 (type) [defaultLibrary] len=5 "never" +// iterator.baml:3:3 (parameter) len=2 "it" +// iterator.baml:3:6 (method) len=7 "collect" +// iterator.baml:6:1 (keyword) len=8 "function" +// iterator.baml:6:10 (function) [declaration] len=9 "DoubleAll" +// iterator.baml:6:25 (namespace) [defaultLibrary] len=4 "baml" +// iterator.baml:6:29 (operator) len=1 "." +// iterator.baml:6:30 (namespace) [defaultLibrary] len=4 "iter" +// iterator.baml:6:34 (operator) len=1 "." +// iterator.baml:6:35 (interface) [defaultLibrary] len=8 "Iterator" +// iterator.baml:6:43 (operator) len=1 "<" +// iterator.baml:6:44 (type) len=4 "Item" +// iterator.baml:6:49 (operator) len=1 "=" +// iterator.baml:6:51 (type) [defaultLibrary] len=3 "int" +// iterator.baml:6:56 (type) len=5 "Error" +// iterator.baml:6:62 (operator) len=1 "=" +// iterator.baml:6:64 (type) [defaultLibrary] len=5 "never" +// iterator.baml:6:69 (operator) len=1 ">" +// iterator.baml:6:71 (keyword) len=6 "throws" +// iterator.baml:6:78 (type) [defaultLibrary] len=5 "never" +// iterator.baml:7:3 (namespace) [defaultLibrary] len=4 "baml" +// iterator.baml:7:8 (namespace) [defaultLibrary] len=4 "iter" +// iterator.baml:7:13 (class) [defaultLibrary] len=13 "ArrayIterator" +// iterator.baml:7:27 (method) len=3 "new" +// iterator.baml:7:32 (number) len=1 "1" +// iterator.baml:7:35 (number) len=1 "2" +// iterator.baml:7:38 (number) len=1 "3" +// iterator.baml:7:42 (method) len=3 "map" +// iterator.baml:7:47 (parameter) [declaration] len=1 "x" +// iterator.baml:7:50 (type) [defaultLibrary] len=3 "int" +// iterator.baml:7:58 (type) [defaultLibrary] len=3 "int" +// iterator.baml:7:64 (parameter) len=1 "x" +// iterator.baml:7:66 (operator) len=1 "*" +// iterator.baml:7:68 (number) len=1 "2" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/jinja_control_prompt.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/jinja_control_prompt.baml new file mode 100644 index 0000000000..716fe38a8c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/jinja_control_prompt.baml @@ -0,0 +1,90 @@ +class Message { + role "user" | "assistant" | string + message string +} + +function Bot(convo: Message[]) -> string { + client "openai/gpt-4o" + prompt #" + You are a helpful assistant. + {{ ctx.output_format }} + + {% for m in convo %} + {{ _.role(m.role) }} + {{ m.message }} + {% endfor %} + "# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// jinja_control_prompt.baml:1:1 (keyword) len=5 "class" +// jinja_control_prompt.baml:1:7 (class) [declaration] len=7 "Message" +// jinja_control_prompt.baml:2:3 (property) [declaration] len=4 "role" +// jinja_control_prompt.baml:2:8 (string) len=6 "\"user\"" +// jinja_control_prompt.baml:2:15 (operator) len=1 "|" +// jinja_control_prompt.baml:2:17 (string) len=11 "\"assistant\"" +// jinja_control_prompt.baml:2:29 (operator) len=1 "|" +// jinja_control_prompt.baml:2:31 (type) [defaultLibrary] len=6 "string" +// jinja_control_prompt.baml:3:3 (property) [declaration] len=7 "message" +// jinja_control_prompt.baml:3:11 (type) [defaultLibrary] len=6 "string" +// jinja_control_prompt.baml:6:1 (keyword) len=8 "function" +// jinja_control_prompt.baml:6:10 (function) [declaration] len=3 "Bot" +// jinja_control_prompt.baml:6:14 (parameter) [declaration] len=5 "convo" +// jinja_control_prompt.baml:6:21 (class) len=7 "Message" +// jinja_control_prompt.baml:6:35 (type) [defaultLibrary] len=6 "string" +// jinja_control_prompt.baml:7:3 (property) len=6 "client" +// jinja_control_prompt.baml:7:10 (string) len=15 "\"openai/gpt-4o\"" +// jinja_control_prompt.baml:8:3 (property) [declaration] len=6 "prompt" +// jinja_control_prompt.baml:8:10 (string) len=1 "#" +// jinja_control_prompt.baml:8:11 (string) len=1 "\"" +// jinja_control_prompt.baml:9:5 (string) len=3 "You" +// jinja_control_prompt.baml:9:9 (string) len=3 "are" +// jinja_control_prompt.baml:9:13 (string) len=1 "a" +// jinja_control_prompt.baml:9:15 (string) len=7 "helpful" +// jinja_control_prompt.baml:9:23 (string) len=9 "assistant" +// jinja_control_prompt.baml:9:32 (string) len=1 "." +// jinja_control_prompt.baml:10:5 (string) len=1 "{" +// jinja_control_prompt.baml:10:6 (string) len=1 "{" +// jinja_control_prompt.baml:10:8 (string) len=3 "ctx" +// jinja_control_prompt.baml:10:11 (string) len=1 "." +// jinja_control_prompt.baml:10:12 (string) len=13 "output_format" +// jinja_control_prompt.baml:10:26 (string) len=1 "}" +// jinja_control_prompt.baml:10:27 (string) len=1 "}" +// jinja_control_prompt.baml:12:5 (string) len=1 "{" +// jinja_control_prompt.baml:12:6 (string) len=1 "%" +// jinja_control_prompt.baml:12:8 (string) len=3 "for" +// jinja_control_prompt.baml:12:12 (string) len=1 "m" +// jinja_control_prompt.baml:12:14 (string) len=2 "in" +// jinja_control_prompt.baml:12:17 (string) len=5 "convo" +// jinja_control_prompt.baml:12:23 (string) len=1 "%" +// jinja_control_prompt.baml:12:24 (string) len=1 "}" +// jinja_control_prompt.baml:13:5 (string) len=1 "{" +// jinja_control_prompt.baml:13:6 (string) len=1 "{" +// jinja_control_prompt.baml:13:8 (string) len=1 "_" +// jinja_control_prompt.baml:13:9 (string) len=1 "." +// jinja_control_prompt.baml:13:10 (string) len=4 "role" +// jinja_control_prompt.baml:13:14 (string) len=1 "(" +// jinja_control_prompt.baml:13:15 (string) len=1 "m" +// jinja_control_prompt.baml:13:16 (string) len=1 "." +// jinja_control_prompt.baml:13:17 (string) len=4 "role" +// jinja_control_prompt.baml:13:21 (string) len=1 ")" +// jinja_control_prompt.baml:13:23 (string) len=1 "}" +// jinja_control_prompt.baml:13:24 (string) len=1 "}" +// jinja_control_prompt.baml:14:5 (string) len=1 "{" +// jinja_control_prompt.baml:14:6 (string) len=1 "{" +// jinja_control_prompt.baml:14:8 (string) len=1 "m" +// jinja_control_prompt.baml:14:9 (string) len=1 "." +// jinja_control_prompt.baml:14:10 (string) len=7 "message" +// jinja_control_prompt.baml:14:18 (string) len=1 "}" +// jinja_control_prompt.baml:14:19 (string) len=1 "}" +// jinja_control_prompt.baml:15:5 (string) len=1 "{" +// jinja_control_prompt.baml:15:6 (string) len=1 "%" +// jinja_control_prompt.baml:15:8 (string) len=6 "endfor" +// jinja_control_prompt.baml:15:15 (string) len=1 "%" +// jinja_control_prompt.baml:15:16 (string) len=1 "}" +// jinja_control_prompt.baml:16:3 (string) len=1 "\"" +// jinja_control_prompt.baml:16:4 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_map_literal.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_map_literal.baml new file mode 100644 index 0000000000..e376e42a0c --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_map_literal.baml @@ -0,0 +1,25 @@ +// Phase 1: Verify that nested map/array literals type-check against the +// recursive `json` alias body. + +function NestedMapLiteral() -> json { + {"a": 1, "b": [2, 3], "c": {"nested": null}} +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// json_map_literal.baml:1:1 (comment) len=72 "// Phase 1: Verify that nested map/array literals type-check against the" +// json_map_literal.baml:2:1 (comment) len=31 "// recursive `json` alias body." +// json_map_literal.baml:4:1 (keyword) len=8 "function" +// json_map_literal.baml:4:10 (function) [declaration] len=16 "NestedMapLiteral" +// json_map_literal.baml:4:32 (type) [defaultLibrary] len=4 "json" +// json_map_literal.baml:5:4 (string) len=3 "\"a\"" +// json_map_literal.baml:5:9 (number) len=1 "1" +// json_map_literal.baml:5:12 (string) len=3 "\"b\"" +// json_map_literal.baml:5:18 (number) len=1 "2" +// json_map_literal.baml:5:21 (number) len=1 "3" +// json_map_literal.baml:5:25 (string) len=3 "\"c\"" +// json_map_literal.baml:5:31 (string) len=8 "\"nested\"" +// json_map_literal.baml:5:41 (type) [defaultLibrary] len=4 "null" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_parse_stringify_intrinsics.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_parse_stringify_intrinsics.baml new file mode 100644 index 0000000000..75811bf3c0 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_parse_stringify_intrinsics.baml @@ -0,0 +1,118 @@ +// Phase 2: Verify that baml.json.parse / stringify / stringify_pretty compile +// and lower correctly through TIR and MIR. + +function parse_and_roundtrip(s: string) -> string { + let j: json = baml.json.parse(s) + baml.json.stringify(j) +} + +function parse_and_roundtrip_pretty(s: string) -> string { + let j: json = baml.json.parse(s) + baml.json.stringify_pretty(j) +} + +function match_parsed(s: string) -> string { + let j: json = baml.json.parse(s) + match (j) { + let arr: json[] => baml.json.stringify(arr) + let m: map => baml.json.stringify(m) + let n: int => "int" + let f: float => "float" + let b: bool => "bool" + let st: string => st + null => "null" + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// json_parse_stringify_intrinsics.baml:1:1 (comment) len=78 "// Phase 2: Verify that baml.json.parse / stringify / stringify_pretty compile" +// json_parse_stringify_intrinsics.baml:2:1 (comment) len=43 "// and lower correctly through TIR and MIR." +// json_parse_stringify_intrinsics.baml:4:1 (keyword) len=8 "function" +// json_parse_stringify_intrinsics.baml:4:10 (function) [declaration] len=19 "parse_and_roundtrip" +// json_parse_stringify_intrinsics.baml:4:30 (parameter) [declaration] len=1 "s" +// json_parse_stringify_intrinsics.baml:4:33 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:4:44 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:5:3 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:5:7 (variable) [declaration] len=1 "j" +// json_parse_stringify_intrinsics.baml:5:10 (type) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:5:15 (operator) len=1 "=" +// json_parse_stringify_intrinsics.baml:5:17 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:5:22 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:5:27 (function) len=5 "parse" +// json_parse_stringify_intrinsics.baml:5:33 (parameter) len=1 "s" +// json_parse_stringify_intrinsics.baml:6:3 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:6:8 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:6:13 (function) len=9 "stringify" +// json_parse_stringify_intrinsics.baml:6:23 (variable) len=1 "j" +// json_parse_stringify_intrinsics.baml:9:1 (keyword) len=8 "function" +// json_parse_stringify_intrinsics.baml:9:10 (function) [declaration] len=26 "parse_and_roundtrip_pretty" +// json_parse_stringify_intrinsics.baml:9:37 (parameter) [declaration] len=1 "s" +// json_parse_stringify_intrinsics.baml:9:40 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:9:51 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:10:3 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:10:7 (variable) [declaration] len=1 "j" +// json_parse_stringify_intrinsics.baml:10:10 (type) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:10:15 (operator) len=1 "=" +// json_parse_stringify_intrinsics.baml:10:17 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:10:22 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:10:27 (function) len=5 "parse" +// json_parse_stringify_intrinsics.baml:10:33 (parameter) len=1 "s" +// json_parse_stringify_intrinsics.baml:11:3 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:11:8 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:11:13 (function) len=16 "stringify_pretty" +// json_parse_stringify_intrinsics.baml:11:30 (variable) len=1 "j" +// json_parse_stringify_intrinsics.baml:14:1 (keyword) len=8 "function" +// json_parse_stringify_intrinsics.baml:14:10 (function) [declaration] len=12 "match_parsed" +// json_parse_stringify_intrinsics.baml:14:23 (parameter) [declaration] len=1 "s" +// json_parse_stringify_intrinsics.baml:14:26 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:14:37 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:15:3 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:15:7 (variable) [declaration] len=1 "j" +// json_parse_stringify_intrinsics.baml:15:10 (type) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:15:15 (operator) len=1 "=" +// json_parse_stringify_intrinsics.baml:15:17 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:15:22 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:15:27 (function) len=5 "parse" +// json_parse_stringify_intrinsics.baml:15:33 (parameter) len=1 "s" +// json_parse_stringify_intrinsics.baml:16:3 (keyword) len=5 "match" +// json_parse_stringify_intrinsics.baml:16:10 (variable) len=1 "j" +// json_parse_stringify_intrinsics.baml:17:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:17:9 (variable) [declaration] len=3 "arr" +// json_parse_stringify_intrinsics.baml:17:14 (type) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:17:24 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:17:29 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:17:34 (function) len=9 "stringify" +// json_parse_stringify_intrinsics.baml:17:44 (variable) len=3 "arr" +// json_parse_stringify_intrinsics.baml:18:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:18:9 (variable) [declaration] len=1 "m" +// json_parse_stringify_intrinsics.baml:18:12 (type) [defaultLibrary] len=3 "map" +// json_parse_stringify_intrinsics.baml:18:15 (operator) len=1 "<" +// json_parse_stringify_intrinsics.baml:18:16 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:18:24 (type) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:18:28 (operator) len=1 ">" +// json_parse_stringify_intrinsics.baml:18:33 (namespace) [defaultLibrary] len=4 "baml" +// json_parse_stringify_intrinsics.baml:18:38 (namespace) [defaultLibrary] len=4 "json" +// json_parse_stringify_intrinsics.baml:18:43 (function) len=9 "stringify" +// json_parse_stringify_intrinsics.baml:18:53 (variable) len=1 "m" +// json_parse_stringify_intrinsics.baml:19:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:19:9 (variable) [declaration] len=1 "n" +// json_parse_stringify_intrinsics.baml:19:12 (type) [defaultLibrary] len=3 "int" +// json_parse_stringify_intrinsics.baml:19:19 (string) len=5 "\"int\"" +// json_parse_stringify_intrinsics.baml:20:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:20:9 (variable) [declaration] len=1 "f" +// json_parse_stringify_intrinsics.baml:20:12 (type) [defaultLibrary] len=5 "float" +// json_parse_stringify_intrinsics.baml:20:21 (string) len=7 "\"float\"" +// json_parse_stringify_intrinsics.baml:21:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:21:9 (variable) [declaration] len=1 "b" +// json_parse_stringify_intrinsics.baml:21:12 (type) [defaultLibrary] len=4 "bool" +// json_parse_stringify_intrinsics.baml:21:20 (string) len=6 "\"bool\"" +// json_parse_stringify_intrinsics.baml:22:5 (keyword) len=3 "let" +// json_parse_stringify_intrinsics.baml:22:9 (variable) [declaration] len=2 "st" +// json_parse_stringify_intrinsics.baml:22:13 (type) [defaultLibrary] len=6 "string" +// json_parse_stringify_intrinsics.baml:22:23 (variable) len=2 "st" +// json_parse_stringify_intrinsics.baml:23:5 (type) [defaultLibrary] len=4 "null" +// json_parse_stringify_intrinsics.baml:23:13 (string) len=6 "\"null\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml new file mode 100644 index 0000000000..5353802249 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml @@ -0,0 +1,1003 @@ +// ── Chained map: two-step transform ─────────────────────────────── +function test_chained_map() -> int[] { + let items: int[] = [1, 2, 3] + let step1: int[] = items.map((x) -> { x * 10 }) + step1.map((x) -> { x + 1 }) +} + +// ── Map over strings to ints ────────────────────────────────────── +function test_map_string_to_int() -> int[] { + let words: string[] = ["hello", "world"] + words.map((w: string) -> int { w.length() }) +} + +// ── Lambda returning a lambda (higher-order return) ─────────────── +function test_higher_order_return() -> int { + let make_adder = (n: int) -> { + let adder = (x: int) -> int { x + n } + adder + } + let add5 = make_adder(5) + add5(37) +} + +// Lambda calling another lambda +function test_lambda_calling_lambda() -> int { + let double = (x: int) -> int { x * 2 } + let apply_twice = (f: (int) -> int, x: int) -> int { + f(f(x)) + } + apply_twice(double, 3) +} + +// ── Capture across two nesting levels ──────────────────────────── +function test_deep_capture() -> int { + let a = 1 + let f = (b: int) -> { + let g = (c: int) -> int { + a + b + c // captures a from grandparent, b from parent + } + g(100) + } + f(10) // 1 + 10 + 100 = 111 +} + +// ── Lambda with match expression in body ───────────────────────── +function test_lambda_with_match() -> string { + let describe = (n: int) -> string { + match (n) { + 0 => "zero" + 1 => "one" + _ => "many" + } + } + describe(1) +} + +// ── Lambda with if/else expression body ────────────────────────── +function test_lambda_with_if() -> string { + let classify = (n: int) -> string { + if (n < 0) { "negative" } + else if (n == 0) { "zero" } + else { "positive" } + } + classify(-5) +} + +// ── Map with captured variable in lambda ───────────────────────── +function test_map_with_capture() -> int[] { + let items: int[] = [1, 2, 3] + let factor = 10 + items.map((x) -> { x * factor }) +} + +// ── Nested map: map inside a map callback ──────────────────────── +function test_nested_map() -> int[][] { + let matrix: int[][] = [[1, 2], [3, 4]] + // Flatten-map: for each row, map and collect + matrix.map((row: int[]) -> { + row.map((x) -> { x * x }) + }) +} + +// ── Map with multi-statement lambda body ───────────────────────── +function test_map_multi_statement() -> int[] { + let items: int[] = [1, 2, 3] + items.map((x) -> { + let doubled = x * 2 + let offset = 100 + doubled + offset + }) +} + +// ── Lambda assigned then passed ────────────────────────────────── +function test_lambda_variable_then_pass() -> int[] { + let items: int[] = [10, 20, 30] + let halve = (x: int) -> int { x / 2 } + items.map(halve) +} + +// ── Shadowing: lambda param shadows outer variable ─────────────── +function test_shadowing() -> string { + let x = "999" + let items: int[] = [1, 2, 3] + let mapped: int[] = items.map((x) -> { x + 1 }) + for (let y in mapped) { + let i = 0 + while (i < y) { + x += "1" + i += 1 + } + } + x +} + +// ── Immediately-invoked lambda expression ──────────────────────── +function test_iife() -> int { + let result = ((x: int) -> int { x * x })(7) // 49 + result +} + +// ── Lambda with optional return type ───────────────────────────── +function test_optional_return() -> int? { + let maybe = (x: int) -> int? { + if (x > 0) { x } + else { null } + } + maybe(-1) +} + +// ══════════════════════════════════════════════════════════════════ +// Advanced type inference scenarios — minimal annotations +// ══════════════════════════════════════════════════════════════════ + +// ── map with no annotations at all: param AND return inferred ──── +function test_fully_inferred_map() -> int[] { + let items: int[] = [1, 2, 3] + items.map((x) -> { x * 2 }) + // x: int inferred from T in Array.map + // return: int inferred from body x * 2 + // U binds to int, result is int[] +} + +// ── map where return type changes: infer U != T ────────────────── +function test_map_type_change_inferred() -> string[] { + let nums: int[] = [1, 2, 3] + nums.map((n) -> { + match (n) { + 1 => "one" + 2 => "two" + _ => "other" + } + }) + // n: int inferred, return: string inferred from match body + // U binds to "one"|"two"|"other", result is string[]? +} + +// ── Lambda returning literal 0 — does U bind to 0 or int? ─────── +function test_literal_return_inference() -> int[] { + let items: int[] = [1, 2, 3] + items.map((x) -> { 0 }) + // body returns literal 0, U binds to 0 (literal type) + // result is 0[], function returns int[] — needs 0 <: int +} + +// ── Compose: fully inferred lambdas ────────────────────────────── +function test_compose_inferred() -> int[] { + let items: int[] = [1, 2, 3] + let step1: int[] = items.map((x) -> { x * 2 }) + step1.map((x) -> { x + 1 }) + // Both lambdas: x inferred as int, return inferred as int +} + +// ── Higher-order: lambda returning inferred lambda ─────────────── +function test_higher_order_inferred() -> int { + let make_adder = (n: int) -> { + let adder = (x: int) -> { x + n } + adder + } + // make_adder return type inferred from body: (int) -> int + let add5 = make_adder(5) + add5(37) +} + +// ── Lambda calling lambda: no return annotations ───────────────── +function test_apply_twice_inferred() -> int { + let double = (x: int) -> { x * 2 } + let apply_twice = (f: (int) -> int, x: int) -> { f(f(x)) } + apply_twice(double, 3) +} + +// ── Deep capture with inferred return types ────────────────────── +function test_deep_capture_inferred() -> int { + let a = 1 + let f = (b: int) -> { + let g = (c: int) -> { a + b + c } + g(100) + } + f(10) +} + +// ── Multiple lambda args: all inferred ─────────────────────────── +function test_two_transforms_inferred() -> int { + let apply_both = (f: (int) -> int, g: (int) -> int, x: int) -> { g(f(x)) } + apply_both( + (x: int) -> { x * 2 }, + (x: int) -> { x + 10 }, + 5 + ) +} + +// ── Lambda in match arms: return type unified across arms ──────── +function test_lambda_in_match_inferred() -> int { + let op = "double" + let f = match (op) { + "double" => (x: int) -> { x * 2 } + "negate" => (x: int) -> { 0 - x } + _ => (x: int) -> { x } + } + f(21) +} + +// ── Capture + map: inferred capture type flows into lambda ─────── +function test_capture_in_map_inferred() -> int[] { + let items: int[] = [1, 2, 3] + let factor = 10 + items.map((x) -> { x * factor }) + // x inferred as int, factor captured as int, return int +} + +// ── Void lambda: no return value ───────────────────────────────── +function test_void_lambda_inferred() -> int { + let count = 0 + let inc = () -> { count += 1 } + inc() + inc() + count +} + +function test_void_lambda_inferred_captures() -> int { + let inc = () -> { + let count = 0 + let inc = () -> { count += 1; count }; + inc + }(); + inc() + inc() + inc() +} + + +// ── Lambda capturing another lambda ────────────────────────────── +function test_capture_lambda_inferred() -> int { + let multiply = (a: int, b: int) -> { a * b } + let double = (x: int) -> { multiply(x, 2) } + double(21) +} + +// ── Map over optional array: param type int? inferred ──────────── +function test_map_optional_inferred() -> int[] { + let items: int?[] = [1, null, 3] + items.map((x) -> { + match (x) { + null => 0 + _ => 1 + } + }) + // x: int? inferred from T in Array.map + // return: 0|1 inferred from match +} + +// ── Shadowing with inferred types ──────────────────────────────── +function test_shadowing_inferred() -> int[] { + let x = "not a number" + let items: int[] = [1, 2, 3] + items.map((x) -> { x + 1 }) + // lambda x: int (from map context), shadows outer x: string +} + +// ── IIFE with inferred types ───────────────────────────────────── +function test_iife_inferred() -> int { + ((x: int) -> { x * x })(7) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// lambda_advanced.baml:1:1 (comment) len=135 "// ── Chained map: two-step transform ───────────────────────────────" +// lambda_advanced.baml:2:1 (keyword) len=8 "function" +// lambda_advanced.baml:2:10 (function) [declaration] len=16 "test_chained_map" +// lambda_advanced.baml:2:32 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:3:5 (keyword) len=3 "let" +// lambda_advanced.baml:3:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:3:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:3:22 (operator) len=1 "=" +// lambda_advanced.baml:3:25 (number) len=1 "1" +// lambda_advanced.baml:3:28 (number) len=1 "2" +// lambda_advanced.baml:3:31 (number) len=1 "3" +// lambda_advanced.baml:4:5 (keyword) len=3 "let" +// lambda_advanced.baml:4:9 (variable) [declaration] len=5 "step1" +// lambda_advanced.baml:4:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:4:22 (operator) len=1 "=" +// lambda_advanced.baml:4:24 (variable) len=5 "items" +// lambda_advanced.baml:4:30 (method) len=3 "map" +// lambda_advanced.baml:4:35 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:4:43 (parameter) len=1 "x" +// lambda_advanced.baml:4:45 (operator) len=1 "*" +// lambda_advanced.baml:4:47 (number) len=2 "10" +// lambda_advanced.baml:5:5 (variable) len=5 "step1" +// lambda_advanced.baml:5:11 (method) len=3 "map" +// lambda_advanced.baml:5:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:5:24 (parameter) len=1 "x" +// lambda_advanced.baml:5:26 (operator) len=1 "+" +// lambda_advanced.baml:5:28 (number) len=1 "1" +// lambda_advanced.baml:8:1 (comment) len=149 "// ── Map over strings to ints ──────────────────────────────────────" +// lambda_advanced.baml:9:1 (keyword) len=8 "function" +// lambda_advanced.baml:9:10 (function) [declaration] len=22 "test_map_string_to_int" +// lambda_advanced.baml:9:38 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:10:5 (keyword) len=3 "let" +// lambda_advanced.baml:10:9 (variable) [declaration] len=5 "words" +// lambda_advanced.baml:10:16 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:10:25 (operator) len=1 "=" +// lambda_advanced.baml:10:28 (string) len=7 "\"hello\"" +// lambda_advanced.baml:10:37 (string) len=7 "\"world\"" +// lambda_advanced.baml:11:5 (variable) len=5 "words" +// lambda_advanced.baml:11:11 (method) len=3 "map" +// lambda_advanced.baml:11:16 (parameter) [declaration] len=1 "w" +// lambda_advanced.baml:11:19 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:11:30 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:11:36 (parameter) len=1 "w" +// lambda_advanced.baml:11:38 (method) len=6 "length" +// lambda_advanced.baml:14:1 (comment) len=103 "// ── Lambda returning a lambda (higher-order return) ───────────────" +// lambda_advanced.baml:15:1 (keyword) len=8 "function" +// lambda_advanced.baml:15:10 (function) [declaration] len=24 "test_higher_order_return" +// lambda_advanced.baml:15:40 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:16:5 (keyword) len=3 "let" +// lambda_advanced.baml:16:9 (variable) [declaration] len=10 "make_adder" +// lambda_advanced.baml:16:20 (operator) len=1 "=" +// lambda_advanced.baml:16:23 (parameter) [declaration] len=1 "n" +// lambda_advanced.baml:16:26 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:17:9 (keyword) len=3 "let" +// lambda_advanced.baml:17:13 (variable) [declaration] len=5 "adder" +// lambda_advanced.baml:17:19 (operator) len=1 "=" +// lambda_advanced.baml:17:22 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:17:25 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:17:33 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:17:39 (parameter) len=1 "x" +// lambda_advanced.baml:17:41 (operator) len=1 "+" +// lambda_advanced.baml:17:43 (parameter) len=1 "n" +// lambda_advanced.baml:18:9 (variable) len=5 "adder" +// lambda_advanced.baml:20:5 (keyword) len=3 "let" +// lambda_advanced.baml:20:9 (variable) [declaration] len=4 "add5" +// lambda_advanced.baml:20:14 (operator) len=1 "=" +// lambda_advanced.baml:20:16 (variable) len=10 "make_adder" +// lambda_advanced.baml:20:27 (number) len=1 "5" +// lambda_advanced.baml:21:5 (variable) len=4 "add5" +// lambda_advanced.baml:21:10 (number) len=2 "37" +// lambda_advanced.baml:24:1 (comment) len=32 "// Lambda calling another lambda" +// lambda_advanced.baml:25:1 (keyword) len=8 "function" +// lambda_advanced.baml:25:10 (function) [declaration] len=26 "test_lambda_calling_lambda" +// lambda_advanced.baml:25:42 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:26:5 (keyword) len=3 "let" +// lambda_advanced.baml:26:9 (variable) [declaration] len=6 "double" +// lambda_advanced.baml:26:16 (operator) len=1 "=" +// lambda_advanced.baml:26:19 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:26:22 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:26:30 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:26:36 (parameter) len=1 "x" +// lambda_advanced.baml:26:38 (operator) len=1 "*" +// lambda_advanced.baml:26:40 (number) len=1 "2" +// lambda_advanced.baml:27:5 (keyword) len=3 "let" +// lambda_advanced.baml:27:9 (variable) [declaration] len=11 "apply_twice" +// lambda_advanced.baml:27:21 (operator) len=1 "=" +// lambda_advanced.baml:27:24 (parameter) [declaration] len=1 "f" +// lambda_advanced.baml:27:28 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:27:36 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:27:41 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:27:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:27:52 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:28:9 (parameter) len=1 "f" +// lambda_advanced.baml:28:11 (parameter) len=1 "f" +// lambda_advanced.baml:28:13 (parameter) len=1 "x" +// lambda_advanced.baml:30:5 (variable) len=11 "apply_twice" +// lambda_advanced.baml:30:17 (variable) len=6 "double" +// lambda_advanced.baml:30:25 (number) len=1 "3" +// lambda_advanced.baml:33:1 (comment) len=128 "// ── Capture across two nesting levels ────────────────────────────" +// lambda_advanced.baml:34:1 (keyword) len=8 "function" +// lambda_advanced.baml:34:10 (function) [declaration] len=17 "test_deep_capture" +// lambda_advanced.baml:34:33 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:35:5 (keyword) len=3 "let" +// lambda_advanced.baml:35:9 (variable) [declaration] len=1 "a" +// lambda_advanced.baml:35:11 (operator) len=1 "=" +// lambda_advanced.baml:35:13 (number) len=1 "1" +// lambda_advanced.baml:36:5 (keyword) len=3 "let" +// lambda_advanced.baml:36:9 (variable) [declaration] len=1 "f" +// lambda_advanced.baml:36:11 (operator) len=1 "=" +// lambda_advanced.baml:36:14 (parameter) [declaration] len=1 "b" +// lambda_advanced.baml:36:17 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:37:9 (keyword) len=3 "let" +// lambda_advanced.baml:37:13 (variable) [declaration] len=1 "g" +// lambda_advanced.baml:37:15 (operator) len=1 "=" +// lambda_advanced.baml:37:18 (parameter) [declaration] len=1 "c" +// lambda_advanced.baml:37:21 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:37:29 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:38:13 (variable) len=1 "a" +// lambda_advanced.baml:38:15 (operator) len=1 "+" +// lambda_advanced.baml:38:17 (parameter) len=1 "b" +// lambda_advanced.baml:38:19 (operator) len=1 "+" +// lambda_advanced.baml:38:21 (parameter) len=1 "c" +// lambda_advanced.baml:38:24 (comment) len=45 "// captures a from grandparent, b from parent" +// lambda_advanced.baml:40:9 (variable) len=1 "g" +// lambda_advanced.baml:40:11 (number) len=3 "100" +// lambda_advanced.baml:42:5 (variable) len=1 "f" +// lambda_advanced.baml:42:7 (number) len=2 "10" +// lambda_advanced.baml:42:11 (comment) len=21 "// 1 + 10 + 100 = 111" +// lambda_advanced.baml:45:1 (comment) len=122 "// ── Lambda with match expression in body ─────────────────────────" +// lambda_advanced.baml:46:1 (keyword) len=8 "function" +// lambda_advanced.baml:46:10 (function) [declaration] len=22 "test_lambda_with_match" +// lambda_advanced.baml:46:38 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:47:5 (keyword) len=3 "let" +// lambda_advanced.baml:47:9 (variable) [declaration] len=8 "describe" +// lambda_advanced.baml:47:18 (operator) len=1 "=" +// lambda_advanced.baml:47:21 (parameter) [declaration] len=1 "n" +// lambda_advanced.baml:47:24 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:47:32 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:48:9 (keyword) len=5 "match" +// lambda_advanced.baml:48:16 (parameter) len=1 "n" +// lambda_advanced.baml:49:13 (number) len=1 "0" +// lambda_advanced.baml:49:18 (string) len=6 "\"zero\"" +// lambda_advanced.baml:50:13 (number) len=1 "1" +// lambda_advanced.baml:50:18 (string) len=5 "\"one\"" +// lambda_advanced.baml:51:18 (string) len=6 "\"many\"" +// lambda_advanced.baml:54:5 (variable) len=8 "describe" +// lambda_advanced.baml:54:14 (number) len=1 "1" +// lambda_advanced.baml:57:1 (comment) len=124 "// ── Lambda with if/else expression body ──────────────────────────" +// lambda_advanced.baml:58:1 (keyword) len=8 "function" +// lambda_advanced.baml:58:10 (function) [declaration] len=19 "test_lambda_with_if" +// lambda_advanced.baml:58:35 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:59:5 (keyword) len=3 "let" +// lambda_advanced.baml:59:9 (variable) [declaration] len=8 "classify" +// lambda_advanced.baml:59:18 (operator) len=1 "=" +// lambda_advanced.baml:59:21 (parameter) [declaration] len=1 "n" +// lambda_advanced.baml:59:24 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:59:32 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:60:9 (keyword) len=2 "if" +// lambda_advanced.baml:60:13 (parameter) len=1 "n" +// lambda_advanced.baml:60:15 (operator) len=1 "<" +// lambda_advanced.baml:60:17 (number) len=1 "0" +// lambda_advanced.baml:60:22 (string) len=10 "\"negative\"" +// lambda_advanced.baml:61:9 (keyword) len=4 "else" +// lambda_advanced.baml:61:14 (keyword) len=2 "if" +// lambda_advanced.baml:61:18 (parameter) len=1 "n" +// lambda_advanced.baml:61:20 (operator) len=2 "==" +// lambda_advanced.baml:61:23 (number) len=1 "0" +// lambda_advanced.baml:61:28 (string) len=6 "\"zero\"" +// lambda_advanced.baml:62:9 (keyword) len=4 "else" +// lambda_advanced.baml:62:16 (string) len=10 "\"positive\"" +// lambda_advanced.baml:64:5 (variable) len=8 "classify" +// lambda_advanced.baml:64:14 (operator) len=1 "-" +// lambda_advanced.baml:64:15 (number) len=1 "5" +// lambda_advanced.baml:67:1 (comment) len=122 "// ── Map with captured variable in lambda ─────────────────────────" +// lambda_advanced.baml:68:1 (keyword) len=8 "function" +// lambda_advanced.baml:68:10 (function) [declaration] len=21 "test_map_with_capture" +// lambda_advanced.baml:68:37 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:69:5 (keyword) len=3 "let" +// lambda_advanced.baml:69:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:69:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:69:22 (operator) len=1 "=" +// lambda_advanced.baml:69:25 (number) len=1 "1" +// lambda_advanced.baml:69:28 (number) len=1 "2" +// lambda_advanced.baml:69:31 (number) len=1 "3" +// lambda_advanced.baml:70:5 (keyword) len=3 "let" +// lambda_advanced.baml:70:9 (variable) [declaration] len=6 "factor" +// lambda_advanced.baml:70:16 (operator) len=1 "=" +// lambda_advanced.baml:70:18 (number) len=2 "10" +// lambda_advanced.baml:71:5 (variable) len=5 "items" +// lambda_advanced.baml:71:11 (method) len=3 "map" +// lambda_advanced.baml:71:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:71:24 (parameter) len=1 "x" +// lambda_advanced.baml:71:26 (operator) len=1 "*" +// lambda_advanced.baml:71:28 (variable) len=6 "factor" +// lambda_advanced.baml:74:1 (comment) len=120 "// ── Nested map: map inside a map callback ────────────────────────" +// lambda_advanced.baml:75:1 (keyword) len=8 "function" +// lambda_advanced.baml:75:10 (function) [declaration] len=15 "test_nested_map" +// lambda_advanced.baml:75:31 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:76:5 (keyword) len=3 "let" +// lambda_advanced.baml:76:9 (variable) [declaration] len=6 "matrix" +// lambda_advanced.baml:76:17 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:76:25 (operator) len=1 "=" +// lambda_advanced.baml:76:29 (number) len=1 "1" +// lambda_advanced.baml:76:32 (number) len=1 "2" +// lambda_advanced.baml:76:37 (number) len=1 "3" +// lambda_advanced.baml:76:40 (number) len=1 "4" +// lambda_advanced.baml:77:5 (comment) len=45 "// Flatten-map: for each row, map and collect" +// lambda_advanced.baml:78:5 (variable) len=6 "matrix" +// lambda_advanced.baml:78:12 (method) len=3 "map" +// lambda_advanced.baml:78:17 (parameter) [declaration] len=3 "row" +// lambda_advanced.baml:78:22 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:79:9 (parameter) len=3 "row" +// lambda_advanced.baml:79:13 (method) len=3 "map" +// lambda_advanced.baml:79:18 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:79:26 (parameter) len=1 "x" +// lambda_advanced.baml:79:28 (operator) len=1 "*" +// lambda_advanced.baml:79:30 (parameter) len=1 "x" +// lambda_advanced.baml:83:1 (comment) len=122 "// ── Map with multi-statement lambda body ─────────────────────────" +// lambda_advanced.baml:84:1 (keyword) len=8 "function" +// lambda_advanced.baml:84:10 (function) [declaration] len=24 "test_map_multi_statement" +// lambda_advanced.baml:84:40 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:85:5 (keyword) len=3 "let" +// lambda_advanced.baml:85:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:85:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:85:22 (operator) len=1 "=" +// lambda_advanced.baml:85:25 (number) len=1 "1" +// lambda_advanced.baml:85:28 (number) len=1 "2" +// lambda_advanced.baml:85:31 (number) len=1 "3" +// lambda_advanced.baml:86:5 (variable) len=5 "items" +// lambda_advanced.baml:86:11 (method) len=3 "map" +// lambda_advanced.baml:86:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:87:9 (keyword) len=3 "let" +// lambda_advanced.baml:87:13 (variable) [declaration] len=7 "doubled" +// lambda_advanced.baml:87:21 (operator) len=1 "=" +// lambda_advanced.baml:87:23 (parameter) len=1 "x" +// lambda_advanced.baml:87:25 (operator) len=1 "*" +// lambda_advanced.baml:87:27 (number) len=1 "2" +// lambda_advanced.baml:88:9 (keyword) len=3 "let" +// lambda_advanced.baml:88:13 (variable) [declaration] len=6 "offset" +// lambda_advanced.baml:88:20 (operator) len=1 "=" +// lambda_advanced.baml:88:22 (number) len=3 "100" +// lambda_advanced.baml:89:9 (variable) len=7 "doubled" +// lambda_advanced.baml:89:17 (operator) len=1 "+" +// lambda_advanced.baml:89:19 (variable) len=6 "offset" +// lambda_advanced.baml:93:1 (comment) len=140 "// ── Lambda assigned then passed ──────────────────────────────────" +// lambda_advanced.baml:94:1 (keyword) len=8 "function" +// lambda_advanced.baml:94:10 (function) [declaration] len=30 "test_lambda_variable_then_pass" +// lambda_advanced.baml:94:46 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:95:5 (keyword) len=3 "let" +// lambda_advanced.baml:95:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:95:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:95:22 (operator) len=1 "=" +// lambda_advanced.baml:95:25 (number) len=2 "10" +// lambda_advanced.baml:95:29 (number) len=2 "20" +// lambda_advanced.baml:95:33 (number) len=2 "30" +// lambda_advanced.baml:96:5 (keyword) len=3 "let" +// lambda_advanced.baml:96:9 (variable) [declaration] len=5 "halve" +// lambda_advanced.baml:96:15 (operator) len=1 "=" +// lambda_advanced.baml:96:18 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:96:21 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:96:29 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:96:35 (parameter) len=1 "x" +// lambda_advanced.baml:96:37 (operator) len=1 "/" +// lambda_advanced.baml:96:39 (number) len=1 "2" +// lambda_advanced.baml:97:5 (variable) len=5 "items" +// lambda_advanced.baml:97:11 (method) len=3 "map" +// lambda_advanced.baml:97:15 (variable) len=5 "halve" +// lambda_advanced.baml:100:1 (comment) len=102 "// ── Shadowing: lambda param shadows outer variable ───────────────" +// lambda_advanced.baml:101:1 (keyword) len=8 "function" +// lambda_advanced.baml:101:10 (function) [declaration] len=14 "test_shadowing" +// lambda_advanced.baml:101:30 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:102:5 (keyword) len=3 "let" +// lambda_advanced.baml:102:9 (variable) [declaration] len=1 "x" +// lambda_advanced.baml:102:11 (operator) len=1 "=" +// lambda_advanced.baml:102:13 (string) len=5 "\"999\"" +// lambda_advanced.baml:103:5 (keyword) len=3 "let" +// lambda_advanced.baml:103:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:103:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:103:22 (operator) len=1 "=" +// lambda_advanced.baml:103:25 (number) len=1 "1" +// lambda_advanced.baml:103:28 (number) len=1 "2" +// lambda_advanced.baml:103:31 (number) len=1 "3" +// lambda_advanced.baml:104:5 (keyword) len=3 "let" +// lambda_advanced.baml:104:9 (variable) [declaration] len=6 "mapped" +// lambda_advanced.baml:104:17 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:104:23 (operator) len=1 "=" +// lambda_advanced.baml:104:25 (variable) len=5 "items" +// lambda_advanced.baml:104:31 (method) len=3 "map" +// lambda_advanced.baml:104:36 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:104:44 (parameter) len=1 "x" +// lambda_advanced.baml:104:46 (operator) len=1 "+" +// lambda_advanced.baml:104:48 (number) len=1 "1" +// lambda_advanced.baml:105:5 (keyword) len=3 "for" +// lambda_advanced.baml:105:10 (keyword) len=3 "let" +// lambda_advanced.baml:105:14 (variable) [declaration] len=1 "y" +// lambda_advanced.baml:105:16 (keyword) len=2 "in" +// lambda_advanced.baml:105:19 (variable) len=6 "mapped" +// lambda_advanced.baml:106:9 (keyword) len=3 "let" +// lambda_advanced.baml:106:13 (variable) [declaration] len=1 "i" +// lambda_advanced.baml:106:15 (operator) len=1 "=" +// lambda_advanced.baml:106:17 (number) len=1 "0" +// lambda_advanced.baml:107:9 (keyword) len=5 "while" +// lambda_advanced.baml:107:16 (variable) len=1 "i" +// lambda_advanced.baml:107:18 (operator) len=1 "<" +// lambda_advanced.baml:107:20 (variable) len=1 "y" +// lambda_advanced.baml:108:13 (variable) len=1 "x" +// lambda_advanced.baml:108:15 (operator) len=2 "+=" +// lambda_advanced.baml:108:18 (string) len=3 "\"1\"" +// lambda_advanced.baml:109:13 (variable) len=1 "i" +// lambda_advanced.baml:109:15 (operator) len=2 "+=" +// lambda_advanced.baml:109:18 (number) len=1 "1" +// lambda_advanced.baml:112:5 (variable) len=1 "x" +// lambda_advanced.baml:115:1 (comment) len=120 "// ── Immediately-invoked lambda expression ────────────────────────" +// lambda_advanced.baml:116:1 (keyword) len=8 "function" +// lambda_advanced.baml:116:10 (function) [declaration] len=9 "test_iife" +// lambda_advanced.baml:116:25 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:117:5 (keyword) len=3 "let" +// lambda_advanced.baml:117:9 (variable) [declaration] len=6 "result" +// lambda_advanced.baml:117:16 (operator) len=1 "=" +// lambda_advanced.baml:117:20 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:117:23 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:117:31 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:117:37 (parameter) len=1 "x" +// lambda_advanced.baml:117:39 (operator) len=1 "*" +// lambda_advanced.baml:117:41 (parameter) len=1 "x" +// lambda_advanced.baml:117:46 (number) len=1 "7" +// lambda_advanced.baml:117:49 (comment) len=5 "// 49" +// lambda_advanced.baml:118:5 (variable) len=6 "result" +// lambda_advanced.baml:121:1 (comment) len=130 "// ── Lambda with optional return type ─────────────────────────────" +// lambda_advanced.baml:122:1 (keyword) len=8 "function" +// lambda_advanced.baml:122:10 (function) [declaration] len=20 "test_optional_return" +// lambda_advanced.baml:122:36 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:123:5 (keyword) len=3 "let" +// lambda_advanced.baml:123:9 (variable) [declaration] len=5 "maybe" +// lambda_advanced.baml:123:15 (operator) len=1 "=" +// lambda_advanced.baml:123:18 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:123:21 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:123:29 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:124:9 (keyword) len=2 "if" +// lambda_advanced.baml:124:13 (parameter) len=1 "x" +// lambda_advanced.baml:124:15 (operator) len=1 ">" +// lambda_advanced.baml:124:17 (number) len=1 "0" +// lambda_advanced.baml:124:22 (parameter) len=1 "x" +// lambda_advanced.baml:125:9 (keyword) len=4 "else" +// lambda_advanced.baml:125:16 (type) [defaultLibrary] len=4 "null" +// lambda_advanced.baml:127:5 (variable) len=5 "maybe" +// lambda_advanced.baml:127:11 (operator) len=1 "-" +// lambda_advanced.baml:127:12 (number) len=1 "1" +// lambda_advanced.baml:130:1 (comment) len=201 "// ══════════════════════════════════════════════════════════════════" +// lambda_advanced.baml:131:1 (comment) len=60 "// Advanced type inference scenarios — minimal annotations" +// lambda_advanced.baml:132:1 (comment) len=201 "// ══════════════════════════════════════════════════════════════════" +// lambda_advanced.baml:134:1 (comment) len=80 "// ── map with no annotations at all: param AND return inferred ────" +// lambda_advanced.baml:135:1 (keyword) len=8 "function" +// lambda_advanced.baml:135:10 (function) [declaration] len=23 "test_fully_inferred_map" +// lambda_advanced.baml:135:39 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:136:5 (keyword) len=3 "let" +// lambda_advanced.baml:136:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:136:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:136:22 (operator) len=1 "=" +// lambda_advanced.baml:136:25 (number) len=1 "1" +// lambda_advanced.baml:136:28 (number) len=1 "2" +// lambda_advanced.baml:136:31 (number) len=1 "3" +// lambda_advanced.baml:137:5 (variable) len=5 "items" +// lambda_advanced.baml:137:11 (method) len=3 "map" +// lambda_advanced.baml:137:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:137:24 (parameter) len=1 "x" +// lambda_advanced.baml:137:26 (operator) len=1 "*" +// lambda_advanced.baml:137:28 (number) len=1 "2" +// lambda_advanced.baml:138:5 (comment) len=43 "// x: int inferred from T in Array.map" +// lambda_advanced.baml:139:5 (comment) len=39 "// return: int inferred from body x * 2" +// lambda_advanced.baml:140:5 (comment) len=34 "// U binds to int, result is int[]" +// lambda_advanced.baml:143:1 (comment) len=108 "// ── map where return type changes: infer U != T ──────────────────" +// lambda_advanced.baml:144:1 (keyword) len=8 "function" +// lambda_advanced.baml:144:10 (function) [declaration] len=29 "test_map_type_change_inferred" +// lambda_advanced.baml:144:45 (type) [defaultLibrary] len=6 "string" +// lambda_advanced.baml:145:5 (keyword) len=3 "let" +// lambda_advanced.baml:145:9 (variable) [declaration] len=4 "nums" +// lambda_advanced.baml:145:15 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:145:21 (operator) len=1 "=" +// lambda_advanced.baml:145:24 (number) len=1 "1" +// lambda_advanced.baml:145:27 (number) len=1 "2" +// lambda_advanced.baml:145:30 (number) len=1 "3" +// lambda_advanced.baml:146:5 (variable) len=4 "nums" +// lambda_advanced.baml:146:10 (method) len=3 "map" +// lambda_advanced.baml:146:15 (parameter) [declaration] len=1 "n" +// lambda_advanced.baml:147:9 (keyword) len=5 "match" +// lambda_advanced.baml:147:16 (parameter) len=1 "n" +// lambda_advanced.baml:148:13 (number) len=1 "1" +// lambda_advanced.baml:148:18 (string) len=5 "\"one\"" +// lambda_advanced.baml:149:13 (number) len=1 "2" +// lambda_advanced.baml:149:18 (string) len=5 "\"two\"" +// lambda_advanced.baml:150:18 (string) len=7 "\"other\"" +// lambda_advanced.baml:153:5 (comment) len=59 "// n: int inferred, return: string inferred from match body" +// lambda_advanced.baml:154:5 (comment) len=54 "// U binds to \"one\"|\"two\"|\"other\", result is string[]?" +// lambda_advanced.baml:157:1 (comment) len=87 "// ── Lambda returning literal 0 — does U bind to 0 or int? ───────" +// lambda_advanced.baml:158:1 (keyword) len=8 "function" +// lambda_advanced.baml:158:10 (function) [declaration] len=29 "test_literal_return_inference" +// lambda_advanced.baml:158:45 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:159:5 (keyword) len=3 "let" +// lambda_advanced.baml:159:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:159:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:159:22 (operator) len=1 "=" +// lambda_advanced.baml:159:25 (number) len=1 "1" +// lambda_advanced.baml:159:28 (number) len=1 "2" +// lambda_advanced.baml:159:31 (number) len=1 "3" +// lambda_advanced.baml:160:5 (variable) len=5 "items" +// lambda_advanced.baml:160:11 (method) len=3 "map" +// lambda_advanced.baml:160:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:160:24 (number) len=1 "0" +// lambda_advanced.baml:161:5 (comment) len=54 "// body returns literal 0, U binds to 0 (literal type)" +// lambda_advanced.baml:162:5 (comment) len=59 "// result is 0[], function returns int[] — needs 0 <: int" +// lambda_advanced.baml:165:1 (comment) len=132 "// ── Compose: fully inferred lambdas ──────────────────────────────" +// lambda_advanced.baml:166:1 (keyword) len=8 "function" +// lambda_advanced.baml:166:10 (function) [declaration] len=21 "test_compose_inferred" +// lambda_advanced.baml:166:37 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:167:5 (keyword) len=3 "let" +// lambda_advanced.baml:167:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:167:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:167:22 (operator) len=1 "=" +// lambda_advanced.baml:167:25 (number) len=1 "1" +// lambda_advanced.baml:167:28 (number) len=1 "2" +// lambda_advanced.baml:167:31 (number) len=1 "3" +// lambda_advanced.baml:168:5 (keyword) len=3 "let" +// lambda_advanced.baml:168:9 (variable) [declaration] len=5 "step1" +// lambda_advanced.baml:168:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:168:22 (operator) len=1 "=" +// lambda_advanced.baml:168:24 (variable) len=5 "items" +// lambda_advanced.baml:168:30 (method) len=3 "map" +// lambda_advanced.baml:168:35 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:168:43 (parameter) len=1 "x" +// lambda_advanced.baml:168:45 (operator) len=1 "*" +// lambda_advanced.baml:168:47 (number) len=1 "2" +// lambda_advanced.baml:169:5 (variable) len=5 "step1" +// lambda_advanced.baml:169:11 (method) len=3 "map" +// lambda_advanced.baml:169:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:169:24 (parameter) len=1 "x" +// lambda_advanced.baml:169:26 (operator) len=1 "+" +// lambda_advanced.baml:169:28 (number) len=1 "1" +// lambda_advanced.baml:170:5 (comment) len=58 "// Both lambdas: x inferred as int, return inferred as int" +// lambda_advanced.baml:173:1 (comment) len=102 "// ── Higher-order: lambda returning inferred lambda ───────────────" +// lambda_advanced.baml:174:1 (keyword) len=8 "function" +// lambda_advanced.baml:174:10 (function) [declaration] len=26 "test_higher_order_inferred" +// lambda_advanced.baml:174:42 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:175:5 (keyword) len=3 "let" +// lambda_advanced.baml:175:9 (variable) [declaration] len=10 "make_adder" +// lambda_advanced.baml:175:20 (operator) len=1 "=" +// lambda_advanced.baml:175:23 (parameter) [declaration] len=1 "n" +// lambda_advanced.baml:175:26 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:176:9 (keyword) len=3 "let" +// lambda_advanced.baml:176:13 (variable) [declaration] len=5 "adder" +// lambda_advanced.baml:176:19 (operator) len=1 "=" +// lambda_advanced.baml:176:22 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:176:25 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:176:35 (parameter) len=1 "x" +// lambda_advanced.baml:176:37 (operator) len=1 "+" +// lambda_advanced.baml:176:39 (parameter) len=1 "n" +// lambda_advanced.baml:177:9 (variable) len=5 "adder" +// lambda_advanced.baml:179:5 (comment) len=58 "// make_adder return type inferred from body: (int) -> int" +// lambda_advanced.baml:180:5 (keyword) len=3 "let" +// lambda_advanced.baml:180:9 (variable) [declaration] len=4 "add5" +// lambda_advanced.baml:180:14 (operator) len=1 "=" +// lambda_advanced.baml:180:16 (variable) len=10 "make_adder" +// lambda_advanced.baml:180:27 (number) len=1 "5" +// lambda_advanced.baml:181:5 (variable) len=4 "add5" +// lambda_advanced.baml:181:10 (number) len=2 "37" +// lambda_advanced.baml:184:1 (comment) len=106 "// ── Lambda calling lambda: no return annotations ─────────────────" +// lambda_advanced.baml:185:1 (keyword) len=8 "function" +// lambda_advanced.baml:185:10 (function) [declaration] len=25 "test_apply_twice_inferred" +// lambda_advanced.baml:185:41 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:186:5 (keyword) len=3 "let" +// lambda_advanced.baml:186:9 (variable) [declaration] len=6 "double" +// lambda_advanced.baml:186:16 (operator) len=1 "=" +// lambda_advanced.baml:186:19 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:186:22 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:186:32 (parameter) len=1 "x" +// lambda_advanced.baml:186:34 (operator) len=1 "*" +// lambda_advanced.baml:186:36 (number) len=1 "2" +// lambda_advanced.baml:187:5 (keyword) len=3 "let" +// lambda_advanced.baml:187:9 (variable) [declaration] len=11 "apply_twice" +// lambda_advanced.baml:187:21 (operator) len=1 "=" +// lambda_advanced.baml:187:24 (parameter) [declaration] len=1 "f" +// lambda_advanced.baml:187:28 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:187:36 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:187:41 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:187:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:187:54 (parameter) len=1 "f" +// lambda_advanced.baml:187:56 (parameter) len=1 "f" +// lambda_advanced.baml:187:58 (parameter) len=1 "x" +// lambda_advanced.baml:188:5 (variable) len=11 "apply_twice" +// lambda_advanced.baml:188:17 (variable) len=6 "double" +// lambda_advanced.baml:188:25 (number) len=1 "3" +// lambda_advanced.baml:191:1 (comment) len=116 "// ── Deep capture with inferred return types ──────────────────────" +// lambda_advanced.baml:192:1 (keyword) len=8 "function" +// lambda_advanced.baml:192:10 (function) [declaration] len=26 "test_deep_capture_inferred" +// lambda_advanced.baml:192:42 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:193:5 (keyword) len=3 "let" +// lambda_advanced.baml:193:9 (variable) [declaration] len=1 "a" +// lambda_advanced.baml:193:11 (operator) len=1 "=" +// lambda_advanced.baml:193:13 (number) len=1 "1" +// lambda_advanced.baml:194:5 (keyword) len=3 "let" +// lambda_advanced.baml:194:9 (variable) [declaration] len=1 "f" +// lambda_advanced.baml:194:11 (operator) len=1 "=" +// lambda_advanced.baml:194:14 (parameter) [declaration] len=1 "b" +// lambda_advanced.baml:194:17 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:195:9 (keyword) len=3 "let" +// lambda_advanced.baml:195:13 (variable) [declaration] len=1 "g" +// lambda_advanced.baml:195:15 (operator) len=1 "=" +// lambda_advanced.baml:195:18 (parameter) [declaration] len=1 "c" +// lambda_advanced.baml:195:21 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:195:31 (variable) len=1 "a" +// lambda_advanced.baml:195:33 (operator) len=1 "+" +// lambda_advanced.baml:195:35 (parameter) len=1 "b" +// lambda_advanced.baml:195:37 (operator) len=1 "+" +// lambda_advanced.baml:195:39 (parameter) len=1 "c" +// lambda_advanced.baml:196:9 (variable) len=1 "g" +// lambda_advanced.baml:196:11 (number) len=3 "100" +// lambda_advanced.baml:198:5 (variable) len=1 "f" +// lambda_advanced.baml:198:7 (number) len=2 "10" +// lambda_advanced.baml:201:1 (comment) len=126 "// ── Multiple lambda args: all inferred ───────────────────────────" +// lambda_advanced.baml:202:1 (keyword) len=8 "function" +// lambda_advanced.baml:202:10 (function) [declaration] len=28 "test_two_transforms_inferred" +// lambda_advanced.baml:202:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:5 (keyword) len=3 "let" +// lambda_advanced.baml:203:9 (variable) [declaration] len=10 "apply_both" +// lambda_advanced.baml:203:20 (operator) len=1 "=" +// lambda_advanced.baml:203:23 (parameter) [declaration] len=1 "f" +// lambda_advanced.baml:203:27 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:35 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:40 (parameter) [declaration] len=1 "g" +// lambda_advanced.baml:203:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:52 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:57 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:203:60 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:203:70 (parameter) len=1 "g" +// lambda_advanced.baml:203:72 (parameter) len=1 "f" +// lambda_advanced.baml:203:74 (parameter) len=1 "x" +// lambda_advanced.baml:204:5 (variable) len=10 "apply_both" +// lambda_advanced.baml:205:10 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:205:13 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:205:23 (parameter) len=1 "x" +// lambda_advanced.baml:205:25 (operator) len=1 "*" +// lambda_advanced.baml:205:27 (number) len=1 "2" +// lambda_advanced.baml:206:10 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:206:13 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:206:23 (parameter) len=1 "x" +// lambda_advanced.baml:206:25 (operator) len=1 "+" +// lambda_advanced.baml:206:27 (number) len=2 "10" +// lambda_advanced.baml:207:9 (number) len=1 "5" +// lambda_advanced.baml:211:1 (comment) len=88 "// ── Lambda in match arms: return type unified across arms ────────" +// lambda_advanced.baml:212:1 (keyword) len=8 "function" +// lambda_advanced.baml:212:10 (function) [declaration] len=29 "test_lambda_in_match_inferred" +// lambda_advanced.baml:212:45 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:213:5 (keyword) len=3 "let" +// lambda_advanced.baml:213:9 (variable) [declaration] len=2 "op" +// lambda_advanced.baml:213:12 (operator) len=1 "=" +// lambda_advanced.baml:213:14 (string) len=8 "\"double\"" +// lambda_advanced.baml:214:5 (keyword) len=3 "let" +// lambda_advanced.baml:214:9 (variable) [declaration] len=1 "f" +// lambda_advanced.baml:214:11 (operator) len=1 "=" +// lambda_advanced.baml:214:13 (keyword) len=5 "match" +// lambda_advanced.baml:214:20 (variable) len=2 "op" +// lambda_advanced.baml:215:9 (string) len=8 "\"double\"" +// lambda_advanced.baml:215:22 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:215:25 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:215:35 (parameter) len=1 "x" +// lambda_advanced.baml:215:37 (operator) len=1 "*" +// lambda_advanced.baml:215:39 (number) len=1 "2" +// lambda_advanced.baml:216:9 (string) len=8 "\"negate\"" +// lambda_advanced.baml:216:22 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:216:25 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:216:35 (number) len=1 "0" +// lambda_advanced.baml:216:37 (operator) len=1 "-" +// lambda_advanced.baml:216:39 (parameter) len=1 "x" +// lambda_advanced.baml:217:15 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:217:18 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:217:28 (parameter) len=1 "x" +// lambda_advanced.baml:219:5 (variable) len=1 "f" +// lambda_advanced.baml:219:7 (number) len=2 "21" +// lambda_advanced.baml:222:1 (comment) len=86 "// ── Capture + map: inferred capture type flows into lambda ───────" +// lambda_advanced.baml:223:1 (keyword) len=8 "function" +// lambda_advanced.baml:223:10 (function) [declaration] len=28 "test_capture_in_map_inferred" +// lambda_advanced.baml:223:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:224:5 (keyword) len=3 "let" +// lambda_advanced.baml:224:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:224:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:224:22 (operator) len=1 "=" +// lambda_advanced.baml:224:25 (number) len=1 "1" +// lambda_advanced.baml:224:28 (number) len=1 "2" +// lambda_advanced.baml:224:31 (number) len=1 "3" +// lambda_advanced.baml:225:5 (keyword) len=3 "let" +// lambda_advanced.baml:225:9 (variable) [declaration] len=6 "factor" +// lambda_advanced.baml:225:16 (operator) len=1 "=" +// lambda_advanced.baml:225:18 (number) len=2 "10" +// lambda_advanced.baml:226:5 (variable) len=5 "items" +// lambda_advanced.baml:226:11 (method) len=3 "map" +// lambda_advanced.baml:226:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:226:24 (parameter) len=1 "x" +// lambda_advanced.baml:226:26 (operator) len=1 "*" +// lambda_advanced.baml:226:28 (variable) len=6 "factor" +// lambda_advanced.baml:227:5 (comment) len=56 "// x inferred as int, factor captured as int, return int" +// lambda_advanced.baml:230:1 (comment) len=138 "// ── Void lambda: no return value ─────────────────────────────────" +// lambda_advanced.baml:231:1 (keyword) len=8 "function" +// lambda_advanced.baml:231:10 (function) [declaration] len=25 "test_void_lambda_inferred" +// lambda_advanced.baml:231:41 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:232:5 (keyword) len=3 "let" +// lambda_advanced.baml:232:9 (variable) [declaration] len=5 "count" +// lambda_advanced.baml:232:15 (operator) len=1 "=" +// lambda_advanced.baml:232:17 (number) len=1 "0" +// lambda_advanced.baml:233:5 (keyword) len=3 "let" +// lambda_advanced.baml:233:9 (variable) [declaration] len=3 "inc" +// lambda_advanced.baml:233:13 (operator) len=1 "=" +// lambda_advanced.baml:233:23 (variable) len=5 "count" +// lambda_advanced.baml:233:29 (operator) len=2 "+=" +// lambda_advanced.baml:233:32 (number) len=1 "1" +// lambda_advanced.baml:234:5 (variable) len=3 "inc" +// lambda_advanced.baml:235:5 (variable) len=3 "inc" +// lambda_advanced.baml:236:5 (variable) len=5 "count" +// lambda_advanced.baml:239:1 (keyword) len=8 "function" +// lambda_advanced.baml:239:10 (function) [declaration] len=34 "test_void_lambda_inferred_captures" +// lambda_advanced.baml:239:50 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:240:5 (keyword) len=3 "let" +// lambda_advanced.baml:240:9 (variable) [declaration] len=3 "inc" +// lambda_advanced.baml:240:13 (operator) len=1 "=" +// lambda_advanced.baml:241:9 (keyword) len=3 "let" +// lambda_advanced.baml:241:13 (variable) [declaration] len=5 "count" +// lambda_advanced.baml:241:19 (operator) len=1 "=" +// lambda_advanced.baml:241:21 (number) len=1 "0" +// lambda_advanced.baml:242:9 (keyword) len=3 "let" +// lambda_advanced.baml:242:13 (variable) [declaration] len=3 "inc" +// lambda_advanced.baml:242:17 (operator) len=1 "=" +// lambda_advanced.baml:242:27 (variable) len=5 "count" +// lambda_advanced.baml:242:33 (operator) len=2 "+=" +// lambda_advanced.baml:242:36 (number) len=1 "1" +// lambda_advanced.baml:242:39 (variable) len=5 "count" +// lambda_advanced.baml:243:9 (variable) len=3 "inc" +// lambda_advanced.baml:245:5 (variable) len=3 "inc" +// lambda_advanced.baml:246:5 (variable) len=3 "inc" +// lambda_advanced.baml:247:5 (variable) len=3 "inc" +// lambda_advanced.baml:251:1 (comment) len=132 "// ── Lambda capturing another lambda ──────────────────────────────" +// lambda_advanced.baml:252:1 (keyword) len=8 "function" +// lambda_advanced.baml:252:10 (function) [declaration] len=28 "test_capture_lambda_inferred" +// lambda_advanced.baml:252:44 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:253:5 (keyword) len=3 "let" +// lambda_advanced.baml:253:9 (variable) [declaration] len=8 "multiply" +// lambda_advanced.baml:253:18 (operator) len=1 "=" +// lambda_advanced.baml:253:21 (parameter) [declaration] len=1 "a" +// lambda_advanced.baml:253:24 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:253:29 (parameter) [declaration] len=1 "b" +// lambda_advanced.baml:253:32 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:253:42 (parameter) len=1 "a" +// lambda_advanced.baml:253:44 (operator) len=1 "*" +// lambda_advanced.baml:253:46 (parameter) len=1 "b" +// lambda_advanced.baml:254:5 (keyword) len=3 "let" +// lambda_advanced.baml:254:9 (variable) [declaration] len=6 "double" +// lambda_advanced.baml:254:16 (operator) len=1 "=" +// lambda_advanced.baml:254:19 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:254:22 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:254:32 (variable) len=8 "multiply" +// lambda_advanced.baml:254:41 (parameter) len=1 "x" +// lambda_advanced.baml:254:44 (number) len=1 "2" +// lambda_advanced.baml:255:5 (variable) len=6 "double" +// lambda_advanced.baml:255:12 (number) len=2 "21" +// lambda_advanced.baml:258:1 (comment) len=96 "// ── Map over optional array: param type int? inferred ────────────" +// lambda_advanced.baml:259:1 (keyword) len=8 "function" +// lambda_advanced.baml:259:10 (function) [declaration] len=26 "test_map_optional_inferred" +// lambda_advanced.baml:259:42 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:260:5 (keyword) len=3 "let" +// lambda_advanced.baml:260:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:260:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:260:23 (operator) len=1 "=" +// lambda_advanced.baml:260:26 (number) len=1 "1" +// lambda_advanced.baml:260:29 (type) [defaultLibrary] len=4 "null" +// lambda_advanced.baml:260:35 (number) len=1 "3" +// lambda_advanced.baml:261:5 (variable) len=5 "items" +// lambda_advanced.baml:261:11 (method) len=3 "map" +// lambda_advanced.baml:261:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:262:9 (keyword) len=5 "match" +// lambda_advanced.baml:262:16 (parameter) len=1 "x" +// lambda_advanced.baml:263:13 (type) [defaultLibrary] len=4 "null" +// lambda_advanced.baml:263:21 (number) len=1 "0" +// lambda_advanced.baml:264:18 (number) len=1 "1" +// lambda_advanced.baml:267:5 (comment) len=45 "// x: int? inferred from T in Array.map" +// lambda_advanced.baml:268:5 (comment) len=34 "// return: 0|1 inferred from match" +// lambda_advanced.baml:271:1 (comment) len=136 "// ── Shadowing with inferred types ────────────────────────────────" +// lambda_advanced.baml:272:1 (keyword) len=8 "function" +// lambda_advanced.baml:272:10 (function) [declaration] len=23 "test_shadowing_inferred" +// lambda_advanced.baml:272:39 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:273:5 (keyword) len=3 "let" +// lambda_advanced.baml:273:9 (variable) [declaration] len=1 "x" +// lambda_advanced.baml:273:11 (operator) len=1 "=" +// lambda_advanced.baml:273:13 (string) len=14 "\"not a number\"" +// lambda_advanced.baml:274:5 (keyword) len=3 "let" +// lambda_advanced.baml:274:9 (variable) [declaration] len=5 "items" +// lambda_advanced.baml:274:16 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:274:22 (operator) len=1 "=" +// lambda_advanced.baml:274:25 (number) len=1 "1" +// lambda_advanced.baml:274:28 (number) len=1 "2" +// lambda_advanced.baml:274:31 (number) len=1 "3" +// lambda_advanced.baml:275:5 (variable) len=5 "items" +// lambda_advanced.baml:275:11 (method) len=3 "map" +// lambda_advanced.baml:275:16 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:275:24 (parameter) len=1 "x" +// lambda_advanced.baml:275:26 (operator) len=1 "+" +// lambda_advanced.baml:275:28 (number) len=1 "1" +// lambda_advanced.baml:276:5 (comment) len=60 "// lambda x: int (from map context), shadows outer x: string" +// lambda_advanced.baml:279:1 (comment) len=146 "// ── IIFE with inferred types ─────────────────────────────────────" +// lambda_advanced.baml:280:1 (keyword) len=8 "function" +// lambda_advanced.baml:280:10 (function) [declaration] len=18 "test_iife_inferred" +// lambda_advanced.baml:280:34 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:281:7 (parameter) [declaration] len=1 "x" +// lambda_advanced.baml:281:10 (type) [defaultLibrary] len=3 "int" +// lambda_advanced.baml:281:20 (parameter) len=1 "x" +// lambda_advanced.baml:281:22 (operator) len=1 "*" +// lambda_advanced.baml:281:24 (parameter) len=1 "x" +// lambda_advanced.baml:281:29 (number) len=1 "7" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/literal_types.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/literal_types.baml new file mode 100644 index 0000000000..69b1828d71 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/literal_types.baml @@ -0,0 +1,52 @@ +class TestLiterals { + a "SingleLiteral" + b "Field" | "With" | "Multiple" | "Literals" + c "Field" | "With" | "Some" @description("Description") + d 2 | 3 + e "Optional"? + f 2 | "SomeString" + g "boolean" | true | false +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// literal_types.baml:1:1 (keyword) len=5 "class" +// literal_types.baml:1:7 (class) [declaration] len=12 "TestLiterals" +// literal_types.baml:2:3 (property) [declaration] len=1 "a" +// literal_types.baml:2:5 (string) len=15 "\"SingleLiteral\"" +// literal_types.baml:3:3 (property) [declaration] len=1 "b" +// literal_types.baml:3:5 (string) len=7 "\"Field\"" +// literal_types.baml:3:13 (operator) len=1 "|" +// literal_types.baml:3:15 (string) len=6 "\"With\"" +// literal_types.baml:3:22 (operator) len=1 "|" +// literal_types.baml:3:24 (string) len=10 "\"Multiple\"" +// literal_types.baml:3:35 (operator) len=1 "|" +// literal_types.baml:3:37 (string) len=10 "\"Literals\"" +// literal_types.baml:4:3 (property) [declaration] len=1 "c" +// literal_types.baml:4:5 (string) len=7 "\"Field\"" +// literal_types.baml:4:13 (operator) len=1 "|" +// literal_types.baml:4:15 (string) len=6 "\"With\"" +// literal_types.baml:4:22 (operator) len=1 "|" +// literal_types.baml:4:24 (string) len=6 "\"Some\"" +// literal_types.baml:4:31 (decorator) len=1 "@" +// literal_types.baml:4:32 (decorator) len=11 "description" +// literal_types.baml:4:44 (string) len=13 "\"Description\"" +// literal_types.baml:5:3 (property) [declaration] len=1 "d" +// literal_types.baml:5:5 (number) len=1 "2" +// literal_types.baml:5:7 (operator) len=1 "|" +// literal_types.baml:5:9 (number) len=1 "3" +// literal_types.baml:6:3 (property) [declaration] len=1 "e" +// literal_types.baml:6:5 (string) len=10 "\"Optional\"" +// literal_types.baml:7:3 (property) [declaration] len=1 "f" +// literal_types.baml:7:5 (number) len=1 "2" +// literal_types.baml:7:7 (operator) len=1 "|" +// literal_types.baml:7:9 (string) len=12 "\"SomeString\"" +// literal_types.baml:8:3 (property) [declaration] len=1 "g" +// literal_types.baml:8:5 (string) len=9 "\"boolean\"" +// literal_types.baml:8:15 (operator) len=1 "|" +// literal_types.baml:8:17 (type) len=4 "true" +// literal_types.baml:8:22 (operator) len=1 "|" +// literal_types.baml:8:24 (type) len=5 "false" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/llm_function.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/llm_function.baml index 49db24f05a..1764804e12 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/llm_function.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/llm_function.baml @@ -32,33 +32,31 @@ function ClassifyEmail(email: Email) -> Category { // //- semantic_tokens // llm_function.baml:1:1 (keyword) len=5 "class" -// llm_function.baml:1:7 (class) len=5 "Email" -// llm_function.baml:2:3 (property) len=7 "subject" -// llm_function.baml:2:11 (type) len=6 "string" -// llm_function.baml:3:3 (property) len=4 "body" -// llm_function.baml:3:8 (type) len=6 "string" +// llm_function.baml:1:7 (class) [declaration] len=5 "Email" +// llm_function.baml:2:3 (property) [declaration] len=7 "subject" +// llm_function.baml:2:11 (type) [defaultLibrary] len=6 "string" +// llm_function.baml:3:3 (property) [declaration] len=4 "body" +// llm_function.baml:3:8 (type) [defaultLibrary] len=6 "string" // llm_function.baml:6:1 (keyword) len=4 "enum" -// llm_function.baml:6:6 (enum) len=8 "Category" -// llm_function.baml:7:3 (enumMember) len=4 "Spam" -// llm_function.baml:8:3 (enumMember) len=3 "Ham" +// llm_function.baml:6:6 (enum) [declaration] len=8 "Category" +// llm_function.baml:7:3 (enumMember) [declaration] len=4 "Spam" +// llm_function.baml:8:3 (enumMember) [declaration] len=3 "Ham" // llm_function.baml:11:1 (keyword) len=6 "client" // llm_function.baml:11:7 (operator) len=1 "<" // llm_function.baml:11:8 (type) len=3 "llm" // llm_function.baml:11:11 (operator) len=1 ">" -// llm_function.baml:11:13 (struct) len=4 "GPT4" +// llm_function.baml:11:13 (struct) [declaration] len=4 "GPT4" // llm_function.baml:12:3 (property) len=8 "provider" // llm_function.baml:13:3 (property) len=7 "options" // llm_function.baml:14:5 (property) len=5 "model" -// llm_function.baml:14:11 (string) len=1 "\"" -// llm_function.baml:14:12 (string) len=5 "gpt-4" -// llm_function.baml:14:17 (string) len=1 "\"" +// llm_function.baml:14:11 (string) len=7 "\"gpt-4\"" // llm_function.baml:18:1 (keyword) len=8 "function" -// llm_function.baml:18:10 (function) len=13 "ClassifyEmail" -// llm_function.baml:18:24 (parameter) len=5 "email" +// llm_function.baml:18:10 (function) [declaration] len=13 "ClassifyEmail" +// llm_function.baml:18:24 (parameter) [declaration] len=5 "email" // llm_function.baml:18:31 (class) len=5 "Email" // llm_function.baml:18:41 (enum) len=8 "Category" // llm_function.baml:19:3 (property) len=6 "client" -// llm_function.baml:20:3 (property) len=6 "prompt" +// llm_function.baml:20:3 (property) [declaration] len=6 "prompt" // llm_function.baml:20:10 (string) len=1 "#" // llm_function.baml:20:11 (string) len=1 "\"" // llm_function.baml:21:5 (string) len=8 "Classify" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_literal_keys.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_literal_keys.baml new file mode 100644 index 0000000000..568693a468 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_literal_keys.baml @@ -0,0 +1,283 @@ +enum MapKey { + A + B + C +} + +class Fields { + e map + l1 map<"literal", string> + l2 map<"one" | "two" | ("three" | "four"), string> +} + +function InOutEnumKey(i1: map, i2: map) -> map { + client "openai/gpt-4o" + prompt #" + Merge these: {{i1}} {{i2}} + + {{ ctx.output_format }} + "# +} + +function InOutLiteralStringUnionMapKey( + i1: map<"one" | "two" | ("three" | "four"), string>, + i2: map<"one" | "two" | ("three" | "four"), string> +) -> map<"one" | "two" | ("three" | "four"), string> { + client "openai/gpt-4o" + prompt #" + Merge these: + + {{i1}} + + {{i2}} + + {{ ctx.output_format }} + "# +} + +//---- +//- diagnostics +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:76 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:27 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:52 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:96 ] +// │ +// 13 │ ╭─▶ function InOutEnumKey(i1: map, i2: map) -> map { +// ┆ ┆ +// 20 │ ├─▶ } +// │ │ +// │ ╰─────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:27 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:52 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:27 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:52 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:27 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:13:52 ] +// │ +// 13 │ function InOutEnumKey(i1: map, i2: map) -> map { +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ────╯ +// error: map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// ╭─[ map_literal_keys.baml:8:5 ] +// │ +// 8 │ e map +// │ ─────────┬───────── +// │ ╰─────────── map keys must be `string`; got `MapKey`. Declare the map as `map`; convert non-string keys with `.to_string()` before `.set()` or `.get()` +// │ +// │ Note: Error code: E0067 +// ───╯ +// +//- semantic_tokens +// map_literal_keys.baml:1:1 (keyword) len=4 "enum" +// map_literal_keys.baml:1:6 (enum) [declaration] len=6 "MapKey" +// map_literal_keys.baml:2:3 (enumMember) [declaration] len=1 "A" +// map_literal_keys.baml:3:3 (enumMember) [declaration] len=1 "B" +// map_literal_keys.baml:4:3 (enumMember) [declaration] len=1 "C" +// map_literal_keys.baml:7:1 (keyword) len=5 "class" +// map_literal_keys.baml:7:7 (class) [declaration] len=6 "Fields" +// map_literal_keys.baml:8:3 (property) [declaration] len=1 "e" +// map_literal_keys.baml:8:5 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:8:8 (operator) len=1 "<" +// map_literal_keys.baml:8:9 (enum) len=6 "MapKey" +// map_literal_keys.baml:8:17 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:8:23 (operator) len=1 ">" +// map_literal_keys.baml:9:3 (property) [declaration] len=2 "l1" +// map_literal_keys.baml:9:6 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:9:9 (operator) len=1 "<" +// map_literal_keys.baml:9:10 (string) len=9 "\"literal\"" +// map_literal_keys.baml:9:21 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:9:27 (operator) len=1 ">" +// map_literal_keys.baml:10:3 (property) [declaration] len=2 "l2" +// map_literal_keys.baml:10:6 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:10:9 (operator) len=1 "<" +// map_literal_keys.baml:10:10 (string) len=5 "\"one\"" +// map_literal_keys.baml:10:16 (operator) len=1 "|" +// map_literal_keys.baml:10:18 (string) len=5 "\"two\"" +// map_literal_keys.baml:10:24 (operator) len=1 "|" +// map_literal_keys.baml:10:27 (string) len=7 "\"three\"" +// map_literal_keys.baml:10:35 (operator) len=1 "|" +// map_literal_keys.baml:10:37 (string) len=6 "\"four\"" +// map_literal_keys.baml:10:46 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:10:52 (operator) len=1 ">" +// map_literal_keys.baml:13:1 (keyword) len=8 "function" +// map_literal_keys.baml:13:10 (function) [declaration] len=12 "InOutEnumKey" +// map_literal_keys.baml:13:23 (parameter) [declaration] len=2 "i1" +// map_literal_keys.baml:13:27 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:13:30 (operator) len=1 "<" +// map_literal_keys.baml:13:31 (enum) len=6 "MapKey" +// map_literal_keys.baml:13:39 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:13:45 (operator) len=1 ">" +// map_literal_keys.baml:13:48 (parameter) [declaration] len=2 "i2" +// map_literal_keys.baml:13:52 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:13:55 (operator) len=1 "<" +// map_literal_keys.baml:13:56 (enum) len=6 "MapKey" +// map_literal_keys.baml:13:64 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:13:70 (operator) len=1 ">" +// map_literal_keys.baml:13:76 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:13:79 (operator) len=1 "<" +// map_literal_keys.baml:13:80 (enum) len=6 "MapKey" +// map_literal_keys.baml:13:88 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:13:94 (operator) len=1 ">" +// map_literal_keys.baml:14:3 (property) len=6 "client" +// map_literal_keys.baml:14:10 (string) len=15 "\"openai/gpt-4o\"" +// map_literal_keys.baml:15:3 (property) [declaration] len=6 "prompt" +// map_literal_keys.baml:15:10 (string) len=1 "#" +// map_literal_keys.baml:15:11 (string) len=1 "\"" +// map_literal_keys.baml:16:5 (string) len=5 "Merge" +// map_literal_keys.baml:16:11 (string) len=5 "these" +// map_literal_keys.baml:16:16 (string) len=1 ":" +// map_literal_keys.baml:16:18 (string) len=1 "{" +// map_literal_keys.baml:16:19 (string) len=1 "{" +// map_literal_keys.baml:16:20 (string) len=2 "i1" +// map_literal_keys.baml:16:22 (string) len=1 "}" +// map_literal_keys.baml:16:23 (string) len=1 "}" +// map_literal_keys.baml:16:25 (string) len=1 "{" +// map_literal_keys.baml:16:26 (string) len=1 "{" +// map_literal_keys.baml:16:27 (string) len=2 "i2" +// map_literal_keys.baml:16:29 (string) len=1 "}" +// map_literal_keys.baml:16:30 (string) len=1 "}" +// map_literal_keys.baml:18:5 (string) len=1 "{" +// map_literal_keys.baml:18:6 (string) len=1 "{" +// map_literal_keys.baml:18:8 (string) len=3 "ctx" +// map_literal_keys.baml:18:11 (string) len=1 "." +// map_literal_keys.baml:18:12 (string) len=13 "output_format" +// map_literal_keys.baml:18:26 (string) len=1 "}" +// map_literal_keys.baml:18:27 (string) len=1 "}" +// map_literal_keys.baml:19:3 (string) len=1 "\"" +// map_literal_keys.baml:19:4 (string) len=1 "#" +// map_literal_keys.baml:22:1 (keyword) len=8 "function" +// map_literal_keys.baml:22:10 (function) [declaration] len=29 "InOutLiteralStringUnionMapKey" +// map_literal_keys.baml:23:3 (parameter) [declaration] len=2 "i1" +// map_literal_keys.baml:23:7 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:23:10 (operator) len=1 "<" +// map_literal_keys.baml:23:11 (string) len=5 "\"one\"" +// map_literal_keys.baml:23:17 (operator) len=1 "|" +// map_literal_keys.baml:23:19 (string) len=5 "\"two\"" +// map_literal_keys.baml:23:25 (operator) len=1 "|" +// map_literal_keys.baml:23:28 (string) len=7 "\"three\"" +// map_literal_keys.baml:23:36 (operator) len=1 "|" +// map_literal_keys.baml:23:38 (string) len=6 "\"four\"" +// map_literal_keys.baml:23:47 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:23:53 (operator) len=1 ">" +// map_literal_keys.baml:24:3 (parameter) [declaration] len=2 "i2" +// map_literal_keys.baml:24:7 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:24:10 (operator) len=1 "<" +// map_literal_keys.baml:24:11 (string) len=5 "\"one\"" +// map_literal_keys.baml:24:17 (operator) len=1 "|" +// map_literal_keys.baml:24:19 (string) len=5 "\"two\"" +// map_literal_keys.baml:24:25 (operator) len=1 "|" +// map_literal_keys.baml:24:28 (string) len=7 "\"three\"" +// map_literal_keys.baml:24:36 (operator) len=1 "|" +// map_literal_keys.baml:24:38 (string) len=6 "\"four\"" +// map_literal_keys.baml:24:47 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:24:53 (operator) len=1 ">" +// map_literal_keys.baml:25:6 (type) [defaultLibrary] len=3 "map" +// map_literal_keys.baml:25:9 (operator) len=1 "<" +// map_literal_keys.baml:25:10 (string) len=5 "\"one\"" +// map_literal_keys.baml:25:16 (operator) len=1 "|" +// map_literal_keys.baml:25:18 (string) len=5 "\"two\"" +// map_literal_keys.baml:25:24 (operator) len=1 "|" +// map_literal_keys.baml:25:27 (string) len=7 "\"three\"" +// map_literal_keys.baml:25:35 (operator) len=1 "|" +// map_literal_keys.baml:25:37 (string) len=6 "\"four\"" +// map_literal_keys.baml:25:46 (type) [defaultLibrary] len=6 "string" +// map_literal_keys.baml:25:52 (operator) len=1 ">" +// map_literal_keys.baml:26:3 (property) len=6 "client" +// map_literal_keys.baml:26:10 (string) len=15 "\"openai/gpt-4o\"" +// map_literal_keys.baml:27:3 (property) [declaration] len=6 "prompt" +// map_literal_keys.baml:27:10 (string) len=1 "#" +// map_literal_keys.baml:27:11 (string) len=1 "\"" +// map_literal_keys.baml:28:5 (string) len=5 "Merge" +// map_literal_keys.baml:28:11 (string) len=5 "these" +// map_literal_keys.baml:28:16 (string) len=1 ":" +// map_literal_keys.baml:30:5 (string) len=1 "{" +// map_literal_keys.baml:30:6 (string) len=1 "{" +// map_literal_keys.baml:30:7 (string) len=2 "i1" +// map_literal_keys.baml:30:9 (string) len=1 "}" +// map_literal_keys.baml:30:10 (string) len=1 "}" +// map_literal_keys.baml:32:5 (string) len=1 "{" +// map_literal_keys.baml:32:6 (string) len=1 "{" +// map_literal_keys.baml:32:7 (string) len=2 "i2" +// map_literal_keys.baml:32:9 (string) len=1 "}" +// map_literal_keys.baml:32:10 (string) len=1 "}" +// map_literal_keys.baml:34:5 (string) len=1 "{" +// map_literal_keys.baml:34:6 (string) len=1 "{" +// map_literal_keys.baml:34:8 (string) len=3 "ctx" +// map_literal_keys.baml:34:11 (string) len=1 "." +// map_literal_keys.baml:34:12 (string) len=13 "output_format" +// map_literal_keys.baml:34:26 (string) len=1 "}" +// map_literal_keys.baml:34:27 (string) len=1 "}" +// map_literal_keys.baml:35:3 (string) len=1 "\"" +// map_literal_keys.baml:35:4 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_type_and_methods.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_type_and_methods.baml new file mode 100644 index 0000000000..7292bde99f --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_type_and_methods.baml @@ -0,0 +1,97 @@ +function CreateMap() -> map { + { "hello": "world" } +} + +function CreateMapJSON() -> map { + {"hello": "world"} +} + +function UseMap() -> string { + let map = CreateMap(); + map["hello"] +} + +function UseMapNoKey() -> string { + let map = CreateMapJSON(); + map["world"] +} + +function UseMapContains() -> string { + let map = CreateMapJSON(); + if (map.has("hello")) { + map["hello"] + } else { + "hi" + } +} + +function Len() -> int { + let map = CreateMap(); + map.length() +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// map_type_and_methods.baml:1:1 (keyword) len=8 "function" +// map_type_and_methods.baml:1:10 (function) [declaration] len=9 "CreateMap" +// map_type_and_methods.baml:1:25 (type) [defaultLibrary] len=3 "map" +// map_type_and_methods.baml:1:28 (operator) len=1 "<" +// map_type_and_methods.baml:1:29 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:1:37 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:1:43 (operator) len=1 ">" +// map_type_and_methods.baml:2:7 (string) len=7 "\"hello\"" +// map_type_and_methods.baml:2:16 (string) len=7 "\"world\"" +// map_type_and_methods.baml:5:1 (keyword) len=8 "function" +// map_type_and_methods.baml:5:10 (function) [declaration] len=13 "CreateMapJSON" +// map_type_and_methods.baml:5:29 (type) [defaultLibrary] len=3 "map" +// map_type_and_methods.baml:5:32 (operator) len=1 "<" +// map_type_and_methods.baml:5:33 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:5:41 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:5:47 (operator) len=1 ">" +// map_type_and_methods.baml:6:6 (string) len=7 "\"hello\"" +// map_type_and_methods.baml:6:15 (string) len=7 "\"world\"" +// map_type_and_methods.baml:9:1 (keyword) len=8 "function" +// map_type_and_methods.baml:9:10 (function) [declaration] len=6 "UseMap" +// map_type_and_methods.baml:9:22 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:10:5 (keyword) len=3 "let" +// map_type_and_methods.baml:10:9 (variable) [declaration] len=3 "map" +// map_type_and_methods.baml:10:13 (operator) len=1 "=" +// map_type_and_methods.baml:10:15 (function) len=9 "CreateMap" +// map_type_and_methods.baml:11:5 (variable) len=3 "map" +// map_type_and_methods.baml:11:9 (string) len=7 "\"hello\"" +// map_type_and_methods.baml:14:1 (keyword) len=8 "function" +// map_type_and_methods.baml:14:10 (function) [declaration] len=11 "UseMapNoKey" +// map_type_and_methods.baml:14:27 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:15:5 (keyword) len=3 "let" +// map_type_and_methods.baml:15:9 (variable) [declaration] len=3 "map" +// map_type_and_methods.baml:15:13 (operator) len=1 "=" +// map_type_and_methods.baml:15:15 (function) len=13 "CreateMapJSON" +// map_type_and_methods.baml:16:5 (variable) len=3 "map" +// map_type_and_methods.baml:16:9 (string) len=7 "\"world\"" +// map_type_and_methods.baml:19:1 (keyword) len=8 "function" +// map_type_and_methods.baml:19:10 (function) [declaration] len=14 "UseMapContains" +// map_type_and_methods.baml:19:30 (type) [defaultLibrary] len=6 "string" +// map_type_and_methods.baml:20:5 (keyword) len=3 "let" +// map_type_and_methods.baml:20:9 (variable) [declaration] len=3 "map" +// map_type_and_methods.baml:20:13 (operator) len=1 "=" +// map_type_and_methods.baml:20:15 (function) len=13 "CreateMapJSON" +// map_type_and_methods.baml:21:5 (keyword) len=2 "if" +// map_type_and_methods.baml:21:9 (variable) len=3 "map" +// map_type_and_methods.baml:21:13 (method) len=3 "has" +// map_type_and_methods.baml:21:17 (string) len=7 "\"hello\"" +// map_type_and_methods.baml:22:9 (variable) len=3 "map" +// map_type_and_methods.baml:22:13 (string) len=7 "\"hello\"" +// map_type_and_methods.baml:23:7 (keyword) len=4 "else" +// map_type_and_methods.baml:24:9 (string) len=4 "\"hi\"" +// map_type_and_methods.baml:28:1 (keyword) len=8 "function" +// map_type_and_methods.baml:28:10 (function) [declaration] len=3 "Len" +// map_type_and_methods.baml:28:19 (type) [defaultLibrary] len=3 "int" +// map_type_and_methods.baml:29:5 (keyword) len=3 "let" +// map_type_and_methods.baml:29:9 (variable) [declaration] len=3 "map" +// map_type_and_methods.baml:29:13 (operator) len=1 "=" +// map_type_and_methods.baml:29:15 (function) len=9 "CreateMap" +// map_type_and_methods.baml:30:5 (variable) len=3 "map" +// map_type_and_methods.baml:30:9 (method) len=6 "length" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_expr.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_expr.baml index 474447bd93..c8fbeeb7b8 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_expr.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_expr.baml @@ -29,31 +29,25 @@ function Describe(pet: Pet) -> string { // //- semantic_tokens // match_expr.baml:1:1 (keyword) len=5 "class" -// match_expr.baml:1:7 (class) len=3 "Dog" -// match_expr.baml:2:3 (property) len=4 "type" -// match_expr.baml:2:8 (string) len=1 "\"" -// match_expr.baml:2:9 (string) len=3 "dog" -// match_expr.baml:2:12 (string) len=1 "\"" -// match_expr.baml:3:3 (property) len=4 "name" -// match_expr.baml:3:8 (type) len=6 "string" +// match_expr.baml:1:7 (class) [declaration] len=3 "Dog" +// match_expr.baml:2:3 (property) [declaration] len=4 "type" +// match_expr.baml:2:8 (string) len=5 "\"dog\"" +// match_expr.baml:3:3 (property) [declaration] len=4 "name" +// match_expr.baml:3:8 (type) [defaultLibrary] len=6 "string" // match_expr.baml:6:1 (keyword) len=5 "class" -// match_expr.baml:6:7 (class) len=3 "Cat" -// match_expr.baml:7:3 (property) len=4 "type" -// match_expr.baml:7:8 (string) len=1 "\"" -// match_expr.baml:7:9 (string) len=3 "cat" -// match_expr.baml:7:12 (string) len=1 "\"" -// match_expr.baml:8:3 (property) len=4 "name" -// match_expr.baml:8:8 (type) len=6 "string" +// match_expr.baml:6:7 (class) [declaration] len=3 "Cat" +// match_expr.baml:7:3 (property) [declaration] len=4 "type" +// match_expr.baml:7:8 (string) len=5 "\"cat\"" +// match_expr.baml:8:3 (property) [declaration] len=4 "name" +// match_expr.baml:8:8 (type) [defaultLibrary] len=6 "string" // match_expr.baml:11:1 (keyword) len=5 "class" -// match_expr.baml:11:7 (class) len=6 "Lizard" -// match_expr.baml:12:3 (property) len=4 "type" -// match_expr.baml:12:8 (string) len=1 "\"" -// match_expr.baml:12:9 (string) len=6 "lizard" -// match_expr.baml:12:15 (string) len=1 "\"" -// match_expr.baml:13:3 (property) len=4 "name" -// match_expr.baml:13:8 (type) len=6 "string" +// match_expr.baml:11:7 (class) [declaration] len=6 "Lizard" +// match_expr.baml:12:3 (property) [declaration] len=4 "type" +// match_expr.baml:12:8 (string) len=8 "\"lizard\"" +// match_expr.baml:13:3 (property) [declaration] len=4 "name" +// match_expr.baml:13:8 (type) [defaultLibrary] len=6 "string" // match_expr.baml:16:1 (keyword) len=4 "type" -// match_expr.baml:16:6 (type) len=3 "Pet" +// match_expr.baml:16:6 (type) [declaration] len=3 "Pet" // match_expr.baml:16:10 (operator) len=1 "=" // match_expr.baml:16:12 (class) len=3 "Cat" // match_expr.baml:16:16 (operator) len=1 "|" @@ -61,16 +55,20 @@ function Describe(pet: Pet) -> string { // match_expr.baml:16:22 (operator) len=1 "|" // match_expr.baml:16:24 (class) len=6 "Lizard" // match_expr.baml:18:1 (keyword) len=8 "function" -// match_expr.baml:18:10 (function) len=8 "Describe" -// match_expr.baml:18:19 (parameter) len=3 "pet" +// match_expr.baml:18:10 (function) [declaration] len=8 "Describe" +// match_expr.baml:18:19 (parameter) [declaration] len=3 "pet" // match_expr.baml:18:24 (type) len=3 "Pet" -// match_expr.baml:18:32 (type) len=6 "string" +// match_expr.baml:18:32 (type) [defaultLibrary] len=6 "string" // match_expr.baml:19:3 (keyword) len=5 "match" +// match_expr.baml:19:10 (parameter) len=3 "pet" // match_expr.baml:20:5 (keyword) len=3 "let" +// match_expr.baml:20:9 (variable) [declaration] len=3 "cat" // match_expr.baml:20:14 (class) len=3 "Cat" +// match_expr.baml:20:21 (variable) len=3 "cat" +// match_expr.baml:20:25 (property) len=4 "name" // match_expr.baml:21:5 (keyword) len=3 "let" +// match_expr.baml:21:9 (variable) [declaration] len=3 "dog" // match_expr.baml:21:14 (class) len=3 "Dog" -// match_expr.baml:22:10 (string) len=1 "\"" -// match_expr.baml:22:11 (string) len=5 "other" -// match_expr.baml:22:17 (string) len=3 "pet" -// match_expr.baml:22:20 (string) len=1 "\"" +// match_expr.baml:21:21 (variable) len=3 "dog" +// match_expr.baml:21:25 (property) len=4 "name" +// match_expr.baml:22:10 (string) len=11 "\"other pet\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_literal_types.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_literal_types.baml new file mode 100644 index 0000000000..4f29c50898 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_literal_types.baml @@ -0,0 +1,74 @@ +class Dog { + type "dog" + name string +} + +class Cat { + type "cat" + name string +} + +class Lizard { + type "lizard" + name string +} + +type Pet = Cat | Dog | Lizard; + +function Describe(pet: Pet) -> string { + match (pet) { + let cat: Cat => cat.name, + let dog: Dog => dog.name, + _ => "other pet", + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// match_literal_types.baml:1:1 (keyword) len=5 "class" +// match_literal_types.baml:1:7 (class) [declaration] len=3 "Dog" +// match_literal_types.baml:2:3 (property) [declaration] len=4 "type" +// match_literal_types.baml:2:8 (string) len=5 "\"dog\"" +// match_literal_types.baml:3:3 (property) [declaration] len=4 "name" +// match_literal_types.baml:3:8 (type) [defaultLibrary] len=6 "string" +// match_literal_types.baml:6:1 (keyword) len=5 "class" +// match_literal_types.baml:6:7 (class) [declaration] len=3 "Cat" +// match_literal_types.baml:7:3 (property) [declaration] len=4 "type" +// match_literal_types.baml:7:8 (string) len=5 "\"cat\"" +// match_literal_types.baml:8:3 (property) [declaration] len=4 "name" +// match_literal_types.baml:8:8 (type) [defaultLibrary] len=6 "string" +// match_literal_types.baml:11:1 (keyword) len=5 "class" +// match_literal_types.baml:11:7 (class) [declaration] len=6 "Lizard" +// match_literal_types.baml:12:3 (property) [declaration] len=4 "type" +// match_literal_types.baml:12:8 (string) len=8 "\"lizard\"" +// match_literal_types.baml:13:3 (property) [declaration] len=4 "name" +// match_literal_types.baml:13:8 (type) [defaultLibrary] len=6 "string" +// match_literal_types.baml:16:1 (keyword) len=4 "type" +// match_literal_types.baml:16:6 (type) [declaration] len=3 "Pet" +// match_literal_types.baml:16:10 (operator) len=1 "=" +// match_literal_types.baml:16:12 (class) len=3 "Cat" +// match_literal_types.baml:16:16 (operator) len=1 "|" +// match_literal_types.baml:16:18 (class) len=3 "Dog" +// match_literal_types.baml:16:22 (operator) len=1 "|" +// match_literal_types.baml:16:24 (class) len=6 "Lizard" +// match_literal_types.baml:18:1 (keyword) len=8 "function" +// match_literal_types.baml:18:10 (function) [declaration] len=8 "Describe" +// match_literal_types.baml:18:19 (parameter) [declaration] len=3 "pet" +// match_literal_types.baml:18:24 (type) len=3 "Pet" +// match_literal_types.baml:18:32 (type) [defaultLibrary] len=6 "string" +// match_literal_types.baml:19:3 (keyword) len=5 "match" +// match_literal_types.baml:19:10 (parameter) len=3 "pet" +// match_literal_types.baml:20:5 (keyword) len=3 "let" +// match_literal_types.baml:20:9 (variable) [declaration] len=3 "cat" +// match_literal_types.baml:20:14 (class) len=3 "Cat" +// match_literal_types.baml:20:21 (variable) len=3 "cat" +// match_literal_types.baml:20:25 (property) len=4 "name" +// match_literal_types.baml:21:5 (keyword) len=3 "let" +// match_literal_types.baml:21:9 (variable) [declaration] len=3 "dog" +// match_literal_types.baml:21:14 (class) len=3 "Dog" +// match_literal_types.baml:21:21 (variable) len=3 "dog" +// match_literal_types.baml:21:25 (property) len=4 "name" +// match_literal_types.baml:22:10 (string) len=11 "\"other pet\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/method_explicit_type_args.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/method_explicit_type_args.baml new file mode 100644 index 0000000000..23cb10452f --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/method_explicit_type_args.baml @@ -0,0 +1,50 @@ +class Foo { + tag string + function zero(self) -> T? { + null + } +} + +function use_method_type_args() -> int { + let f = Foo { tag: "x" }; + let v: int = f.zero() ?? 5; + v +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// method_explicit_type_args.baml:1:1 (keyword) len=5 "class" +// method_explicit_type_args.baml:1:7 (class) [declaration] len=3 "Foo" +// method_explicit_type_args.baml:2:3 (property) [declaration] len=3 "tag" +// method_explicit_type_args.baml:2:7 (type) [defaultLibrary] len=6 "string" +// method_explicit_type_args.baml:3:3 (keyword) len=8 "function" +// method_explicit_type_args.baml:3:12 (method) [declaration] len=4 "zero" +// method_explicit_type_args.baml:3:16 (operator) len=1 "<" +// method_explicit_type_args.baml:3:17 (typeParameter) [declaration] len=1 "T" +// method_explicit_type_args.baml:3:18 (operator) len=1 ">" +// method_explicit_type_args.baml:3:20 (parameter) [declaration] len=4 "self" +// method_explicit_type_args.baml:3:29 (type) len=1 "T" +// method_explicit_type_args.baml:4:5 (type) [defaultLibrary] len=4 "null" +// method_explicit_type_args.baml:8:1 (keyword) len=8 "function" +// method_explicit_type_args.baml:8:10 (function) [declaration] len=20 "use_method_type_args" +// method_explicit_type_args.baml:8:36 (type) [defaultLibrary] len=3 "int" +// method_explicit_type_args.baml:9:3 (keyword) len=3 "let" +// method_explicit_type_args.baml:9:7 (variable) [declaration] len=1 "f" +// method_explicit_type_args.baml:9:9 (operator) len=1 "=" +// method_explicit_type_args.baml:9:11 (class) len=3 "Foo" +// method_explicit_type_args.baml:9:17 (property) len=3 "tag" +// method_explicit_type_args.baml:9:22 (string) len=3 "\"x\"" +// method_explicit_type_args.baml:10:3 (keyword) len=3 "let" +// method_explicit_type_args.baml:10:7 (variable) [declaration] len=1 "v" +// method_explicit_type_args.baml:10:10 (type) [defaultLibrary] len=3 "int" +// method_explicit_type_args.baml:10:14 (operator) len=1 "=" +// method_explicit_type_args.baml:10:16 (variable) len=1 "f" +// method_explicit_type_args.baml:10:18 (method) len=4 "zero" +// method_explicit_type_args.baml:10:22 (operator) len=1 "<" +// method_explicit_type_args.baml:10:23 (type) [defaultLibrary] len=3 "int" +// method_explicit_type_args.baml:10:26 (operator) len=1 ">" +// method_explicit_type_args.baml:10:33 (number) len=1 "5" +// method_explicit_type_args.baml:11:3 (variable) len=1 "v" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/multi_segment_path.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/multi_segment_path.baml index 886b5ee821..f37f2e8d06 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/multi_segment_path.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/multi_segment_path.baml @@ -36,29 +36,40 @@ function test_tokens() -> string { // multi_segment_path.baml:2:1 (comment) len=66 "// Issue #9: The final segment should get a type-aware token kind," // multi_segment_path.baml:3:1 (comment) len=64 "// not a generic \"property\" token for everything after the root." // multi_segment_path.baml:5:1 (keyword) len=4 "enum" -// multi_segment_path.baml:5:6 (enum) len=6 "Status" -// multi_segment_path.baml:6:3 (enumMember) len=6 "Active" -// multi_segment_path.baml:7:3 (enumMember) len=8 "Inactive" +// multi_segment_path.baml:5:6 (enum) [declaration] len=6 "Status" +// multi_segment_path.baml:6:3 (enumMember) [declaration] len=6 "Active" +// multi_segment_path.baml:7:3 (enumMember) [declaration] len=8 "Inactive" // multi_segment_path.baml:10:1 (keyword) len=5 "class" -// multi_segment_path.baml:10:7 (class) len=4 "User" -// multi_segment_path.baml:11:3 (property) len=4 "name" -// multi_segment_path.baml:11:8 (type) len=6 "string" +// multi_segment_path.baml:10:7 (class) [declaration] len=4 "User" +// multi_segment_path.baml:11:3 (property) [declaration] len=4 "name" +// multi_segment_path.baml:11:8 (type) [defaultLibrary] len=6 "string" // multi_segment_path.baml:13:3 (keyword) len=8 "function" -// multi_segment_path.baml:13:12 (function) len=5 "greet" -// multi_segment_path.baml:13:18 (parameter) len=4 "self" -// multi_segment_path.baml:13:27 (type) len=6 "string" +// multi_segment_path.baml:13:12 (method) [declaration] len=5 "greet" +// multi_segment_path.baml:13:18 (parameter) [declaration] len=4 "self" +// multi_segment_path.baml:13:27 (type) [defaultLibrary] len=6 "string" +// multi_segment_path.baml:14:5 (parameter) len=4 "self" +// multi_segment_path.baml:14:10 (property) len=4 "name" // multi_segment_path.baml:18:1 (keyword) len=8 "function" -// multi_segment_path.baml:18:10 (function) len=11 "test_tokens" -// multi_segment_path.baml:18:27 (type) len=6 "string" +// multi_segment_path.baml:18:10 (function) [declaration] len=11 "test_tokens" +// multi_segment_path.baml:18:27 (type) [defaultLibrary] len=6 "string" // multi_segment_path.baml:19:3 (comment) len=64 "// Status.Active — \"Active\" should be enumMember, not property" // multi_segment_path.baml:20:3 (keyword) len=3 "let" +// multi_segment_path.baml:20:7 (variable) [declaration] len=1 "s" // multi_segment_path.baml:20:9 (operator) len=1 "=" +// multi_segment_path.baml:20:11 (enum) len=6 "Status" +// multi_segment_path.baml:20:18 (enumMember) len=6 "Active" // multi_segment_path.baml:22:3 (comment) len=60 "// user.greet() — \"greet\" should be function, not property" // multi_segment_path.baml:23:3 (keyword) len=3 "let" +// multi_segment_path.baml:23:7 (variable) [declaration] len=1 "u" // multi_segment_path.baml:23:9 (operator) len=1 "=" -// multi_segment_path.baml:23:24 (string) len=1 "\"" -// multi_segment_path.baml:23:25 (string) len=2 "hi" -// multi_segment_path.baml:23:27 (string) len=1 "\"" +// multi_segment_path.baml:23:11 (class) len=4 "User" +// multi_segment_path.baml:23:18 (property) len=4 "name" +// multi_segment_path.baml:23:24 (string) len=4 "\"hi\"" // multi_segment_path.baml:24:3 (keyword) len=3 "let" +// multi_segment_path.baml:24:7 (variable) [declaration] len=1 "g" // multi_segment_path.baml:24:9 (operator) len=1 "=" +// multi_segment_path.baml:24:11 (variable) len=1 "u" +// multi_segment_path.baml:24:13 (method) len=5 "greet" // multi_segment_path.baml:26:3 (comment) len=68 "// user.name — \"name\" should be property (this is correct already)" +// multi_segment_path.baml:27:3 (variable) len=1 "u" +// multi_segment_path.baml:27:5 (property) len=4 "name" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_agent_clients.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_agent_clients.baml new file mode 100644 index 0000000000..3a62fe477e --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_agent_clients.baml @@ -0,0 +1,58 @@ +// LLM clients for bamlcode. +// +// Default brain is Anthropic Claude (set ANTHROPIC_API_KEY). +// To use OpenAI instead, swap `client: Brain` for `client: BrainOpenAI` +// in baml_src/ns_agent/agent.baml (and set OPENAI_API_KEY). + +client Brain { + provider: anthropic, + options: { + model: "claude-sonnet-4-6", + api_key: env.ANTHROPIC_API_KEY, + max_tokens: 4096, + }, +} + +client BrainOpenAI { + provider: openai, + options: { + model: "gpt-4o", + api_key: env.OPENAI_API_KEY, + max_tokens: 4096, + }, +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// ns_agent_clients.baml:1:1 (comment) len=28 "// LLM clients for bamlcode." +// ns_agent_clients.baml:2:1 (comment) len=2 "//" +// ns_agent_clients.baml:3:1 (comment) len=61 "// Default brain is Anthropic Claude (set ANTHROPIC_API_KEY)." +// ns_agent_clients.baml:4:1 (comment) len=72 "// To use OpenAI instead, swap `client: Brain` for `client: BrainOpenAI`" +// ns_agent_clients.baml:5:1 (comment) len=60 "// in baml_src/ns_agent/agent.baml (and set OPENAI_API_KEY)." +// ns_agent_clients.baml:7:1 (keyword) len=6 "client" +// ns_agent_clients.baml:7:7 (operator) len=1 "<" +// ns_agent_clients.baml:7:8 (type) len=3 "llm" +// ns_agent_clients.baml:7:11 (operator) len=1 ">" +// ns_agent_clients.baml:7:13 (struct) [declaration] len=5 "Brain" +// ns_agent_clients.baml:8:5 (property) len=8 "provider" +// ns_agent_clients.baml:9:5 (property) len=7 "options" +// ns_agent_clients.baml:10:9 (property) len=5 "model" +// ns_agent_clients.baml:10:16 (string) len=19 "\"claude-sonnet-4-6\"" +// ns_agent_clients.baml:11:9 (property) len=7 "api_key" +// ns_agent_clients.baml:12:9 (property) len=10 "max_tokens" +// ns_agent_clients.baml:12:21 (number) len=4 "4096" +// ns_agent_clients.baml:16:1 (keyword) len=6 "client" +// ns_agent_clients.baml:16:7 (operator) len=1 "<" +// ns_agent_clients.baml:16:8 (type) len=3 "llm" +// ns_agent_clients.baml:16:11 (operator) len=1 ">" +// ns_agent_clients.baml:16:13 (struct) [declaration] len=11 "BrainOpenAI" +// ns_agent_clients.baml:17:5 (property) len=8 "provider" +// ns_agent_clients.baml:18:5 (property) len=7 "options" +// ns_agent_clients.baml:19:9 (property) len=5 "model" +// ns_agent_clients.baml:19:16 (string) len=8 "\"gpt-4o\"" +// ns_agent_clients.baml:20:9 (property) len=7 "api_key" +// ns_agent_clients.baml:21:9 (property) len=10 "max_tokens" +// ns_agent_clients.baml:21:21 (number) len=4 "4096" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_ansi.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_ansi.baml new file mode 100644 index 0000000000..3fe05dc540 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_ansi.baml @@ -0,0 +1,204 @@ +// Namespace: root.ansi — ANSI terminal styling helpers. +// +// BAML string literals don't have an \x1b / \e escape, so we build the ESC +// byte (codepoint 27) with string.from_code_points, then wrap text in SGR +// codes. Honors the NO_COLOR convention (https://no-color.org): if the +// NO_COLOR env var is set to anything, styling is a no-op. +// +// Used from the root namespace as root.ansi.red("..."), root.ansi.bold(...), etc. + +function esc() -> string { + string.from_code_points([27]) +} + +// Wrap `text` in an SGR parameter (e.g. "31" for red) and reset afterwards. +function sgr(code: string, text: string) -> string { + match (baml.env.get("NO_COLOR")) { + null => esc() + "[" + code + "m" + text + esc() + "[0m", + _ => text, + } +} + +// Attributes +function bold(text: string) -> string { + sgr("1", text) +} + +function dim(text: string) -> string { + sgr("2", text) +} + +function italic(text: string) -> string { + sgr("3", text) +} + +function underline(text: string) -> string { + sgr("4", text) +} + +// Foreground colors +function red(text: string) -> string { + sgr("31", text) +} + +function green(text: string) -> string { + sgr("32", text) +} + +function yellow(text: string) -> string { + sgr("33", text) +} + +function blue(text: string) -> string { + sgr("34", text) +} + +function magenta(text: string) -> string { + sgr("35", text) +} + +function cyan(text: string) -> string { + sgr("36", text) +} + +function gray(text: string) -> string { + sgr("90", text) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// ns_ansi.baml:1:1 (comment) len=58 "// Namespace: root.ansi — ANSI terminal styling helpers." +// ns_ansi.baml:2:1 (comment) len=2 "//" +// ns_ansi.baml:3:1 (comment) len=75 "// BAML string literals don't have an \\x1b / \\e escape, so we build the ESC" +// ns_ansi.baml:4:1 (comment) len=74 "// byte (codepoint 27) with string.from_code_points, then wrap text in SGR" +// ns_ansi.baml:5:1 (comment) len=71 "// codes. Honors the NO_COLOR convention (https://no-color.org): if the" +// ns_ansi.baml:6:1 (comment) len=59 "// NO_COLOR env var is set to anything, styling is a no-op." +// ns_ansi.baml:7:1 (comment) len=2 "//" +// ns_ansi.baml:8:1 (comment) len=82 "// Used from the root namespace as root.ansi.red(\"...\"), root.ansi.bold(...), etc." +// ns_ansi.baml:10:1 (keyword) len=8 "function" +// ns_ansi.baml:10:10 (function) [declaration] len=3 "esc" +// ns_ansi.baml:10:19 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:11:5 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:11:12 (method) len=16 "from_code_points" +// ns_ansi.baml:11:30 (number) len=2 "27" +// ns_ansi.baml:14:1 (comment) len=76 "// Wrap `text` in an SGR parameter (e.g. \"31\" for red) and reset afterwards." +// ns_ansi.baml:15:1 (keyword) len=8 "function" +// ns_ansi.baml:15:10 (function) [declaration] len=3 "sgr" +// ns_ansi.baml:15:14 (parameter) [declaration] len=4 "code" +// ns_ansi.baml:15:20 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:15:28 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:15:34 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:15:45 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:16:5 (keyword) len=5 "match" +// ns_ansi.baml:16:12 (namespace) [defaultLibrary] len=4 "baml" +// ns_ansi.baml:16:17 (namespace) [defaultLibrary] len=3 "env" +// ns_ansi.baml:16:21 (function) len=3 "get" +// ns_ansi.baml:16:25 (string) len=10 "\"NO_COLOR\"" +// ns_ansi.baml:17:9 (type) [defaultLibrary] len=4 "null" +// ns_ansi.baml:17:17 (function) len=3 "esc" +// ns_ansi.baml:17:23 (operator) len=1 "+" +// ns_ansi.baml:17:25 (string) len=3 "\"[\"" +// ns_ansi.baml:17:29 (operator) len=1 "+" +// ns_ansi.baml:17:31 (parameter) len=4 "code" +// ns_ansi.baml:17:36 (operator) len=1 "+" +// ns_ansi.baml:17:38 (string) len=3 "\"m\"" +// ns_ansi.baml:17:42 (operator) len=1 "+" +// ns_ansi.baml:17:44 (parameter) len=4 "text" +// ns_ansi.baml:17:49 (operator) len=1 "+" +// ns_ansi.baml:17:51 (function) len=3 "esc" +// ns_ansi.baml:17:57 (operator) len=1 "+" +// ns_ansi.baml:17:59 (string) len=5 "\"[0m\"" +// ns_ansi.baml:18:14 (parameter) len=4 "text" +// ns_ansi.baml:22:1 (comment) len=13 "// Attributes" +// ns_ansi.baml:23:1 (keyword) len=8 "function" +// ns_ansi.baml:23:10 (function) [declaration] len=4 "bold" +// ns_ansi.baml:23:15 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:23:21 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:23:32 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:24:5 (function) len=3 "sgr" +// ns_ansi.baml:24:9 (string) len=3 "\"1\"" +// ns_ansi.baml:24:14 (parameter) len=4 "text" +// ns_ansi.baml:27:1 (keyword) len=8 "function" +// ns_ansi.baml:27:10 (function) [declaration] len=3 "dim" +// ns_ansi.baml:27:14 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:27:20 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:27:31 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:28:5 (function) len=3 "sgr" +// ns_ansi.baml:28:9 (string) len=3 "\"2\"" +// ns_ansi.baml:28:14 (parameter) len=4 "text" +// ns_ansi.baml:31:1 (keyword) len=8 "function" +// ns_ansi.baml:31:10 (function) [declaration] len=6 "italic" +// ns_ansi.baml:31:17 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:31:23 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:31:34 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:32:5 (function) len=3 "sgr" +// ns_ansi.baml:32:9 (string) len=3 "\"3\"" +// ns_ansi.baml:32:14 (parameter) len=4 "text" +// ns_ansi.baml:35:1 (keyword) len=8 "function" +// ns_ansi.baml:35:10 (function) [declaration] len=9 "underline" +// ns_ansi.baml:35:20 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:35:26 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:35:37 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:36:5 (function) len=3 "sgr" +// ns_ansi.baml:36:9 (string) len=3 "\"4\"" +// ns_ansi.baml:36:14 (parameter) len=4 "text" +// ns_ansi.baml:39:1 (comment) len=20 "// Foreground colors" +// ns_ansi.baml:40:1 (keyword) len=8 "function" +// ns_ansi.baml:40:10 (function) [declaration] len=3 "red" +// ns_ansi.baml:40:14 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:40:20 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:40:31 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:41:5 (function) len=3 "sgr" +// ns_ansi.baml:41:9 (string) len=4 "\"31\"" +// ns_ansi.baml:41:15 (parameter) len=4 "text" +// ns_ansi.baml:44:1 (keyword) len=8 "function" +// ns_ansi.baml:44:10 (function) [declaration] len=5 "green" +// ns_ansi.baml:44:16 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:44:22 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:44:33 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:45:5 (function) len=3 "sgr" +// ns_ansi.baml:45:9 (string) len=4 "\"32\"" +// ns_ansi.baml:45:15 (parameter) len=4 "text" +// ns_ansi.baml:48:1 (keyword) len=8 "function" +// ns_ansi.baml:48:10 (function) [declaration] len=6 "yellow" +// ns_ansi.baml:48:17 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:48:23 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:48:34 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:49:5 (function) len=3 "sgr" +// ns_ansi.baml:49:9 (string) len=4 "\"33\"" +// ns_ansi.baml:49:15 (parameter) len=4 "text" +// ns_ansi.baml:52:1 (keyword) len=8 "function" +// ns_ansi.baml:52:10 (function) [declaration] len=4 "blue" +// ns_ansi.baml:52:15 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:52:21 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:52:32 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:53:5 (function) len=3 "sgr" +// ns_ansi.baml:53:9 (string) len=4 "\"34\"" +// ns_ansi.baml:53:15 (parameter) len=4 "text" +// ns_ansi.baml:56:1 (keyword) len=8 "function" +// ns_ansi.baml:56:10 (function) [declaration] len=7 "magenta" +// ns_ansi.baml:56:18 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:56:24 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:56:35 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:57:5 (function) len=3 "sgr" +// ns_ansi.baml:57:9 (string) len=4 "\"35\"" +// ns_ansi.baml:57:15 (parameter) len=4 "text" +// ns_ansi.baml:60:1 (keyword) len=8 "function" +// ns_ansi.baml:60:10 (function) [declaration] len=4 "cyan" +// ns_ansi.baml:60:15 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:60:21 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:60:32 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:61:5 (function) len=3 "sgr" +// ns_ansi.baml:61:9 (string) len=4 "\"36\"" +// ns_ansi.baml:61:15 (parameter) len=4 "text" +// ns_ansi.baml:64:1 (keyword) len=8 "function" +// ns_ansi.baml:64:10 (function) [declaration] len=4 "gray" +// ns_ansi.baml:64:15 (parameter) [declaration] len=4 "text" +// ns_ansi.baml:64:21 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:64:32 (type) [defaultLibrary] len=6 "string" +// ns_ansi.baml:65:5 (function) len=3 "sgr" +// ns_ansi.baml:65:9 (string) len=4 "\"90\"" +// ns_ansi.baml:65:15 (parameter) len=4 "text" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_game_clients.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_game_clients.baml new file mode 100644 index 0000000000..f5358ae762 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_game_clients.baml @@ -0,0 +1,345 @@ +// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview + +function add(a: int, b: int) -> int { + a + b +} + +// Using the new OpenAI Responses API for enhanced formatting +client CustomGPT5 { + provider: openai-responses, + options: { + model: "gpt-5", + api_key: env.TEMP_KEY, + }, +} + +client CustomGPT5Mini { + provider: openai-responses, + retry_policy: Exponential, + options: { + model: "gpt-5-mini", + api_key: env.OPENAI_API_KEY, + }, +} + +// Openai with chat completion +client CustomGPT5Chat { + provider: openai, + options: { + model: "gpt-5", + api_key: env.OPENAI_API_KEY, + }, +} + +// Latest Anthropic Claude 4 models +client CustomOpus4 { + provider: anthropic, + options: { + model: "claude-opus-4-1-20250805", + api_key: env.ANTHROPIC_API_KEY, + }, +} + +client CustomSonnet4 { + provider: anthropic, + options: { + model: "claude-sonnet-4-20250514", + api_key: env.ANTHROPIC_API_KEY, + }, +} + +client CustomHaiku { + provider: anthropic, + options: { + model: "claude-haiku-4-5", + api_key: env.ANTHROPIC_API_KEY, + }, +} + +// Example Google AI client (uncomment to use) +// client CustomGemini { +// provider google-ai +// options { +// model "gemini-2.5-pro" +// api_key env.GOOGLE_API_KEY +// } +// } + +// Example AWS Bedrock client (uncomment to use) +// client CustomBedrock { +// provider aws-bedrock +// options { +// model "anthropic.claude-sonnet-4-20250514-v1:0" +// region "us-east-1" +// // AWS credentials are auto-detected from env vars +// } +// } + +// Example Azure OpenAI client (uncomment to use) +// client CustomAzure { +// provider azure-openai +// options { +// model "gpt-5" +// api_key env.AZURE_OPENAI_API_KEY +// base_url "https://MY_RESOURCE_NAME.openai.azure.com/openai/deployments/MY_DEPLOYMENT_ID" +// api_version "2024-10-01-preview" +// } +// } + +// Example Vertex AI client (uncomment to use) +// client CustomVertex { +// provider vertex-ai +// options { +// model "gemini-2.5-pro" +// location "us-central1" +// // Uses Google Cloud Application Default Credentials +// } +// } + +// Example Ollama client for local models (uncomment to use) +// client CustomOllama { +// provider openai-generic +// options { +// base_url "http://localhost:11434/v1" +// model "llama4" +// default_role "user" // Most local models prefer the user role +// // No API key needed for local Ollama +// } +// } + +// https://docs.boundaryml.com/docs/snippets/clients/round-robin +client CustomFast { + provider: round-robin, + options: { + // This will alternate between the two clients + strategy: [CustomGPT5Mini, CustomHaiku], + }, +} + +// https://docs.boundaryml.com/docs/snippets/clients/fallback +client OpenaiFallback { + provider: fallback, + options: { + // This will try the clients in order until one succeeds + strategy: [CustomGPT5Mini, CustomGPT5], + }, +} + +// https://docs.boundaryml.com/docs/snippets/clients/retry +retry_policy Constant { + max_retries: 3, + strategy: { + type: constant_delay, + delay_ms: 200, + }, +} + +retry_policy Exponential { + max_retries: 2, + strategy: { + type: exponential_backoff, + delay_ms: 300, + multiplier: 1.5, + max_delay_ms: 10000, + }, +} + +function will_double(x: int) -> int { + x * 2 +} + +function double() -> void { + let doubled = [1, 2, 3].map(will_double); + log.info({ "doubled": doubled }); +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// ns_game_clients.baml:1:1 (comment) len=89 "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview" +// ns_game_clients.baml:3:1 (keyword) len=8 "function" +// ns_game_clients.baml:3:10 (function) [declaration] len=3 "add" +// ns_game_clients.baml:3:14 (parameter) [declaration] len=1 "a" +// ns_game_clients.baml:3:17 (type) [defaultLibrary] len=3 "int" +// ns_game_clients.baml:3:22 (parameter) [declaration] len=1 "b" +// ns_game_clients.baml:3:25 (type) [defaultLibrary] len=3 "int" +// ns_game_clients.baml:3:33 (type) [defaultLibrary] len=3 "int" +// ns_game_clients.baml:4:5 (parameter) len=1 "a" +// ns_game_clients.baml:4:7 (operator) len=1 "+" +// ns_game_clients.baml:4:9 (parameter) len=1 "b" +// ns_game_clients.baml:7:1 (comment) len=61 "// Using the new OpenAI Responses API for enhanced formatting" +// ns_game_clients.baml:8:1 (keyword) len=6 "client" +// ns_game_clients.baml:8:7 (operator) len=1 "<" +// ns_game_clients.baml:8:8 (type) len=3 "llm" +// ns_game_clients.baml:8:11 (operator) len=1 ">" +// ns_game_clients.baml:8:13 (struct) [declaration] len=10 "CustomGPT5" +// ns_game_clients.baml:9:5 (property) len=8 "provider" +// ns_game_clients.baml:10:5 (property) len=7 "options" +// ns_game_clients.baml:11:9 (property) len=5 "model" +// ns_game_clients.baml:11:16 (string) len=7 "\"gpt-5\"" +// ns_game_clients.baml:12:9 (property) len=7 "api_key" +// ns_game_clients.baml:16:1 (keyword) len=6 "client" +// ns_game_clients.baml:16:7 (operator) len=1 "<" +// ns_game_clients.baml:16:8 (type) len=3 "llm" +// ns_game_clients.baml:16:11 (operator) len=1 ">" +// ns_game_clients.baml:16:13 (struct) [declaration] len=14 "CustomGPT5Mini" +// ns_game_clients.baml:17:5 (property) len=8 "provider" +// ns_game_clients.baml:18:5 (property) len=12 "retry_policy" +// ns_game_clients.baml:19:5 (property) len=7 "options" +// ns_game_clients.baml:20:9 (property) len=5 "model" +// ns_game_clients.baml:20:16 (string) len=12 "\"gpt-5-mini\"" +// ns_game_clients.baml:21:9 (property) len=7 "api_key" +// ns_game_clients.baml:25:1 (comment) len=30 "// Openai with chat completion" +// ns_game_clients.baml:26:1 (keyword) len=6 "client" +// ns_game_clients.baml:26:7 (operator) len=1 "<" +// ns_game_clients.baml:26:8 (type) len=3 "llm" +// ns_game_clients.baml:26:11 (operator) len=1 ">" +// ns_game_clients.baml:26:13 (struct) [declaration] len=14 "CustomGPT5Chat" +// ns_game_clients.baml:27:5 (property) len=8 "provider" +// ns_game_clients.baml:28:5 (property) len=7 "options" +// ns_game_clients.baml:29:9 (property) len=5 "model" +// ns_game_clients.baml:29:16 (string) len=7 "\"gpt-5\"" +// ns_game_clients.baml:30:9 (property) len=7 "api_key" +// ns_game_clients.baml:34:1 (comment) len=35 "// Latest Anthropic Claude 4 models" +// ns_game_clients.baml:35:1 (keyword) len=6 "client" +// ns_game_clients.baml:35:7 (operator) len=1 "<" +// ns_game_clients.baml:35:8 (type) len=3 "llm" +// ns_game_clients.baml:35:11 (operator) len=1 ">" +// ns_game_clients.baml:35:13 (struct) [declaration] len=11 "CustomOpus4" +// ns_game_clients.baml:36:5 (property) len=8 "provider" +// ns_game_clients.baml:37:5 (property) len=7 "options" +// ns_game_clients.baml:38:9 (property) len=5 "model" +// ns_game_clients.baml:38:16 (string) len=26 "\"claude-opus-4-1-20250805\"" +// ns_game_clients.baml:39:9 (property) len=7 "api_key" +// ns_game_clients.baml:43:1 (keyword) len=6 "client" +// ns_game_clients.baml:43:7 (operator) len=1 "<" +// ns_game_clients.baml:43:8 (type) len=3 "llm" +// ns_game_clients.baml:43:11 (operator) len=1 ">" +// ns_game_clients.baml:43:13 (struct) [declaration] len=13 "CustomSonnet4" +// ns_game_clients.baml:44:5 (property) len=8 "provider" +// ns_game_clients.baml:45:5 (property) len=7 "options" +// ns_game_clients.baml:46:9 (property) len=5 "model" +// ns_game_clients.baml:46:16 (string) len=26 "\"claude-sonnet-4-20250514\"" +// ns_game_clients.baml:47:9 (property) len=7 "api_key" +// ns_game_clients.baml:51:1 (keyword) len=6 "client" +// ns_game_clients.baml:51:7 (operator) len=1 "<" +// ns_game_clients.baml:51:8 (type) len=3 "llm" +// ns_game_clients.baml:51:11 (operator) len=1 ">" +// ns_game_clients.baml:51:13 (struct) [declaration] len=11 "CustomHaiku" +// ns_game_clients.baml:52:5 (property) len=8 "provider" +// ns_game_clients.baml:53:5 (property) len=7 "options" +// ns_game_clients.baml:54:9 (property) len=5 "model" +// ns_game_clients.baml:54:16 (string) len=18 "\"claude-haiku-4-5\"" +// ns_game_clients.baml:55:9 (property) len=7 "api_key" +// ns_game_clients.baml:59:1 (comment) len=46 "// Example Google AI client (uncomment to use)" +// ns_game_clients.baml:60:1 (comment) len=29 "// client CustomGemini {" +// ns_game_clients.baml:61:1 (comment) len=23 "// provider google-ai" +// ns_game_clients.baml:62:1 (comment) len=14 "// options {" +// ns_game_clients.baml:63:1 (comment) len=29 "// model \"gemini-2.5-pro\"" +// ns_game_clients.baml:64:1 (comment) len=33 "// api_key env.GOOGLE_API_KEY" +// ns_game_clients.baml:65:1 (comment) len=6 "// }" +// ns_game_clients.baml:66:1 (comment) len=4 "// }" +// ns_game_clients.baml:68:1 (comment) len=48 "// Example AWS Bedrock client (uncomment to use)" +// ns_game_clients.baml:69:1 (comment) len=30 "// client CustomBedrock {" +// ns_game_clients.baml:70:1 (comment) len=25 "// provider aws-bedrock" +// ns_game_clients.baml:71:1 (comment) len=14 "// options {" +// ns_game_clients.baml:72:1 (comment) len=54 "// model \"anthropic.claude-sonnet-4-20250514-v1:0\"" +// ns_game_clients.baml:73:1 (comment) len=25 "// region \"us-east-1\"" +// ns_game_clients.baml:74:1 (comment) len=57 "// // AWS credentials are auto-detected from env vars" +// ns_game_clients.baml:75:1 (comment) len=6 "// }" +// ns_game_clients.baml:76:1 (comment) len=4 "// }" +// ns_game_clients.baml:78:1 (comment) len=49 "// Example Azure OpenAI client (uncomment to use)" +// ns_game_clients.baml:79:1 (comment) len=28 "// client CustomAzure {" +// ns_game_clients.baml:80:1 (comment) len=26 "// provider azure-openai" +// ns_game_clients.baml:81:1 (comment) len=14 "// options {" +// ns_game_clients.baml:82:1 (comment) len=20 "// model \"gpt-5\"" +// ns_game_clients.baml:83:1 (comment) len=39 "// api_key env.AZURE_OPENAI_API_KEY" +// ns_game_clients.baml:84:1 (comment) len=95 "// base_url \"https://MY_RESOURCE_NAME.openai.azure.com/openai/deployments/MY_DEPLOYMENT_ID\"" +// ns_game_clients.baml:85:1 (comment) len=39 "// api_version \"2024-10-01-preview\"" +// ns_game_clients.baml:86:1 (comment) len=6 "// }" +// ns_game_clients.baml:87:1 (comment) len=4 "// }" +// ns_game_clients.baml:89:1 (comment) len=46 "// Example Vertex AI client (uncomment to use)" +// ns_game_clients.baml:90:1 (comment) len=29 "// client CustomVertex {" +// ns_game_clients.baml:91:1 (comment) len=23 "// provider vertex-ai" +// ns_game_clients.baml:92:1 (comment) len=14 "// options {" +// ns_game_clients.baml:93:1 (comment) len=29 "// model \"gemini-2.5-pro\"" +// ns_game_clients.baml:94:1 (comment) len=29 "// location \"us-central1\"" +// ns_game_clients.baml:95:1 (comment) len=59 "// // Uses Google Cloud Application Default Credentials" +// ns_game_clients.baml:96:1 (comment) len=6 "// }" +// ns_game_clients.baml:97:1 (comment) len=4 "// }" +// ns_game_clients.baml:99:1 (comment) len=60 "// Example Ollama client for local models (uncomment to use)" +// ns_game_clients.baml:100:1 (comment) len=29 "// client CustomOllama {" +// ns_game_clients.baml:101:1 (comment) len=28 "// provider openai-generic" +// ns_game_clients.baml:102:1 (comment) len=14 "// options {" +// ns_game_clients.baml:103:1 (comment) len=43 "// base_url \"http://localhost:11434/v1\"" +// ns_game_clients.baml:104:1 (comment) len=21 "// model \"llama4\"" +// ns_game_clients.baml:105:1 (comment) len=68 "// default_role \"user\" // Most local models prefer the user role" +// ns_game_clients.baml:106:1 (comment) len=44 "// // No API key needed for local Ollama" +// ns_game_clients.baml:107:1 (comment) len=6 "// }" +// ns_game_clients.baml:108:1 (comment) len=4 "// }" +// ns_game_clients.baml:110:1 (comment) len=64 "// https://docs.boundaryml.com/docs/snippets/clients/round-robin" +// ns_game_clients.baml:111:1 (keyword) len=6 "client" +// ns_game_clients.baml:111:7 (operator) len=1 "<" +// ns_game_clients.baml:111:8 (type) len=3 "llm" +// ns_game_clients.baml:111:11 (operator) len=1 ">" +// ns_game_clients.baml:111:13 (struct) [declaration] len=10 "CustomFast" +// ns_game_clients.baml:112:5 (property) len=8 "provider" +// ns_game_clients.baml:113:5 (property) len=7 "options" +// ns_game_clients.baml:114:9 (comment) len=46 "// This will alternate between the two clients" +// ns_game_clients.baml:115:9 (property) len=8 "strategy" +// ns_game_clients.baml:119:1 (comment) len=61 "// https://docs.boundaryml.com/docs/snippets/clients/fallback" +// ns_game_clients.baml:120:1 (keyword) len=6 "client" +// ns_game_clients.baml:120:7 (operator) len=1 "<" +// ns_game_clients.baml:120:8 (type) len=3 "llm" +// ns_game_clients.baml:120:11 (operator) len=1 ">" +// ns_game_clients.baml:120:13 (struct) [declaration] len=14 "OpenaiFallback" +// ns_game_clients.baml:121:5 (property) len=8 "provider" +// ns_game_clients.baml:122:5 (property) len=7 "options" +// ns_game_clients.baml:123:9 (comment) len=56 "// This will try the clients in order until one succeeds" +// ns_game_clients.baml:124:9 (property) len=8 "strategy" +// ns_game_clients.baml:128:1 (comment) len=58 "// https://docs.boundaryml.com/docs/snippets/clients/retry" +// ns_game_clients.baml:129:1 (keyword) len=12 "retry_policy" +// ns_game_clients.baml:129:14 (struct) [declaration] len=8 "Constant" +// ns_game_clients.baml:130:5 (property) len=11 "max_retries" +// ns_game_clients.baml:130:18 (number) len=1 "3" +// ns_game_clients.baml:131:5 (property) len=8 "strategy" +// ns_game_clients.baml:132:9 (property) len=4 "type" +// ns_game_clients.baml:133:9 (property) len=8 "delay_ms" +// ns_game_clients.baml:133:19 (number) len=3 "200" +// ns_game_clients.baml:137:1 (keyword) len=12 "retry_policy" +// ns_game_clients.baml:137:14 (struct) [declaration] len=11 "Exponential" +// ns_game_clients.baml:138:5 (property) len=11 "max_retries" +// ns_game_clients.baml:138:18 (number) len=1 "2" +// ns_game_clients.baml:139:5 (property) len=8 "strategy" +// ns_game_clients.baml:140:9 (property) len=4 "type" +// ns_game_clients.baml:141:9 (property) len=8 "delay_ms" +// ns_game_clients.baml:141:19 (number) len=3 "300" +// ns_game_clients.baml:142:9 (property) len=10 "multiplier" +// ns_game_clients.baml:142:21 (number) len=3 "1.5" +// ns_game_clients.baml:143:9 (property) len=12 "max_delay_ms" +// ns_game_clients.baml:143:23 (number) len=5 "10000" +// ns_game_clients.baml:147:1 (keyword) len=8 "function" +// ns_game_clients.baml:147:10 (function) [declaration] len=11 "will_double" +// ns_game_clients.baml:147:22 (parameter) [declaration] len=1 "x" +// ns_game_clients.baml:147:25 (type) [defaultLibrary] len=3 "int" +// ns_game_clients.baml:147:33 (type) [defaultLibrary] len=3 "int" +// ns_game_clients.baml:148:5 (parameter) len=1 "x" +// ns_game_clients.baml:148:7 (operator) len=1 "*" +// ns_game_clients.baml:148:9 (number) len=1 "2" +// ns_game_clients.baml:151:1 (keyword) len=8 "function" +// ns_game_clients.baml:151:10 (function) [declaration] len=6 "double" +// ns_game_clients.baml:151:22 (type) [defaultLibrary] len=4 "void" +// ns_game_clients.baml:152:5 (keyword) len=3 "let" +// ns_game_clients.baml:152:9 (variable) [declaration] len=7 "doubled" +// ns_game_clients.baml:152:17 (operator) len=1 "=" +// ns_game_clients.baml:152:20 (number) len=1 "1" +// ns_game_clients.baml:152:23 (number) len=1 "2" +// ns_game_clients.baml:152:26 (number) len=1 "3" +// ns_game_clients.baml:152:29 (method) len=3 "map" +// ns_game_clients.baml:152:33 (function) len=11 "will_double" +// ns_game_clients.baml:153:5 (namespace) [defaultLibrary] len=3 "log" +// ns_game_clients.baml:153:9 (function) len=4 "info" +// ns_game_clients.baml:153:16 (string) len=9 "\"doubled\"" +// ns_game_clients.baml:153:27 (variable) len=7 "doubled" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_images_pipeline.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_images_pipeline.baml new file mode 100644 index 0000000000..c7fbf069cf --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_images_pipeline.baml @@ -0,0 +1,64 @@ +client AiGatewayImagenImageClient { + provider: ai-gateway-images, + options: { + model: "google/imagen-4.0-fast-generate-001", + api_key: env.AI_GATEWAY_API_KEY, + n: 1, + }, +} + +function generate_image(thing: string) -> image { + client: AiGatewayImagenImageClient + prompt: #" + Create an image from this prompt: + + {{ thing }} + + {{ ctx.output_format }} + "# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// ns_images_pipeline.baml:1:1 (keyword) len=6 "client" +// ns_images_pipeline.baml:1:8 (struct) [declaration] len=26 "AiGatewayImagenImageClient" +// ns_images_pipeline.baml:2:5 (property) len=8 "provider" +// ns_images_pipeline.baml:3:5 (property) len=7 "options" +// ns_images_pipeline.baml:4:9 (property) len=5 "model" +// ns_images_pipeline.baml:4:16 (string) len=37 "\"google/imagen-4.0-fast-generate-001\"" +// ns_images_pipeline.baml:5:9 (property) len=7 "api_key" +// ns_images_pipeline.baml:6:9 (property) len=1 "n" +// ns_images_pipeline.baml:6:12 (number) len=1 "1" +// ns_images_pipeline.baml:10:1 (keyword) len=8 "function" +// ns_images_pipeline.baml:10:10 (function) [declaration] len=14 "generate_image" +// ns_images_pipeline.baml:10:25 (parameter) [declaration] len=5 "thing" +// ns_images_pipeline.baml:10:32 (type) [defaultLibrary] len=6 "string" +// ns_images_pipeline.baml:10:43 (type) [defaultLibrary] len=5 "image" +// ns_images_pipeline.baml:11:5 (property) len=6 "client" +// ns_images_pipeline.baml:12:5 (property) [declaration] len=6 "prompt" +// ns_images_pipeline.baml:12:13 (string) len=1 "#" +// ns_images_pipeline.baml:12:14 (string) len=1 "\"" +// ns_images_pipeline.baml:13:9 (string) len=6 "Create" +// ns_images_pipeline.baml:13:16 (string) len=2 "an" +// ns_images_pipeline.baml:13:19 (string) len=5 "image" +// ns_images_pipeline.baml:13:25 (string) len=4 "from" +// ns_images_pipeline.baml:13:30 (string) len=4 "this" +// ns_images_pipeline.baml:13:35 (string) len=6 "prompt" +// ns_images_pipeline.baml:13:41 (string) len=1 ":" +// ns_images_pipeline.baml:15:9 (string) len=1 "{" +// ns_images_pipeline.baml:15:10 (string) len=1 "{" +// ns_images_pipeline.baml:15:12 (string) len=5 "thing" +// ns_images_pipeline.baml:15:18 (string) len=1 "}" +// ns_images_pipeline.baml:15:19 (string) len=1 "}" +// ns_images_pipeline.baml:17:9 (string) len=1 "{" +// ns_images_pipeline.baml:17:10 (string) len=1 "{" +// ns_images_pipeline.baml:17:12 (string) len=3 "ctx" +// ns_images_pipeline.baml:17:15 (string) len=1 "." +// ns_images_pipeline.baml:17:16 (string) len=13 "output_format" +// ns_images_pipeline.baml:17:30 (string) len=1 "}" +// ns_images_pipeline.baml:17:31 (string) len=1 "}" +// ns_images_pipeline.baml:18:5 (string) len=1 "\"" +// ns_images_pipeline.baml:18:6 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_sentiment.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_sentiment.baml new file mode 100644 index 0000000000..cc413cf471 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_sentiment.baml @@ -0,0 +1,133 @@ +// Namespace root.sentiment — a tiny sentiment classifier whose real purpose +// is to teach TESTING in BAML. This file is just the function under test; +// the eval machinery (judge, synthetic data, file/API case loading) lives in +// eval.baml, and the guided tour of testsets in tests.baml. + +// Cheap + fast model for classification. +client Mini { + provider: anthropic, + options: { + model: "claude-haiku-4-5", + api_key: env.ANTHROPIC_API_KEY, + max_tokens: 1024, + }, +} + +type Label = "positive" | "negative" | "neutral"; + +class Verdict { + label: Label, + confidence: float, +} + +// The function under test. +function classify(text: string) -> Verdict { + client: Mini + prompt: #" + Classify the sentiment of the text below as positive, negative, or + neutral. Sarcasm counts as the sentiment actually expressed, not the + literal words. Plain statements of fact are neutral. + + Text: {{ text }} + + {{ ctx.output_format }} + "# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// ns_sentiment.baml:1:1 (comment) len=78 "// Namespace root.sentiment — a tiny sentiment classifier whose real purpose" +// ns_sentiment.baml:2:1 (comment) len=74 "// is to teach TESTING in BAML. This file is just the function under test;" +// ns_sentiment.baml:3:1 (comment) len=77 "// the eval machinery (judge, synthetic data, file/API case loading) lives in" +// ns_sentiment.baml:4:1 (comment) len=60 "// eval.baml, and the guided tour of testsets in tests.baml." +// ns_sentiment.baml:6:1 (comment) len=41 "// Cheap + fast model for classification." +// ns_sentiment.baml:7:1 (keyword) len=6 "client" +// ns_sentiment.baml:7:7 (operator) len=1 "<" +// ns_sentiment.baml:7:8 (type) len=3 "llm" +// ns_sentiment.baml:7:11 (operator) len=1 ">" +// ns_sentiment.baml:7:13 (struct) [declaration] len=4 "Mini" +// ns_sentiment.baml:8:5 (property) len=8 "provider" +// ns_sentiment.baml:9:5 (property) len=7 "options" +// ns_sentiment.baml:10:9 (property) len=5 "model" +// ns_sentiment.baml:10:16 (string) len=18 "\"claude-haiku-4-5\"" +// ns_sentiment.baml:11:9 (property) len=7 "api_key" +// ns_sentiment.baml:12:9 (property) len=10 "max_tokens" +// ns_sentiment.baml:12:21 (number) len=4 "1024" +// ns_sentiment.baml:16:1 (keyword) len=4 "type" +// ns_sentiment.baml:16:6 (type) [declaration] len=5 "Label" +// ns_sentiment.baml:16:12 (operator) len=1 "=" +// ns_sentiment.baml:16:14 (string) len=10 "\"positive\"" +// ns_sentiment.baml:16:25 (operator) len=1 "|" +// ns_sentiment.baml:16:27 (string) len=10 "\"negative\"" +// ns_sentiment.baml:16:38 (operator) len=1 "|" +// ns_sentiment.baml:16:40 (string) len=9 "\"neutral\"" +// ns_sentiment.baml:18:1 (keyword) len=5 "class" +// ns_sentiment.baml:18:7 (class) [declaration] len=7 "Verdict" +// ns_sentiment.baml:19:5 (property) [declaration] len=5 "label" +// ns_sentiment.baml:19:12 (type) len=5 "Label" +// ns_sentiment.baml:20:5 (property) [declaration] len=10 "confidence" +// ns_sentiment.baml:20:17 (type) [defaultLibrary] len=5 "float" +// ns_sentiment.baml:23:1 (comment) len=27 "// The function under test." +// ns_sentiment.baml:24:1 (keyword) len=8 "function" +// ns_sentiment.baml:24:10 (function) [declaration] len=8 "classify" +// ns_sentiment.baml:24:19 (parameter) [declaration] len=4 "text" +// ns_sentiment.baml:24:25 (type) [defaultLibrary] len=6 "string" +// ns_sentiment.baml:24:36 (class) len=7 "Verdict" +// ns_sentiment.baml:25:5 (property) len=6 "client" +// ns_sentiment.baml:26:5 (property) [declaration] len=6 "prompt" +// ns_sentiment.baml:26:13 (string) len=1 "#" +// ns_sentiment.baml:26:14 (string) len=1 "\"" +// ns_sentiment.baml:27:9 (string) len=8 "Classify" +// ns_sentiment.baml:27:18 (string) len=3 "the" +// ns_sentiment.baml:27:22 (string) len=9 "sentiment" +// ns_sentiment.baml:27:32 (string) len=2 "of" +// ns_sentiment.baml:27:35 (string) len=3 "the" +// ns_sentiment.baml:27:39 (string) len=4 "text" +// ns_sentiment.baml:27:44 (string) len=5 "below" +// ns_sentiment.baml:27:50 (string) len=2 "as" +// ns_sentiment.baml:27:53 (string) len=8 "positive" +// ns_sentiment.baml:27:61 (string) len=1 "," +// ns_sentiment.baml:27:63 (string) len=8 "negative" +// ns_sentiment.baml:27:71 (string) len=1 "," +// ns_sentiment.baml:27:73 (string) len=2 "or" +// ns_sentiment.baml:28:9 (string) len=7 "neutral" +// ns_sentiment.baml:28:16 (string) len=1 "." +// ns_sentiment.baml:28:18 (string) len=7 "Sarcasm" +// ns_sentiment.baml:28:26 (string) len=6 "counts" +// ns_sentiment.baml:28:33 (string) len=2 "as" +// ns_sentiment.baml:28:36 (string) len=3 "the" +// ns_sentiment.baml:28:40 (string) len=9 "sentiment" +// ns_sentiment.baml:28:50 (string) len=8 "actually" +// ns_sentiment.baml:28:59 (string) len=9 "expressed" +// ns_sentiment.baml:28:68 (string) len=1 "," +// ns_sentiment.baml:28:70 (string) len=3 "not" +// ns_sentiment.baml:28:74 (string) len=3 "the" +// ns_sentiment.baml:29:9 (string) len=7 "literal" +// ns_sentiment.baml:29:17 (string) len=5 "words" +// ns_sentiment.baml:29:22 (string) len=1 "." +// ns_sentiment.baml:29:24 (string) len=5 "Plain" +// ns_sentiment.baml:29:30 (string) len=10 "statements" +// ns_sentiment.baml:29:41 (string) len=2 "of" +// ns_sentiment.baml:29:44 (string) len=4 "fact" +// ns_sentiment.baml:29:49 (string) len=3 "are" +// ns_sentiment.baml:29:53 (string) len=7 "neutral" +// ns_sentiment.baml:29:60 (string) len=1 "." +// ns_sentiment.baml:31:9 (string) len=4 "Text" +// ns_sentiment.baml:31:13 (string) len=1 ":" +// ns_sentiment.baml:31:15 (string) len=1 "{" +// ns_sentiment.baml:31:16 (string) len=1 "{" +// ns_sentiment.baml:31:18 (string) len=4 "text" +// ns_sentiment.baml:31:23 (string) len=1 "}" +// ns_sentiment.baml:31:24 (string) len=1 "}" +// ns_sentiment.baml:33:9 (string) len=1 "{" +// ns_sentiment.baml:33:10 (string) len=1 "{" +// ns_sentiment.baml:33:12 (string) len=3 "ctx" +// ns_sentiment.baml:33:15 (string) len=1 "." +// ns_sentiment.baml:33:16 (string) len=13 "output_format" +// ns_sentiment.baml:33:30 (string) len=1 "}" +// ns_sentiment.baml:33:31 (string) len=1 "}" +// ns_sentiment.baml:34:5 (string) len=1 "\"" +// ns_sentiment.baml:34:6 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml new file mode 100644 index 0000000000..c1eb1b91a4 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml @@ -0,0 +1,804 @@ +// Patterns: weird union and binding cases. + +// Same typed binding repeated across both `|` branches with explicit parens. +function or_with_repeated_typed_binding(v: int | string) -> int { + match (v) { + (let x: int) | (let x: int) => x, + let _ => 0 + } +} + +// Same bare binding repeated across multiple `|` branches. +function or_with_repeated_bare_binding(v: int) -> int { + match (v) { + let x | let x | let x => x + } +} + +// Wildcard arm last; non-trivial chain narrow in the first arm. +function chain_narrow_then_wildcard(v: int | string | bool) -> int { + match (v) { + let n: int => n, + _ => 0 + } +} + +// Bare type pattern (no binding, no narrow) in match-arm position. +function bare_type_arm(v: int | string) -> int { + match (v) { + int => 1, + string => 2 + } +} + +// ============================================================================ +// Function-type patterns +// ============================================================================ + +// Match on a single function type — arm narrows to the callable. +function call_int_callback(cb: (int) -> int) -> int { + match (cb) { + let f: (int) -> int => f(10) + } +} + +// Match on a union of two distinct function types; dispatch by signature. +function dispatch_callback(cb: ((int) -> int) | ((string) -> string)) -> int { + match (cb) { + let f: (int) -> int => f(0), + (string) -> string => 0 + } +} + +// Or-pattern across two function-typed alternatives that share the same return. +function call_either_int_caller(cb: ((int) -> int) | ((bool) -> int)) -> int { + match (cb) { + (int) -> int => 1, + (bool) -> int => 2 + } +} + +// Function-type narrow with chain-narrow position (`(int) -> T`). +function dispatch_with_wildcard(cb: ((int) -> int) | ((string) -> int)) -> int { + match (cb) { + (int) -> int => 1, + _ => 0 + } +} + +// Generic function-type pattern. T is unified at the call site. The outer +// parens disambiguate the union — without them the parser binds `|` inside +// the return type, yielding `(int) -> (T | (string) -> T)`. +function unwrap_typed(cb: ((int) -> T) | ((string) -> T)) -> T { + match (cb) { + let f: (int) -> T => f(0), + let f: (string) -> T => f("") + } +} + +// ============================================================================ +// Triple higher-order: function returning a function returning a function +// ============================================================================ + +// `f: (int) -> (int) -> (int) -> int` — three-deep curried int function. +// `g: (string) -> (string) -> string` — two-deep curried string function. +// The match dispatches on which curried shape was passed and unwraps it. +function unwrap_curried( + f: ((int) -> (int) -> (int) -> int) | ((string) -> (string) -> string) +) -> int { + match (f) { + let triple: (int) -> (int) -> (int) -> int => triple(1)(2)(3), + let pair: (string) -> (string) -> string => 0 + } +} + +// Match on a function that takes a callback. The arm narrows to the +// callback-accepting shape, then we synthesize an int callback inline. +function call_with_callback( + runner: (((int) -> int) -> int) | (((string) -> int) -> int) +) -> int { + match (runner) { + let r: ((int) -> int) -> int => r((x: int) -> int { x + 1 }), + let r: ((string) -> int) -> int => r((s: string) -> int { 0 }) + } +} + +// ============================================================================ +// Chain narrows + subtyping: each link must be a subtype of the next, so the +// chain widens left-to-right. The rightmost concrete narrow is the effective +// annotation. +// ============================================================================ + +// Literal-narrow widening to primitive: `1 <: int`. +function literal_widens_to_int(v: int) -> int { + match (v) { + let n: int => n, + } +} + +// Function-type widening: a narrower return type is a subtype of a wider one, +// so `(int) -> int <: (int) -> int | string`. +function fn_return_widens(cb: (int) -> int | string) -> int { + match (cb) { + (int) -> int | string => 1, + } +} + +type Number = int | float +function int_widens_to_alias(v: Number) -> int { + match (v) { + let n: Number => 1, + } +} + +// ============================================================================ +// Nested unions and chains in parentheses +// ============================================================================ + +// Paren-wrapped Or with each branch itself a chain. +function paren_chains_in_or(v: int) -> int { + match (v) { + ((let x: int)) | ((let x: int)) => 1 + } +} + +function fn_pattern(cb: (int) -> int) -> int { + match (cb) { + let f: (int) -> int => f(0) + } +} + +// ============================================================================ +// for-let with crazy chains +// ============================================================================ + +// for-let with a single type narrow. +function for_let_with_narrow(items: int[]) -> int { + let sum = 0; + for (let n: int in items) { + sum += n + } + sum +} + +function for_let_ascription(items: int[]) -> int { + let sum = 0; + for (let n: int | string in items) { + sum += 1 + } + sum +} + +// for-let with a function-type narrow. +function for_let_fn_narrow(items: ((int) -> int)[]) -> int { + let total = 0; + for (let f: (int) -> int in items) { + total += f(0) + } + total +} + +// ============================================================================ +// catch arms with crazy chains +// ============================================================================ + +class AppError { code int } + +function risky_error(mode: int) -> int throws AppError | string { + if (mode == 0) { + throw AppError { code: 1 } + } + throw "boom" +} + +// Catch arm with a chain narrow of a union — binds the joined type. +function catch_chain_union(mode: int) -> int { + risky_error(mode) catch (e) { + AppError | string => 1 + } +} + +// Catch arms with paren-wrapped Or chains, each branch a typed binding. +function catch_paren_or_chain(mode: int) -> int { + risky_error(mode) catch (e) { + (AppError) | (string) => 1 + } +} + +// Catch arms with widening chain narrows (literal -> primitive -> union). +function catch_widening_chain(mode: int) -> int { + risky_error(mode) catch (e) { + let s: string => 1, + let app: AppError => 2 + } +} + +// ============================================================================ +// Type unions with suffixes wrapped in many layers of parens +// ============================================================================ + +// Single-layer paren around a union with array suffix. +function nested_paren_union_array_one(items: (int | string)[]) -> int { + items.length() +} + +// Two paren layers: `((int | string)[])` is the same as `(int | string)[]`. +function nested_paren_union_array_two(items: ((int | string)[])) -> int { + items.length() +} + +// Three paren layers. Chain narrow on the outside. +function nested_paren_union_array_three(v: (((int | string)[])[])) -> int { + v.length() +} + +// Chained suffix: union with `[]` wrapped, then `?` outside. +function nested_paren_union_array_optional(v: ((int | string)[])?) -> int { + match (v) { + ((int | string)[])? => 1 + } +} + +// In a match arm, deeply parenthesized type union as the pattern. +function match_nested_paren_union(v: (int | string)[]) -> int { + match (v) { + (((int | string)[])) => 1 + } +} + +// ============================================================================ +// Nested array/class destructuring with branch-local bindings +// ============================================================================ + +class PatternBucket { + values int[] +} + +class PatternMatrix { + rows int[][] +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// patterns_new.baml:1:1 (comment) len=43 "// Patterns: weird union and binding cases." +// patterns_new.baml:3:1 (comment) len=77 "// Same typed binding repeated across both `|` branches with explicit parens." +// patterns_new.baml:4:1 (keyword) len=8 "function" +// patterns_new.baml:4:10 (function) [declaration] len=30 "or_with_repeated_typed_binding" +// patterns_new.baml:4:41 (parameter) [declaration] len=1 "v" +// patterns_new.baml:4:44 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:4:48 (operator) len=1 "|" +// patterns_new.baml:4:50 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:4:61 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:5:5 (keyword) len=5 "match" +// patterns_new.baml:5:12 (parameter) len=1 "v" +// patterns_new.baml:6:10 (keyword) len=3 "let" +// patterns_new.baml:6:14 (variable) [declaration] len=1 "x" +// patterns_new.baml:6:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:6:22 (operator) len=1 "|" +// patterns_new.baml:6:25 (keyword) len=3 "let" +// patterns_new.baml:6:29 (variable) [declaration] len=1 "x" +// patterns_new.baml:6:32 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:6:40 (variable) len=1 "x" +// patterns_new.baml:7:9 (keyword) len=3 "let" +// patterns_new.baml:7:18 (number) len=1 "0" +// patterns_new.baml:11:1 (comment) len=59 "// Same bare binding repeated across multiple `|` branches." +// patterns_new.baml:12:1 (keyword) len=8 "function" +// patterns_new.baml:12:10 (function) [declaration] len=29 "or_with_repeated_bare_binding" +// patterns_new.baml:12:40 (parameter) [declaration] len=1 "v" +// patterns_new.baml:12:43 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:12:51 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:13:5 (keyword) len=5 "match" +// patterns_new.baml:13:12 (parameter) len=1 "v" +// patterns_new.baml:14:9 (keyword) len=3 "let" +// patterns_new.baml:14:13 (variable) [declaration] len=1 "x" +// patterns_new.baml:14:15 (operator) len=1 "|" +// patterns_new.baml:14:17 (keyword) len=3 "let" +// patterns_new.baml:14:21 (variable) [declaration] len=1 "x" +// patterns_new.baml:14:23 (operator) len=1 "|" +// patterns_new.baml:14:25 (keyword) len=3 "let" +// patterns_new.baml:14:29 (variable) [declaration] len=1 "x" +// patterns_new.baml:14:34 (variable) len=1 "x" +// patterns_new.baml:18:1 (comment) len=64 "// Wildcard arm last; non-trivial chain narrow in the first arm." +// patterns_new.baml:19:1 (keyword) len=8 "function" +// patterns_new.baml:19:10 (function) [declaration] len=26 "chain_narrow_then_wildcard" +// patterns_new.baml:19:37 (parameter) [declaration] len=1 "v" +// patterns_new.baml:19:40 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:19:44 (operator) len=1 "|" +// patterns_new.baml:19:46 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:19:53 (operator) len=1 "|" +// patterns_new.baml:19:55 (type) [defaultLibrary] len=4 "bool" +// patterns_new.baml:19:64 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:20:5 (keyword) len=5 "match" +// patterns_new.baml:20:12 (parameter) len=1 "v" +// patterns_new.baml:21:9 (keyword) len=3 "let" +// patterns_new.baml:21:13 (variable) [declaration] len=1 "n" +// patterns_new.baml:21:16 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:21:23 (variable) len=1 "n" +// patterns_new.baml:22:14 (number) len=1 "0" +// patterns_new.baml:26:1 (comment) len=67 "// Bare type pattern (no binding, no narrow) in match-arm position." +// patterns_new.baml:27:1 (keyword) len=8 "function" +// patterns_new.baml:27:10 (function) [declaration] len=13 "bare_type_arm" +// patterns_new.baml:27:24 (parameter) [declaration] len=1 "v" +// patterns_new.baml:27:27 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:27:31 (operator) len=1 "|" +// patterns_new.baml:27:33 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:27:44 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:28:5 (keyword) len=5 "match" +// patterns_new.baml:28:12 (parameter) len=1 "v" +// patterns_new.baml:29:9 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:29:16 (number) len=1 "1" +// patterns_new.baml:30:9 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:30:19 (number) len=1 "2" +// patterns_new.baml:34:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:35:1 (comment) len=25 "// Function-type patterns" +// patterns_new.baml:36:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:38:1 (comment) len=67 "// Match on a single function type — arm narrows to the callable." +// patterns_new.baml:39:1 (keyword) len=8 "function" +// patterns_new.baml:39:10 (function) [declaration] len=17 "call_int_callback" +// patterns_new.baml:39:28 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:39:33 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:39:41 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:39:49 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:40:5 (keyword) len=5 "match" +// patterns_new.baml:40:12 (parameter) len=2 "cb" +// patterns_new.baml:41:9 (keyword) len=3 "let" +// patterns_new.baml:41:13 (variable) [declaration] len=1 "f" +// patterns_new.baml:41:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:41:25 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:41:32 (variable) len=1 "f" +// patterns_new.baml:41:34 (number) len=2 "10" +// patterns_new.baml:45:1 (comment) len=74 "// Match on a union of two distinct function types; dispatch by signature." +// patterns_new.baml:46:1 (keyword) len=8 "function" +// patterns_new.baml:46:10 (function) [declaration] len=17 "dispatch_callback" +// patterns_new.baml:46:28 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:46:34 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:46:42 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:46:47 (operator) len=1 "|" +// patterns_new.baml:46:51 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:46:62 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:46:74 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:47:5 (keyword) len=5 "match" +// patterns_new.baml:47:12 (parameter) len=2 "cb" +// patterns_new.baml:48:9 (keyword) len=3 "let" +// patterns_new.baml:48:13 (variable) [declaration] len=1 "f" +// patterns_new.baml:48:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:48:25 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:48:32 (variable) len=1 "f" +// patterns_new.baml:48:34 (number) len=1 "0" +// patterns_new.baml:49:10 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:49:21 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:49:31 (number) len=1 "0" +// patterns_new.baml:53:1 (comment) len=80 "// Or-pattern across two function-typed alternatives that share the same return." +// patterns_new.baml:54:1 (keyword) len=8 "function" +// patterns_new.baml:54:10 (function) [declaration] len=22 "call_either_int_caller" +// patterns_new.baml:54:33 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:54:39 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:54:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:54:52 (operator) len=1 "|" +// patterns_new.baml:54:56 (type) [defaultLibrary] len=4 "bool" +// patterns_new.baml:54:65 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:54:74 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:55:5 (keyword) len=5 "match" +// patterns_new.baml:55:12 (parameter) len=2 "cb" +// patterns_new.baml:56:10 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:56:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:56:25 (number) len=1 "1" +// patterns_new.baml:57:10 (type) [defaultLibrary] len=4 "bool" +// patterns_new.baml:57:19 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:57:26 (number) len=1 "2" +// patterns_new.baml:61:1 (comment) len=66 "// Function-type narrow with chain-narrow position (`(int) -> T`)." +// patterns_new.baml:62:1 (keyword) len=8 "function" +// patterns_new.baml:62:10 (function) [declaration] len=22 "dispatch_with_wildcard" +// patterns_new.baml:62:33 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:62:39 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:62:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:62:52 (operator) len=1 "|" +// patterns_new.baml:62:56 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:62:67 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:62:76 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:63:5 (keyword) len=5 "match" +// patterns_new.baml:63:12 (parameter) len=2 "cb" +// patterns_new.baml:64:10 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:64:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:64:25 (number) len=1 "1" +// patterns_new.baml:65:14 (number) len=1 "0" +// patterns_new.baml:69:1 (comment) len=74 "// Generic function-type pattern. T is unified at the call site. The outer" +// patterns_new.baml:70:1 (comment) len=77 "// parens disambiguate the union — without them the parser binds `|` inside" +// patterns_new.baml:71:1 (comment) len=60 "// the return type, yielding `(int) -> (T | (string) -> T)`." +// patterns_new.baml:72:1 (keyword) len=8 "function" +// patterns_new.baml:72:10 (function) [declaration] len=12 "unwrap_typed" +// patterns_new.baml:72:22 (operator) len=1 "<" +// patterns_new.baml:72:23 (typeParameter) [declaration] len=1 "T" +// patterns_new.baml:72:24 (operator) len=1 ">" +// patterns_new.baml:72:26 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:72:32 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:72:40 (type) len=1 "T" +// patterns_new.baml:72:43 (operator) len=1 "|" +// patterns_new.baml:72:47 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:72:58 (type) len=1 "T" +// patterns_new.baml:72:65 (type) len=1 "T" +// patterns_new.baml:73:5 (keyword) len=5 "match" +// patterns_new.baml:73:12 (parameter) len=2 "cb" +// patterns_new.baml:74:9 (keyword) len=3 "let" +// patterns_new.baml:74:13 (variable) [declaration] len=1 "f" +// patterns_new.baml:74:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:74:25 (type) len=1 "T" +// patterns_new.baml:74:30 (variable) len=1 "f" +// patterns_new.baml:74:32 (number) len=1 "0" +// patterns_new.baml:75:9 (keyword) len=3 "let" +// patterns_new.baml:75:13 (variable) [declaration] len=1 "f" +// patterns_new.baml:75:17 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:75:28 (type) len=1 "T" +// patterns_new.baml:75:33 (variable) len=1 "f" +// patterns_new.baml:75:35 (string) len=2 "\"\"" +// patterns_new.baml:79:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:80:1 (comment) len=74 "// Triple higher-order: function returning a function returning a function" +// patterns_new.baml:81:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:83:1 (comment) len=75 "// `f: (int) -> (int) -> (int) -> int` — three-deep curried int function." +// patterns_new.baml:84:1 (comment) len=78 "// `g: (string) -> (string) -> string` — two-deep curried string function." +// patterns_new.baml:85:1 (comment) len=73 "// The match dispatches on which curried shape was passed and unwraps it." +// patterns_new.baml:86:1 (keyword) len=8 "function" +// patterns_new.baml:86:10 (function) [declaration] len=14 "unwrap_curried" +// patterns_new.baml:87:5 (parameter) [declaration] len=1 "f" +// patterns_new.baml:87:10 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:87:19 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:87:28 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:87:36 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:87:41 (operator) len=1 "|" +// patterns_new.baml:87:45 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:87:57 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:87:68 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:88:6 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:89:5 (keyword) len=5 "match" +// patterns_new.baml:89:12 (parameter) len=1 "f" +// patterns_new.baml:90:9 (keyword) len=3 "let" +// patterns_new.baml:90:13 (variable) [declaration] len=6 "triple" +// patterns_new.baml:90:22 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:90:31 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:90:40 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:90:48 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:90:55 (variable) len=6 "triple" +// patterns_new.baml:90:62 (number) len=1 "1" +// patterns_new.baml:90:65 (number) len=1 "2" +// patterns_new.baml:90:68 (number) len=1 "3" +// patterns_new.baml:91:9 (keyword) len=3 "let" +// patterns_new.baml:91:13 (variable) [declaration] len=4 "pair" +// patterns_new.baml:91:20 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:91:32 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:91:43 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:91:53 (number) len=1 "0" +// patterns_new.baml:95:1 (comment) len=68 "// Match on a function that takes a callback. The arm narrows to the" +// patterns_new.baml:96:1 (comment) len=71 "// callback-accepting shape, then we synthesize an int callback inline." +// patterns_new.baml:97:1 (keyword) len=8 "function" +// patterns_new.baml:97:10 (function) [declaration] len=18 "call_with_callback" +// patterns_new.baml:98:5 (parameter) [declaration] len=6 "runner" +// patterns_new.baml:98:16 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:98:24 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:98:32 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:98:37 (operator) len=1 "|" +// patterns_new.baml:98:42 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:98:53 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:98:61 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:99:6 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:100:5 (keyword) len=5 "match" +// patterns_new.baml:100:12 (parameter) len=6 "runner" +// patterns_new.baml:101:9 (keyword) len=3 "let" +// patterns_new.baml:101:13 (variable) [declaration] len=1 "r" +// patterns_new.baml:101:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:101:26 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:101:34 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:101:41 (variable) len=1 "r" +// patterns_new.baml:101:44 (parameter) [declaration] len=1 "x" +// patterns_new.baml:101:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:101:55 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:101:61 (parameter) len=1 "x" +// patterns_new.baml:101:63 (operator) len=1 "+" +// patterns_new.baml:101:65 (number) len=1 "1" +// patterns_new.baml:102:9 (keyword) len=3 "let" +// patterns_new.baml:102:13 (variable) [declaration] len=1 "r" +// patterns_new.baml:102:18 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:102:29 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:102:37 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:102:44 (variable) len=1 "r" +// patterns_new.baml:102:47 (parameter) [declaration] len=1 "s" +// patterns_new.baml:102:50 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:102:61 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:102:67 (number) len=1 "0" +// patterns_new.baml:106:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:107:1 (comment) len=77 "// Chain narrows + subtyping: each link must be a subtype of the next, so the" +// patterns_new.baml:108:1 (comment) len=77 "// chain widens left-to-right. The rightmost concrete narrow is the effective" +// patterns_new.baml:109:1 (comment) len=14 "// annotation." +// patterns_new.baml:110:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:112:1 (comment) len=52 "// Literal-narrow widening to primitive: `1 <: int`." +// patterns_new.baml:113:1 (keyword) len=8 "function" +// patterns_new.baml:113:10 (function) [declaration] len=21 "literal_widens_to_int" +// patterns_new.baml:113:32 (parameter) [declaration] len=1 "v" +// patterns_new.baml:113:35 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:113:43 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:114:5 (keyword) len=5 "match" +// patterns_new.baml:114:12 (parameter) len=1 "v" +// patterns_new.baml:115:9 (keyword) len=3 "let" +// patterns_new.baml:115:13 (variable) [declaration] len=1 "n" +// patterns_new.baml:115:16 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:115:23 (variable) len=1 "n" +// patterns_new.baml:119:1 (comment) len=78 "// Function-type widening: a narrower return type is a subtype of a wider one," +// patterns_new.baml:120:1 (comment) len=46 "// so `(int) -> int <: (int) -> int | string`." +// patterns_new.baml:121:1 (keyword) len=8 "function" +// patterns_new.baml:121:10 (function) [declaration] len=16 "fn_return_widens" +// patterns_new.baml:121:27 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:121:32 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:121:40 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:121:44 (operator) len=1 "|" +// patterns_new.baml:121:46 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:121:57 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:122:5 (keyword) len=5 "match" +// patterns_new.baml:122:12 (parameter) len=2 "cb" +// patterns_new.baml:123:10 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:123:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:123:22 (operator) len=1 "|" +// patterns_new.baml:123:24 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:123:34 (number) len=1 "1" +// patterns_new.baml:127:1 (keyword) len=4 "type" +// patterns_new.baml:127:6 (type) [declaration] len=6 "Number" +// patterns_new.baml:127:13 (operator) len=1 "=" +// patterns_new.baml:127:15 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:127:19 (operator) len=1 "|" +// patterns_new.baml:127:21 (type) [defaultLibrary] len=5 "float" +// patterns_new.baml:128:1 (keyword) len=8 "function" +// patterns_new.baml:128:10 (function) [declaration] len=19 "int_widens_to_alias" +// patterns_new.baml:128:30 (parameter) [declaration] len=1 "v" +// patterns_new.baml:128:33 (type) len=6 "Number" +// patterns_new.baml:128:44 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:129:5 (keyword) len=5 "match" +// patterns_new.baml:129:12 (parameter) len=1 "v" +// patterns_new.baml:130:9 (keyword) len=3 "let" +// patterns_new.baml:130:13 (variable) [declaration] len=1 "n" +// patterns_new.baml:130:16 (type) len=6 "Number" +// patterns_new.baml:130:26 (number) len=1 "1" +// patterns_new.baml:134:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:135:1 (comment) len=42 "// Nested unions and chains in parentheses" +// patterns_new.baml:136:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:138:1 (comment) len=52 "// Paren-wrapped Or with each branch itself a chain." +// patterns_new.baml:139:1 (keyword) len=8 "function" +// patterns_new.baml:139:10 (function) [declaration] len=18 "paren_chains_in_or" +// patterns_new.baml:139:29 (parameter) [declaration] len=1 "v" +// patterns_new.baml:139:32 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:139:40 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:140:5 (keyword) len=5 "match" +// patterns_new.baml:140:12 (parameter) len=1 "v" +// patterns_new.baml:141:11 (keyword) len=3 "let" +// patterns_new.baml:141:15 (variable) [declaration] len=1 "x" +// patterns_new.baml:141:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:141:24 (operator) len=1 "|" +// patterns_new.baml:141:28 (keyword) len=3 "let" +// patterns_new.baml:141:32 (variable) [declaration] len=1 "x" +// patterns_new.baml:141:35 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:141:44 (number) len=1 "1" +// patterns_new.baml:145:1 (keyword) len=8 "function" +// patterns_new.baml:145:10 (function) [declaration] len=10 "fn_pattern" +// patterns_new.baml:145:21 (parameter) [declaration] len=2 "cb" +// patterns_new.baml:145:26 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:145:34 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:145:42 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:146:5 (keyword) len=5 "match" +// patterns_new.baml:146:12 (parameter) len=2 "cb" +// patterns_new.baml:147:9 (keyword) len=3 "let" +// patterns_new.baml:147:13 (variable) [declaration] len=1 "f" +// patterns_new.baml:147:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:147:25 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:147:32 (variable) len=1 "f" +// patterns_new.baml:147:34 (number) len=1 "0" +// patterns_new.baml:151:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:152:1 (comment) len=28 "// for-let with crazy chains" +// patterns_new.baml:153:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:155:1 (comment) len=37 "// for-let with a single type narrow." +// patterns_new.baml:156:1 (keyword) len=8 "function" +// patterns_new.baml:156:10 (function) [declaration] len=19 "for_let_with_narrow" +// patterns_new.baml:156:30 (parameter) [declaration] len=5 "items" +// patterns_new.baml:156:37 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:156:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:157:5 (keyword) len=3 "let" +// patterns_new.baml:157:9 (variable) [declaration] len=3 "sum" +// patterns_new.baml:157:13 (operator) len=1 "=" +// patterns_new.baml:157:15 (number) len=1 "0" +// patterns_new.baml:158:5 (keyword) len=3 "for" +// patterns_new.baml:158:10 (keyword) len=3 "let" +// patterns_new.baml:158:14 (variable) [declaration] len=1 "n" +// patterns_new.baml:158:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:158:21 (keyword) len=2 "in" +// patterns_new.baml:158:24 (parameter) len=5 "items" +// patterns_new.baml:159:9 (variable) len=3 "sum" +// patterns_new.baml:159:13 (operator) len=2 "+=" +// patterns_new.baml:159:16 (variable) len=1 "n" +// patterns_new.baml:161:5 (variable) len=3 "sum" +// patterns_new.baml:164:1 (keyword) len=8 "function" +// patterns_new.baml:164:10 (function) [declaration] len=18 "for_let_ascription" +// patterns_new.baml:164:29 (parameter) [declaration] len=5 "items" +// patterns_new.baml:164:36 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:164:46 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:165:5 (keyword) len=3 "let" +// patterns_new.baml:165:9 (variable) [declaration] len=3 "sum" +// patterns_new.baml:165:13 (operator) len=1 "=" +// patterns_new.baml:165:15 (number) len=1 "0" +// patterns_new.baml:166:5 (keyword) len=3 "for" +// patterns_new.baml:166:10 (keyword) len=3 "let" +// patterns_new.baml:166:14 (variable) [declaration] len=1 "n" +// patterns_new.baml:166:17 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:166:21 (operator) len=1 "|" +// patterns_new.baml:166:23 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:166:30 (keyword) len=2 "in" +// patterns_new.baml:166:33 (parameter) len=5 "items" +// patterns_new.baml:167:9 (variable) len=3 "sum" +// patterns_new.baml:167:13 (operator) len=2 "+=" +// patterns_new.baml:167:16 (number) len=1 "1" +// patterns_new.baml:169:5 (variable) len=3 "sum" +// patterns_new.baml:172:1 (comment) len=39 "// for-let with a function-type narrow." +// patterns_new.baml:173:1 (keyword) len=8 "function" +// patterns_new.baml:173:10 (function) [declaration] len=17 "for_let_fn_narrow" +// patterns_new.baml:173:28 (parameter) [declaration] len=5 "items" +// patterns_new.baml:173:37 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:173:45 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:173:56 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:174:5 (keyword) len=3 "let" +// patterns_new.baml:174:9 (variable) [declaration] len=5 "total" +// patterns_new.baml:174:15 (operator) len=1 "=" +// patterns_new.baml:174:17 (number) len=1 "0" +// patterns_new.baml:175:5 (keyword) len=3 "for" +// patterns_new.baml:175:10 (keyword) len=3 "let" +// patterns_new.baml:175:14 (variable) [declaration] len=1 "f" +// patterns_new.baml:175:18 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:175:26 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:175:30 (keyword) len=2 "in" +// patterns_new.baml:175:33 (parameter) len=5 "items" +// patterns_new.baml:176:9 (variable) len=5 "total" +// patterns_new.baml:176:15 (operator) len=2 "+=" +// patterns_new.baml:176:18 (variable) len=1 "f" +// patterns_new.baml:176:20 (number) len=1 "0" +// patterns_new.baml:178:5 (variable) len=5 "total" +// patterns_new.baml:181:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:182:1 (comment) len=31 "// catch arms with crazy chains" +// patterns_new.baml:183:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:185:1 (keyword) len=5 "class" +// patterns_new.baml:185:7 (class) [declaration] len=8 "AppError" +// patterns_new.baml:185:18 (property) [declaration] len=4 "code" +// patterns_new.baml:185:23 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:187:1 (keyword) len=8 "function" +// patterns_new.baml:187:10 (function) [declaration] len=11 "risky_error" +// patterns_new.baml:187:22 (parameter) [declaration] len=4 "mode" +// patterns_new.baml:187:28 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:187:36 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:187:40 (keyword) len=6 "throws" +// patterns_new.baml:187:47 (class) len=8 "AppError" +// patterns_new.baml:187:56 (operator) len=1 "|" +// patterns_new.baml:187:58 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:188:5 (keyword) len=2 "if" +// patterns_new.baml:188:9 (parameter) len=4 "mode" +// patterns_new.baml:188:14 (operator) len=2 "==" +// patterns_new.baml:188:17 (number) len=1 "0" +// patterns_new.baml:189:9 (keyword) len=5 "throw" +// patterns_new.baml:189:15 (class) len=8 "AppError" +// patterns_new.baml:189:26 (property) len=4 "code" +// patterns_new.baml:189:32 (number) len=1 "1" +// patterns_new.baml:191:5 (keyword) len=5 "throw" +// patterns_new.baml:191:11 (string) len=6 "\"boom\"" +// patterns_new.baml:194:1 (comment) len=70 "// Catch arm with a chain narrow of a union — binds the joined type." +// patterns_new.baml:195:1 (keyword) len=8 "function" +// patterns_new.baml:195:10 (function) [declaration] len=17 "catch_chain_union" +// patterns_new.baml:195:28 (parameter) [declaration] len=4 "mode" +// patterns_new.baml:195:34 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:195:42 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:196:5 (function) len=11 "risky_error" +// patterns_new.baml:196:17 (parameter) len=4 "mode" +// patterns_new.baml:196:23 (keyword) len=5 "catch" +// patterns_new.baml:196:30 (parameter) [declaration] len=1 "e" +// patterns_new.baml:197:9 (class) len=8 "AppError" +// patterns_new.baml:197:18 (operator) len=1 "|" +// patterns_new.baml:197:20 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:197:30 (number) len=1 "1" +// patterns_new.baml:201:1 (comment) len=72 "// Catch arms with paren-wrapped Or chains, each branch a typed binding." +// patterns_new.baml:202:1 (keyword) len=8 "function" +// patterns_new.baml:202:10 (function) [declaration] len=20 "catch_paren_or_chain" +// patterns_new.baml:202:31 (parameter) [declaration] len=4 "mode" +// patterns_new.baml:202:37 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:202:45 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:203:5 (function) len=11 "risky_error" +// patterns_new.baml:203:17 (parameter) len=4 "mode" +// patterns_new.baml:203:23 (keyword) len=5 "catch" +// patterns_new.baml:203:30 (parameter) [declaration] len=1 "e" +// patterns_new.baml:204:10 (class) len=8 "AppError" +// patterns_new.baml:204:20 (operator) len=1 "|" +// patterns_new.baml:204:23 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:204:34 (number) len=1 "1" +// patterns_new.baml:208:1 (comment) len=74 "// Catch arms with widening chain narrows (literal -> primitive -> union)." +// patterns_new.baml:209:1 (keyword) len=8 "function" +// patterns_new.baml:209:10 (function) [declaration] len=20 "catch_widening_chain" +// patterns_new.baml:209:31 (parameter) [declaration] len=4 "mode" +// patterns_new.baml:209:37 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:209:45 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:210:5 (function) len=11 "risky_error" +// patterns_new.baml:210:17 (parameter) len=4 "mode" +// patterns_new.baml:210:23 (keyword) len=5 "catch" +// patterns_new.baml:210:30 (parameter) [declaration] len=1 "e" +// patterns_new.baml:211:9 (keyword) len=3 "let" +// patterns_new.baml:211:13 (variable) [declaration] len=1 "s" +// patterns_new.baml:211:16 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:211:26 (number) len=1 "1" +// patterns_new.baml:212:9 (keyword) len=3 "let" +// patterns_new.baml:212:13 (variable) [declaration] len=3 "app" +// patterns_new.baml:212:18 (class) len=8 "AppError" +// patterns_new.baml:212:30 (number) len=1 "2" +// patterns_new.baml:216:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:217:1 (comment) len=61 "// Type unions with suffixes wrapped in many layers of parens" +// patterns_new.baml:218:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:220:1 (comment) len=55 "// Single-layer paren around a union with array suffix." +// patterns_new.baml:221:1 (keyword) len=8 "function" +// patterns_new.baml:221:10 (function) [declaration] len=28 "nested_paren_union_array_one" +// patterns_new.baml:221:39 (parameter) [declaration] len=5 "items" +// patterns_new.baml:221:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:221:51 (operator) len=1 "|" +// patterns_new.baml:221:53 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:221:67 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:222:5 (parameter) len=5 "items" +// patterns_new.baml:222:11 (method) len=6 "length" +// patterns_new.baml:225:1 (comment) len=76 "// Two paren layers: `((int | string)[])` is the same as `(int | string)[]`." +// patterns_new.baml:226:1 (keyword) len=8 "function" +// patterns_new.baml:226:10 (function) [declaration] len=28 "nested_paren_union_array_two" +// patterns_new.baml:226:39 (parameter) [declaration] len=5 "items" +// patterns_new.baml:226:48 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:226:52 (operator) len=1 "|" +// patterns_new.baml:226:54 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:226:69 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:227:5 (parameter) len=5 "items" +// patterns_new.baml:227:11 (method) len=6 "length" +// patterns_new.baml:230:1 (comment) len=51 "// Three paren layers. Chain narrow on the outside." +// patterns_new.baml:231:1 (keyword) len=8 "function" +// patterns_new.baml:231:10 (function) [declaration] len=30 "nested_paren_union_array_three" +// patterns_new.baml:231:41 (parameter) [declaration] len=1 "v" +// patterns_new.baml:231:47 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:231:51 (operator) len=1 "|" +// patterns_new.baml:231:53 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:231:71 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:232:5 (parameter) len=1 "v" +// patterns_new.baml:232:7 (method) len=6 "length" +// patterns_new.baml:235:1 (comment) len=61 "// Chained suffix: union with `[]` wrapped, then `?` outside." +// patterns_new.baml:236:1 (keyword) len=8 "function" +// patterns_new.baml:236:10 (function) [declaration] len=33 "nested_paren_union_array_optional" +// patterns_new.baml:236:44 (parameter) [declaration] len=1 "v" +// patterns_new.baml:236:49 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:236:53 (operator) len=1 "|" +// patterns_new.baml:236:55 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:236:71 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:237:5 (keyword) len=5 "match" +// patterns_new.baml:237:12 (parameter) len=1 "v" +// patterns_new.baml:238:11 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:238:15 (operator) len=1 "|" +// patterns_new.baml:238:17 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:238:32 (number) len=1 "1" +// patterns_new.baml:242:1 (comment) len=66 "// In a match arm, deeply parenthesized type union as the pattern." +// patterns_new.baml:243:1 (keyword) len=8 "function" +// patterns_new.baml:243:10 (function) [declaration] len=24 "match_nested_paren_union" +// patterns_new.baml:243:35 (parameter) [declaration] len=1 "v" +// patterns_new.baml:243:39 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:243:43 (operator) len=1 "|" +// patterns_new.baml:243:45 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:243:59 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:244:5 (keyword) len=5 "match" +// patterns_new.baml:244:12 (parameter) len=1 "v" +// patterns_new.baml:245:12 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:245:16 (operator) len=1 "|" +// patterns_new.baml:245:18 (type) [defaultLibrary] len=6 "string" +// patterns_new.baml:245:33 (number) len=1 "1" +// patterns_new.baml:249:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:250:1 (comment) len=62 "// Nested array/class destructuring with branch-local bindings" +// patterns_new.baml:251:1 (comment) len=79 "// ============================================================================" +// patterns_new.baml:253:1 (keyword) len=5 "class" +// patterns_new.baml:253:7 (class) [declaration] len=13 "PatternBucket" +// patterns_new.baml:254:5 (property) [declaration] len=6 "values" +// patterns_new.baml:254:12 (type) [defaultLibrary] len=3 "int" +// patterns_new.baml:257:1 (keyword) len=5 "class" +// patterns_new.baml:257:7 (class) [declaration] len=13 "PatternMatrix" +// patterns_new.baml:258:5 (property) [declaration] len=4 "rows" +// patterns_new.baml:258:10 (type) [defaultLibrary] len=3 "int" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/remap_role.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/remap_role.baml new file mode 100644 index 0000000000..01c189a3c6 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/remap_role.baml @@ -0,0 +1,80 @@ +client MyClient { + provider openai + options { + model "gpt-4o" + allowed_roles ["user", "assistant", "system"] + remap_roles { + user "human" + assistant "ai" + system "instructions" + } + default_role "user" + } +} + +function TestRemap(input: string) -> string { + client MyClient + prompt #" + {{ _.chat("user") }} + Test message: {{ input }} + "# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// remap_role.baml:1:1 (keyword) len=6 "client" +// remap_role.baml:1:7 (operator) len=1 "<" +// remap_role.baml:1:8 (type) len=3 "llm" +// remap_role.baml:1:11 (operator) len=1 ">" +// remap_role.baml:1:13 (struct) [declaration] len=8 "MyClient" +// remap_role.baml:2:3 (property) len=8 "provider" +// remap_role.baml:3:3 (property) len=7 "options" +// remap_role.baml:4:5 (property) len=5 "model" +// remap_role.baml:4:11 (string) len=8 "\"gpt-4o\"" +// remap_role.baml:5:5 (property) len=13 "allowed_roles" +// remap_role.baml:5:20 (string) len=6 "\"user\"" +// remap_role.baml:5:28 (string) len=11 "\"assistant\"" +// remap_role.baml:5:41 (string) len=8 "\"system\"" +// remap_role.baml:6:5 (property) len=11 "remap_roles" +// remap_role.baml:7:7 (property) len=4 "user" +// remap_role.baml:7:12 (string) len=7 "\"human\"" +// remap_role.baml:8:7 (property) len=9 "assistant" +// remap_role.baml:8:17 (string) len=4 "\"ai\"" +// remap_role.baml:9:7 (property) len=6 "system" +// remap_role.baml:9:14 (string) len=14 "\"instructions\"" +// remap_role.baml:11:5 (property) len=12 "default_role" +// remap_role.baml:11:18 (string) len=6 "\"user\"" +// remap_role.baml:15:1 (keyword) len=8 "function" +// remap_role.baml:15:10 (function) [declaration] len=9 "TestRemap" +// remap_role.baml:15:20 (parameter) [declaration] len=5 "input" +// remap_role.baml:15:27 (type) [defaultLibrary] len=6 "string" +// remap_role.baml:15:38 (type) [defaultLibrary] len=6 "string" +// remap_role.baml:16:3 (property) len=6 "client" +// remap_role.baml:17:3 (property) [declaration] len=6 "prompt" +// remap_role.baml:17:10 (string) len=1 "#" +// remap_role.baml:17:11 (string) len=1 "\"" +// remap_role.baml:18:5 (string) len=1 "{" +// remap_role.baml:18:6 (string) len=1 "{" +// remap_role.baml:18:8 (string) len=1 "_" +// remap_role.baml:18:9 (string) len=1 "." +// remap_role.baml:18:10 (string) len=4 "chat" +// remap_role.baml:18:14 (string) len=1 "(" +// remap_role.baml:18:15 (string) len=1 "\"" +// remap_role.baml:18:16 (string) len=4 "user" +// remap_role.baml:18:20 (string) len=1 "\"" +// remap_role.baml:18:21 (string) len=1 ")" +// remap_role.baml:18:23 (string) len=1 "}" +// remap_role.baml:18:24 (string) len=1 "}" +// remap_role.baml:19:5 (string) len=4 "Test" +// remap_role.baml:19:10 (string) len=7 "message" +// remap_role.baml:19:17 (string) len=1 ":" +// remap_role.baml:19:19 (string) len=1 "{" +// remap_role.baml:19:20 (string) len=1 "{" +// remap_role.baml:19:22 (string) len=5 "input" +// remap_role.baml:19:28 (string) len=1 "}" +// remap_role.baml:19:29 (string) len=1 "}" +// remap_role.baml:20:3 (string) len=1 "\"" +// remap_role.baml:20:4 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/requires_clause.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/requires_clause.baml new file mode 100644 index 0000000000..8bae185de2 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/requires_clause.baml @@ -0,0 +1,113 @@ +// BEP-044: fields contributed by a grandparent interface should flow into +// the implementor through the full requires chain. + +interface Named { name: string } +interface Aged { age: int } +interface Person requires Named, Aged { + occupation: string + + function introduce(self) -> string throws never { + return self.name + ", " + self.occupation + } + + function age_value(self) -> int throws never { + return self.age + } +} + +class Employee { + name: string + age: int + occupation: string + salary: float + + implements Named {} + implements Aged {} + implements Person {} +} + +function get_name(e: Employee) -> string { + return e.name +} + +function get_age(e: Employee) -> int { + return e.age +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// requires_clause.baml:1:1 (comment) len=74 "// BEP-044: fields contributed by a grandparent interface should flow into" +// requires_clause.baml:2:1 (comment) len=51 "// the implementor through the full requires chain." +// requires_clause.baml:4:1 (keyword) len=9 "interface" +// requires_clause.baml:4:11 (interface) [declaration] len=5 "Named" +// requires_clause.baml:4:19 (property) [declaration] len=4 "name" +// requires_clause.baml:4:25 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:5:1 (keyword) len=9 "interface" +// requires_clause.baml:5:11 (interface) [declaration] len=4 "Aged" +// requires_clause.baml:5:18 (property) [declaration] len=3 "age" +// requires_clause.baml:5:23 (type) [defaultLibrary] len=3 "int" +// requires_clause.baml:6:1 (keyword) len=9 "interface" +// requires_clause.baml:6:11 (interface) [declaration] len=6 "Person" +// requires_clause.baml:6:18 (keyword) len=8 "requires" +// requires_clause.baml:6:27 (interface) len=5 "Named" +// requires_clause.baml:6:34 (interface) len=4 "Aged" +// requires_clause.baml:7:3 (property) [declaration] len=10 "occupation" +// requires_clause.baml:7:15 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:9:3 (keyword) len=8 "function" +// requires_clause.baml:9:12 (method) [declaration] len=9 "introduce" +// requires_clause.baml:9:22 (parameter) [declaration] len=4 "self" +// requires_clause.baml:9:31 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:9:38 (keyword) len=6 "throws" +// requires_clause.baml:9:45 (type) [defaultLibrary] len=5 "never" +// requires_clause.baml:10:5 (keyword) len=6 "return" +// requires_clause.baml:10:12 (parameter) len=4 "self" +// requires_clause.baml:10:17 (property) len=4 "name" +// requires_clause.baml:10:22 (operator) len=1 "+" +// requires_clause.baml:10:24 (string) len=4 "\", \"" +// requires_clause.baml:10:29 (operator) len=1 "+" +// requires_clause.baml:10:31 (parameter) len=4 "self" +// requires_clause.baml:10:36 (property) len=10 "occupation" +// requires_clause.baml:13:3 (keyword) len=8 "function" +// requires_clause.baml:13:12 (method) [declaration] len=9 "age_value" +// requires_clause.baml:13:22 (parameter) [declaration] len=4 "self" +// requires_clause.baml:13:31 (type) [defaultLibrary] len=3 "int" +// requires_clause.baml:13:35 (keyword) len=6 "throws" +// requires_clause.baml:13:42 (type) [defaultLibrary] len=5 "never" +// requires_clause.baml:14:5 (keyword) len=6 "return" +// requires_clause.baml:14:12 (parameter) len=4 "self" +// requires_clause.baml:14:17 (property) len=3 "age" +// requires_clause.baml:18:1 (keyword) len=5 "class" +// requires_clause.baml:18:7 (class) [declaration] len=8 "Employee" +// requires_clause.baml:19:3 (property) [declaration] len=4 "name" +// requires_clause.baml:19:9 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:20:3 (property) [declaration] len=3 "age" +// requires_clause.baml:20:8 (type) [defaultLibrary] len=3 "int" +// requires_clause.baml:21:3 (property) [declaration] len=10 "occupation" +// requires_clause.baml:21:15 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:22:3 (property) [declaration] len=6 "salary" +// requires_clause.baml:22:11 (type) [defaultLibrary] len=5 "float" +// requires_clause.baml:24:3 (keyword) len=10 "implements" +// requires_clause.baml:24:14 (interface) len=5 "Named" +// requires_clause.baml:25:3 (keyword) len=10 "implements" +// requires_clause.baml:25:14 (interface) len=4 "Aged" +// requires_clause.baml:26:3 (keyword) len=10 "implements" +// requires_clause.baml:26:14 (interface) len=6 "Person" +// requires_clause.baml:29:1 (keyword) len=8 "function" +// requires_clause.baml:29:10 (function) [declaration] len=8 "get_name" +// requires_clause.baml:29:19 (parameter) [declaration] len=1 "e" +// requires_clause.baml:29:22 (class) len=8 "Employee" +// requires_clause.baml:29:35 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:30:3 (keyword) len=6 "return" +// requires_clause.baml:30:10 (parameter) len=1 "e" +// requires_clause.baml:30:12 (property) len=4 "name" +// requires_clause.baml:33:1 (keyword) len=8 "function" +// requires_clause.baml:33:10 (function) [declaration] len=7 "get_age" +// requires_clause.baml:33:18 (parameter) [declaration] len=1 "e" +// requires_clause.baml:33:21 (class) len=8 "Employee" +// requires_clause.baml:33:34 (type) [defaultLibrary] len=3 "int" +// requires_clause.baml:34:3 (keyword) len=6 "return" +// requires_clause.baml:34:10 (parameter) len=1 "e" +// requires_clause.baml:34:12 (property) len=3 "age" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/retry_policy_valid_retry.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/retry_policy_valid_retry.baml new file mode 100644 index 0000000000..d75da806dc --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/retry_policy_valid_retry.baml @@ -0,0 +1,34 @@ +// Minimal repro: retry_policy inside client block causes parsing errors + +client MyClient { + provider openai + retry_policy MyRetry + options { + model "gpt-4" + } +} + +retry_policy MyRetry { + max_retries 3 +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// retry_policy_valid_retry.baml:1:1 (comment) len=72 "// Minimal repro: retry_policy inside client block causes parsing errors" +// retry_policy_valid_retry.baml:3:1 (keyword) len=6 "client" +// retry_policy_valid_retry.baml:3:7 (operator) len=1 "<" +// retry_policy_valid_retry.baml:3:8 (type) len=3 "llm" +// retry_policy_valid_retry.baml:3:11 (operator) len=1 ">" +// retry_policy_valid_retry.baml:3:13 (struct) [declaration] len=8 "MyClient" +// retry_policy_valid_retry.baml:4:3 (property) len=8 "provider" +// retry_policy_valid_retry.baml:5:3 (property) len=12 "retry_policy" +// retry_policy_valid_retry.baml:6:3 (property) len=7 "options" +// retry_policy_valid_retry.baml:7:5 (property) len=5 "model" +// retry_policy_valid_retry.baml:7:11 (string) len=7 "\"gpt-4\"" +// retry_policy_valid_retry.baml:11:1 (keyword) len=12 "retry_policy" +// retry_policy_valid_retry.baml:11:14 (struct) [declaration] len=7 "MyRetry" +// retry_policy_valid_retry.baml:12:3 (property) len=11 "max_retries" +// retry_policy_valid_retry.baml:12:15 (number) len=1 "3" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/self_qualified_call.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/self_qualified_call.baml new file mode 100644 index 0000000000..8d87763be5 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/self_qualified_call.baml @@ -0,0 +1,82 @@ +// BEP-044 §"self Access": `self.as.method()` works from inside an +// `implements` block to reach a sibling interface's method even when names +// are flat. + +interface Greeter { + function greet(self) -> string throws never +} + +interface Farewell { + function bye(self) -> string throws never +} + +class Polite { + name: string + + implements Greeter { + function greet(self) -> string { + return "Hello, I'm " + self.name + } + } + + implements Farewell { + function bye(self) -> string { + return self.as.greet() + " — and goodbye!" + } + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// self_qualified_call.baml:1:1 (comment) len=82 "// BEP-044 §\"self Access\": `self.as.method()` works from inside an" +// self_qualified_call.baml:2:1 (comment) len=75 "// `implements` block to reach a sibling interface's method even when names" +// self_qualified_call.baml:3:1 (comment) len=12 "// are flat." +// self_qualified_call.baml:5:1 (keyword) len=9 "interface" +// self_qualified_call.baml:5:11 (interface) [declaration] len=7 "Greeter" +// self_qualified_call.baml:6:3 (keyword) len=8 "function" +// self_qualified_call.baml:6:12 (method) [declaration] len=5 "greet" +// self_qualified_call.baml:6:18 (parameter) [declaration] len=4 "self" +// self_qualified_call.baml:6:27 (type) [defaultLibrary] len=6 "string" +// self_qualified_call.baml:6:34 (keyword) len=6 "throws" +// self_qualified_call.baml:6:41 (type) [defaultLibrary] len=5 "never" +// self_qualified_call.baml:9:1 (keyword) len=9 "interface" +// self_qualified_call.baml:9:11 (interface) [declaration] len=8 "Farewell" +// self_qualified_call.baml:10:3 (keyword) len=8 "function" +// self_qualified_call.baml:10:12 (method) [declaration] len=3 "bye" +// self_qualified_call.baml:10:16 (parameter) [declaration] len=4 "self" +// self_qualified_call.baml:10:25 (type) [defaultLibrary] len=6 "string" +// self_qualified_call.baml:10:32 (keyword) len=6 "throws" +// self_qualified_call.baml:10:39 (type) [defaultLibrary] len=5 "never" +// self_qualified_call.baml:13:1 (keyword) len=5 "class" +// self_qualified_call.baml:13:7 (class) [declaration] len=6 "Polite" +// self_qualified_call.baml:14:3 (property) [declaration] len=4 "name" +// self_qualified_call.baml:14:9 (type) [defaultLibrary] len=6 "string" +// self_qualified_call.baml:16:3 (keyword) len=10 "implements" +// self_qualified_call.baml:16:14 (interface) len=7 "Greeter" +// self_qualified_call.baml:17:5 (keyword) len=8 "function" +// self_qualified_call.baml:17:14 (method) [declaration] len=5 "greet" +// self_qualified_call.baml:17:20 (parameter) [declaration] len=4 "self" +// self_qualified_call.baml:17:29 (type) [defaultLibrary] len=6 "string" +// self_qualified_call.baml:18:7 (keyword) len=6 "return" +// self_qualified_call.baml:18:14 (string) len=13 "\"Hello, I'm \"" +// self_qualified_call.baml:18:28 (operator) len=1 "+" +// self_qualified_call.baml:18:30 (parameter) len=4 "self" +// self_qualified_call.baml:18:35 (property) len=4 "name" +// self_qualified_call.baml:22:3 (keyword) len=10 "implements" +// self_qualified_call.baml:22:14 (interface) len=8 "Farewell" +// self_qualified_call.baml:23:5 (keyword) len=8 "function" +// self_qualified_call.baml:23:14 (method) [declaration] len=3 "bye" +// self_qualified_call.baml:23:18 (parameter) [declaration] len=4 "self" +// self_qualified_call.baml:23:27 (type) [defaultLibrary] len=6 "string" +// self_qualified_call.baml:24:7 (keyword) len=6 "return" +// self_qualified_call.baml:24:14 (parameter) len=4 "self" +// self_qualified_call.baml:24:19 (keyword) len=2 "as" +// self_qualified_call.baml:24:21 (operator) len=1 "<" +// self_qualified_call.baml:24:22 (interface) len=7 "Greeter" +// self_qualified_call.baml:24:29 (operator) len=1 ">" +// self_qualified_call.baml:24:31 (method) len=5 "greet" +// self_qualified_call.baml:24:39 (operator) len=1 "+" +// self_qualified_call.baml:24:41 (string) len=19 "\" — and goodbye!\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/signature_variety.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/signature_variety.baml new file mode 100644 index 0000000000..fecbac4ee0 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/signature_variety.baml @@ -0,0 +1,239 @@ +function InputNone() -> int { + client "openai/gpt-4o" + prompt #"fa"# +} + +function InputSimple(a: string, b: int | bool) -> int { + client "openai/gpt-4o" + prompt #"fa"# +} + +class Email { + subject string + body string +} + +function InputObject(email: Email) -> string { + client "openai/gpt-4o" + prompt #" subject line {{ email.subject }} "# +} + +enum Color { + RED + BLUE + GREEN +} + +function InputEnum(color: Color) -> string { + client "openai/gpt-4o" + prompt #" color {{ color }} "# +} + +// Try it with wierd spacing and comments + +function InputEnum2( + color: Color, + bar: string, // ok + + // This param is great! + foo: string[], + + // But we should do something... + baz: (string | int?)[] +) +// Err +-> +// Do something +string + +// Or else +{ + client "openai/gpt-4o" + prompt #" color {{ color }} "# +} + + +function InputImage(img: image) -> string { + client "openai/gpt-4o" + prompt #" image {{ img }} "# +} + +// Test unquoted client string (no quotes around the client name) +function ExtractName(text: string) -> string { + client "openai/gpt-4o-mini" + prompt #" + Extract the person's name from this text: {{ text }} + Return only the name, nothing else. + "# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// signature_variety.baml:1:1 (keyword) len=8 "function" +// signature_variety.baml:1:10 (function) [declaration] len=9 "InputNone" +// signature_variety.baml:1:25 (type) [defaultLibrary] len=3 "int" +// signature_variety.baml:2:3 (property) len=6 "client" +// signature_variety.baml:2:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:3:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:3:10 (string) len=1 "#" +// signature_variety.baml:3:11 (string) len=1 "\"" +// signature_variety.baml:3:12 (string) len=2 "fa" +// signature_variety.baml:3:14 (string) len=1 "\"" +// signature_variety.baml:3:15 (string) len=1 "#" +// signature_variety.baml:6:1 (keyword) len=8 "function" +// signature_variety.baml:6:10 (function) [declaration] len=11 "InputSimple" +// signature_variety.baml:6:22 (parameter) [declaration] len=1 "a" +// signature_variety.baml:6:25 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:6:33 (parameter) [declaration] len=1 "b" +// signature_variety.baml:6:36 (type) [defaultLibrary] len=3 "int" +// signature_variety.baml:6:40 (operator) len=1 "|" +// signature_variety.baml:6:42 (type) [defaultLibrary] len=4 "bool" +// signature_variety.baml:6:51 (type) [defaultLibrary] len=3 "int" +// signature_variety.baml:7:3 (property) len=6 "client" +// signature_variety.baml:7:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:8:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:8:10 (string) len=1 "#" +// signature_variety.baml:8:11 (string) len=1 "\"" +// signature_variety.baml:8:12 (string) len=2 "fa" +// signature_variety.baml:8:14 (string) len=1 "\"" +// signature_variety.baml:8:15 (string) len=1 "#" +// signature_variety.baml:11:1 (keyword) len=5 "class" +// signature_variety.baml:11:7 (class) [declaration] len=5 "Email" +// signature_variety.baml:12:5 (property) [declaration] len=7 "subject" +// signature_variety.baml:12:13 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:13:5 (property) [declaration] len=4 "body" +// signature_variety.baml:13:10 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:16:1 (keyword) len=8 "function" +// signature_variety.baml:16:10 (function) [declaration] len=11 "InputObject" +// signature_variety.baml:16:22 (parameter) [declaration] len=5 "email" +// signature_variety.baml:16:29 (class) len=5 "Email" +// signature_variety.baml:16:39 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:17:3 (property) len=6 "client" +// signature_variety.baml:17:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:18:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:18:10 (string) len=1 "#" +// signature_variety.baml:18:11 (string) len=1 "\"" +// signature_variety.baml:18:13 (string) len=7 "subject" +// signature_variety.baml:18:21 (string) len=4 "line" +// signature_variety.baml:18:26 (string) len=1 "{" +// signature_variety.baml:18:27 (string) len=1 "{" +// signature_variety.baml:18:29 (string) len=5 "email" +// signature_variety.baml:18:34 (string) len=1 "." +// signature_variety.baml:18:35 (string) len=7 "subject" +// signature_variety.baml:18:43 (string) len=1 "}" +// signature_variety.baml:18:44 (string) len=1 "}" +// signature_variety.baml:18:46 (string) len=1 "\"" +// signature_variety.baml:18:47 (string) len=1 "#" +// signature_variety.baml:21:1 (keyword) len=4 "enum" +// signature_variety.baml:21:6 (enum) [declaration] len=5 "Color" +// signature_variety.baml:22:3 (enumMember) [declaration] len=3 "RED" +// signature_variety.baml:23:3 (enumMember) [declaration] len=4 "BLUE" +// signature_variety.baml:24:3 (enumMember) [declaration] len=5 "GREEN" +// signature_variety.baml:27:1 (keyword) len=8 "function" +// signature_variety.baml:27:10 (function) [declaration] len=9 "InputEnum" +// signature_variety.baml:27:20 (parameter) [declaration] len=5 "color" +// signature_variety.baml:27:27 (enum) len=5 "Color" +// signature_variety.baml:27:37 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:28:3 (property) len=6 "client" +// signature_variety.baml:28:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:29:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:29:10 (string) len=1 "#" +// signature_variety.baml:29:11 (string) len=1 "\"" +// signature_variety.baml:29:13 (string) len=5 "color" +// signature_variety.baml:29:19 (string) len=1 "{" +// signature_variety.baml:29:20 (string) len=1 "{" +// signature_variety.baml:29:22 (string) len=5 "color" +// signature_variety.baml:29:28 (string) len=1 "}" +// signature_variety.baml:29:29 (string) len=1 "}" +// signature_variety.baml:29:31 (string) len=1 "\"" +// signature_variety.baml:29:32 (string) len=1 "#" +// signature_variety.baml:32:1 (comment) len=41 "// Try it with wierd spacing and comments" +// signature_variety.baml:34:1 (keyword) len=8 "function" +// signature_variety.baml:34:10 (function) [declaration] len=10 "InputEnum2" +// signature_variety.baml:35:3 (parameter) [declaration] len=5 "color" +// signature_variety.baml:35:10 (enum) len=5 "Color" +// signature_variety.baml:36:3 (parameter) [declaration] len=3 "bar" +// signature_variety.baml:36:8 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:36:16 (comment) len=5 "// ok" +// signature_variety.baml:38:3 (comment) len=23 "// This param is great!" +// signature_variety.baml:39:3 (parameter) [declaration] len=3 "foo" +// signature_variety.baml:39:8 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:41:3 (comment) len=32 "// But we should do something..." +// signature_variety.baml:42:3 (parameter) [declaration] len=3 "baz" +// signature_variety.baml:42:9 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:42:16 (operator) len=1 "|" +// signature_variety.baml:42:18 (type) [defaultLibrary] len=3 "int" +// signature_variety.baml:44:1 (comment) len=6 "// Err" +// signature_variety.baml:46:1 (comment) len=15 "// Do something" +// signature_variety.baml:47:1 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:49:1 (comment) len=10 "// Or else" +// signature_variety.baml:51:3 (property) len=6 "client" +// signature_variety.baml:51:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:52:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:52:10 (string) len=1 "#" +// signature_variety.baml:52:11 (string) len=1 "\"" +// signature_variety.baml:52:13 (string) len=5 "color" +// signature_variety.baml:52:19 (string) len=1 "{" +// signature_variety.baml:52:20 (string) len=1 "{" +// signature_variety.baml:52:22 (string) len=5 "color" +// signature_variety.baml:52:28 (string) len=1 "}" +// signature_variety.baml:52:29 (string) len=1 "}" +// signature_variety.baml:52:31 (string) len=1 "\"" +// signature_variety.baml:52:32 (string) len=1 "#" +// signature_variety.baml:56:1 (keyword) len=8 "function" +// signature_variety.baml:56:10 (function) [declaration] len=10 "InputImage" +// signature_variety.baml:56:21 (parameter) [declaration] len=3 "img" +// signature_variety.baml:56:26 (type) [defaultLibrary] len=5 "image" +// signature_variety.baml:56:36 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:57:3 (property) len=6 "client" +// signature_variety.baml:57:10 (string) len=15 "\"openai/gpt-4o\"" +// signature_variety.baml:58:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:58:10 (string) len=1 "#" +// signature_variety.baml:58:11 (string) len=1 "\"" +// signature_variety.baml:58:13 (string) len=5 "image" +// signature_variety.baml:58:19 (string) len=1 "{" +// signature_variety.baml:58:20 (string) len=1 "{" +// signature_variety.baml:58:22 (string) len=3 "img" +// signature_variety.baml:58:26 (string) len=1 "}" +// signature_variety.baml:58:27 (string) len=1 "}" +// signature_variety.baml:58:29 (string) len=1 "\"" +// signature_variety.baml:58:30 (string) len=1 "#" +// signature_variety.baml:61:1 (comment) len=65 "// Test unquoted client string (no quotes around the client name)" +// signature_variety.baml:62:1 (keyword) len=8 "function" +// signature_variety.baml:62:10 (function) [declaration] len=11 "ExtractName" +// signature_variety.baml:62:22 (parameter) [declaration] len=4 "text" +// signature_variety.baml:62:28 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:62:39 (type) [defaultLibrary] len=6 "string" +// signature_variety.baml:63:3 (property) len=6 "client" +// signature_variety.baml:63:10 (string) len=20 "\"openai/gpt-4o-mini\"" +// signature_variety.baml:64:3 (property) [declaration] len=6 "prompt" +// signature_variety.baml:64:10 (string) len=1 "#" +// signature_variety.baml:64:11 (string) len=1 "\"" +// signature_variety.baml:65:5 (string) len=7 "Extract" +// signature_variety.baml:65:13 (string) len=3 "the" +// signature_variety.baml:65:17 (string) len=6 "person" +// signature_variety.baml:65:23 (string) len=1 "'" +// signature_variety.baml:65:24 (string) len=1 "s" +// signature_variety.baml:65:26 (string) len=4 "name" +// signature_variety.baml:65:31 (string) len=4 "from" +// signature_variety.baml:65:36 (string) len=4 "this" +// signature_variety.baml:65:41 (string) len=4 "text" +// signature_variety.baml:65:45 (string) len=1 ":" +// signature_variety.baml:65:47 (string) len=1 "{" +// signature_variety.baml:65:48 (string) len=1 "{" +// signature_variety.baml:65:50 (string) len=4 "text" +// signature_variety.baml:65:55 (string) len=1 "}" +// signature_variety.baml:65:56 (string) len=1 "}" +// signature_variety.baml:66:5 (string) len=6 "Return" +// signature_variety.baml:66:12 (string) len=4 "only" +// signature_variety.baml:66:17 (string) len=3 "the" +// signature_variety.baml:66:21 (string) len=4 "name" +// signature_variety.baml:66:25 (string) len=1 "," +// signature_variety.baml:66:27 (string) len=7 "nothing" +// signature_variety.baml:66:35 (string) len=4 "else" +// signature_variety.baml:66:39 (string) len=1 "." +// signature_variety.baml:67:3 (string) len=1 "\"" +// signature_variety.baml:67:4 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/stream_llm_inferred_typeargs.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/stream_llm_inferred_typeargs.baml new file mode 100644 index 0000000000..4dc017c1e9 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/stream_llm_inferred_typeargs.baml @@ -0,0 +1,114 @@ +// Call-shape pin. +// +// `stream_llm_function` is generic, and direct user-code +// call sites may rely on type inference (via the let-binding / return-type +// annotation) to fill `` rather than spelling them +// explicitly. This project locks in that *call shape* — the stdlib must +// continue to accept `stream_llm_function(client, name, args)` without +// explicit type args. +// +// Note: the PPIR-synthesized `$stream`/`$parse_stream`/`$parse` companions +// do NOT rely on inference — they pass `` as +// explicit type args (see `ppir_expansion_items`). Inference-reliant calls +// like the one below work because TIR persists inferred instantiations in +// `CallPlan.type_args` (including phase-0 reverse inference from the +// expected return type) and MIR materializes them into the callee frame, +// where `__make_stream` reifies them via `reflect.type_of()`. +// There is no name-keyed registry fallback anymore — a propagation gap +// would surface as "Non-parsable type: ..." from `StreamCache.new`. +// Runtime coverage: `streaming_parsing::stream_string_final_value` and +// `streaming_parsing::stream_class_in_namespace_final_value`. + +client TestClient { + provider openai + options { + model "gpt-4o-mini" + api_key "test-key" + base_url "http://localhost:1234" + } +} + +function TestFunc(input: string) -> string { + client TestClient + prompt #"hi {{ input }}"# +} + +function call_stream_inferred() -> baml.llm.Stream { + baml.llm.stream_llm_function(TestClient, "TestFunc", { "input": "world" }) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// stream_llm_inferred_typeargs.baml:1:1 (comment) len=18 "// Call-shape pin." +// stream_llm_inferred_typeargs.baml:2:1 (comment) len=2 "//" +// stream_llm_inferred_typeargs.baml:3:1 (comment) len=74 "// `stream_llm_function` is generic, and direct user-code" +// stream_llm_inferred_typeargs.baml:4:1 (comment) len=75 "// call sites may rely on type inference (via the let-binding / return-type" +// stream_llm_inferred_typeargs.baml:5:1 (comment) len=68 "// annotation) to fill `` rather than spelling them" +// stream_llm_inferred_typeargs.baml:6:1 (comment) len=74 "// explicitly. This project locks in that *call shape* — the stdlib must" +// stream_llm_inferred_typeargs.baml:7:1 (comment) len=71 "// continue to accept `stream_llm_function(client, name, args)` without" +// stream_llm_inferred_typeargs.baml:8:1 (comment) len=22 "// explicit type args." +// stream_llm_inferred_typeargs.baml:9:1 (comment) len=2 "//" +// stream_llm_inferred_typeargs.baml:10:1 (comment) len=75 "// Note: the PPIR-synthesized `$stream`/`$parse_stream`/`$parse` companions" +// stream_llm_inferred_typeargs.baml:11:1 (comment) len=74 "// do NOT rely on inference — they pass `` as" +// stream_llm_inferred_typeargs.baml:12:1 (comment) len=75 "// explicit type args (see `ppir_expansion_items`). Inference-reliant calls" +// stream_llm_inferred_typeargs.baml:13:1 (comment) len=74 "// like the one below work because TIR persists inferred instantiations in" +// stream_llm_inferred_typeargs.baml:14:1 (comment) len=69 "// `CallPlan.type_args` (including phase-0 reverse inference from the" +// stream_llm_inferred_typeargs.baml:15:1 (comment) len=73 "// expected return type) and MIR materializes them into the callee frame," +// stream_llm_inferred_typeargs.baml:16:1 (comment) len=78 "// where `__make_stream` reifies them via `reflect.type_of()`." +// stream_llm_inferred_typeargs.baml:17:1 (comment) len=73 "// There is no name-keyed registry fallback anymore — a propagation gap" +// stream_llm_inferred_typeargs.baml:18:1 (comment) len=68 "// would surface as \"Non-parsable type: ...\" from `StreamCache.new`." +// stream_llm_inferred_typeargs.baml:19:1 (comment) len=71 "// Runtime coverage: `streaming_parsing::stream_string_final_value` and" +// stream_llm_inferred_typeargs.baml:20:1 (comment) len=62 "// `streaming_parsing::stream_class_in_namespace_final_value`." +// stream_llm_inferred_typeargs.baml:22:1 (keyword) len=6 "client" +// stream_llm_inferred_typeargs.baml:22:7 (operator) len=1 "<" +// stream_llm_inferred_typeargs.baml:22:8 (type) len=3 "llm" +// stream_llm_inferred_typeargs.baml:22:11 (operator) len=1 ">" +// stream_llm_inferred_typeargs.baml:22:13 (struct) [declaration] len=10 "TestClient" +// stream_llm_inferred_typeargs.baml:23:5 (property) len=8 "provider" +// stream_llm_inferred_typeargs.baml:24:5 (property) len=7 "options" +// stream_llm_inferred_typeargs.baml:25:9 (property) len=5 "model" +// stream_llm_inferred_typeargs.baml:25:15 (string) len=13 "\"gpt-4o-mini\"" +// stream_llm_inferred_typeargs.baml:26:9 (property) len=7 "api_key" +// stream_llm_inferred_typeargs.baml:26:17 (string) len=10 "\"test-key\"" +// stream_llm_inferred_typeargs.baml:27:9 (property) len=8 "base_url" +// stream_llm_inferred_typeargs.baml:27:18 (string) len=23 "\"http://localhost:1234\"" +// stream_llm_inferred_typeargs.baml:31:1 (keyword) len=8 "function" +// stream_llm_inferred_typeargs.baml:31:10 (function) [declaration] len=8 "TestFunc" +// stream_llm_inferred_typeargs.baml:31:19 (parameter) [declaration] len=5 "input" +// stream_llm_inferred_typeargs.baml:31:26 (type) [defaultLibrary] len=6 "string" +// stream_llm_inferred_typeargs.baml:31:37 (type) [defaultLibrary] len=6 "string" +// stream_llm_inferred_typeargs.baml:32:5 (property) len=6 "client" +// stream_llm_inferred_typeargs.baml:33:5 (property) [declaration] len=6 "prompt" +// stream_llm_inferred_typeargs.baml:33:12 (string) len=1 "#" +// stream_llm_inferred_typeargs.baml:33:13 (string) len=1 "\"" +// stream_llm_inferred_typeargs.baml:33:14 (string) len=2 "hi" +// stream_llm_inferred_typeargs.baml:33:17 (string) len=1 "{" +// stream_llm_inferred_typeargs.baml:33:18 (string) len=1 "{" +// stream_llm_inferred_typeargs.baml:33:20 (string) len=5 "input" +// stream_llm_inferred_typeargs.baml:33:26 (string) len=1 "}" +// stream_llm_inferred_typeargs.baml:33:27 (string) len=1 "}" +// stream_llm_inferred_typeargs.baml:33:28 (string) len=1 "\"" +// stream_llm_inferred_typeargs.baml:33:29 (string) len=1 "#" +// stream_llm_inferred_typeargs.baml:36:1 (keyword) len=8 "function" +// stream_llm_inferred_typeargs.baml:36:10 (function) [declaration] len=20 "call_stream_inferred" +// stream_llm_inferred_typeargs.baml:36:36 (namespace) [defaultLibrary] len=4 "baml" +// stream_llm_inferred_typeargs.baml:36:40 (operator) len=1 "." +// stream_llm_inferred_typeargs.baml:36:41 (namespace) [defaultLibrary] len=3 "llm" +// stream_llm_inferred_typeargs.baml:36:44 (operator) len=1 "." +// stream_llm_inferred_typeargs.baml:36:45 (class) [defaultLibrary] len=6 "Stream" +// stream_llm_inferred_typeargs.baml:36:51 (operator) len=1 "<" +// stream_llm_inferred_typeargs.baml:36:52 (type) [defaultLibrary] len=4 "null" +// stream_llm_inferred_typeargs.baml:36:57 (operator) len=1 "|" +// stream_llm_inferred_typeargs.baml:36:59 (type) [defaultLibrary] len=6 "string" +// stream_llm_inferred_typeargs.baml:36:67 (type) [defaultLibrary] len=6 "string" +// stream_llm_inferred_typeargs.baml:36:73 (operator) len=1 ">" +// stream_llm_inferred_typeargs.baml:37:5 (namespace) [defaultLibrary] len=4 "baml" +// stream_llm_inferred_typeargs.baml:37:10 (namespace) [defaultLibrary] len=3 "llm" +// stream_llm_inferred_typeargs.baml:37:14 (function) len=19 "stream_llm_function" +// stream_llm_inferred_typeargs.baml:37:34 (variable) len=10 "TestClient" +// stream_llm_inferred_typeargs.baml:37:46 (string) len=10 "\"TestFunc\"" +// stream_llm_inferred_typeargs.baml:37:60 (string) len=7 "\"input\"" +// stream_llm_inferred_typeargs.baml:37:69 (string) len=7 "\"world\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/task_group.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/task_group.baml new file mode 100644 index 0000000000..744bc42b8a --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/task_group.baml @@ -0,0 +1,374 @@ +// BEP-034 spawn options — `TaskGroup` rate limiting via +// `spawn ... with baml.spawn.options(group = g)`. +// +// Deterministic tests only: a `TaskGroup` member is registered synchronously +// at `spawn`, so `active_count`/`queued_count` read right after spawning are +// exact, and `await`/`catch` outcomes don't depend on scheduler timing. + +// The cap is enforced at admission: four members into a `limit = 2` group +// leave exactly two active and two queued (bodies not yet polled). `g.cancel()` +// tears the parked sleeps down. +function caps_active_and_queues_rest() -> int { + let g = baml.spawn.TaskGroup.new(2); + let a = spawn with baml.spawn.options(group = g) { baml.sys.sleep(baml.time.Duration.from_milliseconds(5000n)); 1 }; + let b = spawn with baml.spawn.options(group = g) { baml.sys.sleep(baml.time.Duration.from_milliseconds(5000n)); 1 }; + let c = spawn with baml.spawn.options(group = g) { baml.sys.sleep(baml.time.Duration.from_milliseconds(5000n)); 1 }; + let d = spawn with baml.spawn.options(group = g) { baml.sys.sleep(baml.time.Duration.from_milliseconds(5000n)); 1 }; + let snapshot = g.active_count() * 100 + g.queued_count(); + let _ = g.cancel(); + snapshot +} + +test "caps_active_and_queues_rest" { + assert.is_true(baml.deep_equals(caps_active_and_queues_rest(), 202)) +} + +// More spawns than the limit all complete — the queued ones start as slots free. +function queues_excess_and_all_complete() -> int { + let g = baml.spawn.TaskGroup.new(2); + let a = spawn with baml.spawn.options(group = g) { 1 }; + let b = spawn with baml.spawn.options(group = g) { 1 }; + let c = spawn with baml.spawn.options(group = g) { 1 }; + let d = spawn with baml.spawn.options(group = g) { 1 }; + let e = spawn with baml.spawn.options(group = g) { 1 }; + (await a) + (await b) + (await c) + (await d) + (await e) +} + +test "queues_excess_and_all_complete" { + assert.is_true(baml.deep_equals(queues_excess_and_all_complete(), 5)) +} + +// `group.cancel()` fires its members' tokens; awaiting a cancelled member +// re-throws `Cancelled`, which is catchable. +function group_cancel_cancels_member() -> int { + let g = baml.spawn.TaskGroup.new(5); + let f = spawn with baml.spawn.options(group = g) { baml.sys.sleep(baml.time.Duration.from_milliseconds(10000n)); 42 }; + let _ = g.cancel(); + (await f) catch (e) { baml.panics.Cancelled => 0 } +} + +test "group_cancel_cancels_member" { + assert.is_true(baml.deep_equals(group_cancel_cancels_member(), 0)) +} + +// `limit()` / `set_limit()` round-trip. +function set_limit_updates_limit() -> int { + let g = baml.spawn.TaskGroup.new(3); + let before = g.limit(); + g.set_limit(7); + before + g.limit() +} + +test "set_limit_updates_limit" { + assert.is_true(baml.deep_equals(set_limit_updates_limit(), 10)) +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// task_group.baml:1:1 (comment) len=58 "// BEP-034 spawn options — `TaskGroup` rate limiting via" +// task_group.baml:2:1 (comment) len=50 "// `spawn ... with baml.spawn.options(group = g)`." +// task_group.baml:3:1 (comment) len=2 "//" +// task_group.baml:4:1 (comment) len=77 "// Deterministic tests only: a `TaskGroup` member is registered synchronously" +// task_group.baml:5:1 (comment) len=77 "// at `spawn`, so `active_count`/`queued_count` read right after spawning are" +// task_group.baml:6:1 (comment) len=72 "// exact, and `await`/`catch` outcomes don't depend on scheduler timing." +// task_group.baml:8:1 (comment) len=74 "// The cap is enforced at admission: four members into a `limit = 2` group" +// task_group.baml:9:1 (comment) len=80 "// leave exactly two active and two queued (bodies not yet polled). `g.cancel()`" +// task_group.baml:10:1 (comment) len=32 "// tears the parked sleeps down." +// task_group.baml:11:1 (keyword) len=8 "function" +// task_group.baml:11:10 (function) [declaration] len=27 "caps_active_and_queues_rest" +// task_group.baml:11:43 (type) [defaultLibrary] len=3 "int" +// task_group.baml:12:5 (keyword) len=3 "let" +// task_group.baml:12:9 (variable) [declaration] len=1 "g" +// task_group.baml:12:11 (operator) len=1 "=" +// task_group.baml:12:13 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:12:18 (keyword) len=5 "spawn" +// task_group.baml:12:24 (class) [defaultLibrary] len=9 "TaskGroup" +// task_group.baml:12:34 (method) len=3 "new" +// task_group.baml:12:38 (number) len=1 "2" +// task_group.baml:13:5 (keyword) len=3 "let" +// task_group.baml:13:9 (variable) [declaration] len=1 "a" +// task_group.baml:13:11 (operator) len=1 "=" +// task_group.baml:13:13 (keyword) len=5 "spawn" +// task_group.baml:13:19 (keyword) len=4 "with" +// task_group.baml:13:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:13:29 (keyword) len=5 "spawn" +// task_group.baml:13:35 (function) len=7 "options" +// task_group.baml:13:43 (parameter) len=5 "group" +// task_group.baml:13:49 (operator) len=1 "=" +// task_group.baml:13:51 (variable) len=1 "g" +// task_group.baml:13:56 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:13:61 (namespace) [defaultLibrary] len=3 "sys" +// task_group.baml:13:65 (function) len=5 "sleep" +// task_group.baml:13:71 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:13:76 (namespace) [defaultLibrary] len=4 "time" +// task_group.baml:13:81 (class) [defaultLibrary] len=8 "Duration" +// task_group.baml:13:90 (method) len=17 "from_milliseconds" +// task_group.baml:13:108 (number) len=5 "5000n" +// task_group.baml:13:117 (number) len=1 "1" +// task_group.baml:14:5 (keyword) len=3 "let" +// task_group.baml:14:9 (variable) [declaration] len=1 "b" +// task_group.baml:14:11 (operator) len=1 "=" +// task_group.baml:14:13 (keyword) len=5 "spawn" +// task_group.baml:14:19 (keyword) len=4 "with" +// task_group.baml:14:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:14:29 (keyword) len=5 "spawn" +// task_group.baml:14:35 (function) len=7 "options" +// task_group.baml:14:43 (parameter) len=5 "group" +// task_group.baml:14:49 (operator) len=1 "=" +// task_group.baml:14:51 (variable) len=1 "g" +// task_group.baml:14:56 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:14:61 (namespace) [defaultLibrary] len=3 "sys" +// task_group.baml:14:65 (function) len=5 "sleep" +// task_group.baml:14:71 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:14:76 (namespace) [defaultLibrary] len=4 "time" +// task_group.baml:14:81 (class) [defaultLibrary] len=8 "Duration" +// task_group.baml:14:90 (method) len=17 "from_milliseconds" +// task_group.baml:14:108 (number) len=5 "5000n" +// task_group.baml:14:117 (number) len=1 "1" +// task_group.baml:15:5 (keyword) len=3 "let" +// task_group.baml:15:9 (variable) [declaration] len=1 "c" +// task_group.baml:15:11 (operator) len=1 "=" +// task_group.baml:15:13 (keyword) len=5 "spawn" +// task_group.baml:15:19 (keyword) len=4 "with" +// task_group.baml:15:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:15:29 (keyword) len=5 "spawn" +// task_group.baml:15:35 (function) len=7 "options" +// task_group.baml:15:43 (parameter) len=5 "group" +// task_group.baml:15:49 (operator) len=1 "=" +// task_group.baml:15:51 (variable) len=1 "g" +// task_group.baml:15:56 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:15:61 (namespace) [defaultLibrary] len=3 "sys" +// task_group.baml:15:65 (function) len=5 "sleep" +// task_group.baml:15:71 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:15:76 (namespace) [defaultLibrary] len=4 "time" +// task_group.baml:15:81 (class) [defaultLibrary] len=8 "Duration" +// task_group.baml:15:90 (method) len=17 "from_milliseconds" +// task_group.baml:15:108 (number) len=5 "5000n" +// task_group.baml:15:117 (number) len=1 "1" +// task_group.baml:16:5 (keyword) len=3 "let" +// task_group.baml:16:9 (variable) [declaration] len=1 "d" +// task_group.baml:16:11 (operator) len=1 "=" +// task_group.baml:16:13 (keyword) len=5 "spawn" +// task_group.baml:16:19 (keyword) len=4 "with" +// task_group.baml:16:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:16:29 (keyword) len=5 "spawn" +// task_group.baml:16:35 (function) len=7 "options" +// task_group.baml:16:43 (parameter) len=5 "group" +// task_group.baml:16:49 (operator) len=1 "=" +// task_group.baml:16:51 (variable) len=1 "g" +// task_group.baml:16:56 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:16:61 (namespace) [defaultLibrary] len=3 "sys" +// task_group.baml:16:65 (function) len=5 "sleep" +// task_group.baml:16:71 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:16:76 (namespace) [defaultLibrary] len=4 "time" +// task_group.baml:16:81 (class) [defaultLibrary] len=8 "Duration" +// task_group.baml:16:90 (method) len=17 "from_milliseconds" +// task_group.baml:16:108 (number) len=5 "5000n" +// task_group.baml:16:117 (number) len=1 "1" +// task_group.baml:17:5 (keyword) len=3 "let" +// task_group.baml:17:9 (variable) [declaration] len=8 "snapshot" +// task_group.baml:17:18 (operator) len=1 "=" +// task_group.baml:17:20 (variable) len=1 "g" +// task_group.baml:17:22 (method) len=12 "active_count" +// task_group.baml:17:37 (operator) len=1 "*" +// task_group.baml:17:39 (number) len=3 "100" +// task_group.baml:17:43 (operator) len=1 "+" +// task_group.baml:17:45 (variable) len=1 "g" +// task_group.baml:17:47 (method) len=12 "queued_count" +// task_group.baml:18:5 (keyword) len=3 "let" +// task_group.baml:18:11 (operator) len=1 "=" +// task_group.baml:18:13 (variable) len=1 "g" +// task_group.baml:18:15 (method) len=6 "cancel" +// task_group.baml:19:5 (variable) len=8 "snapshot" +// task_group.baml:22:1 (keyword) len=4 "test" +// task_group.baml:22:6 (string) len=29 "\"caps_active_and_queues_rest\"" +// task_group.baml:23:5 (namespace) [defaultLibrary] len=6 "assert" +// task_group.baml:23:12 (function) len=7 "is_true" +// task_group.baml:23:20 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:23:25 (function) len=11 "deep_equals" +// task_group.baml:23:37 (function) len=27 "caps_active_and_queues_rest" +// task_group.baml:23:68 (number) len=3 "202" +// task_group.baml:26:1 (comment) len=83 "// More spawns than the limit all complete — the queued ones start as slots free." +// task_group.baml:27:1 (keyword) len=8 "function" +// task_group.baml:27:10 (function) [declaration] len=30 "queues_excess_and_all_complete" +// task_group.baml:27:46 (type) [defaultLibrary] len=3 "int" +// task_group.baml:28:5 (keyword) len=3 "let" +// task_group.baml:28:9 (variable) [declaration] len=1 "g" +// task_group.baml:28:11 (operator) len=1 "=" +// task_group.baml:28:13 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:28:18 (keyword) len=5 "spawn" +// task_group.baml:28:24 (class) [defaultLibrary] len=9 "TaskGroup" +// task_group.baml:28:34 (method) len=3 "new" +// task_group.baml:28:38 (number) len=1 "2" +// task_group.baml:29:5 (keyword) len=3 "let" +// task_group.baml:29:9 (variable) [declaration] len=1 "a" +// task_group.baml:29:11 (operator) len=1 "=" +// task_group.baml:29:13 (keyword) len=5 "spawn" +// task_group.baml:29:19 (keyword) len=4 "with" +// task_group.baml:29:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:29:29 (keyword) len=5 "spawn" +// task_group.baml:29:35 (function) len=7 "options" +// task_group.baml:29:43 (parameter) len=5 "group" +// task_group.baml:29:49 (operator) len=1 "=" +// task_group.baml:29:51 (variable) len=1 "g" +// task_group.baml:29:56 (number) len=1 "1" +// task_group.baml:30:5 (keyword) len=3 "let" +// task_group.baml:30:9 (variable) [declaration] len=1 "b" +// task_group.baml:30:11 (operator) len=1 "=" +// task_group.baml:30:13 (keyword) len=5 "spawn" +// task_group.baml:30:19 (keyword) len=4 "with" +// task_group.baml:30:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:30:29 (keyword) len=5 "spawn" +// task_group.baml:30:35 (function) len=7 "options" +// task_group.baml:30:43 (parameter) len=5 "group" +// task_group.baml:30:49 (operator) len=1 "=" +// task_group.baml:30:51 (variable) len=1 "g" +// task_group.baml:30:56 (number) len=1 "1" +// task_group.baml:31:5 (keyword) len=3 "let" +// task_group.baml:31:9 (variable) [declaration] len=1 "c" +// task_group.baml:31:11 (operator) len=1 "=" +// task_group.baml:31:13 (keyword) len=5 "spawn" +// task_group.baml:31:19 (keyword) len=4 "with" +// task_group.baml:31:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:31:29 (keyword) len=5 "spawn" +// task_group.baml:31:35 (function) len=7 "options" +// task_group.baml:31:43 (parameter) len=5 "group" +// task_group.baml:31:49 (operator) len=1 "=" +// task_group.baml:31:51 (variable) len=1 "g" +// task_group.baml:31:56 (number) len=1 "1" +// task_group.baml:32:5 (keyword) len=3 "let" +// task_group.baml:32:9 (variable) [declaration] len=1 "d" +// task_group.baml:32:11 (operator) len=1 "=" +// task_group.baml:32:13 (keyword) len=5 "spawn" +// task_group.baml:32:19 (keyword) len=4 "with" +// task_group.baml:32:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:32:29 (keyword) len=5 "spawn" +// task_group.baml:32:35 (function) len=7 "options" +// task_group.baml:32:43 (parameter) len=5 "group" +// task_group.baml:32:49 (operator) len=1 "=" +// task_group.baml:32:51 (variable) len=1 "g" +// task_group.baml:32:56 (number) len=1 "1" +// task_group.baml:33:5 (keyword) len=3 "let" +// task_group.baml:33:9 (variable) [declaration] len=1 "e" +// task_group.baml:33:11 (operator) len=1 "=" +// task_group.baml:33:13 (keyword) len=5 "spawn" +// task_group.baml:33:19 (keyword) len=4 "with" +// task_group.baml:33:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:33:29 (keyword) len=5 "spawn" +// task_group.baml:33:35 (function) len=7 "options" +// task_group.baml:33:43 (parameter) len=5 "group" +// task_group.baml:33:49 (operator) len=1 "=" +// task_group.baml:33:51 (variable) len=1 "g" +// task_group.baml:33:56 (number) len=1 "1" +// task_group.baml:34:6 (keyword) len=5 "await" +// task_group.baml:34:12 (variable) len=1 "a" +// task_group.baml:34:15 (operator) len=1 "+" +// task_group.baml:34:18 (keyword) len=5 "await" +// task_group.baml:34:24 (variable) len=1 "b" +// task_group.baml:34:27 (operator) len=1 "+" +// task_group.baml:34:30 (keyword) len=5 "await" +// task_group.baml:34:36 (variable) len=1 "c" +// task_group.baml:34:39 (operator) len=1 "+" +// task_group.baml:34:42 (keyword) len=5 "await" +// task_group.baml:34:48 (variable) len=1 "d" +// task_group.baml:34:51 (operator) len=1 "+" +// task_group.baml:34:54 (keyword) len=5 "await" +// task_group.baml:34:60 (variable) len=1 "e" +// task_group.baml:37:1 (keyword) len=4 "test" +// task_group.baml:37:6 (string) len=32 "\"queues_excess_and_all_complete\"" +// task_group.baml:38:5 (namespace) [defaultLibrary] len=6 "assert" +// task_group.baml:38:12 (function) len=7 "is_true" +// task_group.baml:38:20 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:38:25 (function) len=11 "deep_equals" +// task_group.baml:38:37 (function) len=30 "queues_excess_and_all_complete" +// task_group.baml:38:71 (number) len=1 "5" +// task_group.baml:41:1 (comment) len=74 "// `group.cancel()` fires its members' tokens; awaiting a cancelled member" +// task_group.baml:42:1 (comment) len=45 "// re-throws `Cancelled`, which is catchable." +// task_group.baml:43:1 (keyword) len=8 "function" +// task_group.baml:43:10 (function) [declaration] len=27 "group_cancel_cancels_member" +// task_group.baml:43:43 (type) [defaultLibrary] len=3 "int" +// task_group.baml:44:5 (keyword) len=3 "let" +// task_group.baml:44:9 (variable) [declaration] len=1 "g" +// task_group.baml:44:11 (operator) len=1 "=" +// task_group.baml:44:13 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:44:18 (keyword) len=5 "spawn" +// task_group.baml:44:24 (class) [defaultLibrary] len=9 "TaskGroup" +// task_group.baml:44:34 (method) len=3 "new" +// task_group.baml:44:38 (number) len=1 "5" +// task_group.baml:45:5 (keyword) len=3 "let" +// task_group.baml:45:9 (variable) [declaration] len=1 "f" +// task_group.baml:45:11 (operator) len=1 "=" +// task_group.baml:45:13 (keyword) len=5 "spawn" +// task_group.baml:45:19 (keyword) len=4 "with" +// task_group.baml:45:24 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:45:29 (keyword) len=5 "spawn" +// task_group.baml:45:35 (function) len=7 "options" +// task_group.baml:45:43 (parameter) len=5 "group" +// task_group.baml:45:49 (operator) len=1 "=" +// task_group.baml:45:51 (variable) len=1 "g" +// task_group.baml:45:56 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:45:61 (namespace) [defaultLibrary] len=3 "sys" +// task_group.baml:45:65 (function) len=5 "sleep" +// task_group.baml:45:71 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:45:76 (namespace) [defaultLibrary] len=4 "time" +// task_group.baml:45:81 (class) [defaultLibrary] len=8 "Duration" +// task_group.baml:45:90 (method) len=17 "from_milliseconds" +// task_group.baml:45:108 (number) len=6 "10000n" +// task_group.baml:45:118 (number) len=2 "42" +// task_group.baml:46:5 (keyword) len=3 "let" +// task_group.baml:46:11 (operator) len=1 "=" +// task_group.baml:46:13 (variable) len=1 "g" +// task_group.baml:46:15 (method) len=6 "cancel" +// task_group.baml:47:6 (keyword) len=5 "await" +// task_group.baml:47:12 (variable) len=1 "f" +// task_group.baml:47:15 (keyword) len=5 "catch" +// task_group.baml:47:22 (parameter) [declaration] len=1 "e" +// task_group.baml:47:27 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:47:31 (operator) len=1 "." +// task_group.baml:47:32 (namespace) [defaultLibrary] len=6 "panics" +// task_group.baml:47:38 (operator) len=1 "." +// task_group.baml:47:39 (class) [defaultLibrary] len=9 "Cancelled" +// task_group.baml:47:52 (number) len=1 "0" +// task_group.baml:50:1 (keyword) len=4 "test" +// task_group.baml:50:6 (string) len=29 "\"group_cancel_cancels_member\"" +// task_group.baml:51:5 (namespace) [defaultLibrary] len=6 "assert" +// task_group.baml:51:12 (function) len=7 "is_true" +// task_group.baml:51:20 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:51:25 (function) len=11 "deep_equals" +// task_group.baml:51:37 (function) len=27 "group_cancel_cancels_member" +// task_group.baml:51:68 (number) len=1 "0" +// task_group.baml:54:1 (comment) len=40 "// `limit()` / `set_limit()` round-trip." +// task_group.baml:55:1 (keyword) len=8 "function" +// task_group.baml:55:10 (function) [declaration] len=23 "set_limit_updates_limit" +// task_group.baml:55:39 (type) [defaultLibrary] len=3 "int" +// task_group.baml:56:5 (keyword) len=3 "let" +// task_group.baml:56:9 (variable) [declaration] len=1 "g" +// task_group.baml:56:11 (operator) len=1 "=" +// task_group.baml:56:13 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:56:18 (keyword) len=5 "spawn" +// task_group.baml:56:24 (class) [defaultLibrary] len=9 "TaskGroup" +// task_group.baml:56:34 (method) len=3 "new" +// task_group.baml:56:38 (number) len=1 "3" +// task_group.baml:57:5 (keyword) len=3 "let" +// task_group.baml:57:9 (variable) [declaration] len=6 "before" +// task_group.baml:57:16 (operator) len=1 "=" +// task_group.baml:57:18 (variable) len=1 "g" +// task_group.baml:57:20 (method) len=5 "limit" +// task_group.baml:58:5 (variable) len=1 "g" +// task_group.baml:58:7 (method) len=9 "set_limit" +// task_group.baml:58:17 (number) len=1 "7" +// task_group.baml:59:5 (variable) len=6 "before" +// task_group.baml:59:12 (operator) len=1 "+" +// task_group.baml:59:14 (variable) len=1 "g" +// task_group.baml:59:16 (method) len=5 "limit" +// task_group.baml:62:1 (keyword) len=4 "test" +// task_group.baml:62:6 (string) len=25 "\"set_limit_updates_limit\"" +// task_group.baml:63:5 (namespace) [defaultLibrary] len=6 "assert" +// task_group.baml:63:12 (function) len=7 "is_true" +// task_group.baml:63:20 (namespace) [defaultLibrary] len=4 "baml" +// task_group.baml:63:25 (function) len=11 "deep_equals" +// task_group.baml:63:37 (function) len=23 "set_limit_updates_limit" +// task_group.baml:63:64 (number) len=2 "10" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string.baml index b2f313d1eb..28e2a6477b 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string.baml @@ -12,9 +12,9 @@ template_string NoParams() #" // //- semantic_tokens // template_string.baml:1:1 (keyword) len=15 "template_string" -// template_string.baml:1:17 (function) len=8 "Greeting" -// template_string.baml:1:26 (parameter) len=4 "name" -// template_string.baml:1:32 (type) len=6 "string" +// template_string.baml:1:17 (function) [declaration] len=8 "Greeting" +// template_string.baml:1:26 (parameter) [declaration] len=4 "name" +// template_string.baml:1:32 (type) [defaultLibrary] len=6 "string" // template_string.baml:1:40 (string) len=1 "#" // template_string.baml:1:41 (string) len=1 "\"" // template_string.baml:2:5 (string) len=5 "Hello" @@ -28,7 +28,7 @@ template_string NoParams() #" // template_string.baml:3:1 (string) len=1 "\"" // template_string.baml:3:2 (string) len=1 "#" // template_string.baml:5:1 (keyword) len=15 "template_string" -// template_string.baml:5:17 (function) len=8 "NoParams" +// template_string.baml:5:17 (function) [declaration] len=8 "NoParams" // template_string.baml:5:28 (string) len=1 "#" // template_string.baml:5:29 (string) len=1 "\"" // template_string.baml:6:5 (string) len=1 "A" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string_calls.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string_calls.baml new file mode 100644 index 0000000000..f3cc06b5e7 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string_calls.baml @@ -0,0 +1,56 @@ +template_string WithParams(a: int) #" + ... +"# + +template_string GoodCall1 #" + {{ WithParams(a=2) }} +"# + +template_string GoodCall2 #" + {{ WithParams(2) }} +"# + +//---- +//- diagnostics +// +// +//- semantic_tokens +// template_string_calls.baml:1:1 (keyword) len=15 "template_string" +// template_string_calls.baml:1:17 (function) [declaration] len=10 "WithParams" +// template_string_calls.baml:1:28 (parameter) [declaration] len=1 "a" +// template_string_calls.baml:1:31 (type) [defaultLibrary] len=3 "int" +// template_string_calls.baml:1:36 (string) len=1 "#" +// template_string_calls.baml:1:37 (string) len=1 "\"" +// template_string_calls.baml:2:3 (string) len=3 "..." +// template_string_calls.baml:3:1 (string) len=1 "\"" +// template_string_calls.baml:3:2 (string) len=1 "#" +// template_string_calls.baml:5:1 (keyword) len=15 "template_string" +// template_string_calls.baml:5:17 (function) [declaration] len=9 "GoodCall1" +// template_string_calls.baml:5:27 (string) len=1 "#" +// template_string_calls.baml:5:28 (string) len=1 "\"" +// template_string_calls.baml:6:3 (string) len=1 "{" +// template_string_calls.baml:6:4 (string) len=1 "{" +// template_string_calls.baml:6:6 (string) len=10 "WithParams" +// template_string_calls.baml:6:16 (string) len=1 "(" +// template_string_calls.baml:6:17 (string) len=1 "a" +// template_string_calls.baml:6:18 (string) len=1 "=" +// template_string_calls.baml:6:19 (string) len=1 "2" +// template_string_calls.baml:6:20 (string) len=1 ")" +// template_string_calls.baml:6:22 (string) len=1 "}" +// template_string_calls.baml:6:23 (string) len=1 "}" +// template_string_calls.baml:7:1 (string) len=1 "\"" +// template_string_calls.baml:7:2 (string) len=1 "#" +// template_string_calls.baml:9:1 (keyword) len=15 "template_string" +// template_string_calls.baml:9:17 (function) [declaration] len=9 "GoodCall2" +// template_string_calls.baml:9:27 (string) len=1 "#" +// template_string_calls.baml:9:28 (string) len=1 "\"" +// template_string_calls.baml:10:3 (string) len=1 "{" +// template_string_calls.baml:10:4 (string) len=1 "{" +// template_string_calls.baml:10:6 (string) len=10 "WithParams" +// template_string_calls.baml:10:16 (string) len=1 "(" +// template_string_calls.baml:10:17 (string) len=1 "2" +// template_string_calls.baml:10:18 (string) len=1 ")" +// template_string_calls.baml:10:20 (string) len=1 "}" +// template_string_calls.baml:10:21 (string) len=1 "}" +// template_string_calls.baml:11:1 (string) len=1 "\"" +// template_string_calls.baml:11:2 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_block.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_block.baml index 91e1058d3e..daa2b19d87 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_block.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_block.baml @@ -31,27 +31,25 @@ test BasicTest { // //- semantic_tokens // test_block.baml:1:1 (keyword) len=5 "class" -// test_block.baml:1:7 (class) len=5 "Input" -// test_block.baml:2:3 (property) len=4 "text" -// test_block.baml:2:8 (type) len=6 "string" +// test_block.baml:1:7 (class) [declaration] len=5 "Input" +// test_block.baml:2:3 (property) [declaration] len=4 "text" +// test_block.baml:2:8 (type) [defaultLibrary] len=6 "string" // test_block.baml:5:1 (keyword) len=6 "client" // test_block.baml:5:7 (operator) len=1 "<" // test_block.baml:5:8 (type) len=3 "llm" // test_block.baml:5:11 (operator) len=1 ">" -// test_block.baml:5:13 (struct) len=4 "GPT4" +// test_block.baml:5:13 (struct) [declaration] len=4 "GPT4" // test_block.baml:6:3 (property) len=8 "provider" // test_block.baml:7:3 (property) len=7 "options" // test_block.baml:8:5 (property) len=5 "model" -// test_block.baml:8:11 (string) len=1 "\"" -// test_block.baml:8:12 (string) len=5 "gpt-4" -// test_block.baml:8:17 (string) len=1 "\"" +// test_block.baml:8:11 (string) len=7 "\"gpt-4\"" // test_block.baml:12:1 (keyword) len=8 "function" -// test_block.baml:12:10 (function) len=9 "Summarize" -// test_block.baml:12:20 (parameter) len=5 "input" +// test_block.baml:12:10 (function) [declaration] len=9 "Summarize" +// test_block.baml:12:20 (parameter) [declaration] len=5 "input" // test_block.baml:12:27 (class) len=5 "Input" -// test_block.baml:12:37 (type) len=6 "string" +// test_block.baml:12:37 (type) [defaultLibrary] len=6 "string" // test_block.baml:13:3 (property) len=6 "client" -// test_block.baml:14:3 (property) len=6 "prompt" +// test_block.baml:14:3 (property) [declaration] len=6 "prompt" // test_block.baml:14:10 (string) len=1 "#" // test_block.baml:14:11 (string) len=1 "\"" // test_block.baml:15:5 (string) len=9 "Summarize" @@ -66,12 +64,9 @@ test BasicTest { // test_block.baml:16:3 (string) len=1 "\"" // test_block.baml:16:4 (string) len=1 "#" // test_block.baml:19:1 (keyword) len=4 "test" -// test_block.baml:19:6 (struct) len=9 "BasicTest" +// test_block.baml:19:6 (struct) [declaration] len=9 "BasicTest" // test_block.baml:20:3 (property) len=9 "functions" // test_block.baml:21:3 (property) len=4 "args" // test_block.baml:22:5 (property) len=5 "input" // test_block.baml:23:7 (property) len=4 "text" -// test_block.baml:23:12 (string) len=1 "\"" -// test_block.baml:23:13 (string) len=5 "Hello" -// test_block.baml:23:19 (string) len=5 "world" -// test_block.baml:23:24 (string) len=1 "\"" +// test_block.baml:23:12 (string) len=13 "\"Hello world\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_expr_throwing_body.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_expr_throwing_body.baml new file mode 100644 index 0000000000..60a9a21959 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_expr_throwing_body.baml @@ -0,0 +1,23 @@ +function risky() -> void throws string { + throw "boom" +} + +test "throwing body becomes failure" { + risky() +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// test_expr_throwing_body.baml:1:1 (keyword) len=8 "function" +// test_expr_throwing_body.baml:1:10 (function) [declaration] len=5 "risky" +// test_expr_throwing_body.baml:1:21 (type) [defaultLibrary] len=4 "void" +// test_expr_throwing_body.baml:1:26 (keyword) len=6 "throws" +// test_expr_throwing_body.baml:1:33 (type) [defaultLibrary] len=6 "string" +// test_expr_throwing_body.baml:2:3 (keyword) len=5 "throw" +// test_expr_throwing_body.baml:2:9 (string) len=6 "\"boom\"" +// test_expr_throwing_body.baml:5:1 (keyword) len=4 "test" +// test_expr_throwing_body.baml:5:6 (string) len=31 "\"throwing body becomes failure\"" +// test_expr_throwing_body.baml:6:3 (function) len=5 "risky" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset.baml new file mode 100644 index 0000000000..b9ee19914f --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset.baml @@ -0,0 +1,66 @@ +// New-style programmatic test blocks: `testset` / `test { }` with +// bindings, loops, dynamic names, and `assert` (BEP testset migration). +function Double(n: int) -> int { + n * 2 +} + +testset "doubling" { + test "simple" { + let result = Double(21); + assert.equal(result, 42); + } + + let cases = ["a", "b", "c"]; + for (let c in cases) { + test c { + assert.equal(Double(1), 2); + } + } +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// testset.baml:1:1 (comment) len=73 "// New-style programmatic test blocks: `testset` / `test { }` with" +// testset.baml:2:1 (comment) len=72 "// bindings, loops, dynamic names, and `assert` (BEP testset migration)." +// testset.baml:3:1 (keyword) len=8 "function" +// testset.baml:3:10 (function) [declaration] len=6 "Double" +// testset.baml:3:17 (parameter) [declaration] len=1 "n" +// testset.baml:3:20 (type) [defaultLibrary] len=3 "int" +// testset.baml:3:28 (type) [defaultLibrary] len=3 "int" +// testset.baml:4:3 (parameter) len=1 "n" +// testset.baml:4:5 (operator) len=1 "*" +// testset.baml:4:7 (number) len=1 "2" +// testset.baml:7:1 (keyword) len=7 "testset" +// testset.baml:7:9 (string) len=10 "\"doubling\"" +// testset.baml:8:3 (keyword) len=4 "test" +// testset.baml:8:8 (string) len=8 "\"simple\"" +// testset.baml:9:5 (keyword) len=3 "let" +// testset.baml:9:9 (variable) [declaration] len=6 "result" +// testset.baml:9:16 (operator) len=1 "=" +// testset.baml:9:18 (function) len=6 "Double" +// testset.baml:9:25 (number) len=2 "21" +// testset.baml:10:5 (namespace) [defaultLibrary] len=6 "assert" +// testset.baml:10:12 (function) len=5 "equal" +// testset.baml:10:18 (variable) len=6 "result" +// testset.baml:10:26 (number) len=2 "42" +// testset.baml:13:3 (keyword) len=3 "let" +// testset.baml:13:7 (variable) [declaration] len=5 "cases" +// testset.baml:13:13 (operator) len=1 "=" +// testset.baml:13:16 (string) len=3 "\"a\"" +// testset.baml:13:21 (string) len=3 "\"b\"" +// testset.baml:13:26 (string) len=3 "\"c\"" +// testset.baml:14:3 (keyword) len=3 "for" +// testset.baml:14:8 (keyword) len=3 "let" +// testset.baml:14:12 (variable) [declaration] len=1 "c" +// testset.baml:14:14 (keyword) len=2 "in" +// testset.baml:14:17 (variable) len=5 "cases" +// testset.baml:15:5 (keyword) len=4 "test" +// testset.baml:15:10 (variable) len=1 "c" +// testset.baml:16:7 (namespace) [defaultLibrary] len=6 "assert" +// testset.baml:16:14 (function) len=5 "equal" +// testset.baml:16:20 (function) len=6 "Double" +// testset.baml:16:27 (number) len=1 "1" +// testset.baml:16:31 (number) len=1 "2" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset_vibes_nested.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset_vibes_nested.baml new file mode 100644 index 0000000000..998d6a11b6 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset_vibes_nested.baml @@ -0,0 +1,270 @@ +client GPT4o { + provider openai + options { + model "gpt-4o" + api_key env.OPENAI_API_KEY + } +} + +class Sentiment { + feeling string + confidence float + reasoning string +} + +function ClassifySentiment(text: string) -> Sentiment { + client GPT4o + prompt #"classify {{ text }}"# +} + +function GenerateTests(count: int, topic: string) -> string[] { + client GPT4o + prompt #"generate {{ count }} tests about {{ topic }}"# +} + +testset "test" { + let topics = ["happy", "sad"]; + for (let sentiments in topics) { + testset sentiments { + let req = baml.http.fetch("http://localhost:8000/" + sentiments); + let data = req.text(); + let tests = GenerateTests$parse(data); + for (let ex in tests) { + test ex { + let result = ClassifySentiment("hi"); + assert.equal(result.feeling, "positive"); + } + } + } + } + + testset "vibes" { + let topics = ["happy", "sad"]; + for (let sentiments in topics) { + testset sentiments { + let tests = GenerateTests(5, sentiments); + for (let ex in tests) { + test ex { + let result = ClassifySentiment("hi"); + assert.equal(result.feeling, "positive"); + } + } + } + } + } +} + +function Foo() -> string | image { + let x = "foo"; + let y = 2; + for (let i = 0; i < y; i += 1) { + x = "hi: " + x + } + x +} + +function ClassifySentiment2(text: string) -> string { + client GPT4o + prompt #"classify {{ text }}"# +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// testset_vibes_nested.baml:1:1 (keyword) len=6 "client" +// testset_vibes_nested.baml:1:7 (operator) len=1 "<" +// testset_vibes_nested.baml:1:8 (type) len=3 "llm" +// testset_vibes_nested.baml:1:11 (operator) len=1 ">" +// testset_vibes_nested.baml:1:13 (struct) [declaration] len=5 "GPT4o" +// testset_vibes_nested.baml:2:5 (property) len=8 "provider" +// testset_vibes_nested.baml:3:5 (property) len=7 "options" +// testset_vibes_nested.baml:4:9 (property) len=5 "model" +// testset_vibes_nested.baml:4:15 (string) len=8 "\"gpt-4o\"" +// testset_vibes_nested.baml:5:9 (property) len=7 "api_key" +// testset_vibes_nested.baml:9:1 (keyword) len=5 "class" +// testset_vibes_nested.baml:9:7 (class) [declaration] len=9 "Sentiment" +// testset_vibes_nested.baml:10:5 (property) [declaration] len=7 "feeling" +// testset_vibes_nested.baml:10:13 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:11:5 (property) [declaration] len=10 "confidence" +// testset_vibes_nested.baml:11:16 (type) [defaultLibrary] len=5 "float" +// testset_vibes_nested.baml:12:5 (property) [declaration] len=9 "reasoning" +// testset_vibes_nested.baml:12:15 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:15:1 (keyword) len=8 "function" +// testset_vibes_nested.baml:15:10 (function) [declaration] len=17 "ClassifySentiment" +// testset_vibes_nested.baml:15:28 (parameter) [declaration] len=4 "text" +// testset_vibes_nested.baml:15:34 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:15:45 (class) len=9 "Sentiment" +// testset_vibes_nested.baml:16:5 (property) len=6 "client" +// testset_vibes_nested.baml:17:5 (property) [declaration] len=6 "prompt" +// testset_vibes_nested.baml:17:12 (string) len=1 "#" +// testset_vibes_nested.baml:17:13 (string) len=1 "\"" +// testset_vibes_nested.baml:17:14 (string) len=8 "classify" +// testset_vibes_nested.baml:17:23 (string) len=1 "{" +// testset_vibes_nested.baml:17:24 (string) len=1 "{" +// testset_vibes_nested.baml:17:26 (string) len=4 "text" +// testset_vibes_nested.baml:17:31 (string) len=1 "}" +// testset_vibes_nested.baml:17:32 (string) len=1 "}" +// testset_vibes_nested.baml:17:33 (string) len=1 "\"" +// testset_vibes_nested.baml:17:34 (string) len=1 "#" +// testset_vibes_nested.baml:20:1 (keyword) len=8 "function" +// testset_vibes_nested.baml:20:10 (function) [declaration] len=13 "GenerateTests" +// testset_vibes_nested.baml:20:24 (parameter) [declaration] len=5 "count" +// testset_vibes_nested.baml:20:31 (type) [defaultLibrary] len=3 "int" +// testset_vibes_nested.baml:20:36 (parameter) [declaration] len=5 "topic" +// testset_vibes_nested.baml:20:43 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:20:54 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:21:5 (property) len=6 "client" +// testset_vibes_nested.baml:22:5 (property) [declaration] len=6 "prompt" +// testset_vibes_nested.baml:22:12 (string) len=1 "#" +// testset_vibes_nested.baml:22:13 (string) len=1 "\"" +// testset_vibes_nested.baml:22:14 (string) len=8 "generate" +// testset_vibes_nested.baml:22:23 (string) len=1 "{" +// testset_vibes_nested.baml:22:24 (string) len=1 "{" +// testset_vibes_nested.baml:22:26 (string) len=5 "count" +// testset_vibes_nested.baml:22:32 (string) len=1 "}" +// testset_vibes_nested.baml:22:33 (string) len=1 "}" +// testset_vibes_nested.baml:22:35 (string) len=5 "tests" +// testset_vibes_nested.baml:22:41 (string) len=5 "about" +// testset_vibes_nested.baml:22:47 (string) len=1 "{" +// testset_vibes_nested.baml:22:48 (string) len=1 "{" +// testset_vibes_nested.baml:22:50 (string) len=5 "topic" +// testset_vibes_nested.baml:22:56 (string) len=1 "}" +// testset_vibes_nested.baml:22:57 (string) len=1 "}" +// testset_vibes_nested.baml:22:58 (string) len=1 "\"" +// testset_vibes_nested.baml:22:59 (string) len=1 "#" +// testset_vibes_nested.baml:25:1 (keyword) len=7 "testset" +// testset_vibes_nested.baml:25:9 (string) len=6 "\"test\"" +// testset_vibes_nested.baml:26:5 (keyword) len=3 "let" +// testset_vibes_nested.baml:26:9 (variable) [declaration] len=6 "topics" +// testset_vibes_nested.baml:26:16 (operator) len=1 "=" +// testset_vibes_nested.baml:26:19 (string) len=7 "\"happy\"" +// testset_vibes_nested.baml:26:28 (string) len=5 "\"sad\"" +// testset_vibes_nested.baml:27:5 (keyword) len=3 "for" +// testset_vibes_nested.baml:27:10 (keyword) len=3 "let" +// testset_vibes_nested.baml:27:14 (variable) [declaration] len=10 "sentiments" +// testset_vibes_nested.baml:27:25 (keyword) len=2 "in" +// testset_vibes_nested.baml:27:28 (variable) len=6 "topics" +// testset_vibes_nested.baml:28:9 (keyword) len=7 "testset" +// testset_vibes_nested.baml:28:17 (variable) len=10 "sentiments" +// testset_vibes_nested.baml:29:13 (keyword) len=3 "let" +// testset_vibes_nested.baml:29:17 (variable) [declaration] len=3 "req" +// testset_vibes_nested.baml:29:21 (operator) len=1 "=" +// testset_vibes_nested.baml:29:23 (namespace) [defaultLibrary] len=4 "baml" +// testset_vibes_nested.baml:29:28 (namespace) [defaultLibrary] len=4 "http" +// testset_vibes_nested.baml:29:33 (function) len=5 "fetch" +// testset_vibes_nested.baml:29:39 (string) len=24 "\"http://localhost:8000/\"" +// testset_vibes_nested.baml:29:64 (operator) len=1 "+" +// testset_vibes_nested.baml:29:66 (variable) len=10 "sentiments" +// testset_vibes_nested.baml:30:13 (keyword) len=3 "let" +// testset_vibes_nested.baml:30:17 (variable) [declaration] len=4 "data" +// testset_vibes_nested.baml:30:22 (operator) len=1 "=" +// testset_vibes_nested.baml:30:24 (variable) len=3 "req" +// testset_vibes_nested.baml:30:28 (method) len=4 "text" +// testset_vibes_nested.baml:31:13 (keyword) len=3 "let" +// testset_vibes_nested.baml:31:17 (variable) [declaration] len=5 "tests" +// testset_vibes_nested.baml:31:23 (operator) len=1 "=" +// testset_vibes_nested.baml:31:25 (function) len=19 "GenerateTests$parse" +// testset_vibes_nested.baml:31:45 (variable) len=4 "data" +// testset_vibes_nested.baml:32:13 (keyword) len=3 "for" +// testset_vibes_nested.baml:32:18 (keyword) len=3 "let" +// testset_vibes_nested.baml:32:22 (variable) [declaration] len=2 "ex" +// testset_vibes_nested.baml:32:25 (keyword) len=2 "in" +// testset_vibes_nested.baml:32:28 (variable) len=5 "tests" +// testset_vibes_nested.baml:33:17 (keyword) len=4 "test" +// testset_vibes_nested.baml:33:22 (variable) len=2 "ex" +// testset_vibes_nested.baml:34:21 (keyword) len=3 "let" +// testset_vibes_nested.baml:34:25 (variable) [declaration] len=6 "result" +// testset_vibes_nested.baml:34:32 (operator) len=1 "=" +// testset_vibes_nested.baml:34:34 (function) len=17 "ClassifySentiment" +// testset_vibes_nested.baml:34:52 (string) len=4 "\"hi\"" +// testset_vibes_nested.baml:35:21 (namespace) [defaultLibrary] len=6 "assert" +// testset_vibes_nested.baml:35:28 (function) len=5 "equal" +// testset_vibes_nested.baml:35:34 (variable) len=6 "result" +// testset_vibes_nested.baml:35:41 (property) len=7 "feeling" +// testset_vibes_nested.baml:35:50 (string) len=10 "\"positive\"" +// testset_vibes_nested.baml:41:5 (keyword) len=7 "testset" +// testset_vibes_nested.baml:41:13 (string) len=7 "\"vibes\"" +// testset_vibes_nested.baml:42:9 (keyword) len=3 "let" +// testset_vibes_nested.baml:42:13 (variable) [declaration] len=6 "topics" +// testset_vibes_nested.baml:42:20 (operator) len=1 "=" +// testset_vibes_nested.baml:42:23 (string) len=7 "\"happy\"" +// testset_vibes_nested.baml:42:32 (string) len=5 "\"sad\"" +// testset_vibes_nested.baml:43:9 (keyword) len=3 "for" +// testset_vibes_nested.baml:43:14 (keyword) len=3 "let" +// testset_vibes_nested.baml:43:18 (variable) [declaration] len=10 "sentiments" +// testset_vibes_nested.baml:43:29 (keyword) len=2 "in" +// testset_vibes_nested.baml:43:32 (variable) len=6 "topics" +// testset_vibes_nested.baml:44:13 (keyword) len=7 "testset" +// testset_vibes_nested.baml:44:21 (variable) len=10 "sentiments" +// testset_vibes_nested.baml:45:17 (keyword) len=3 "let" +// testset_vibes_nested.baml:45:21 (variable) [declaration] len=5 "tests" +// testset_vibes_nested.baml:45:27 (operator) len=1 "=" +// testset_vibes_nested.baml:45:29 (function) len=13 "GenerateTests" +// testset_vibes_nested.baml:45:43 (number) len=1 "5" +// testset_vibes_nested.baml:45:46 (variable) len=10 "sentiments" +// testset_vibes_nested.baml:46:17 (keyword) len=3 "for" +// testset_vibes_nested.baml:46:22 (keyword) len=3 "let" +// testset_vibes_nested.baml:46:26 (variable) [declaration] len=2 "ex" +// testset_vibes_nested.baml:46:29 (keyword) len=2 "in" +// testset_vibes_nested.baml:46:32 (variable) len=5 "tests" +// testset_vibes_nested.baml:47:21 (keyword) len=4 "test" +// testset_vibes_nested.baml:47:26 (variable) len=2 "ex" +// testset_vibes_nested.baml:48:25 (keyword) len=3 "let" +// testset_vibes_nested.baml:48:29 (variable) [declaration] len=6 "result" +// testset_vibes_nested.baml:48:36 (operator) len=1 "=" +// testset_vibes_nested.baml:48:38 (function) len=17 "ClassifySentiment" +// testset_vibes_nested.baml:48:56 (string) len=4 "\"hi\"" +// testset_vibes_nested.baml:49:25 (namespace) [defaultLibrary] len=6 "assert" +// testset_vibes_nested.baml:49:32 (function) len=5 "equal" +// testset_vibes_nested.baml:49:38 (variable) len=6 "result" +// testset_vibes_nested.baml:49:45 (property) len=7 "feeling" +// testset_vibes_nested.baml:49:54 (string) len=10 "\"positive\"" +// testset_vibes_nested.baml:57:1 (keyword) len=8 "function" +// testset_vibes_nested.baml:57:10 (function) [declaration] len=3 "Foo" +// testset_vibes_nested.baml:57:19 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:57:26 (operator) len=1 "|" +// testset_vibes_nested.baml:57:28 (type) [defaultLibrary] len=5 "image" +// testset_vibes_nested.baml:58:5 (keyword) len=3 "let" +// testset_vibes_nested.baml:58:9 (variable) [declaration] len=1 "x" +// testset_vibes_nested.baml:58:11 (operator) len=1 "=" +// testset_vibes_nested.baml:58:13 (string) len=5 "\"foo\"" +// testset_vibes_nested.baml:59:5 (keyword) len=3 "let" +// testset_vibes_nested.baml:59:9 (variable) [declaration] len=1 "y" +// testset_vibes_nested.baml:59:11 (operator) len=1 "=" +// testset_vibes_nested.baml:59:13 (number) len=1 "2" +// testset_vibes_nested.baml:60:5 (keyword) len=3 "for" +// testset_vibes_nested.baml:60:10 (keyword) len=3 "let" +// testset_vibes_nested.baml:60:14 (variable) [declaration] len=1 "i" +// testset_vibes_nested.baml:60:16 (operator) len=1 "=" +// testset_vibes_nested.baml:60:18 (number) len=1 "0" +// testset_vibes_nested.baml:60:21 (variable) len=1 "i" +// testset_vibes_nested.baml:60:23 (operator) len=1 "<" +// testset_vibes_nested.baml:60:25 (variable) len=1 "y" +// testset_vibes_nested.baml:60:28 (variable) len=1 "i" +// testset_vibes_nested.baml:60:30 (operator) len=2 "+=" +// testset_vibes_nested.baml:60:33 (number) len=1 "1" +// testset_vibes_nested.baml:61:9 (variable) len=1 "x" +// testset_vibes_nested.baml:61:11 (operator) len=1 "=" +// testset_vibes_nested.baml:61:13 (string) len=7 "\"hi: \"" +// testset_vibes_nested.baml:61:21 (operator) len=1 "+" +// testset_vibes_nested.baml:61:23 (variable) len=1 "x" +// testset_vibes_nested.baml:63:5 (variable) len=1 "x" +// testset_vibes_nested.baml:66:1 (keyword) len=8 "function" +// testset_vibes_nested.baml:66:10 (function) [declaration] len=18 "ClassifySentiment2" +// testset_vibes_nested.baml:66:29 (parameter) [declaration] len=4 "text" +// testset_vibes_nested.baml:66:35 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:66:46 (type) [defaultLibrary] len=6 "string" +// testset_vibes_nested.baml:67:5 (property) len=6 "client" +// testset_vibes_nested.baml:68:5 (property) [declaration] len=6 "prompt" +// testset_vibes_nested.baml:68:12 (string) len=1 "#" +// testset_vibes_nested.baml:68:13 (string) len=1 "\"" +// testset_vibes_nested.baml:68:14 (string) len=8 "classify" +// testset_vibes_nested.baml:68:23 (string) len=1 "{" +// testset_vibes_nested.baml:68:24 (string) len=1 "{" +// testset_vibes_nested.baml:68:26 (string) len=4 "text" +// testset_vibes_nested.baml:68:31 (string) len=1 "}" +// testset_vibes_nested.baml:68:32 (string) len=1 "}" +// testset_vibes_nested.baml:68:33 (string) len=1 "\"" +// testset_vibes_nested.baml:68:34 (string) len=1 "#" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/throws_clause.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/throws_clause.baml new file mode 100644 index 0000000000..0c00647bd7 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/throws_clause.baml @@ -0,0 +1,86 @@ +// BEP-007: Basic throws syntax on function declarations + +class MyError { + message string +} + +// Function with throws clause +function MayThrow(x: int) -> string throws MyError { + if (x < 0) { + throw MyError { message: "negative" } + } + "ok" +} + +// Function with throws never (does not throw) +function NoThrow(x: int) -> string { + "always ok" +} + +// Function with union throws clause +function MayThrowMultiple(x: int) -> string throws string | int { + if (x < 0) { + throw "negative" + } + "ok" +} + +//---- +//- diagnostics +// warning: extraneous throws declaration: int +// ╭─[ throws_clause.baml:21:52 ] +// │ +// 21 │ function MayThrowMultiple(x: int) -> string throws string | int { +// │ ──────┬───── +// │ ╰─────── extraneous throws declaration: int +// │ +// │ Note: Error code: E0097 +// ────╯ +// +//- semantic_tokens +// throws_clause.baml:1:1 (comment) len=56 "// BEP-007: Basic throws syntax on function declarations" +// throws_clause.baml:3:1 (keyword) len=5 "class" +// throws_clause.baml:3:7 (class) [declaration] len=7 "MyError" +// throws_clause.baml:4:3 (property) [declaration] len=7 "message" +// throws_clause.baml:4:11 (type) [defaultLibrary] len=6 "string" +// throws_clause.baml:7:1 (comment) len=30 "// Function with throws clause" +// throws_clause.baml:8:1 (keyword) len=8 "function" +// throws_clause.baml:8:10 (function) [declaration] len=8 "MayThrow" +// throws_clause.baml:8:19 (parameter) [declaration] len=1 "x" +// throws_clause.baml:8:22 (type) [defaultLibrary] len=3 "int" +// throws_clause.baml:8:30 (type) [defaultLibrary] len=6 "string" +// throws_clause.baml:8:37 (keyword) len=6 "throws" +// throws_clause.baml:8:44 (class) len=7 "MyError" +// throws_clause.baml:9:3 (keyword) len=2 "if" +// throws_clause.baml:9:7 (parameter) len=1 "x" +// throws_clause.baml:9:9 (operator) len=1 "<" +// throws_clause.baml:9:11 (number) len=1 "0" +// throws_clause.baml:10:5 (keyword) len=5 "throw" +// throws_clause.baml:10:11 (class) len=7 "MyError" +// throws_clause.baml:10:21 (property) len=7 "message" +// throws_clause.baml:10:30 (string) len=10 "\"negative\"" +// throws_clause.baml:12:3 (string) len=4 "\"ok\"" +// throws_clause.baml:15:1 (comment) len=46 "// Function with throws never (does not throw)" +// throws_clause.baml:16:1 (keyword) len=8 "function" +// throws_clause.baml:16:10 (function) [declaration] len=7 "NoThrow" +// throws_clause.baml:16:18 (parameter) [declaration] len=1 "x" +// throws_clause.baml:16:21 (type) [defaultLibrary] len=3 "int" +// throws_clause.baml:16:29 (type) [defaultLibrary] len=6 "string" +// throws_clause.baml:17:3 (string) len=11 "\"always ok\"" +// throws_clause.baml:20:1 (comment) len=36 "// Function with union throws clause" +// throws_clause.baml:21:1 (keyword) len=8 "function" +// throws_clause.baml:21:10 (function) [declaration] len=16 "MayThrowMultiple" +// throws_clause.baml:21:27 (parameter) [declaration] len=1 "x" +// throws_clause.baml:21:30 (type) [defaultLibrary] len=3 "int" +// throws_clause.baml:21:38 (type) [defaultLibrary] len=6 "string" +// throws_clause.baml:21:45 (keyword) len=6 "throws" +// throws_clause.baml:21:52 (type) [defaultLibrary] len=6 "string" +// throws_clause.baml:21:59 (operator) len=1 "|" +// throws_clause.baml:21:61 (type) [defaultLibrary] len=3 "int" +// throws_clause.baml:22:3 (keyword) len=2 "if" +// throws_clause.baml:22:7 (parameter) len=1 "x" +// throws_clause.baml:22:9 (operator) len=1 "<" +// throws_clause.baml:22:11 (number) len=1 "0" +// throws_clause.baml:23:5 (keyword) len=5 "throw" +// throws_clause.baml:23:11 (string) len=10 "\"negative\"" +// throws_clause.baml:25:3 (string) len=4 "\"ok\"" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/top_level_binding.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/top_level_binding.baml new file mode 100644 index 0000000000..c821fe8fdb --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/top_level_binding.baml @@ -0,0 +1,26 @@ +let x = 1; + +let y = { + let b = 2; + [1,2,3] +}; + +//---- +//- diagnostics +// +// +//- semantic_tokens +// top_level_binding.baml:1:1 (keyword) len=3 "let" +// top_level_binding.baml:1:5 (variable) [declaration] len=1 "x" +// top_level_binding.baml:1:7 (operator) len=1 "=" +// top_level_binding.baml:1:9 (number) len=1 "1" +// top_level_binding.baml:3:1 (keyword) len=3 "let" +// top_level_binding.baml:3:5 (variable) [declaration] len=1 "y" +// top_level_binding.baml:3:7 (operator) len=1 "=" +// top_level_binding.baml:4:5 (keyword) len=3 "let" +// top_level_binding.baml:4:9 (variable) [declaration] len=1 "b" +// top_level_binding.baml:4:11 (operator) len=1 "=" +// top_level_binding.baml:4:13 (number) len=1 "2" +// top_level_binding.baml:5:6 (number) len=1 "1" +// top_level_binding.baml:5:8 (number) len=1 "2" +// top_level_binding.baml:5:10 (number) len=1 "3" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_alias.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_alias.baml index 0a3de5d6e7..e0085c5144 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_alias.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_alias.baml @@ -16,19 +16,19 @@ type Person = User | Admin; // //- semantic_tokens // type_alias.baml:1:1 (keyword) len=4 "type" -// type_alias.baml:1:6 (type) len=4 "Name" +// type_alias.baml:1:6 (type) [declaration] len=4 "Name" // type_alias.baml:1:11 (operator) len=1 "=" -// type_alias.baml:1:13 (type) len=6 "string" +// type_alias.baml:1:13 (type) [defaultLibrary] len=6 "string" // type_alias.baml:3:1 (keyword) len=5 "class" -// type_alias.baml:3:7 (class) len=4 "User" -// type_alias.baml:4:5 (property) len=4 "name" +// type_alias.baml:3:7 (class) [declaration] len=4 "User" +// type_alias.baml:4:5 (property) [declaration] len=4 "name" // type_alias.baml:4:10 (type) len=4 "Name" // type_alias.baml:7:1 (keyword) len=5 "class" -// type_alias.baml:7:7 (class) len=5 "Admin" -// type_alias.baml:8:5 (property) len=4 "name" +// type_alias.baml:7:7 (class) [declaration] len=5 "Admin" +// type_alias.baml:8:5 (property) [declaration] len=4 "name" // type_alias.baml:8:10 (type) len=4 "Name" // type_alias.baml:11:1 (keyword) len=4 "type" -// type_alias.baml:11:6 (type) len=6 "Person" +// type_alias.baml:11:6 (type) [declaration] len=6 "Person" // type_alias.baml:11:13 (operator) len=1 "=" // type_alias.baml:11:15 (class) len=4 "User" // type_alias.baml:11:20 (operator) len=1 "|" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_aliases_jinja.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_aliases_jinja.baml new file mode 100644 index 0000000000..965ad5adc9 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_aliases_jinja.baml @@ -0,0 +1,270 @@ +type ProjectId = int + +function NormalAlias(pid: ProjectId) -> string { + client "openai/gpt-4o" + prompt #"Pid: {{ pid.id }}. Generate a fake name for it."# +} + +type A = float +type B = A +type C = B + +function LongerAlias(c: C) -> string { + client "openai/gpt-4o" + prompt #"{{ c.value }}"# +} + +type JsonValue = int | string | bool | float | JsonObject | JsonArray +type JsonObject = map +type JsonArray = JsonValue[] + +function RecursiveAliases(j: JsonValue) -> string { + client "openai/gpt-4o" + prompt #"{{ j.value }}"# +} + +type I = J +type J = I + +function InvalidAlias(i: I) -> string { + client "openai/gpt-4o" + prompt #"{{ i.value }}"# +} + +// warning: 'pid' is a type alias ProjectId (resolves to int), expected class +// --> class/type_aliases_jinja.baml:5 +// | +// 4 | client "openai/gpt-4o" +// 5 | prompt #"Pid: {{ pid.id }}. Generate a fake name for it."# +// | +// warning: 'c' is a type alias C (resolves to float), expected class +// --> class/type_aliases_jinja.baml:14 +// | +// 13 | client "openai/gpt-4o" +// 14 | prompt #"{{ c.value }}"# +// | +// warning: 'j' is a recursive type alias JsonValue, expected class +// --> class/type_aliases_jinja.baml:23 +// | +// 22 | client "openai/gpt-4o" +// 23 | prompt #"{{ j.value }}"# +// | +// warning: 'i' is a recursive type alias I, expected class +// --> class/type_aliases_jinja.baml:31 +// | +// 30 | client "openai/gpt-4o" +// 31 | prompt #"{{ i.value }}"# +// | +// error: Error validating: These aliases form a dependency cycle: I -> J +// --> class/type_aliases_jinja.baml:26 +// | +// 25 | +// 26 | type I = J +// | + +//---- +//- diagnostics +// warning: cannot access property 'value' on 'j': union contains non-class type map[string, recursive type alias JsonValue] +// ╭─[ type_aliases_jinja.baml:23:15 ] +// │ +// 23 │ prompt #"{{ j.value }}"# +// │ ───┬─── +// │ ╰───── cannot access property 'value' on 'j': union contains non-class type map[string, recursive type alias JsonValue] +// │ +// │ Note: Error code: E0074 +// ────╯ +// warning: 'c' is a type alias C (resolves to type alias B (resolves to type alias A (resolves to float))), expected class +// ╭─[ type_aliases_jinja.baml:14:15 ] +// │ +// 14 │ prompt #"{{ c.value }}"# +// │ ───┬─── +// │ ╰───── 'c' is a type alias C (resolves to type alias B (resolves to type alias A (resolves to float))), expected class +// │ +// │ Note: Error code: E0073 +// ────╯ +// warning: 'i' is a type alias I (resolves to type alias J (resolves to recursive type alias I)), expected class +// ╭─[ type_aliases_jinja.baml:31:15 ] +// │ +// 31 │ prompt #"{{ i.value }}"# +// │ ───┬─── +// │ ╰───── 'i' is a type alias I (resolves to type alias J (resolves to recursive type alias I)), expected class +// │ +// │ Note: Error code: E0073 +// ────╯ +// warning: 'pid' is a type alias ProjectId (resolves to int), expected class +// ╭─[ type_aliases_jinja.baml:5:20 ] +// │ +// 5 │ prompt #"Pid: {{ pid.id }}. Generate a fake name for it."# +// │ ───┬── +// │ ╰──── 'pid' is a type alias ProjectId (resolves to int), expected class +// │ +// │ Note: Error code: E0073 +// ───╯ +// +//- semantic_tokens +// type_aliases_jinja.baml:1:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:1:6 (type) [declaration] len=9 "ProjectId" +// type_aliases_jinja.baml:1:16 (operator) len=1 "=" +// type_aliases_jinja.baml:1:18 (type) [defaultLibrary] len=3 "int" +// type_aliases_jinja.baml:3:1 (keyword) len=8 "function" +// type_aliases_jinja.baml:3:10 (function) [declaration] len=11 "NormalAlias" +// type_aliases_jinja.baml:3:22 (parameter) [declaration] len=3 "pid" +// type_aliases_jinja.baml:3:27 (type) len=9 "ProjectId" +// type_aliases_jinja.baml:3:41 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:4:3 (property) len=6 "client" +// type_aliases_jinja.baml:4:10 (string) len=15 "\"openai/gpt-4o\"" +// type_aliases_jinja.baml:5:3 (property) [declaration] len=6 "prompt" +// type_aliases_jinja.baml:5:10 (string) len=1 "#" +// type_aliases_jinja.baml:5:11 (string) len=1 "\"" +// type_aliases_jinja.baml:5:12 (string) len=3 "Pid" +// type_aliases_jinja.baml:5:15 (string) len=1 ":" +// type_aliases_jinja.baml:5:17 (string) len=1 "{" +// type_aliases_jinja.baml:5:18 (string) len=1 "{" +// type_aliases_jinja.baml:5:20 (string) len=3 "pid" +// type_aliases_jinja.baml:5:23 (string) len=1 "." +// type_aliases_jinja.baml:5:24 (string) len=2 "id" +// type_aliases_jinja.baml:5:27 (string) len=1 "}" +// type_aliases_jinja.baml:5:28 (string) len=1 "}" +// type_aliases_jinja.baml:5:29 (string) len=1 "." +// type_aliases_jinja.baml:5:31 (string) len=8 "Generate" +// type_aliases_jinja.baml:5:40 (string) len=1 "a" +// type_aliases_jinja.baml:5:42 (string) len=4 "fake" +// type_aliases_jinja.baml:5:47 (string) len=4 "name" +// type_aliases_jinja.baml:5:52 (string) len=3 "for" +// type_aliases_jinja.baml:5:56 (string) len=2 "it" +// type_aliases_jinja.baml:5:58 (string) len=1 "." +// type_aliases_jinja.baml:5:59 (string) len=1 "\"" +// type_aliases_jinja.baml:5:60 (string) len=1 "#" +// type_aliases_jinja.baml:8:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:8:6 (type) [declaration] len=1 "A" +// type_aliases_jinja.baml:8:8 (operator) len=1 "=" +// type_aliases_jinja.baml:8:10 (type) [defaultLibrary] len=5 "float" +// type_aliases_jinja.baml:9:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:9:6 (type) [declaration] len=1 "B" +// type_aliases_jinja.baml:9:8 (operator) len=1 "=" +// type_aliases_jinja.baml:9:10 (type) len=1 "A" +// type_aliases_jinja.baml:10:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:10:6 (type) [declaration] len=1 "C" +// type_aliases_jinja.baml:10:8 (operator) len=1 "=" +// type_aliases_jinja.baml:10:10 (type) len=1 "B" +// type_aliases_jinja.baml:12:1 (keyword) len=8 "function" +// type_aliases_jinja.baml:12:10 (function) [declaration] len=11 "LongerAlias" +// type_aliases_jinja.baml:12:22 (parameter) [declaration] len=1 "c" +// type_aliases_jinja.baml:12:25 (type) len=1 "C" +// type_aliases_jinja.baml:12:31 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:13:3 (property) len=6 "client" +// type_aliases_jinja.baml:13:10 (string) len=15 "\"openai/gpt-4o\"" +// type_aliases_jinja.baml:14:3 (property) [declaration] len=6 "prompt" +// type_aliases_jinja.baml:14:10 (string) len=1 "#" +// type_aliases_jinja.baml:14:11 (string) len=1 "\"" +// type_aliases_jinja.baml:14:12 (string) len=1 "{" +// type_aliases_jinja.baml:14:13 (string) len=1 "{" +// type_aliases_jinja.baml:14:15 (string) len=1 "c" +// type_aliases_jinja.baml:14:16 (string) len=1 "." +// type_aliases_jinja.baml:14:17 (string) len=5 "value" +// type_aliases_jinja.baml:14:23 (string) len=1 "}" +// type_aliases_jinja.baml:14:24 (string) len=1 "}" +// type_aliases_jinja.baml:14:25 (string) len=1 "\"" +// type_aliases_jinja.baml:14:26 (string) len=1 "#" +// type_aliases_jinja.baml:17:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:17:6 (type) [declaration] len=9 "JsonValue" +// type_aliases_jinja.baml:17:16 (operator) len=1 "=" +// type_aliases_jinja.baml:17:18 (type) [defaultLibrary] len=3 "int" +// type_aliases_jinja.baml:17:22 (operator) len=1 "|" +// type_aliases_jinja.baml:17:24 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:17:31 (operator) len=1 "|" +// type_aliases_jinja.baml:17:33 (type) [defaultLibrary] len=4 "bool" +// type_aliases_jinja.baml:17:38 (operator) len=1 "|" +// type_aliases_jinja.baml:17:40 (type) [defaultLibrary] len=5 "float" +// type_aliases_jinja.baml:17:46 (operator) len=1 "|" +// type_aliases_jinja.baml:17:48 (type) len=10 "JsonObject" +// type_aliases_jinja.baml:17:59 (operator) len=1 "|" +// type_aliases_jinja.baml:17:61 (type) len=9 "JsonArray" +// type_aliases_jinja.baml:18:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:18:6 (type) [declaration] len=10 "JsonObject" +// type_aliases_jinja.baml:18:17 (operator) len=1 "=" +// type_aliases_jinja.baml:18:19 (type) [defaultLibrary] len=3 "map" +// type_aliases_jinja.baml:18:22 (operator) len=1 "<" +// type_aliases_jinja.baml:18:23 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:18:31 (type) len=9 "JsonValue" +// type_aliases_jinja.baml:18:40 (operator) len=1 ">" +// type_aliases_jinja.baml:19:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:19:6 (type) [declaration] len=9 "JsonArray" +// type_aliases_jinja.baml:19:16 (operator) len=1 "=" +// type_aliases_jinja.baml:19:18 (type) len=9 "JsonValue" +// type_aliases_jinja.baml:21:1 (keyword) len=8 "function" +// type_aliases_jinja.baml:21:10 (function) [declaration] len=16 "RecursiveAliases" +// type_aliases_jinja.baml:21:27 (parameter) [declaration] len=1 "j" +// type_aliases_jinja.baml:21:30 (type) len=9 "JsonValue" +// type_aliases_jinja.baml:21:44 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:22:3 (property) len=6 "client" +// type_aliases_jinja.baml:22:10 (string) len=15 "\"openai/gpt-4o\"" +// type_aliases_jinja.baml:23:3 (property) [declaration] len=6 "prompt" +// type_aliases_jinja.baml:23:10 (string) len=1 "#" +// type_aliases_jinja.baml:23:11 (string) len=1 "\"" +// type_aliases_jinja.baml:23:12 (string) len=1 "{" +// type_aliases_jinja.baml:23:13 (string) len=1 "{" +// type_aliases_jinja.baml:23:15 (string) len=1 "j" +// type_aliases_jinja.baml:23:16 (string) len=1 "." +// type_aliases_jinja.baml:23:17 (string) len=5 "value" +// type_aliases_jinja.baml:23:23 (string) len=1 "}" +// type_aliases_jinja.baml:23:24 (string) len=1 "}" +// type_aliases_jinja.baml:23:25 (string) len=1 "\"" +// type_aliases_jinja.baml:23:26 (string) len=1 "#" +// type_aliases_jinja.baml:26:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:26:6 (type) [declaration] len=1 "I" +// type_aliases_jinja.baml:26:8 (operator) len=1 "=" +// type_aliases_jinja.baml:26:10 (type) len=1 "J" +// type_aliases_jinja.baml:27:1 (keyword) len=4 "type" +// type_aliases_jinja.baml:27:6 (type) [declaration] len=1 "J" +// type_aliases_jinja.baml:27:8 (operator) len=1 "=" +// type_aliases_jinja.baml:27:10 (type) len=1 "I" +// type_aliases_jinja.baml:29:1 (keyword) len=8 "function" +// type_aliases_jinja.baml:29:10 (function) [declaration] len=12 "InvalidAlias" +// type_aliases_jinja.baml:29:23 (parameter) [declaration] len=1 "i" +// type_aliases_jinja.baml:29:26 (type) len=1 "I" +// type_aliases_jinja.baml:29:32 (type) [defaultLibrary] len=6 "string" +// type_aliases_jinja.baml:30:3 (property) len=6 "client" +// type_aliases_jinja.baml:30:10 (string) len=15 "\"openai/gpt-4o\"" +// type_aliases_jinja.baml:31:3 (property) [declaration] len=6 "prompt" +// type_aliases_jinja.baml:31:10 (string) len=1 "#" +// type_aliases_jinja.baml:31:11 (string) len=1 "\"" +// type_aliases_jinja.baml:31:12 (string) len=1 "{" +// type_aliases_jinja.baml:31:13 (string) len=1 "{" +// type_aliases_jinja.baml:31:15 (string) len=1 "i" +// type_aliases_jinja.baml:31:16 (string) len=1 "." +// type_aliases_jinja.baml:31:17 (string) len=5 "value" +// type_aliases_jinja.baml:31:23 (string) len=1 "}" +// type_aliases_jinja.baml:31:24 (string) len=1 "}" +// type_aliases_jinja.baml:31:25 (string) len=1 "\"" +// type_aliases_jinja.baml:31:26 (string) len=1 "#" +// type_aliases_jinja.baml:34:1 (comment) len=77 "// warning: 'pid' is a type alias ProjectId (resolves to int), expected class" +// type_aliases_jinja.baml:35:1 (comment) len=41 "// --> class/type_aliases_jinja.baml:5" +// type_aliases_jinja.baml:36:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:37:1 (comment) len=32 "// 4 | client \"openai/gpt-4o\"" +// type_aliases_jinja.baml:38:1 (comment) len=68 "// 5 | prompt #\"Pid: {{ pid.id }}. Generate a fake name for it.\"#" +// type_aliases_jinja.baml:39:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:40:1 (comment) len=69 "// warning: 'c' is a type alias C (resolves to float), expected class" +// type_aliases_jinja.baml:41:1 (comment) len=42 "// --> class/type_aliases_jinja.baml:14" +// type_aliases_jinja.baml:42:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:43:1 (comment) len=32 "// 13 | client \"openai/gpt-4o\"" +// type_aliases_jinja.baml:44:1 (comment) len=34 "// 14 | prompt #\"{{ c.value }}\"#" +// type_aliases_jinja.baml:45:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:46:1 (comment) len=67 "// warning: 'j' is a recursive type alias JsonValue, expected class" +// type_aliases_jinja.baml:47:1 (comment) len=42 "// --> class/type_aliases_jinja.baml:23" +// type_aliases_jinja.baml:48:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:49:1 (comment) len=32 "// 22 | client \"openai/gpt-4o\"" +// type_aliases_jinja.baml:50:1 (comment) len=34 "// 23 | prompt #\"{{ j.value }}\"#" +// type_aliases_jinja.baml:51:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:52:1 (comment) len=59 "// warning: 'i' is a recursive type alias I, expected class" +// type_aliases_jinja.baml:53:1 (comment) len=42 "// --> class/type_aliases_jinja.baml:31" +// type_aliases_jinja.baml:54:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:55:1 (comment) len=32 "// 30 | client \"openai/gpt-4o\"" +// type_aliases_jinja.baml:56:1 (comment) len=34 "// 31 | prompt #\"{{ i.value }}\"#" +// type_aliases_jinja.baml:57:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:58:1 (comment) len=73 "// error: Error validating: These aliases form a dependency cycle: I -> J" +// type_aliases_jinja.baml:59:1 (comment) len=42 "// --> class/type_aliases_jinja.baml:26" +// type_aliases_jinja.baml:60:1 (comment) len=7 "// |" +// type_aliases_jinja.baml:61:1 (comment) len=7 "// 25 |" +// type_aliases_jinja.baml:62:1 (comment) len=18 "// 26 | type I = J" +// type_aliases_jinja.baml:63:1 (comment) len=7 "// |" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/watch_let.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/watch_let.baml new file mode 100644 index 0000000000..86fea8675b --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/watch_let.baml @@ -0,0 +1,306 @@ +function branch_locals(b: bool) -> int { + if (b) { + let a = 1; + a + } else { + let a = 2; + a + } +} + +function same_scope_shadow() -> int { + let x = 1; + let x = 2; + x +} + +function initializer_uses_previous() -> int { + let x = 1; + let x = x + 1; + x +} + +function shadow_param(x: int) -> int { + let x = x + 1; + x +} + +function outer_restored() -> int { + let x = 1; + { + let x = 2; + }; + x +} + +function declared_type_restored() -> string { + let x: string = "outer"; + { + let x: int = 1; + }; + x +} + +function for_loop_restores_outer() -> int { + let x = 1; + for (let x in [2, 3]) { + x; + }; + x +} + +function watch_block_cleanup() -> int { + watch let x = 1; + { + watch let x = 2; + x; + }; + x +} + +function nested_outer_restored() -> int { + let x = 1; + { + let x = 2; + { + let x = 3; + x; + }; + x; + }; + x +} + +function capture_before_after_shadow() -> int { + let x = 1; + let g = () -> int { x }; + let x = 2; + let f = () -> int { x }; + g() * 10 + f() +} + +function nested_lambda_capture() -> int { + let x = 7; + let outer = () -> int { + let inner = () -> int { x }; + inner() + }; + outer() +} + +// A `let` declared inside a `while` body must NOT leak to the enclosing +// scope. The inner `x = 99` shadows the outer `x` for the duration of the +// body only — after the loop, `x` resolves to the outermost binding. +function while_body_restores_outer() -> int { + let x = 1; + let once = true; + while (once) { + let x = 99; + once = false; + }; + x +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// watch_let.baml:1:1 (keyword) len=8 "function" +// watch_let.baml:1:10 (function) [declaration] len=13 "branch_locals" +// watch_let.baml:1:24 (parameter) [declaration] len=1 "b" +// watch_let.baml:1:27 (type) [defaultLibrary] len=4 "bool" +// watch_let.baml:1:36 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:2:3 (keyword) len=2 "if" +// watch_let.baml:2:7 (parameter) len=1 "b" +// watch_let.baml:3:5 (keyword) len=3 "let" +// watch_let.baml:3:9 (variable) [declaration] len=1 "a" +// watch_let.baml:3:11 (operator) len=1 "=" +// watch_let.baml:3:13 (number) len=1 "1" +// watch_let.baml:4:5 (variable) len=1 "a" +// watch_let.baml:5:5 (keyword) len=4 "else" +// watch_let.baml:6:5 (keyword) len=3 "let" +// watch_let.baml:6:9 (variable) [declaration] len=1 "a" +// watch_let.baml:6:11 (operator) len=1 "=" +// watch_let.baml:6:13 (number) len=1 "2" +// watch_let.baml:7:5 (variable) len=1 "a" +// watch_let.baml:11:1 (keyword) len=8 "function" +// watch_let.baml:11:10 (function) [declaration] len=17 "same_scope_shadow" +// watch_let.baml:11:33 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:12:3 (keyword) len=3 "let" +// watch_let.baml:12:7 (variable) [declaration] len=1 "x" +// watch_let.baml:12:9 (operator) len=1 "=" +// watch_let.baml:12:11 (number) len=1 "1" +// watch_let.baml:13:3 (keyword) len=3 "let" +// watch_let.baml:13:7 (variable) [declaration] len=1 "x" +// watch_let.baml:13:9 (operator) len=1 "=" +// watch_let.baml:13:11 (number) len=1 "2" +// watch_let.baml:14:3 (variable) len=1 "x" +// watch_let.baml:17:1 (keyword) len=8 "function" +// watch_let.baml:17:10 (function) [declaration] len=25 "initializer_uses_previous" +// watch_let.baml:17:41 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:18:3 (keyword) len=3 "let" +// watch_let.baml:18:7 (variable) [declaration] len=1 "x" +// watch_let.baml:18:9 (operator) len=1 "=" +// watch_let.baml:18:11 (number) len=1 "1" +// watch_let.baml:19:3 (keyword) len=3 "let" +// watch_let.baml:19:7 (variable) [declaration] len=1 "x" +// watch_let.baml:19:9 (operator) len=1 "=" +// watch_let.baml:19:11 (variable) len=1 "x" +// watch_let.baml:19:13 (operator) len=1 "+" +// watch_let.baml:19:15 (number) len=1 "1" +// watch_let.baml:20:3 (variable) len=1 "x" +// watch_let.baml:23:1 (keyword) len=8 "function" +// watch_let.baml:23:10 (function) [declaration] len=12 "shadow_param" +// watch_let.baml:23:23 (parameter) [declaration] len=1 "x" +// watch_let.baml:23:26 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:23:34 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:24:3 (keyword) len=3 "let" +// watch_let.baml:24:7 (variable) [declaration] len=1 "x" +// watch_let.baml:24:9 (operator) len=1 "=" +// watch_let.baml:24:11 (parameter) len=1 "x" +// watch_let.baml:24:13 (operator) len=1 "+" +// watch_let.baml:24:15 (number) len=1 "1" +// watch_let.baml:25:3 (variable) len=1 "x" +// watch_let.baml:28:1 (keyword) len=8 "function" +// watch_let.baml:28:10 (function) [declaration] len=14 "outer_restored" +// watch_let.baml:28:30 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:29:3 (keyword) len=3 "let" +// watch_let.baml:29:7 (variable) [declaration] len=1 "x" +// watch_let.baml:29:9 (operator) len=1 "=" +// watch_let.baml:29:11 (number) len=1 "1" +// watch_let.baml:31:5 (keyword) len=3 "let" +// watch_let.baml:31:9 (variable) [declaration] len=1 "x" +// watch_let.baml:31:11 (operator) len=1 "=" +// watch_let.baml:31:13 (number) len=1 "2" +// watch_let.baml:33:3 (variable) len=1 "x" +// watch_let.baml:36:1 (keyword) len=8 "function" +// watch_let.baml:36:10 (function) [declaration] len=22 "declared_type_restored" +// watch_let.baml:36:38 (type) [defaultLibrary] len=6 "string" +// watch_let.baml:37:3 (keyword) len=3 "let" +// watch_let.baml:37:7 (variable) [declaration] len=1 "x" +// watch_let.baml:37:10 (type) [defaultLibrary] len=6 "string" +// watch_let.baml:37:17 (operator) len=1 "=" +// watch_let.baml:37:19 (string) len=7 "\"outer\"" +// watch_let.baml:39:5 (keyword) len=3 "let" +// watch_let.baml:39:9 (variable) [declaration] len=1 "x" +// watch_let.baml:39:12 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:39:16 (operator) len=1 "=" +// watch_let.baml:39:18 (number) len=1 "1" +// watch_let.baml:41:3 (variable) len=1 "x" +// watch_let.baml:44:1 (keyword) len=8 "function" +// watch_let.baml:44:10 (function) [declaration] len=23 "for_loop_restores_outer" +// watch_let.baml:44:39 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:45:3 (keyword) len=3 "let" +// watch_let.baml:45:7 (variable) [declaration] len=1 "x" +// watch_let.baml:45:9 (operator) len=1 "=" +// watch_let.baml:45:11 (number) len=1 "1" +// watch_let.baml:46:3 (keyword) len=3 "for" +// watch_let.baml:46:8 (keyword) len=3 "let" +// watch_let.baml:46:12 (variable) [declaration] len=1 "x" +// watch_let.baml:46:14 (keyword) len=2 "in" +// watch_let.baml:46:18 (number) len=1 "2" +// watch_let.baml:46:21 (number) len=1 "3" +// watch_let.baml:47:5 (variable) len=1 "x" +// watch_let.baml:49:3 (variable) len=1 "x" +// watch_let.baml:52:1 (keyword) len=8 "function" +// watch_let.baml:52:10 (function) [declaration] len=19 "watch_block_cleanup" +// watch_let.baml:52:35 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:53:3 (keyword) len=5 "watch" +// watch_let.baml:53:9 (keyword) len=3 "let" +// watch_let.baml:53:13 (variable) [declaration] len=1 "x" +// watch_let.baml:53:15 (operator) len=1 "=" +// watch_let.baml:53:17 (number) len=1 "1" +// watch_let.baml:55:5 (keyword) len=5 "watch" +// watch_let.baml:55:11 (keyword) len=3 "let" +// watch_let.baml:55:15 (variable) [declaration] len=1 "x" +// watch_let.baml:55:17 (operator) len=1 "=" +// watch_let.baml:55:19 (number) len=1 "2" +// watch_let.baml:56:5 (variable) len=1 "x" +// watch_let.baml:58:3 (variable) len=1 "x" +// watch_let.baml:61:1 (keyword) len=8 "function" +// watch_let.baml:61:10 (function) [declaration] len=21 "nested_outer_restored" +// watch_let.baml:61:37 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:62:3 (keyword) len=3 "let" +// watch_let.baml:62:7 (variable) [declaration] len=1 "x" +// watch_let.baml:62:9 (operator) len=1 "=" +// watch_let.baml:62:11 (number) len=1 "1" +// watch_let.baml:64:5 (keyword) len=3 "let" +// watch_let.baml:64:9 (variable) [declaration] len=1 "x" +// watch_let.baml:64:11 (operator) len=1 "=" +// watch_let.baml:64:13 (number) len=1 "2" +// watch_let.baml:66:7 (keyword) len=3 "let" +// watch_let.baml:66:11 (variable) [declaration] len=1 "x" +// watch_let.baml:66:13 (operator) len=1 "=" +// watch_let.baml:66:15 (number) len=1 "3" +// watch_let.baml:67:7 (variable) len=1 "x" +// watch_let.baml:69:5 (variable) len=1 "x" +// watch_let.baml:71:3 (variable) len=1 "x" +// watch_let.baml:74:1 (keyword) len=8 "function" +// watch_let.baml:74:10 (function) [declaration] len=27 "capture_before_after_shadow" +// watch_let.baml:74:43 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:75:3 (keyword) len=3 "let" +// watch_let.baml:75:7 (variable) [declaration] len=1 "x" +// watch_let.baml:75:9 (operator) len=1 "=" +// watch_let.baml:75:11 (number) len=1 "1" +// watch_let.baml:76:3 (keyword) len=3 "let" +// watch_let.baml:76:7 (variable) [declaration] len=1 "g" +// watch_let.baml:76:9 (operator) len=1 "=" +// watch_let.baml:76:17 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:76:23 (variable) len=1 "x" +// watch_let.baml:77:3 (keyword) len=3 "let" +// watch_let.baml:77:7 (variable) [declaration] len=1 "x" +// watch_let.baml:77:9 (operator) len=1 "=" +// watch_let.baml:77:11 (number) len=1 "2" +// watch_let.baml:78:3 (keyword) len=3 "let" +// watch_let.baml:78:7 (variable) [declaration] len=1 "f" +// watch_let.baml:78:9 (operator) len=1 "=" +// watch_let.baml:78:17 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:78:23 (variable) len=1 "x" +// watch_let.baml:79:3 (variable) len=1 "g" +// watch_let.baml:79:7 (operator) len=1 "*" +// watch_let.baml:79:9 (number) len=2 "10" +// watch_let.baml:79:12 (operator) len=1 "+" +// watch_let.baml:79:14 (variable) len=1 "f" +// watch_let.baml:82:1 (keyword) len=8 "function" +// watch_let.baml:82:10 (function) [declaration] len=21 "nested_lambda_capture" +// watch_let.baml:82:37 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:83:3 (keyword) len=3 "let" +// watch_let.baml:83:7 (variable) [declaration] len=1 "x" +// watch_let.baml:83:9 (operator) len=1 "=" +// watch_let.baml:83:11 (number) len=1 "7" +// watch_let.baml:84:3 (keyword) len=3 "let" +// watch_let.baml:84:7 (variable) [declaration] len=5 "outer" +// watch_let.baml:84:13 (operator) len=1 "=" +// watch_let.baml:84:21 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:85:5 (keyword) len=3 "let" +// watch_let.baml:85:9 (variable) [declaration] len=5 "inner" +// watch_let.baml:85:15 (operator) len=1 "=" +// watch_let.baml:85:23 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:85:29 (variable) len=1 "x" +// watch_let.baml:86:5 (variable) len=5 "inner" +// watch_let.baml:88:3 (variable) len=5 "outer" +// watch_let.baml:91:1 (comment) len=72 "// A `let` declared inside a `while` body must NOT leak to the enclosing" +// watch_let.baml:92:1 (comment) len=74 "// scope. The inner `x = 99` shadows the outer `x` for the duration of the" +// watch_let.baml:93:1 (comment) len=71 "// body only — after the loop, `x` resolves to the outermost binding." +// watch_let.baml:94:1 (keyword) len=8 "function" +// watch_let.baml:94:10 (function) [declaration] len=25 "while_body_restores_outer" +// watch_let.baml:94:41 (type) [defaultLibrary] len=3 "int" +// watch_let.baml:95:3 (keyword) len=3 "let" +// watch_let.baml:95:7 (variable) [declaration] len=1 "x" +// watch_let.baml:95:9 (operator) len=1 "=" +// watch_let.baml:95:11 (number) len=1 "1" +// watch_let.baml:96:3 (keyword) len=3 "let" +// watch_let.baml:96:7 (variable) [declaration] len=4 "once" +// watch_let.baml:96:12 (operator) len=1 "=" +// watch_let.baml:96:14 (boolean) len=4 "true" +// watch_let.baml:97:3 (keyword) len=5 "while" +// watch_let.baml:97:10 (variable) len=4 "once" +// watch_let.baml:98:5 (keyword) len=3 "let" +// watch_let.baml:98:9 (variable) [declaration] len=1 "x" +// watch_let.baml:98:11 (operator) len=1 "=" +// watch_let.baml:98:13 (number) len=2 "99" +// watch_let.baml:99:5 (variable) len=4 "once" +// watch_let.baml:99:10 (operator) len=1 "=" +// watch_let.baml:99:12 (boolean) len=5 "false" +// watch_let.baml:101:3 (variable) len=1 "x" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/while_loop.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/while_loop.baml index eeab810e3f..4fa1927f38 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/while_loop.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/while_loop.baml @@ -15,18 +15,29 @@ function GCD(a: int, b: int) -> int { // //- semantic_tokens // while_loop.baml:1:1 (keyword) len=8 "function" -// while_loop.baml:1:10 (function) len=3 "GCD" -// while_loop.baml:1:14 (parameter) len=1 "a" -// while_loop.baml:1:17 (type) len=3 "int" -// while_loop.baml:1:22 (parameter) len=1 "b" -// while_loop.baml:1:25 (type) len=3 "int" -// while_loop.baml:1:33 (type) len=3 "int" +// while_loop.baml:1:10 (function) [declaration] len=3 "GCD" +// while_loop.baml:1:14 (parameter) [declaration] len=1 "a" +// while_loop.baml:1:17 (type) [defaultLibrary] len=3 "int" +// while_loop.baml:1:22 (parameter) [declaration] len=1 "b" +// while_loop.baml:1:25 (type) [defaultLibrary] len=3 "int" +// while_loop.baml:1:33 (type) [defaultLibrary] len=3 "int" // while_loop.baml:2:3 (keyword) len=5 "while" +// while_loop.baml:2:10 (parameter) len=1 "a" // while_loop.baml:2:12 (operator) len=2 "!=" +// while_loop.baml:2:15 (parameter) len=1 "b" // while_loop.baml:3:5 (keyword) len=2 "if" +// while_loop.baml:3:9 (parameter) len=1 "a" // while_loop.baml:3:11 (operator) len=1 ">" +// while_loop.baml:3:13 (parameter) len=1 "b" +// while_loop.baml:4:7 (parameter) len=1 "a" // while_loop.baml:4:9 (operator) len=1 "=" +// while_loop.baml:4:11 (parameter) len=1 "a" // while_loop.baml:4:13 (operator) len=1 "-" +// while_loop.baml:4:15 (parameter) len=1 "b" // while_loop.baml:5:7 (keyword) len=4 "else" +// while_loop.baml:6:7 (parameter) len=1 "b" // while_loop.baml:6:9 (operator) len=1 "=" +// while_loop.baml:6:11 (parameter) len=1 "b" // while_loop.baml:6:13 (operator) len=1 "-" +// while_loop.baml:6:15 (parameter) len=1 "a" +// while_loop.baml:9:3 (parameter) len=1 "a" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/with_keyword.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/with_keyword.baml new file mode 100644 index 0000000000..f7f94e55f8 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/with_keyword.baml @@ -0,0 +1,68 @@ +// `with` is a CONTEXTUAL keyword: the runner clause of `spawn`/`test`/`testset` +// (`... with { ... }`) re-lexes it as `KW_WITH`, but it stays an +// ordinary identifier as a variable / field / member name. + +// `with` as a keyword: the test runner clause. (`testset ... with ` and +// `spawn ... with ` re-lex `with` to the same `KW_WITH` token.) +test "test with runner" with testing.Quorum(5, 3) { + let result = "hello" + assert.not_null(result) +} + +// `with` as an ordinary identifier (NOT a keyword): a variable and a field. +class HasWith { + with int +} + +function use_with_as_identifiers() -> int { + let with = 42 + let h = HasWith { with: 1 } + with + h.with +} + +//---- +//- diagnostics +// +// +//- semantic_tokens +// with_keyword.baml:1:1 (comment) len=80 "// `with` is a CONTEXTUAL keyword: the runner clause of `spawn`/`test`/`testset`" +// with_keyword.baml:2:1 (comment) len=74 "// (`... with { ... }`) re-lexes it as `KW_WITH`, but it stays an" +// with_keyword.baml:3:1 (comment) len=59 "// ordinary identifier as a variable / field / member name." +// with_keyword.baml:5:1 (comment) len=80 "// `with` as a keyword: the test runner clause. (`testset ... with ` and" +// with_keyword.baml:6:1 (comment) len=70 "// `spawn ... with ` re-lex `with` to the same `KW_WITH` token.)" +// with_keyword.baml:7:1 (keyword) len=4 "test" +// with_keyword.baml:7:6 (string) len=18 "\"test with runner\"" +// with_keyword.baml:7:25 (keyword) len=4 "with" +// with_keyword.baml:7:30 (namespace) [defaultLibrary] len=7 "testing" +// with_keyword.baml:7:38 (function) len=6 "Quorum" +// with_keyword.baml:7:45 (number) len=1 "5" +// with_keyword.baml:7:48 (number) len=1 "3" +// with_keyword.baml:8:3 (keyword) len=3 "let" +// with_keyword.baml:8:7 (variable) [declaration] len=6 "result" +// with_keyword.baml:8:14 (operator) len=1 "=" +// with_keyword.baml:8:16 (string) len=7 "\"hello\"" +// with_keyword.baml:9:3 (namespace) [defaultLibrary] len=6 "assert" +// with_keyword.baml:9:10 (function) len=8 "not_null" +// with_keyword.baml:9:19 (variable) len=6 "result" +// with_keyword.baml:12:1 (comment) len=76 "// `with` as an ordinary identifier (NOT a keyword): a variable and a field." +// with_keyword.baml:13:1 (keyword) len=5 "class" +// with_keyword.baml:13:7 (class) [declaration] len=7 "HasWith" +// with_keyword.baml:14:3 (property) [declaration] len=4 "with" +// with_keyword.baml:14:8 (type) [defaultLibrary] len=3 "int" +// with_keyword.baml:17:1 (keyword) len=8 "function" +// with_keyword.baml:17:10 (function) [declaration] len=23 "use_with_as_identifiers" +// with_keyword.baml:17:39 (type) [defaultLibrary] len=3 "int" +// with_keyword.baml:18:3 (keyword) len=3 "let" +// with_keyword.baml:18:7 (variable) [declaration] len=4 "with" +// with_keyword.baml:18:12 (operator) len=1 "=" +// with_keyword.baml:18:14 (number) len=2 "42" +// with_keyword.baml:19:3 (keyword) len=3 "let" +// with_keyword.baml:19:7 (variable) [declaration] len=1 "h" +// with_keyword.baml:19:9 (operator) len=1 "=" +// with_keyword.baml:19:11 (class) len=7 "HasWith" +// with_keyword.baml:19:21 (property) len=4 "with" +// with_keyword.baml:19:27 (number) len=1 "1" +// with_keyword.baml:20:3 (variable) len=4 "with" +// with_keyword.baml:20:8 (operator) len=1 "+" +// with_keyword.baml:20:10 (variable) len=1 "h" +// with_keyword.baml:20:12 (property) len=4 "with" diff --git a/baml_language/crates/baml_lsp2_actions_tests/test_files/syntax/hover/catch_binding.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/syntax/hover/catch_binding.baml index af6030962c..d64f4e8b16 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/test_files/syntax/hover/catch_binding.baml +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/syntax/hover/catch_binding.baml @@ -25,5 +25,5 @@ function Handler(x: int) -> string { //- on_hover expressions // hover at hover_catch_binding.baml:15:21 // ```baml -// e: unknown +// e: Errors.AuthError | Errors.NotFoundError // ``` diff --git a/baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap b/baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap index 16041efa64..a5e3d83b7b 100644 --- a/baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap +++ b/baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "BadDefaultInFunctionType" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/broken_syntax/pending_greaters_fix/baml_tests__broken_syntax__pending_greaters_fix__02_parser__extra_greater.snap b/baml_language/crates/baml_tests/snapshots/broken_syntax/pending_greaters_fix/baml_tests__broken_syntax__pending_greaters_fix__02_parser__extra_greater.snap index 9a122f8240..3d0d0a665d 100644 --- a/baml_language/crates/baml_tests/snapshots/broken_syntax/pending_greaters_fix/baml_tests__broken_syntax__pending_greaters_fix__02_parser__extra_greater.snap +++ b/baml_language/crates/baml_tests/snapshots/broken_syntax/pending_greaters_fix/baml_tests__broken_syntax__pending_greaters_fix__02_parser__extra_greater.snap @@ -146,7 +146,7 @@ SOURCE_FILE HASH "#" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "BadAlias" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/broken_syntax/test_invalid_contexts/baml_tests__broken_syntax__test_invalid_contexts__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/broken_syntax/test_invalid_contexts/baml_tests__broken_syntax__test_invalid_contexts__02_parser__main.snap index ec3cdeef50..8758cc3893 100644 --- a/baml_language/crates/baml_tests/snapshots/broken_syntax/test_invalid_contexts/baml_tests__broken_syntax__test_invalid_contexts__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/broken_syntax/test_invalid_contexts/baml_tests__broken_syntax__test_invalid_contexts__02_parser__main.snap @@ -32,7 +32,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" @@ -74,7 +74,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" @@ -98,7 +98,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TESTSET_DEF @@ -131,7 +131,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/broken_syntax/type_annotation_errors/baml_tests__broken_syntax__type_annotation_errors__02_parser__type_malformed.snap b/baml_language/crates/baml_tests/snapshots/broken_syntax/type_annotation_errors/baml_tests__broken_syntax__type_annotation_errors__02_parser__type_malformed.snap index dbec0d22cf..7b3cf76cb9 100644 --- a/baml_language/crates/baml_tests/snapshots/broken_syntax/type_annotation_errors/baml_tests__broken_syntax__type_annotation_errors__02_parser__type_malformed.snap +++ b/baml_language/crates/baml_tests/snapshots/broken_syntax/type_annotation_errors/baml_tests__broken_syntax__type_annotation_errors__02_parser__type_malformed.snap @@ -4,12 +4,12 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "type" TYPE_EXPR "Foo" WORD "Foo" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Bar" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/compiles/config_dictionary/baml_tests__compiles__config_dictionary__02_parser__valid_dictionary.snap b/baml_language/crates/baml_tests/snapshots/compiles/config_dictionary/baml_tests__compiles__config_dictionary__02_parser__valid_dictionary.snap index aeb161ecd1..d91f9a5b07 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/config_dictionary/baml_tests__compiles__config_dictionary__02_parser__valid_dictionary.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/config_dictionary/baml_tests__compiles__config_dictionary__02_parser__valid_dictionary.snap @@ -119,7 +119,7 @@ SOURCE_FILE CONFIG_ITEM WORD "booleanValue" CONFIG_VALUE "true" - WORD "true" + KW_TRUE "true" CONFIG_ITEM WORD "stringKey" CONFIG_VALUE diff --git a/baml_language/crates/baml_tests/snapshots/compiles/json_alias_basic/baml_tests__compiles__json_alias_basic__02_parser__json_alias_basic.snap b/baml_language/crates/baml_tests/snapshots/compiles/json_alias_basic/baml_tests__compiles__json_alias_basic__02_parser__json_alias_basic.snap index 5965365e72..f218ec15bb 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/json_alias_basic/baml_tests__compiles__json_alias_basic__02_parser__json_alias_basic.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/json_alias_basic/baml_tests__compiles__json_alias_basic__02_parser__json_alias_basic.snap @@ -30,7 +30,7 @@ SOURCE_FILE OBJECT_FIELD "data: null" WORD "data" COLON ":" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" FUNCTION_DEF @@ -47,7 +47,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" FUNCTION_DEF KW_FUNCTION "function" @@ -63,7 +63,7 @@ SOURCE_FILE true }" L_BRACE "{" - WORD "true" + KW_TRUE "true" R_BRACE "}" FUNCTION_DEF KW_FUNCTION "function" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/json_map_literal/baml_tests__compiles__json_map_literal__02_parser__json_map_literal.snap b/baml_language/crates/baml_tests/snapshots/compiles/json_map_literal/baml_tests__compiles__json_map_literal__02_parser__json_map_literal.snap index b13d7b1e22..23090b5e6d 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/json_map_literal/baml_tests__compiles__json_map_literal__02_parser__json_map_literal.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/json_map_literal/baml_tests__compiles__json_map_literal__02_parser__json_map_literal.snap @@ -52,7 +52,7 @@ SOURCE_FILE WORD "nested" QUOTE """ COLON ":" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__02_parser__lambda_advanced.snap b/baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__02_parser__lambda_advanced.snap index 14f1399a4d..605d0ae8c1 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__02_parser__lambda_advanced.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__02_parser__lambda_advanced.snap @@ -1117,7 +1117,7 @@ SOURCE_FILE KW_ELSE "else" BLOCK_EXPR "{ null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" CALL_EXPR @@ -2209,7 +2209,7 @@ SOURCE_FILE L_BRACKET "[" INTEGER_LITERAL "1" COMMA "," - WORD "null" + KW_NULL "null" COMMA "," INTEGER_LITERAL "3" R_BRACKET "]" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__02_parser__lexical_scoping.snap b/baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__02_parser__lexical_scoping.snap index 5d068da0da..f55f124938 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__02_parser__lexical_scoping.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__02_parser__lexical_scoping.snap @@ -532,7 +532,7 @@ SOURCE_FILE KW_LET "let" WORD "once" EQUALS "=" - WORD "true" + KW_TRUE "true" SEMICOLON ";" WHILE_STMT KW_WHILE "while" @@ -553,7 +553,7 @@ SOURCE_FILE BINARY_EXPR "once = false" WORD "once" EQUALS "=" - WORD "false" + KW_FALSE "false" SEMICOLON ";" R_BRACE "}" SEMICOLON ";" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap index 87bfe44a81..9ca8bd8948 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 10955 --- === SYNTAX TREE === SOURCE_FILE @@ -23,7 +22,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR "{ 2 }" L_BRACE "{" @@ -104,7 +103,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR "{ 1 }" L_BRACE "{" @@ -123,7 +122,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(false)" L_PAREN "(" - WORD "false" + KW_FALSE "false" R_PAREN ")" BLOCK_EXPR "{ 3 }" L_BRACE "{" @@ -155,7 +154,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR "{ 7 }" L_BRACE "{" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/llm_parse_catchable_parse_error/baml_tests__compiles__llm_parse_catchable_parse_error__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/llm_parse_catchable_parse_error/baml_tests__compiles__llm_parse_catchable_parse_error__02_parser__main.snap index 0def3764ad..ca84649ca9 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/llm_parse_catchable_parse_error/baml_tests__compiles__llm_parse_catchable_parse_error__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/llm_parse_catchable_parse_error/baml_tests__compiles__llm_parse_catchable_parse_error__02_parser__main.snap @@ -142,7 +142,7 @@ SOURCE_FILE WORD "message" R_BRACE "}" FAT_ARROW "=>" - WORD "null" + KW_NULL "null" COMMA "," R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/method_explicit_type_args/baml_tests__compiles__method_explicit_type_args__02_parser__method_explicit_type_args.snap b/baml_language/crates/baml_tests/snapshots/compiles/method_explicit_type_args/baml_tests__compiles__method_explicit_type_args__02_parser__method_explicit_type_args.snap index 410322f649..d48a1c5c26 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/method_explicit_type_args/baml_tests__compiles__method_explicit_type_args__02_parser__method_explicit_type_args.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/method_explicit_type_args/baml_tests__compiles__method_explicit_type_args__02_parser__method_explicit_type_args.snap @@ -33,7 +33,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" FUNCTION_DEF diff --git a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__main.snap index 29690731b7..31709a965d 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__main.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 13711 --- === SYNTAX TREE === SOURCE_FILE @@ -42,7 +41,7 @@ SOURCE_FILE WORD "Pending" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ConfigAlias" EQUALS "=" TYPE_EXPR "Config" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_auth_auth.snap b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_auth_auth.snap index 333fd56a73..c9fe220dad 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_auth_auth.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_auth_auth.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 13750 --- === SYNTAX TREE === SOURCE_FILE @@ -55,7 +54,7 @@ SOURCE_FILE WORD "Role" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TokenAlias" EQUALS "=" TYPE_EXPR "Token" @@ -263,7 +262,7 @@ SOURCE_FILE OBJECT_FIELD "expired: true" WORD "expired" COLON ":" - WORD "true" + KW_TRUE "true" R_BRACE "}" COMMA "," MATCH_ARM diff --git a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_llm_models.snap b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_llm_models.snap index 39438ff0e7..1618f4ab34 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_llm_models.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/namespaces_type_resolution/baml_tests__compiles__namespaces_type_resolution__02_parser__ns_llm_models.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 13789 --- === SYNTAX TREE === SOURCE_FILE @@ -64,13 +63,13 @@ SOURCE_FILE WORD "int" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ConfigAlias" EQUALS "=" TYPE_EXPR "Config" WORD "Config" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ResponseAlias" EQUALS "=" TYPE_EXPR "Response" @@ -275,7 +274,7 @@ SOURCE_FILE OBJECT_FIELD "retryable: true" WORD "retryable" COLON ":" - WORD "true" + KW_TRUE "true" R_BRACE "}" COMMA "," MATCH_ARM diff --git a/baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap index b9fc0792d5..5eb90912d3 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap @@ -1,11 +1,10 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 18292 --- === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Searcher" EQUALS "=" TYPE_EXPR @@ -27,7 +26,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NarrowSearcher" EQUALS "=" TYPE_EXPR @@ -148,7 +147,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" COMMA "," PARAMETER WORD "chunk_size" @@ -351,7 +350,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" R_PAREN ")" ARROW "->" TYPE_EXPR "int" @@ -366,7 +365,7 @@ SOURCE_FILE BINARY_EXPR "filter == null" WORD "filter" EQUALS_EQUALS "==" - WORD "null" + KW_NULL "null" R_PAREN ")" BLOCK_EXPR "{ max_results @@ -528,7 +527,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" R_PAREN ")" ARROW "->" TYPE_EXPR "string[]" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap index 60822278e2..01c7f18f8f 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 15330 --- === SYNTAX TREE === SOURCE_FILE @@ -73,12 +72,12 @@ SOURCE_FILE WORD "d" EQUALS "=" BINARY_EXPR - WORD "true" + KW_TRUE "true" OR_OR "||" BINARY_EXPR "false && false" - WORD "false" + KW_FALSE "false" AND_AND "&&" - WORD "false" + KW_FALSE "false" SEMICOLON ";" RETURN_STMT "// Should be true (AND before OR) diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__break_continue.snap b/baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__break_continue.snap index 3af72b089d..443b8ba455 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__break_continue.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__break_continue.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 16268 --- === SYNTAX TREE === SOURCE_FILE @@ -20,7 +19,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -50,7 +49,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -176,7 +175,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -184,7 +183,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -217,7 +216,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -233,7 +232,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -273,7 +272,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" @@ -289,7 +288,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap b/baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap index 0218e0f6b3..6646806136 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap @@ -1002,7 +1002,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Number" EQUALS "=" TYPE_EXPR "int | float" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/stream_crossfile/baml_tests__compiles__stream_crossfile__02_parser__file_a.snap b/baml_language/crates/baml_tests/snapshots/compiles/stream_crossfile/baml_tests__compiles__stream_crossfile__02_parser__file_a.snap index 10151045fd..7e33992cdc 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/stream_crossfile/baml_tests__compiles__stream_crossfile__02_parser__file_a.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/stream_crossfile/baml_tests__compiles__stream_crossfile__02_parser__file_a.snap @@ -32,7 +32,7 @@ SOURCE_FILE WORD "PhD" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "EducationList" EQUALS "=" TYPE_EXPR "Education[]" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap index ab9daba9e4..3cb3697913 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap @@ -28,7 +28,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" TESTSET_DEF KW_TESTSET "testset" @@ -54,7 +54,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_raw_string_name/baml_tests__compiles__test_raw_string_name__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/test_raw_string_name/baml_tests__compiles__test_raw_string_name__02_parser__main.snap index adfd78f398..d841f60465 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_raw_string_name/baml_tests__compiles__test_raw_string_name__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_raw_string_name/baml_tests__compiles__test_raw_string_name__02_parser__main.snap @@ -24,7 +24,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TEST_EXPR_DEF @@ -50,7 +50,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TESTSET_DEF @@ -87,7 +87,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/testset_basic/baml_tests__compiles__testset_basic__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/testset_basic/baml_tests__compiles__testset_basic__02_parser__main.snap index 3f07ff5855..466608b7e4 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/testset_basic/baml_tests__compiles__testset_basic__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/testset_basic/baml_tests__compiles__testset_basic__02_parser__main.snap @@ -28,7 +28,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TEST_EXPR_DEF @@ -47,7 +47,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/testset_dynamic/baml_tests__compiles__testset_dynamic__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/testset_dynamic/baml_tests__compiles__testset_dynamic__02_parser__main.snap index 687b18b804..8df8ccfb70 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/testset_dynamic/baml_tests__compiles__testset_dynamic__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/testset_dynamic/baml_tests__compiles__testset_dynamic__02_parser__main.snap @@ -85,7 +85,7 @@ SOURCE_FILE KW_LET "let" WORD "run_slow" EQUALS "=" - WORD "false" + KW_FALSE "false" TEST_EXPR_DEF KW_TEST "test" STRING_LITERAL "always runs" @@ -103,7 +103,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" IF_EXPR @@ -132,7 +132,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/testset_nested/baml_tests__compiles__testset_nested__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/compiles/testset_nested/baml_tests__compiles__testset_nested__02_parser__main.snap index 502d3075ba..e02defef44 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/testset_nested/baml_tests__compiles__testset_nested__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/testset_nested/baml_tests__compiles__testset_nested__02_parser__main.snap @@ -38,7 +38,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" @@ -68,7 +68,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_alias_interaction.snap b/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_alias_interaction.snap index a90704dc36..40843096f4 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_alias_interaction.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_alias_interaction.snap @@ -4,13 +4,13 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MetaAlias" EQUALS "=" TYPE_EXPR "type" WORD "type" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MetaList" EQUALS "=" TYPE_EXPR "type[]" @@ -18,7 +18,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MetaUnion" EQUALS "=" TYPE_EXPR "type | string" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_positions.snap b/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_positions.snap index 364727dd08..29c5183d96 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_positions.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/type_annotation/baml_tests__compiles__type_annotation__02_parser__type_positions.snap @@ -139,7 +139,7 @@ SOURCE_FILE WORD "type" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" SEMICOLON ";" RETURN_STMT KW_RETURN "return" diff --git a/baml_language/crates/baml_tests/snapshots/compiles/type_builder_test/baml_tests__compiles__type_builder_test__02_parser__test.snap b/baml_language/crates/baml_tests/snapshots/compiles/type_builder_test/baml_tests__compiles__type_builder_test__02_parser__test.snap index a9e64c17ee..dbb7f7eacf 100644 --- a/baml_language/crates/baml_tests/snapshots/compiles/type_builder_test/baml_tests__compiles__type_builder_test__02_parser__test.snap +++ b/baml_language/crates/baml_tests/snapshots/compiles/type_builder_test/baml_tests__compiles__type_builder_test__02_parser__test.snap @@ -107,7 +107,7 @@ SOURCE_FILE WORD "Q" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MyAlias" EQUALS "=" TYPE_EXPR "string | int" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/attr_disambiguation/baml_tests__diagnostic_errors__attr_disambiguation__02_parser__non_field.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/attr_disambiguation/baml_tests__diagnostic_errors__attr_disambiguation__02_parser__non_field.snap index d17ad98873..d49034bc91 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/attr_disambiguation/baml_tests__diagnostic_errors__attr_disambiguation__02_parser__non_field.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/attr_disambiguation/baml_tests__diagnostic_errors__attr_disambiguation__02_parser__non_field.snap @@ -40,7 +40,7 @@ SOURCE_FILE WORD "int" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "E1" EQUALS "=" TYPE_EXPR @@ -56,7 +56,7 @@ SOURCE_FILE QUOTE """ R_PAREN ")" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "E2" EQUALS "=" TYPE_EXPR @@ -67,7 +67,7 @@ SOURCE_FILE DOT "." WORD "done" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "E3" EQUALS "=" TYPE_EXPR @@ -88,7 +88,7 @@ SOURCE_FILE DOT "." WORD "done" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "E4" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/backtick_strict_types/baml_tests__diagnostic_errors__backtick_strict_types__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/backtick_strict_types/baml_tests__diagnostic_errors__backtick_strict_types__02_parser__main.snap index 2b62802beb..eadf91112d 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/backtick_strict_types/baml_tests__diagnostic_errors__backtick_strict_types__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/backtick_strict_types/baml_tests__diagnostic_errors__backtick_strict_types__02_parser__main.snap @@ -27,7 +27,7 @@ SOURCE_FILE WORD "int" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" BACKTICK_STRING_LITERAL BACKTICK "`" WORD "val" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/basic_types/baml_tests__diagnostic_errors__basic_types__02_parser__types.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/basic_types/baml_tests__diagnostic_errors__basic_types__02_parser__types.snap index 66b1015e8a..364f3030dd 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/basic_types/baml_tests__diagnostic_errors__basic_types__02_parser__types.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/basic_types/baml_tests__diagnostic_errors__basic_types__02_parser__types.snap @@ -30,7 +30,7 @@ SOURCE_FILE WORD "Inactive" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Role" EQUALS "=" TYPE_EXPR @@ -49,7 +49,7 @@ SOURCE_FILE WORD "system" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalRole" EQUALS "=" TYPE_EXPR @@ -59,7 +59,7 @@ SOURCE_FILE QUOTE """ QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "RoleList" EQUALS "=" TYPE_EXPR @@ -70,7 +70,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalRoleList" EQUALS "=" TYPE_EXPR @@ -82,21 +82,21 @@ SOURCE_FILE R_BRACKET "]" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalCode" EQUALS "=" TYPE_EXPR "200?" INTEGER_LITERAL "200" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalFlag" EQUALS "=" TYPE_EXPR "true?" WORD "true" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedList" EQUALS "=" TYPE_EXPR @@ -110,7 +110,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedMap" EQUALS "=" TYPE_EXPR @@ -126,7 +126,7 @@ SOURCE_FILE WORD "string" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnionOfArrays" EQUALS "=" TYPE_EXPR "int[] | string[]" @@ -138,7 +138,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ReallyLongMapType" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__io_ops.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__io_ops.snap index 3f9586a2d1..cc12107dba 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__io_ops.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__io_ops.snap @@ -57,7 +57,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__shell_ops.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__shell_ops.snap index 0fadf77321..0421e7a363 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__shell_ops.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/builtin_io/baml_tests__diagnostic_errors__builtin_io__02_parser__shell_ops.snap @@ -33,7 +33,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" DOT "." WORD "stdout" @@ -77,7 +77,7 @@ SOURCE_FILE WORD "cmd" COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" DOT "." WORD "stdout" @@ -116,7 +116,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" SEMICOLON ";" LET_STMT @@ -141,7 +141,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" SEMICOLON ";" BINARY_EXPR @@ -191,7 +191,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" DOT "." WORD "exit_code" @@ -227,7 +227,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" DOT "." WORD "ok" @@ -273,7 +273,7 @@ SOURCE_FILE R_BRACKET "]" COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" R_PAREN ")" DOT "." WORD "stdout" @@ -307,7 +307,7 @@ SOURCE_FILE QUOTE """ COMMA "," CALL_ARG "null" - WORD "null" + KW_NULL "null" COMMA "," CALL_ARG OBJECT_LITERAL diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_arm_braceless_return/baml_tests__diagnostic_errors__catch_arm_braceless_return__02_parser__repro.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_arm_braceless_return/baml_tests__diagnostic_errors__catch_arm_braceless_return__02_parser__repro.snap index 3fb55309b8..03bbd6c684 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_arm_braceless_return/baml_tests__diagnostic_errors__catch_arm_braceless_return__02_parser__repro.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_arm_braceless_return/baml_tests__diagnostic_errors__catch_arm_braceless_return__02_parser__repro.snap @@ -43,7 +43,7 @@ SOURCE_FILE WORD "boom" QUOTE """ R_BRACE "}" - WORD "true" + KW_TRUE "true" R_BRACE "}" FUNCTION_DEF KW_FUNCTION "function" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_return_type_mismatch/baml_tests__diagnostic_errors__catch_return_type_mismatch__02_parser__catch_return_type_mismatch.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_return_type_mismatch/baml_tests__diagnostic_errors__catch_return_type_mismatch__02_parser__catch_return_type_mismatch.snap index 59b003a29f..77f9f253f7 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_return_type_mismatch/baml_tests__diagnostic_errors__catch_return_type_mismatch__02_parser__catch_return_type_mismatch.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/catch_return_type_mismatch/baml_tests__diagnostic_errors__catch_return_type_mismatch__02_parser__catch_return_type_mismatch.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 27541 --- === SYNTAX TREE === SOURCE_FILE @@ -35,7 +34,7 @@ SOURCE_FILE L_BRACE "{" RETURN_STMT "return true" KW_RETURN "return" - WORD "true" + KW_TRUE "true" R_BRACE "}" FUNCTION_DEF KW_FUNCTION "function" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/duplicate_class_span/baml_tests__diagnostic_errors__duplicate_class_span__02_parser__repro.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/duplicate_class_span/baml_tests__diagnostic_errors__duplicate_class_span__02_parser__repro.snap index 937041f814..4f05ab0ebc 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/duplicate_class_span/baml_tests__diagnostic_errors__duplicate_class_span__02_parser__repro.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/duplicate_class_span/baml_tests__diagnostic_errors__duplicate_class_span__02_parser__repro.snap @@ -22,7 +22,7 @@ SOURCE_FILE WORD "string" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "A" EQUALS "=" TYPE_EXPR "int" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap index 3cc2001eb2..44191a471a 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap @@ -108,12 +108,12 @@ SOURCE_FILE BINARY_EXPR "flag && true" WORD "flag" AND_AND "&&" - WORD "true" + KW_TRUE "true" SEMICOLON ";" BINARY_EXPR "flag || false" WORD "flag" OR_OR "||" - WORD "false" + KW_FALSE "false" SEMICOLON ";" BINARY_EXPR "a & b" WORD "a" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap index 6e46bf7c8e..f8f2a44ed9 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap @@ -316,7 +316,7 @@ SOURCE_FILE CONFIG_ITEM WORD "stream" CONFIG_VALUE "true" - WORD "true" + KW_TRUE "true" R_BRACE "}" R_BRACE "}" CLIENT_DEF @@ -527,7 +527,7 @@ SOURCE_FILE CONFIG_ITEM WORD "stream" CONFIG_VALUE "true" - WORD "true" + KW_TRUE "true" CONFIG_ITEM WORD "stop" CONFIG_VALUE @@ -717,7 +717,7 @@ llm /* 6 type trailing */ CONFIG_ITEM WORD "retry_on_failure" CONFIG_VALUE "true" - WORD "true" + KW_TRUE "true" CONFIG_ITEM WORD "timeout_ms" CONFIG_VALUE "30000" @@ -881,7 +881,7 @@ llm /* 6 type trailing */ CONFIG_ITEM WORD "stream" CONFIG_VALUE "true" - WORD "true" + KW_TRUE "true" CONFIG_ITEM WORD "stop_sequences" CONFIG_VALUE @@ -1522,7 +1522,7 @@ llm /* 4 type trailing */ WORD "Q" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "InnerAlias" EQUALS "=" TYPE_EXPR "string | int" @@ -1625,7 +1625,7 @@ llm /* 4 type trailing */ WORD "AnotherVeryLongVariantName" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "VeryLongTypeAliasNameThatExceedsLimit" EQUALS "=" TYPE_EXPR "int | string | bool | float | null | int[] | string[]" @@ -1693,7 +1693,7 @@ llm /* 4 type trailing */ WORD "X" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TbAlias" EQUALS "=" TYPE_EXPR "// 42 equals trailing @@ -1749,7 +1749,7 @@ llm /* 4 type trailing */ WORD "X" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TbAliasBlock" EQUALS "=" TYPE_EXPR "/* 42 equals trailing */ diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__loop_stmts.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__loop_stmts.snap index 508d2f37e9..85ace410aa 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__loop_stmts.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__loop_stmts.snap @@ -80,7 +80,7 @@ SOURCE_FILE KW_WHILE "while" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__match_exprs.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__match_exprs.snap index c27b31f9cc..f466bbf159 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__match_exprs.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__match_exprs.snap @@ -44,7 +44,7 @@ SOURCE_FILE WORD "Pending" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MatchResult" EQUALS "=" TYPE_EXPR "MatchSuccess | MatchFailure" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap index d142fb7f31..24f164f77c 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap @@ -127,11 +127,11 @@ SOURCE_FILE WORD "expressions" QUOTE """ SEMICOLON ";" - WORD "true" + KW_TRUE "true" SEMICOLON ";" - WORD "false" + KW_FALSE "false" SEMICOLON ";" - WORD "null" + KW_NULL "null" SEMICOLON ";" RAW_STRING_LITERAL HASH "#" @@ -336,7 +336,7 @@ SOURCE_FILE SEMICOLON ";" UNARY_EXPR "!true" NOT "!" - WORD "true" + KW_TRUE "true" SEMICOLON ";" UNARY_EXPR MINUS "-" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap index 4e83d4cade..5ce8c6deff 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap @@ -4,25 +4,25 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "SimpleAlias" EQUALS "=" TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AliasChain" EQUALS "=" TYPE_EXPR "SimpleAlias" WORD "SimpleAlias" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Name" EQUALS "=" TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Role" EQUALS "=" TYPE_EXPR @@ -41,19 +41,19 @@ SOURCE_FILE WORD "system" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "HttpOk" EQUALS "=" TYPE_EXPR "200" INTEGER_LITERAL "200" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AlwaysTrue" EQUALS "=" TYPE_EXPR "true" WORD "true" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "SuccessCode" EQUALS "=" TYPE_EXPR "200 | 201 | 204" @@ -63,7 +63,7 @@ SOURCE_FILE PIPE "|" INTEGER_LITERAL "204" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedLiterals" EQUALS "=" TYPE_EXPR @@ -76,14 +76,14 @@ SOURCE_FILE PIPE "|" WORD "true" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MaybeInt" EQUALS "=" TYPE_EXPR "int?" WORD "int" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "IntList" EQUALS "=" TYPE_EXPR "int[]" @@ -91,7 +91,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Matrix" EQUALS "=" TYPE_EXPR "int[][]" @@ -101,7 +101,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "StringMap" EQUALS "=" TYPE_EXPR @@ -115,7 +115,7 @@ SOURCE_FILE WORD "int" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ComplexMap" EQUALS "=" TYPE_EXPR @@ -133,7 +133,7 @@ SOURCE_FILE WORD "bool" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NestedMap" EQUALS "=" TYPE_EXPR @@ -157,7 +157,7 @@ SOURCE_FILE GREATER ">" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ParenUnion" EQUALS "=" TYPE_EXPR @@ -171,7 +171,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalUnion" EQUALS "=" TYPE_EXPR @@ -184,7 +184,7 @@ SOURCE_FILE R_PAREN ")" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Json" EQUALS "=" TYPE_EXPR @@ -212,7 +212,7 @@ SOURCE_FILE WORD "Json" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "IntToInt" EQUALS "=" TYPE_EXPR @@ -227,7 +227,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "BinaryOp" EQUALS "=" TYPE_EXPR @@ -248,7 +248,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnnamedParams" EQUALS "=" TYPE_EXPR @@ -265,7 +265,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Producer" EQUALS "=" TYPE_EXPR @@ -275,7 +275,7 @@ SOURCE_FILE TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Curried" EQUALS "=" TYPE_EXPR @@ -299,7 +299,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ComplexFn" EQUALS "=" TYPE_EXPR @@ -331,7 +331,7 @@ SOURCE_FILE WORD "string" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnionParamFn" EQUALS "=" TYPE_EXPR @@ -348,7 +348,7 @@ SOURCE_FILE TYPE_EXPR "bool" WORD "bool" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "FnFactory" EQUALS "=" TYPE_EXPR @@ -370,7 +370,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "LongUnion" EQUALS "=" TYPE_EXPR @@ -434,7 +434,7 @@ SOURCE_FILE WORD "lima" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "WideUnion" EQUALS "=" TYPE_EXPR @@ -480,7 +480,7 @@ SOURCE_FILE WORD "string" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ThisIsAnExtremelyLongTypeAliasNameThatDefinitelyExceedsLimit" EQUALS "=" TYPE_EXPR "int | string | bool | float | null" @@ -494,7 +494,7 @@ SOURCE_FILE PIPE "|" WORD "null" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "VeryLongNamePlusLongUnion" EQUALS "=" TYPE_EXPR @@ -543,7 +543,7 @@ SOURCE_FILE WORD "india" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DeepGeneric" EQUALS "=" TYPE_EXPR @@ -589,7 +589,7 @@ SOURCE_FILE GREATER ">" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DeepFnType" EQUALS "=" TYPE_EXPR @@ -643,7 +643,7 @@ SOURCE_FILE WORD "bool" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "LongParamFn" EQUALS "=" TYPE_EXPR @@ -694,7 +694,7 @@ SOURCE_FILE TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NestedParenUnion" EQUALS "=" TYPE_EXPR @@ -720,7 +720,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DeepParenUnion" EQUALS "=" TYPE_EXPR @@ -761,7 +761,7 @@ SOURCE_FILE R_BRACKET "]" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Tree" EQUALS "=" TYPE_EXPR @@ -805,7 +805,7 @@ SOURCE_FILE GREATER ">" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalArray" EQUALS "=" TYPE_EXPR "int?[]" @@ -814,7 +814,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ArrayOptional" EQUALS "=" TYPE_EXPR "int[]?" @@ -823,7 +823,7 @@ SOURCE_FILE R_BRACKET "]" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DoubleOptional" EQUALS "=" TYPE_EXPR "int??" @@ -831,7 +831,7 @@ SOURCE_FILE QUESTION "?" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DoubleArray" EQUALS "=" TYPE_EXPR "int[][]" @@ -841,7 +841,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ComplexPostfix" EQUALS "=" TYPE_EXPR @@ -858,7 +858,7 @@ SOURCE_FILE L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DeepPostfix" EQUALS "=" TYPE_EXPR @@ -902,7 +902,7 @@ SOURCE_FILE WORD "string" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Result" EQUALS "=" TYPE_EXPR "TypeAliasSuccess | TypeAliasFailure" @@ -910,14 +910,14 @@ SOURCE_FILE PIPE "|" WORD "TypeAliasFailure" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MaybeResult" EQUALS "=" TYPE_EXPR "Result?" WORD "Result" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaAlias" EQUALS "=" TYPE_EXPR "// 6 equals trailing @@ -925,7 +925,7 @@ SOURCE_FILE int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaAliasBlock" EQUALS "=" TYPE_EXPR "/* 6 equals trailing */ @@ -933,7 +933,7 @@ int" int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaUnion" EQUALS "=" TYPE_EXPR "// 1 first member leading @@ -952,7 +952,7 @@ int" PIPE "|" WORD "bool" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaUnionBlock" EQUALS "=" TYPE_EXPR "/* 1 first member leading */ @@ -971,7 +971,7 @@ int" PIPE "|" WORD "bool" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaLongUnion" EQUALS "=" TYPE_EXPR @@ -1015,7 +1015,7 @@ int" WORD "hotel" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaLongUnionBlock" EQUALS "=" TYPE_EXPR @@ -1059,7 +1059,7 @@ int" WORD "hotel" QUOTE """ TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaGeneric" EQUALS "=" TYPE_EXPR @@ -1077,7 +1077,7 @@ int" WORD "int" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaGenericBlock" EQUALS "=" TYPE_EXPR @@ -1095,7 +1095,7 @@ int" WORD "int" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaDeepGeneric" EQUALS "=" TYPE_EXPR @@ -1138,7 +1138,7 @@ int" GREATER ">" GREATER ">" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaFnType" EQUALS "=" TYPE_EXPR @@ -1157,7 +1157,7 @@ int" string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaFnTypeBlock" EQUALS "=" TYPE_EXPR @@ -1176,7 +1176,7 @@ int" string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaLongFnType" EQUALS "=" TYPE_EXPR @@ -1229,7 +1229,7 @@ int" string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaOptional" EQUALS "=" TYPE_EXPR "int // 1 base type trailing @@ -1238,7 +1238,7 @@ int" WORD "int" QUESTION "?" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaArray" EQUALS "=" TYPE_EXPR "int // 1 base type trailing @@ -1250,7 +1250,7 @@ int" L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "TriviaParen" EQUALS "=" TYPE_EXPR @@ -1269,13 +1269,13 @@ int" L_BRACKET "[" R_BRACKET "]" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "T" EQUALS "=" TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ExtraWhitespace" EQUALS "=" TYPE_EXPR "int | string | bool | float | null" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap index c0de8372a4..e09a3ac4e9 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "HiddenHandler" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap index e2f97f145f..fc1828a5bd 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "IntToInt" EQUALS "=" TYPE_EXPR @@ -19,7 +19,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "BinaryOp" EQUALS "=" TYPE_EXPR @@ -40,7 +40,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnnamedParams" EQUALS "=" TYPE_EXPR @@ -57,7 +57,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedParams" EQUALS "=" TYPE_EXPR @@ -82,7 +82,7 @@ SOURCE_FILE TYPE_EXPR "bool" WORD "bool" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Producer" EQUALS "=" TYPE_EXPR @@ -92,7 +92,7 @@ SOURCE_FILE TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Curried" EQUALS "=" TYPE_EXPR @@ -116,7 +116,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Complex" EQUALS "=" TYPE_EXPR @@ -174,7 +174,7 @@ SOURCE_FILE INTEGER_LITERAL "1" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnionParam" EQUALS "=" TYPE_EXPR @@ -191,7 +191,7 @@ SOURCE_FILE TYPE_EXPR "bool" WORD "bool" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "FunctionFactory" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/generics/baml_tests__diagnostic_errors__generics__02_parser__classes.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/generics/baml_tests__diagnostic_errors__generics__02_parser__classes.snap index 998ab08a37..75e07c1721 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/generics/baml_tests__diagnostic_errors__generics__02_parser__classes.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/generics/baml_tests__diagnostic_errors__generics__02_parser__classes.snap @@ -1078,7 +1078,7 @@ SOURCE_FILE OBJECT_FIELD "value: null" WORD "value" COLON ":" - WORD "null" + KW_NULL "null" R_BRACE "}" CALL_EXPR PATH_EXPR "b.get_or_default" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/headers_edge_cases/baml_tests__diagnostic_errors__headers_edge_cases__02_parser__edge_cases.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/headers_edge_cases/baml_tests__diagnostic_errors__headers_edge_cases__02_parser__edge_cases.snap index 4bc9acdc92..ce38c8f620 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/headers_edge_cases/baml_tests__diagnostic_errors__headers_edge_cases__02_parser__edge_cases.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/headers_edge_cases/baml_tests__diagnostic_errors__headers_edge_cases__02_parser__edge_cases.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 32534 --- === SYNTAX TREE === SOURCE_FILE @@ -324,7 +323,7 @@ SOURCE_FILE KW_IF "if" PAREN_EXPR "(true)" L_PAREN "(" - WORD "true" + KW_TRUE "true" R_PAREN ")" BLOCK_EXPR L_BRACE "{" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/match_exhaustiveness/baml_tests__diagnostic_errors__match_exhaustiveness__02_parser__match_exhaustiveness.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/match_exhaustiveness/baml_tests__diagnostic_errors__match_exhaustiveness__02_parser__match_exhaustiveness.snap index 1f4720d3b8..f2d4c4de80 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/match_exhaustiveness/baml_tests__diagnostic_errors__match_exhaustiveness__02_parser__match_exhaustiveness.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/match_exhaustiveness/baml_tests__diagnostic_errors__match_exhaustiveness__02_parser__match_exhaustiveness.snap @@ -356,7 +356,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Result" EQUALS "=" TYPE_EXPR "Success | Failure" @@ -815,7 +815,7 @@ SOURCE_FILE WORD "int" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "FullResult" EQUALS "=" TYPE_EXPR "Success | Failure | Pending" @@ -1262,19 +1262,19 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AlwaysTrue" EQUALS "=" TYPE_EXPR "true" WORD "true" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AlwaysFalse" EQUALS "=" TYPE_EXPR "false" WORD "false" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "CustomBool" EQUALS "=" TYPE_EXPR "true | false" @@ -1573,7 +1573,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Role" EQUALS "=" TYPE_EXPR @@ -1835,19 +1835,19 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "HttpOk" EQUALS "=" TYPE_EXPR "200" INTEGER_LITERAL "200" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "HttpCreated" EQUALS "=" TYPE_EXPR "201" INTEGER_LITERAL "201" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "SuccessCode" EQUALS "=" TYPE_EXPR "200 | 201 | 204" @@ -2050,7 +2050,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MaybeResult" EQUALS "=" TYPE_EXPR "Result?" @@ -2564,7 +2564,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MaybeOk" EQUALS "=" TYPE_EXPR "200?" @@ -2689,7 +2689,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedLiterals" EQUALS "=" TYPE_EXPR @@ -2816,13 +2816,13 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OkCode" EQUALS "=" TYPE_EXPR "200" INTEGER_LITERAL "200" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OkOrCreated" EQUALS "=" TYPE_EXPR "OkCode | 201" @@ -2911,7 +2911,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "DoubleMaybe" EQUALS "=" TYPE_EXPR "MaybeResult?" @@ -3449,7 +3449,7 @@ SOURCE_FILE R_BRACE "}" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "SuccessOr200" EQUALS "=" TYPE_EXPR "Success | 200" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/null_handling/baml_tests__diagnostic_errors__null_handling__02_parser__null_handling.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/null_handling/baml_tests__diagnostic_errors__null_handling__02_parser__null_handling.snap index 566c75cca8..232ae8bc9a 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/null_handling/baml_tests__diagnostic_errors__null_handling__02_parser__null_handling.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/null_handling/baml_tests__diagnostic_errors__null_handling__02_parser__null_handling.snap @@ -1214,7 +1214,7 @@ SOURCE_FILE WORD "name" QUESTION "?" QUESTION "?" - WORD "null" + KW_NULL "null" SEMICOLON ";" LET_STMT PATTERN diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap index f17a1c8515..53db57a615 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap @@ -33,7 +33,7 @@ SOURCE_FILE QUOTE """ HASH "#" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NamedFilter" EQUALS "=" TYPE_EXPR @@ -56,7 +56,7 @@ SOURCE_FILE TYPE_EXPR "int" WORD "int" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NamedLimit" EQUALS "=" TYPE_EXPR @@ -94,7 +94,7 @@ SOURCE_FILE PARAMETER "self = null" WORD "self" EQUALS "=" - WORD "null" + KW_NULL "null" R_PAREN ")" ARROW "->" TYPE_EXPR "int" @@ -170,7 +170,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" R_PAREN ")" ARROW "->" TYPE_EXPR "int" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__array_constructor.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__array_constructor.snap index 733f7e6ca0..06c0b59775 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__array_constructor.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__array_constructor.snap @@ -110,11 +110,11 @@ SOURCE_FILE L_BRACE "{" ARRAY_LITERAL "[true, false, true]" L_BRACKET "[" - WORD "true" + KW_TRUE "true" COMMA "," - WORD "false" + KW_FALSE "false" COMMA "," - WORD "true" + KW_TRUE "true" R_BRACKET "]" R_BRACE "}" FUNCTION_DEF diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__map_constructor.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__map_constructor.snap index 4c6a445a25..3fa85fd2d9 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__map_constructor.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/parser_constructors/baml_tests__diagnostic_errors__parser_constructors__02_parser__map_constructor.snap @@ -154,7 +154,7 @@ SOURCE_FILE WORD "hello" QUOTE """ COLON ":" - WORD "true" + KW_TRUE "true" COMMA "," OBJECT_FIELD STRING_LITERAL "test" @@ -162,7 +162,7 @@ SOURCE_FILE KW_TEST "test" QUOTE """ COLON ":" - WORD "false" + KW_FALSE "false" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/self_in_body/baml_tests__diagnostic_errors__self_in_body__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/self_in_body/baml_tests__diagnostic_errors__self_in_body__02_parser__main.snap index 3ec5bdd248..3c461c11f2 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/self_in_body/baml_tests__diagnostic_errors__self_in_body__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/self_in_body/baml_tests__diagnostic_errors__self_in_body__02_parser__main.snap @@ -393,7 +393,7 @@ SOURCE_FILE EQUALS "=" WORD "other" SEMICOLON ";" - WORD "true" + KW_TRUE "true" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__complex.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__complex.snap index 1fd6ce7184..a28b3e5f5e 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__complex.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__complex.snap @@ -24,7 +24,7 @@ SOURCE_FILE WORD "int" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "StringAlias" EQUALS "=" TYPE_EXPR "string" @@ -83,7 +83,7 @@ SOURCE_FILE WORD "string" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AliasToClass" EQUALS "=" TYPE_EXPR "Inner" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__main.snap index cb1794fac1..97226bfc6f 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__main.snap @@ -227,19 +227,19 @@ SOURCE_FILE QUESTION "?" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "SimpleAlias" EQUALS "=" TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ClassAlias" EQUALS "=" TYPE_EXPR "Inner" WORD "Inner" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "UnionAlias" EQUALS "=" TYPE_EXPR "int | Inner" @@ -247,7 +247,7 @@ SOURCE_FILE PIPE "|" WORD "Inner" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "OptionalAlias" EQUALS "=" TYPE_EXPR "Inner?" @@ -279,7 +279,7 @@ SOURCE_FILE WORD "int" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "AliasedType" EQUALS "=" TYPE_EXPR "string | int" @@ -429,7 +429,7 @@ SOURCE_FILE GREATER ">" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "MixedType" EQUALS "=" TYPE_EXPR "int | Education" @@ -487,7 +487,7 @@ SOURCE_FILE GREATER ">" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Foo" EQUALS "=" TYPE_EXPR "int | string" @@ -495,7 +495,7 @@ SOURCE_FILE PIPE "|" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Bar" EQUALS "=" TYPE_EXPR "Foo | bool" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__ns_foo_with_top_level_refs.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__ns_foo_with_top_level_refs.snap index d4dae086f8..c5a89f9203 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__ns_foo_with_top_level_refs.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/stream_types/baml_tests__diagnostic_errors__stream_types__02_parser__ns_foo_with_top_level_refs.snap @@ -22,7 +22,7 @@ SOURCE_FILE WORD "Beta" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "NsAlias" EQUALS "=" TYPE_EXPR "string | int" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__02_parser__main.snap index c4882eeedd..8b8cdd69e9 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__02_parser__main.snap @@ -1,6 +1,5 @@ --- source: crates/baml_tests/src/generated_tests.rs -assertion_line: 37935 --- === SYNTAX TREE === SOURCE_FILE @@ -17,7 +16,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" TEST_EXPR_DEF KW_TEST "test" @@ -26,7 +25,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" TESTSET_DEF KW_TESTSET "testset" @@ -69,7 +68,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap index 4fb0e7b674..892c2dda45 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap @@ -23,7 +23,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TEST_EXPR_DEF @@ -51,7 +51,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TESTSET_DEF @@ -82,7 +82,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_with_runner_ambiguity/baml_tests__diagnostic_errors__test_with_runner_ambiguity__02_parser__main.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_with_runner_ambiguity/baml_tests__diagnostic_errors__test_with_runner_ambiguity__02_parser__main.snap index df5350d628..db4b37e2e1 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_with_runner_ambiguity/baml_tests__diagnostic_errors__test_with_runner_ambiguity__02_parser__main.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_with_runner_ambiguity/baml_tests__diagnostic_errors__test_with_runner_ambiguity__02_parser__main.snap @@ -22,7 +22,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" TEST_EXPR_DEF @@ -56,7 +56,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" CLASS_DEF @@ -94,7 +94,7 @@ SOURCE_FILE CALL_ARGS L_PAREN "(" CALL_ARG "true" - WORD "true" + KW_TRUE "true" R_PAREN ")" R_BRACE "}" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases.snap index ec9fef8fa5..4f251efce1 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases.snap @@ -4,13 +4,13 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "foo" EQUALS "=" TYPE_EXPR "bar" WORD "bar" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "bar" EQUALS "=" TYPE_EXPR "int" @@ -45,10 +45,10 @@ SOURCE_FILE true }" L_BRACE "{" - WORD "true" + KW_TRUE "true" R_BRACE "}" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Json" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases_json.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases_json.snap index 754ca9892e..61f8f9f167 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases_json.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/type_aliases/baml_tests__diagnostic_errors__type_aliases__02_parser__type_aliases_json.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "JSON" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/unknown_type_error/baml_tests__diagnostic_errors__unknown_type_error__02_parser__unknown_type_error.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/unknown_type_error/baml_tests__diagnostic_errors__unknown_type_error__02_parser__unknown_type_error.snap index bf7df327ac..c207d2a142 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/unknown_type_error/baml_tests__diagnostic_errors__unknown_type_error__02_parser__unknown_type_error.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/unknown_type_error/baml_tests__diagnostic_errors__unknown_type_error__02_parser__unknown_type_error.snap @@ -55,7 +55,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" ENUM_DEF KW_ENUM "enum" diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap index 0c542ce479..8317bd1b1c 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ExplicitHandler" EQUALS "=" TYPE_EXPR @@ -23,7 +23,7 @@ SOURCE_FILE TYPE_EXPR "never" WORD "never" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "ImplicitHandler" EQUALS "=" TYPE_EXPR @@ -38,7 +38,7 @@ SOURCE_FILE TYPE_EXPR "string" WORD "string" TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "HiddenHandler" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap index 1614cbe90f..311e9d61ed 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap @@ -4,7 +4,7 @@ source: crates/baml_tests/src/generated_tests.rs === SYNTAX TREE === SOURCE_FILE TYPE_ALIAS_DEF - WORD "type" + KW_TYPE "type" WORD "Callback" EQUALS "=" TYPE_EXPR diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_type_position_errors.snap b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_type_position_errors.snap index aa8d36477e..060a14cb00 100644 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_type_position_errors.snap +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_type_position_errors.snap @@ -98,7 +98,7 @@ SOURCE_FILE null }" L_BRACE "{" - WORD "null" + KW_NULL "null" R_BRACE "}" FUNCTION_DEF KW_FUNCTION "function" diff --git a/baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs b/baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs index 23a61a1a1d..6de2fdd98e 100644 --- a/baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs +++ b/baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs @@ -38,6 +38,13 @@ struct LiveProject { rebuild_epoch: std::sync::atomic::AtomicU64, } +/// Per-file `result_id` + last-sent encoded token array, keyed by file path. +type SemanticTokensCache = std::sync::Arc< + std::sync::Mutex< + std::collections::HashMap)>, + >, +>; + #[derive(Clone)] struct BexMulitProject { projects: @@ -60,6 +67,13 @@ struct BexMulitProject { fs: crate::fs::BamlVFS, spawner: BackgroundSpawner, + + /// Per-file cache of the last semantic tokens returned (its `result_id` and + /// the encoded token array), so `semanticTokens/full/delta` can reply with + /// only the changed edits instead of the whole array. + semantic_tokens_cache: SemanticTokensCache, + /// Monotonic source of semantic-token `result_id`s. + semantic_tokens_seq: std::sync::Arc, } pub trait LspClientSenderTrait { @@ -116,6 +130,10 @@ impl BexMulitProject { workspace_roots: std::sync::Arc::new(std::sync::Mutex::new(Vec::new())), fs, spawner, + semantic_tokens_cache: std::sync::Arc::new(std::sync::Mutex::new( + std::collections::HashMap::new(), + )), + semantic_tokens_seq: std::sync::Arc::new(std::sync::atomic::AtomicU64::new(0)), } } diff --git a/baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs b/baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs index f283b75c13..7a0178ea11 100644 --- a/baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs +++ b/baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs @@ -44,10 +44,13 @@ pub(super) fn server_capabilities() -> ServerCapabilities { .iter() .map(|t| lsp_types::SemanticTokenType::new(t.as_str())) .collect(), - token_modifiers: vec![], + token_modifiers: baml_lsp2_actions::TOKEN_MODIFIERS + .iter() + .map(|name| lsp_types::SemanticTokenModifier::new(name)) + .collect(), }, - full: Some(SemanticTokensFullOptions::Bool(true)), - range: None, + full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }), + range: Some(true), ..Default::default() }, )), @@ -316,42 +319,97 @@ impl BexLspRequest for BexMulitProject { // Get the semantic tokens using compiler2 (hybrid CST + type-aware). // Always returns tokens in document order. let tokens = baml_lsp2_actions::semantic_tokens(lsp_db, source_file); + let lsp_tokens = encode_semantic_tokens(&tokens, text); + let result_id = self.cache_semantic_tokens(&path, lsp_tokens.clone()); - // Convert to LSP delta-encoded format - let line_index = baml_project::position::LineIndex::new(text); - let mut lsp_tokens = Vec::with_capacity(tokens.len()); - let mut prev_line = 0u32; - let mut prev_start = 0u32; - - for token in &tokens { - let start_offset: u32 = token.range.start().into(); - let end_offset: u32 = token.range.end().into(); - let length = end_offset - start_offset; + Ok(Some(lsp_types::SemanticTokensResult::Tokens( + lsp_types::SemanticTokens { + result_id: Some(result_id), + data: lsp_tokens, + }, + ))) + } - let Some(pos) = line_index.offset_to_position(start_offset) else { - continue; - }; + /// Incremental semantic tokens — rust-analyzer's `full/delta`. Diffs the new + /// token array against the cached one for the client's `previous_result_id` + /// and returns just the edits; falls back to the full set on a cache miss. + fn on_request_text_document_semantic_tokens_full_delta( + &self, + params: lsp_request_params!("textDocument/semanticTokens/full/delta"), + ) -> Result { + let path = self.get_path_from_uri(¶ms.text_document.uri)?; + let root_path = Self::get_baml_project_root(&path)?; + let project_handle = self.get_or_create_project(root_path)?; - let delta_line = pos.line - prev_line; - let delta_start = if delta_line == 0 { - pos.character - prev_start - } else { - pos.character - }; + let project = project_handle.project.try_lock_db()?; + let lsp_db = project.db(); + let Some(source_file) = lsp_db.get_file(std::path::Path::new(path.as_str())) else { + return Ok(None); + }; + let text = source_file.text(lsp_db); - lsp_tokens.push(lsp_types::SemanticToken { - delta_line, - delta_start, - length, - token_type: token.token_type.legend_index(), - token_modifiers_bitset: 0, - }); + let tokens = baml_lsp2_actions::semantic_tokens(lsp_db, source_file); + let new_tokens = encode_semantic_tokens(&tokens, text); + + // The previous token array iff its result_id matches what the client holds. + let key = crate::fs::FsPath::from_vfs(&path); + let prev = { + let cache = self.semantic_tokens_cache.lock().unwrap(); + cache + .get(&key) + .filter(|(id, _)| *id == params.previous_result_id) + .map(|(_, toks)| toks.clone()) + }; + let result_id = self.cache_semantic_tokens(&path, new_tokens.clone()); - prev_line = pos.line; - prev_start = pos.character; + match prev { + Some(prev_tokens) => Ok(Some(lsp_types::SemanticTokensFullDeltaResult::TokensDelta( + lsp_types::SemanticTokensDelta { + result_id: Some(result_id), + edits: diff_semantic_tokens(&prev_tokens, &new_tokens), + }, + ))), + None => Ok(Some(lsp_types::SemanticTokensFullDeltaResult::Tokens( + lsp_types::SemanticTokens { + result_id: Some(result_id), + data: new_tokens, + }, + ))), } + } - Ok(Some(lsp_types::SemanticTokensResult::Tokens( + /// Viewport semantic tokens — rust-analyzer's `highlight_range`. Resolves + /// only the scopes the requested range touches. + fn on_request_text_document_semantic_tokens_range( + &self, + params: lsp_request_params!("textDocument/semanticTokens/range"), + ) -> Result { + let path = self.get_path_from_uri(¶ms.text_document.uri)?; + let root_path = Self::get_baml_project_root(&path)?; + let project_handle = self.get_or_create_project(root_path)?; + + let project = project_handle.project.try_lock_db()?; + let lsp_db = project.db(); + let Some(source_file) = lsp_db.get_file(std::path::Path::new(path.as_str())) else { + return Ok(None); + }; + let text = source_file.text(lsp_db); + + let start = u32::try_from(baml_project::position::lsp_position_to_offset( + text, + ¶ms.range.start, + )) + .unwrap_or(u32::MAX); + let end = u32::try_from(baml_project::position::lsp_position_to_offset( + text, + ¶ms.range.end, + )) + .unwrap_or(u32::MAX); + let tokens = + baml_lsp2_actions::tokens::semantic_tokens_in_range(lsp_db, source_file, start, end); + let lsp_tokens = encode_semantic_tokens(&tokens, text); + + Ok(Some(lsp_types::SemanticTokensRangeResult::Tokens( lsp_types::SemanticTokens { result_id: None, data: lsp_tokens, @@ -853,6 +911,119 @@ impl BexLspRequest for BexMulitProject { } } +/// Delta-encode semantic tokens into the LSP wire format (relative line/start, +/// legend indices). Shared by the `full` and `range` requests. +fn encode_semantic_tokens( + tokens: &[baml_lsp2_actions::tokens::SemanticToken], + text: &str, +) -> Vec { + let line_index = baml_project::position::LineIndex::new(text); + let mut out = Vec::with_capacity(tokens.len()); + let mut prev_line = 0u32; + let mut prev_start = 0u32; + for token in tokens { + let start_offset: u32 = token.range.start().into(); + let end_offset: u32 = token.range.end().into(); + let length = end_offset - start_offset; + let Some(pos) = line_index.offset_to_position(start_offset) else { + continue; + }; + let delta_line = pos.line - prev_line; + let delta_start = if delta_line == 0 { + pos.character - prev_start + } else { + pos.character + }; + out.push(lsp_types::SemanticToken { + delta_line, + delta_start, + length, + token_type: token.token_type.legend_index(), + token_modifiers_bitset: token.modifiers.bits(), + }); + prev_line = pos.line; + prev_start = pos.character; + } + out +} + +/// Minimal single-edit diff of two encoded token arrays (rust-analyzer's +/// approach): trim the common prefix and suffix at token granularity and +/// replace only the differing middle. `start`/`delete_count` are offsets into +/// the flat LSP `u32` stream (5 integers per token), so they scale by 5. +fn diff_semantic_tokens( + prev: &[lsp_types::SemanticToken], + new: &[lsp_types::SemanticToken], +) -> Vec { + let mut p = 0; + while p < prev.len() && p < new.len() && prev[p] == new[p] { + p += 1; + } + let mut s = 0; + while s < prev.len() - p + && s < new.len() - p + && prev[prev.len() - 1 - s] == new[new.len() - 1 - s] + { + s += 1; + } + let deleted = prev.len() - p - s; + let data = new[p..new.len() - s].to_vec(); + if deleted == 0 && data.is_empty() { + return Vec::new(); + } + vec![lsp_types::SemanticTokensEdit { + start: u32::try_from(p * 5).unwrap_or(u32::MAX), + delete_count: u32::try_from(deleted * 5).unwrap_or(u32::MAX), + data: Some(data), + }] +} + +#[cfg(test)] +mod semantic_tokens_delta_tests { + use super::diff_semantic_tokens; + + fn tok(line: u32) -> lsp_types::SemanticToken { + lsp_types::SemanticToken { + delta_line: line, + delta_start: 0, + length: 1, + token_type: 0, + token_modifiers_bitset: 0, + } + } + + #[test] + fn identical_yields_no_edits() { + let a = vec![tok(1), tok(2), tok(3)]; + assert!(diff_semantic_tokens(&a, &a).is_empty()); + } + + #[test] + fn middle_replacement_scales_by_five() { + let edits = diff_semantic_tokens(&[tok(1), tok(2), tok(3)], &[tok(1), tok(9), tok(3)]); + assert_eq!(edits.len(), 1); + assert_eq!(edits[0].start, 5); // one unchanged leading token + assert_eq!(edits[0].delete_count, 5); // one token replaced + assert_eq!(edits[0].data.as_ref().unwrap(), &[tok(9)]); + } + + #[test] + fn append_is_pure_insert() { + let edits = diff_semantic_tokens(&[tok(1)], &[tok(1), tok(2)]); + assert_eq!(edits[0].start, 5); + assert_eq!(edits[0].delete_count, 0); + assert_eq!(edits[0].data.as_ref().unwrap(), &[tok(2)]); + } + + #[test] + fn truncate_is_pure_delete() { + let edits = diff_semantic_tokens(&[tok(1), tok(2)], &[tok(1)]); + assert_eq!(edits[0].start, 5); + assert_eq!(edits[0].delete_count, 5); + assert!(edits[0].data.as_ref().unwrap().is_empty()); + } +} + /// Convert a compiler2 `DefinitionKind` to an LSP `SymbolKind`. /// /// Used by the `textDocument/documentSymbol` and `workspace/symbol` handlers @@ -888,6 +1059,24 @@ fn compute_line_starts(source: &str) -> Vec { } impl BexMulitProject { + /// Store `tokens` as the latest semantic tokens for `path` under a fresh + /// `result_id`, returning that id so the next `full/delta` can diff against it. + fn cache_semantic_tokens( + &self, + path: &vfs::VfsPath, + tokens: Vec, + ) -> String { + let id = self + .semantic_tokens_seq + .fetch_add(1, std::sync::atomic::Ordering::Relaxed) + .to_string(); + self.semantic_tokens_cache + .lock() + .unwrap() + .insert(crate::fs::FsPath::from_vfs(path), (id.clone(), tokens)); + id + } + fn compute_on_position( &self, params: &lsp_types::TextDocumentPositionParams, diff --git a/baml_language/crates/tools_semantic_tokens/Cargo.toml b/baml_language/crates/tools_semantic_tokens/Cargo.toml new file mode 100644 index 0000000000..08e6ed2c00 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "tools_semantic_tokens" +version = { workspace = true } +publish = false +authors = { workspace = true } +edition = { workspace = true } + +[[bin]] +name = "tools_semantic_tokens" +path = "src/main.rs" + +[dependencies] +baml_lsp2_actions = { workspace = true } +baml_lsp2_actions_tests = { workspace = true } +baml_project = { workspace = true } +anyhow = { workspace = true } +axum = { workspace = true, features = [ "json" ] } +clap = { workspace = true, features = [ "derive" ] } +serde = { workspace = true, features = [ "derive" ] } +serde_json = { workspace = true } +tokio = { workspace = true, features = [ "rt", "macros", "net" ] } + +[lints] +workspace = true + +[package.metadata.ci] +wasm_support = false diff --git a/baml_language/crates/tools_semantic_tokens/README.md b/baml_language/crates/tools_semantic_tokens/README.md new file mode 100644 index 0000000000..8a4c4bbacc --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/README.md @@ -0,0 +1,40 @@ +# tools_semantic_tokens + +A local web viewer for BAML **semantic tokens** — the LSP-style, type-aware +classification produced by `baml_lsp2_actions::semantic_tokens`. It is the +semantic-token analog of `typescript2/pkg-grammar`'s grammar-preview app, but +because semantic tokens are computed by the Rust compiler (not a portable +TextMate grammar) this tool embeds the compiler directly instead of running in +the browser. + +```sh +cargo run -p tools_semantic_tokens +# semantic-tokens viewer -> http://127.0.0.1:4319 +``` + +It opens a browser (pass `--no-open` to skip) with: + +- **Fixtures** — every `*.baml` under + `crates/baml_lsp2_actions_tests/test_files/semantic_tokens/`. Each is shown + side-by-side: **Current** (live tokens) vs **Expected snapshot** (the committed + `//- semantic_tokens` block), with changed/added/removed tokens underlined and + a per-fixture diff badge in the sidebar. **Accept snapshot** rewrites the + fixture exactly as `UPDATE_EXPECT=1 cargo test` would. +- **Scratchpad** — paste arbitrary BAML and see live tokens (no snapshot). + +Hover any token to inspect its type; the legend maps every token type to its +color. + +## Flags + +- `--port ` preferred port (falls back to the next free port; default 4319) +- `--fixtures-dir ` browse a different directory of `*.baml` fixtures +- `--no-open` don't launch a browser + +## How it works + +The tool reuses the inline-assertion test harness +(`baml_lsp2_actions_tests::{parser, runner, updater}`) so the token output, the +parsed expectations, and "accept" are identical to the Rust tests — there is no +second implementation to drift. Rendering assumes ASCII source (token positions +are byte offsets); the committed fixtures are ASCII. diff --git a/baml_language/crates/tools_semantic_tokens/src/analysis.rs b/baml_language/crates/tools_semantic_tokens/src/analysis.rs new file mode 100644 index 0000000000..19b8020021 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/analysis.rs @@ -0,0 +1,288 @@ +//! Semantic-token computation and reconciliation against committed test +//! expectations. +//! +//! The viewer needs three things per fixture: +//! 1. the BAML source (the part before the `//----` separator), +//! 2. the *current* tokens — what `semantic_tokens` produces today, and +//! 3. the *expected* tokens — the committed `//- semantic_tokens` block. +//! +//! (1) and (3) come from the test harness parser; (2) is recomputed live with +//! the same `ProjectDatabase` + `semantic_tokens` call the LSP and tests use. +//! "Accept" goes through the real `runner::run_test` + `updater::update_test_file` +//! path, so it is byte-for-byte what `UPDATE_EXPECT=1 cargo test` would write. + +use std::{collections::HashMap, fs, path::Path}; + +use baml_lsp2_actions::semantic_tokens; +use baml_lsp2_actions_tests::{parser, runner, updater}; +use baml_project::ProjectDatabase; +use serde::Serialize; + +/// One classified token. +/// +/// Positioned redundantly: `line`/`col`/`len` (1-based, byte columns) match the +/// snapshot format and key the diff; `start`/`end` are absolute byte offsets the +/// frontend uses to slice the source when rendering. +#[derive(Serialize, Clone)] +pub(crate) struct Token { + pub(crate) line: usize, + pub(crate) col: usize, + pub(crate) len: usize, + #[serde(rename = "type")] + pub(crate) ty: String, + pub(crate) mods: Vec, + pub(crate) text: String, + pub(crate) start: usize, + pub(crate) end: usize, +} + +/// A fixture's source plus its current and committed-expected token sets. +pub(crate) struct Fixture { + pub(crate) source: String, + pub(crate) current: Vec, + pub(crate) expected: Vec, +} + +/// Replicates `runner::offset_to_line_col`: 1-based line, 1-based byte column. +fn offset_to_line_col(content: &str, offset: usize) -> (usize, usize) { + let clamped = offset.min(content.len()); + let safe = (0..=clamped) + .rev() + .find(|&i| content.is_char_boundary(i)) + .unwrap_or(0); + let before = &content[..safe]; + let line = before.matches('\n').count() + 1; + let last_newline = before.rfind('\n').map_or(0, |p| p + 1); + (line, safe - last_newline + 1) +} + +/// Byte offset of the start of each line (index 0 == line 1). +fn line_start_offsets(source: &str) -> Vec { + let mut offsets = vec![0usize]; + for (i, byte) in source.bytes().enumerate() { + if byte == b'\n' { + offsets.push(i + 1); + } + } + offsets +} + +/// UTF-16 code-unit offset of `byte_offset` within `source`. +/// +/// The frontend slices the source as a JS string (UTF-16), so render positions +/// must be UTF-16 offsets — not byte offsets — or non-ASCII source (e.g. an +/// em-dash in a comment) shifts every later token's coloring. +fn utf16_offset(source: &str, byte_offset: usize) -> usize { + let clamped = byte_offset.min(source.len()); + let safe = (0..=clamped) + .rev() + .find(|&i| source.is_char_boundary(i)) + .unwrap_or(0); + source[..safe].encode_utf16().count() +} + +/// Compute live semantic tokens for an arbitrary BAML source string. +pub(crate) fn compute_tokens(source: &str) -> Vec { + let mut db = ProjectDatabase::new(); + db.set_project_root(Path::new(".")); + let file = db.add_or_update_file(Path::new("scratch.baml"), source); + + let mut tokens = semantic_tokens(&db, file); + tokens.sort_by_key(|t| t.range.start()); + + tokens + .iter() + .map(|t| { + let start: usize = t.range.start().into(); + let end: usize = t.range.end().into(); + let (line, col) = offset_to_line_col(source, start); + Token { + line, + col, + len: end - start, + ty: t.token_type.as_str().to_string(), + mods: t.modifiers.names().map(str::to_string).collect(), + text: source.get(start..end).unwrap_or_default().to_string(), + start: utf16_offset(source, start), + end: utf16_offset(source, end), + } + }) + .collect() +} + +/// Parse a committed `//- semantic_tokens` block back into tokens. +/// +/// Each line looks like: `// name.baml:LINE:COL (type) len=N "text"`. We rebuild +/// absolute byte offsets from LINE/COL against `source` so the expected pane can +/// render the same way the current pane does. +fn parse_expected(block: &str, source: &str) -> Vec { + let line_starts = line_start_offsets(source); + let mut out = Vec::new(); + + for raw in block.lines() { + let line = raw.trim_start(); + let line = line.strip_prefix("//").unwrap_or(line).trim_start(); + + let Some(paren) = line.find(" (") else { + continue; + }; + let loc = &line[..paren]; + let rest = &line[paren + 2..]; + let Some(close) = rest.find(')') else { + continue; + }; + let ty = rest[..close].to_string(); + let after = &rest[close + 1..]; + + // Optional ` [mod,mod]` modifier list precedes ` len=`. + let mods = after + .find('[') + .zip(after.find(']')) + .filter(|&(open, end)| open < end && open < after.find("len=").unwrap_or(usize::MAX)) + .map(|(open, end)| { + after[open + 1..end] + .split(',') + .map(|s| s.trim().to_string()) + .filter(|s| !s.is_empty()) + .collect() + }) + .unwrap_or_default(); + + // `loc` is `name:LINE:COL`; take the last two colon-separated numbers. + let mut nums = loc.rsplit(':'); + let col: usize = nums.next().and_then(|s| s.parse().ok()).unwrap_or(0); + let lineno: usize = nums.next().and_then(|s| s.parse().ok()).unwrap_or(0); + + let len = after + .find("len=") + .map(|i| { + after[i + 4..] + .chars() + .take_while(char::is_ascii_digit) + .collect::() + }) + .and_then(|s| s.parse::().ok()) + .unwrap_or(0); + + let text = after + .find('"') + .and_then(|i| after.rfind('"').filter(|&j| j > i).map(|j| (i, j))) + .map(|(i, j)| after[i + 1..j].to_string()) + .unwrap_or_default(); + + if lineno == 0 || col == 0 { + continue; + } + let start_byte = line_starts.get(lineno - 1).copied().unwrap_or(0) + (col - 1); + out.push(Token { + line: lineno, + col, + len, + ty, + mods, + text, + start: utf16_offset(source, start_byte), + end: utf16_offset(source, start_byte + len), + }); + } + + out +} + +/// Read a fixture and compute its source + current + expected token sets. +pub(crate) fn load_fixture(path: &Path) -> std::io::Result { + let content = fs::read_to_string(path)?.replace("\r\n", "\n"); + let filename = path + .file_name() + .map(|n| n.to_string_lossy().into_owned()) + .unwrap_or_else(|| "fixture.baml".to_string()); + + let parsed = parser::parse_test_file(&content, &filename); + // Semantic-token fixtures are single-file; take the first virtual file. + let source = parsed + .files + .values() + .next() + .map(|f| f.content.clone()) + .ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + format!("no virtual file parsed from fixture {}", path.display()), + ) + })?; + + let current = compute_tokens(&source); + let expected = parsed + .expected_semantic_tokens + .as_deref() + .map(|block| parse_expected(block, &source)) + .unwrap_or_default(); + + Ok(Fixture { + source, + current, + expected, + }) +} + +/// Number of tokens that differ between current and expected (changed type, +/// modifiers, or lexeme; added; or removed), keyed by (line, col, len) to match +/// the snapshot. The lexeme is compared so a same-length rename that keeps its +/// classification still counts as a diff (otherwise accept would silently +/// rewrite the committed line while the viewer showed zero diffs). +pub(crate) fn diff_count(current: &[Token], expected: &[Token]) -> usize { + let key = |t: &Token| (t.line, t.col, t.len); + // The committed block stores each lexeme in Rust debug form (escaped, no + // outer quotes), so escape `current` the same way before comparing. + let cur_sig = |t: &Token| { + let dbg = format!("{:?}", t.text); + ( + t.ty.clone(), + t.mods.clone(), + dbg[1..dbg.len() - 1].to_string(), + ) + }; + // `expected` lexemes were parsed straight out of that debug form already. + let exp_sig = |t: &Token| (t.ty.clone(), t.mods.clone(), t.text.clone()); + let cur: HashMap<_, _> = current.iter().map(|t| (key(t), cur_sig(t))).collect(); + let exp: HashMap<_, _> = expected.iter().map(|t| (key(t), exp_sig(t))).collect(); + + let mut diff = 0; + for (k, v) in &cur { + if exp.get(k) != Some(v) { + diff += 1; + } + } + for k in exp.keys() { + if !cur.contains_key(k) { + diff += 1; + } + } + diff +} + +/// Rewrite a fixture's expectation block to match current output, exactly as +/// `UPDATE_EXPECT=1 cargo test` would (regenerates every `//-` section). +pub(crate) fn accept_fixture(path: &Path) -> anyhow::Result<()> { + let content = fs::read_to_string(path)?.replace("\r\n", "\n"); + let filename = path + .file_name() + .map(|n| n.to_string_lossy().into_owned()) + .unwrap_or_else(|| "fixture.baml".to_string()); + + let parsed = parser::parse_test_file(&content, &filename); + let result = runner::run_test(&parsed); + updater::update_test_file(path, &content, &result)?; + Ok(()) +} + +/// List `*.baml` fixture file names in `dir`, sorted. +pub(crate) fn list_fixture_names(dir: &Path) -> std::io::Result> { + let mut names: Vec = fs::read_dir(dir)? + .filter_map(Result::ok) + .filter(|entry| entry.path().extension().and_then(|s| s.to_str()) == Some("baml")) + .map(|entry| entry.file_name().to_string_lossy().into_owned()) + .collect(); + names.sort(); + Ok(names) +} diff --git a/baml_language/crates/tools_semantic_tokens/src/index.html b/baml_language/crates/tools_semantic_tokens/src/index.html new file mode 100644 index 0000000000..7cb8ed5921 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/index.html @@ -0,0 +1,552 @@ + + + + + BAML semantic tokens + + + + +
+
BAML semantic tokens
+ No selection + +
+
+ +
+
+
+
+
+
+
+
+ + + diff --git a/baml_language/crates/tools_semantic_tokens/src/main.rs b/baml_language/crates/tools_semantic_tokens/src/main.rs new file mode 100644 index 0000000000..d782de3e80 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/main.rs @@ -0,0 +1,111 @@ +//! Local web viewer for BAML semantic tokens. +//! +//! A dev tool (sibling to `tools_sap_visualizer` / `tools_onionskin`) that serves +//! the `pkg-grammar`-style preview for *semantic* tokens instead of `TextMate` +//! scopes. Because semantic tokens are computed by the Rust compiler (not a +//! portable grammar), this tool embeds the compiler directly and serves a small +//! web UI — no VS Code, no playground, no node toolchain. +//! +//! `cargo run -p tools_semantic_tokens` +//! +//! Browse the committed `semantic_tokens` test fixtures (diff current vs the +//! expected snapshot, accept to rewrite it), or use the scratchpad to paste +//! arbitrary BAML and see live tokens. + +// Dev CLI: it prints the local URL to stdout (workspace lints deny print_*). +#![allow(clippy::print_stdout, clippy::print_stderr)] + +mod analysis; +mod server; +mod staleness; + +use std::{ + net::SocketAddr, + path::PathBuf, + sync::{Arc, atomic::AtomicBool}, +}; + +use anyhow::Result; +use clap::Parser; +use tokio::net::TcpListener; + +#[derive(Parser, Debug)] +#[command( + about = "Web viewer for BAML semantic tokens (dev tool)", + long_about = None, +)] +struct Args { + /// Preferred port; the next free port is used if it is taken. + #[arg(long, default_value_t = 4319)] + port: u16, + + /// Directory of `*.baml` semantic-token fixtures to browse. + #[arg(long)] + fixtures_dir: Option, + + /// Do not try to open a browser on startup. + #[arg(long)] + no_open: bool, +} + +/// The committed semantic-token fixtures, located relative to this crate so the +/// tool works regardless of the current working directory. +fn default_fixtures_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../baml_lsp2_actions_tests/test_files/semantic_tokens") +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<()> { + let args = Args::parse(); + let fixtures_dir = args.fixtures_dir.unwrap_or_else(default_fixtures_dir); + + let (listener, port) = bind(args.port).await?; + let url = format!("http://127.0.0.1:{port}"); + + println!("semantic-tokens viewer -> {url}"); + println!("fixtures: {}", fixtures_dir.display()); + + if !args.no_open { + open_browser(&url); + } + + // Auto-rebuild + restart when the classifier or viewer source changes. + let started_exe_mtime = staleness::exe_mtime(); + let rebuilding = Arc::new(AtomicBool::new(false)); + staleness::spawn_watcher(started_exe_mtime, rebuilding.clone()); + + axum::serve( + listener, + server::router(fixtures_dir, started_exe_mtime, rebuilding), + ) + .await?; + Ok(()) +} + +/// Bind to `base`, falling back to the next free port within a small range. +async fn bind(base: u16) -> Result<(TcpListener, u16)> { + for port in base..=base.saturating_add(49) { + let addr = SocketAddr::from(([127, 0, 0, 1], port)); + if let Ok(listener) = TcpListener::bind(addr).await { + return Ok((listener, port)); + } + } + anyhow::bail!("no free port in {base}..={}", base.saturating_add(49)) +} + +/// Best-effort open the default browser; failure is silently ignored. +fn open_browser(url: &str) { + let command = if cfg!(target_os = "macos") { + Some("open") + } else if cfg!(target_os = "windows") { + Some("explorer") + } else if cfg!(target_os = "linux") { + Some("xdg-open") + } else { + None + }; + if let Some(command) = command { + let _ = std::process::Command::new(command).arg(url).spawn(); + } +} diff --git a/baml_language/crates/tools_semantic_tokens/src/server.rs b/baml_language/crates/tools_semantic_tokens/src/server.rs new file mode 100644 index 0000000000..b898fabde9 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/server.rs @@ -0,0 +1,212 @@ +//! Axum HTTP surface for the semantic-token viewer. +//! +//! Mirrors the pkg-grammar preview's vite middleware: list fixtures, fetch one +//! fixture's source + tokens, tokenize ad-hoc input, and accept a fixture's +//! snapshot. The frontend is a single embedded HTML page (no node build step). + +use std::{ + path::{Path, PathBuf}, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, + time::SystemTime, +}; + +use axum::{ + Json, Router, + extract::{Query, State}, + http::StatusCode, + response::Html, + routing::{get, post}, +}; +use serde::{Deserialize, Serialize}; + +use crate::{ + analysis::{self, Token}, + staleness, +}; + +#[derive(Clone)] +pub(crate) struct AppState { + fixtures_dir: Arc, + /// mtime of this binary when the server started — identifies this build. + started_exe_mtime: Option, + /// Set by the watcher while a rebuild is in flight. + rebuilding: Arc, +} + +pub(crate) fn router( + fixtures_dir: PathBuf, + started_exe_mtime: Option, + rebuilding: Arc, +) -> Router { + let state = AppState { + fixtures_dir: Arc::from(fixtures_dir), + started_exe_mtime, + rebuilding, + }; + Router::new() + .route("/", get(index)) + .route("/api/status", get(status)) + .route("/api/fixtures", get(fixtures)) + .route("/api/fixture", get(fixture)) + .route("/api/tokens", post(tokens)) + .route("/api/accept", post(accept)) + .with_state(state) +} + +#[derive(Serialize)] +struct StatusResponse { + /// Identifies this build; the frontend reloads when it changes (restart). + build_id: u64, + /// Whether a rebuild is currently running. + rebuilding: bool, +} + +async fn status(State(state): State) -> Json { + Json(StatusResponse { + build_id: staleness::build_id(state.started_exe_mtime), + rebuilding: state.rebuilding.load(Ordering::Relaxed), + }) +} + +type ApiError = (StatusCode, String); + +async fn index() -> Html<&'static str> { + Html(include_str!("index.html")) +} + +#[derive(Serialize)] +struct FixtureSummary { + name: String, + diff_count: usize, +} + +#[derive(Serialize)] +struct FixturesResponse { + fixtures: Vec, +} + +async fn fixtures(State(state): State) -> Result, ApiError> { + let dir = state.fixtures_dir.as_ref(); + let names = analysis::list_fixture_names(dir) + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + + // Each fixture builds its own ProjectDatabase + runs the compiler, so compute + // the diff badges in parallel (one thread per fixture) rather than serially. + let summaries = std::thread::scope(|scope| { + let handles: Vec<_> = names + .iter() + .map(|name| { + scope.spawn(move || { + let diff_count = analysis::load_fixture(&dir.join(name)) + .map(|fx| analysis::diff_count(&fx.current, &fx.expected)) + .unwrap_or(0); + FixtureSummary { + name: name.clone(), + diff_count, + } + }) + }) + .collect(); + handles + .into_iter() + .map(|h| h.join().expect("fixture summary thread panicked")) + .collect() + }); + + Ok(Json(FixturesResponse { + fixtures: summaries, + })) +} + +#[derive(Deserialize)] +struct NameQuery { + name: String, +} + +#[derive(Serialize)] +struct FixtureResponse { + source: String, + current: Vec, + expected: Vec, +} + +async fn fixture( + State(state): State, + Query(query): Query, +) -> Result, ApiError> { + let path = resolve_fixture(&state.fixtures_dir, &query.name)?; + let fx = analysis::load_fixture(&path) + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + Ok(Json(FixtureResponse { + source: fx.source, + current: fx.current, + expected: fx.expected, + })) +} + +#[derive(Deserialize)] +struct SourceBody { + source: String, +} + +#[derive(Serialize)] +struct TokensResponse { + tokens: Vec, +} + +async fn tokens(Json(body): Json) -> Json { + Json(TokensResponse { + tokens: analysis::compute_tokens(&body.source), + }) +} + +#[derive(Deserialize)] +struct AcceptBody { + name: String, +} + +#[derive(Serialize)] +struct AcceptResponse { + ok: bool, +} + +async fn accept( + State(state): State, + Json(body): Json, +) -> Result, ApiError> { + let path = resolve_fixture(&state.fixtures_dir, &body.name)?; + analysis::accept_fixture(&path) + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + Ok(Json(AcceptResponse { ok: true })) +} + +/// Resolve a fixture name to a path, rejecting traversal and non-`.baml` names. +fn resolve_fixture(dir: &Path, name: &str) -> Result { + let is_basename = Path::new(name).file_name().map(|f| f.to_string_lossy()) + == Some(std::borrow::Cow::Borrowed(name)); + let is_baml = Path::new(name) + .extension() + .is_some_and(|ext| ext.eq_ignore_ascii_case("baml")); + if !is_basename || !is_baml { + return Err((StatusCode::BAD_REQUEST, "invalid fixture name".to_string())); + } + let root = dir + .canonicalize() + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + let path = dir.join(name); + let meta = std::fs::symlink_metadata(&path) + .map_err(|_| (StatusCode::NOT_FOUND, "unknown fixture".to_string()))?; + if meta.file_type().is_symlink() { + return Err((StatusCode::BAD_REQUEST, "invalid fixture name".to_string())); + } + let path = path + .canonicalize() + .map_err(|_| (StatusCode::NOT_FOUND, "unknown fixture".to_string()))?; + if !path.starts_with(&root) || !path.is_file() { + return Err((StatusCode::NOT_FOUND, "unknown fixture".to_string())); + } + Ok(path) +} diff --git a/baml_language/crates/tools_semantic_tokens/src/staleness.rs b/baml_language/crates/tools_semantic_tokens/src/staleness.rs new file mode 100644 index 0000000000..65b56d2b69 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/staleness.rs @@ -0,0 +1,122 @@ +//! Self-restart on source change. +//! +//! The classifier (`baml_lsp2_actions`) and this viewer are compiled into the +//! binary, so editing them leaves a running viewer stale until rebuilt. A +//! background watcher compares the running binary's mtime against those source +//! trees; when newer, it rebuilds and re-execs itself. The frontend polls +//! [`build_id`] and reloads when it changes. + +use std::{ + path::Path, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + +/// On-disk mtime of the running binary. +pub(crate) fn exe_mtime() -> Option { + std::env::current_exe() + .ok() + .and_then(|p| std::fs::metadata(p).ok()) + .and_then(|m| m.modified().ok()) +} + +/// A stable id for the running build (its binary mtime in epoch millis), so the +/// frontend can detect a restart and reload. +pub(crate) fn build_id(started: Option) -> u64 { + started + .and_then(|t| t.duration_since(UNIX_EPOCH).ok()) + .map_or(0, |d| u64::try_from(d.as_millis()).unwrap_or(u64::MAX)) +} + +/// Newest mtime among the viewer, the classifier (`baml_lsp2_actions`), and the +/// compiler crates the classifier depends on for token output. +fn newest_source_mtime() -> Option { + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + let roots = [ + manifest.join("src"), + manifest.join("../baml_lsp2_actions/src"), + manifest.join("../baml_compiler2_tir/src"), + manifest.join("../baml_compiler_syntax/src"), + ]; + let mut newest = None; + for root in roots { + newest_under(&root, &mut newest); + } + newest +} + +/// Recurse `dir`, folding the newest `.rs`/`.html` mtime into `newest`. +fn newest_under(dir: &Path, newest: &mut Option) { + let Ok(entries) = std::fs::read_dir(dir) else { + return; + }; + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + newest_under(&path, newest); + } else if matches!( + path.extension().and_then(|e| e.to_str()), + Some("rs" | "html") + ) { + if let Ok(m) = entry.metadata().and_then(|md| md.modified()) { + if newest.is_none_or(|n| m > n) { + *newest = Some(m); + } + } + } + } +} + +/// Whether watched source has changed since this binary was built (or a newer +/// binary has since been built). +fn is_stale(started: Option) -> bool { + started.is_some_and(|s| { + newest_source_mtime().is_some_and(|m| m > s) || exe_mtime().is_some_and(|m| m > s) + }) +} + +/// Spawn a watcher that rebuilds and re-execs the viewer when its source +/// changes. `rebuilding` is flipped while a rebuild is in flight so the frontend +/// can show a banner. Unix-only (uses `exec`); a no-op elsewhere. +pub(crate) fn spawn_watcher(started: Option, rebuilding: Arc) { + #[cfg(unix)] + std::thread::Builder::new() + .name("viewer-rebuild-watcher".into()) + .spawn(move || { + loop { + std::thread::sleep(Duration::from_secs(2)); + if !is_stale(started) { + continue; + } + rebuilding.store(true, Ordering::Relaxed); + println!("[viewer] source changed -> rebuilding..."); + let built = std::process::Command::new("cargo") + .args(["build", "-p", "tools_semantic_tokens"]) + .current_dir(env!("CARGO_MANIFEST_DIR")) + .status() + .is_ok_and(|s| s.success()); + if built { + println!("[viewer] rebuilt -> restarting"); + if let Ok(exe) = std::env::current_exe() { + use std::os::unix::process::CommandExt; + let args: Vec = std::env::args().skip(1).collect(); + // `exec` replaces this process; it only returns on error. + let err = std::process::Command::new(exe).args(args).exec(); + eprintln!("[viewer] re-exec failed: {err}"); + } + } else { + eprintln!("[viewer] rebuild failed; serving previous build"); + } + rebuilding.store(false, Ordering::Relaxed); + } + }) + .expect("spawn rebuild watcher"); + + #[cfg(not(unix))] + { + let _ = (started, rebuilding); + } +} diff --git a/baml_language/stow.toml b/baml_language/stow.toml index 6c4f891fd2..e6a0b1bc1a 100644 --- a/baml_language/stow.toml +++ b/baml_language/stow.toml @@ -115,7 +115,7 @@ reason = "Only compiler_emit and baml_project crates should depend on bex_vm_typ # tools namespace configuration [[namespaces]] name = "tools" -approved_prefixes = ["sap"] +approved_prefixes = ["sap", "semantic"] # Allow tools_stow folder to have package name "cargo-stow" for cargo subcommand convention name_exceptions = { "tools_stow" = "cargo-stow", "tools_size_gate" = "cargo-size-gate" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e824900550..e4b4f81702 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1149,25 +1149,6 @@ importers: specifier: 5.8.3 version: 5.8.3 - typescript/packages/fiddle-proxy: - dependencies: - cors: - specifier: 2.8.6 - version: 2.8.6 - dotenv: - specifier: 17.4.2 - version: 17.4.2 - express: - specifier: 5.2.1 - version: 5.2.1 - http-proxy-middleware: - specifier: 4.1.1 - version: 4.1.1 - devDependencies: - vitest: - specifier: 3.2.4 - version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@25.0.3)(jsdom@20.0.3(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.1) - typescript/packages/nextjs-plugin: devDependencies: '@types/node': @@ -9273,10 +9254,6 @@ packages: resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} engines: {node: '>=18'} - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} - engines: {node: '>=18'} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -9795,10 +9772,6 @@ packages: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} - cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} @@ -10312,10 +10285,6 @@ packages: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} - dotenv@17.4.2: - resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} - engines: {node: '>=12'} - downshift@7.6.2: resolution: {integrity: sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==} peerDependencies: @@ -10800,10 +10769,6 @@ packages: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} - exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} @@ -11390,10 +11355,6 @@ packages: resolution: {integrity: sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - http-proxy-middleware@4.1.1: - resolution: {integrity: sha512-KX5ZofGXLFXqFAkQoOWZ+rTtaLTut7m0gyL+QzJrdejtIZ+F4bPPDoe7reISg2+v0CAz5OfVwEJEhty7X+e57g==} - engines: {node: ^22.15.0 || ^24.0.0 || >=26.0.0} - http-proxy@1.18.1: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} @@ -11406,9 +11367,6 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - httpxy@0.5.3: - resolution: {integrity: sha512-SMS9V6Sn7VWaS11lYhoAr0ceoaiolTWf4jYdJn0NJhCdKMu9R2H9Fh0LBDWBHQF6HRLI1PmaePYsjanSpE5PEw==} - human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} @@ -14134,10 +14092,6 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} - engines: {node: '>=0.6'} - qs@6.9.7: resolution: {integrity: sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==} engines: {node: '>=0.6'} @@ -14169,10 +14123,6 @@ packages: resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} engines: {node: '>= 0.8'} - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - rc-config-loader@4.1.3: resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==} @@ -14955,10 +14905,6 @@ packages: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - side-channel-map@1.0.1: resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} engines: {node: '>= 0.4'} @@ -14971,10 +14917,6 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -15798,10 +15740,6 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} - type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} - type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} @@ -25360,14 +25298,6 @@ snapshots: optionalDependencies: vite: 5.4.21(@types/node@24.0.3)(lightningcss@1.30.2)(terser@5.44.1) - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1))': - dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1) - '@vitest/mocker@4.0.15(vite@7.2.2(@types/node@24.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.0))': dependencies: '@vitest/spy': 4.0.15 @@ -26158,20 +26088,6 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.3.0: - dependencies: - bytes: 3.1.2 - content-type: 2.0.0 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.2 - on-finished: 2.4.1 - qs: 6.15.3 - raw-body: 3.0.2 - type-is: 2.1.0 - transitivePeerDependencies: - - supports-color - boolbase@1.0.0: {} bottleneck@2.19.5: {} @@ -26681,11 +26597,6 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cors@2.8.6: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cose-base@1.0.3: dependencies: layout-base: 1.0.2 @@ -27220,8 +27131,6 @@ snapshots: dotenv@16.5.0: {} - dotenv@17.4.2: {} - downshift@7.6.2(react@19.2.5): dependencies: '@babel/runtime': 7.28.4 @@ -27973,39 +27882,6 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.3.0 - content-disposition: 1.0.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.0 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.1 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.14.0 - range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.0 - serve-static: 2.2.0 - statuses: 2.0.2 - type-is: 2.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - exsolve@1.0.7: {} ext@1.7.0: @@ -28728,16 +28604,6 @@ snapshots: transitivePeerDependencies: - supports-color - http-proxy-middleware@4.1.1: - dependencies: - debug: 4.4.3 - httpxy: 0.5.3 - is-glob: 4.0.3 - is-plain-obj: 4.1.0 - micromatch: 4.0.8 - transitivePeerDependencies: - - supports-color - http-proxy@1.18.1(debug@4.4.1): dependencies: eventemitter3: 4.0.7 @@ -28760,8 +28626,6 @@ snapshots: transitivePeerDependencies: - supports-color - httpxy@0.5.3: {} - human-signals@1.1.1: {} human-signals@2.1.0: {} @@ -32333,11 +32197,6 @@ snapshots: dependencies: side-channel: 1.1.0 - qs@6.15.3: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 - qs@6.9.7: {} quansync@0.2.10: {} @@ -32370,13 +32229,6 @@ snapshots: iconv-lite: 0.6.3 unpipe: 1.0.0 - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.2 - unpipe: 1.0.0 - rc-config-loader@4.1.3: dependencies: debug: 4.4.3 @@ -33546,11 +33398,6 @@ snapshots: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-map@1.0.1: dependencies: call-bound: 1.0.4 @@ -33574,14 +33421,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -34580,12 +34419,6 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.1 - type-is@2.1.0: - dependencies: - content-type: 2.0.0 - media-typer: 1.1.0 - mime-types: 3.0.1 - type@2.7.3: {} typed-array-buffer@1.0.3: @@ -35023,24 +34856,6 @@ snapshots: - supports-color - terser - vite-node@3.2.4(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - vite-plugin-static-copy@3.1.0(vite@7.2.2(@types/node@24.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.0)): dependencies: chokidar: 3.6.0 @@ -35240,47 +35055,6 @@ snapshots: - supports-color - terser - vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@25.0.3)(jsdom@20.0.3(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.1): - dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.0 - debug: 4.4.3 - expect-type: 1.2.2 - magic-string: 0.30.21 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1) - vite-node: 3.2.4(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.44.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@edge-runtime/vm': 3.2.0 - '@types/debug': 4.1.12 - '@types/node': 25.0.3 - jsdom: 20.0.3(canvas@2.11.2) - transitivePeerDependencies: - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - vitest@4.0.15(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@24.0.3)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@20.0.3(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.0): dependencies: '@vitest/expect': 4.0.15