From 775a89eb1e028624cb88df06c7b55fbacb2335ca Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 00:53:23 -0700 Subject: [PATCH 01/17] feat(lsp): resolution-first semantic tokens rework Rework the BAML semantic-tokens classifier to be resolution-driven (rust-analyzer style): walk the lossless CST for token positions and syntactic tokens (keywords/operators/punctuation), and resolve identifier meaning through the HIR/inference rather than guessing from the CST. - tokens/index.rs: span-keyed resolution index built over every inference-bearing scope (function / lambda / let) via the new uniform tir::scope_body lookup, so names in spawn/block/closure bodies classify with their own scope's inference. - Interface members now resolve like class members: resolve_interface_member records MemberResolution::InterfaceMethod / InterfaceField. MIR-safe (new variants lower to None item-refs and fall through to interface dispatch). - Highlighting fixes: as / with / is keywords, generators, generic type args and params (typeParameter), associated types (decl + binding), self member accesses, methods after .as, string escapes (escapeSequence), byte strings, qualified type paths, true/false/null literals, object/map keys vs values. - bitflags-backed ModifierSet; classifier shared with `baml describe`. - tools_semantic_tokens: standalone web viewer for the classifier. 78 fixtures. See crates/baml_lsp2_actions/src/tokens/GAPS.md for the scaling next-steps (on-demand resolution, range/viewport, delta) and the remaining known gaps. --- baml_language/Cargo.lock | 17 + baml_language/Cargo.toml | 1 + baml_language/crates/baml_cli/src/paint.rs | 1 + .../crates/baml_compiler2_mir/src/lower.rs | 42 +- .../crates/baml_compiler2_tir/src/builder.rs | 37 +- .../baml_compiler2_tir/src/inference.rs | 104 + .../baml_compiler_syntax/src/syntax_kind.rs | 2 + .../crates/baml_lsp2_actions/Cargo.toml | 1 + .../baml_lsp2_actions/src/definition.rs | 11 + .../crates/baml_lsp2_actions/src/lib.rs | 4 +- .../crates/baml_lsp2_actions/src/tokens.rs | 1095 +++++----- .../baml_lsp2_actions/src/tokens/GAPS.md | 69 + .../baml_lsp2_actions/src/tokens/classify.rs | 85 + .../baml_lsp2_actions/src/tokens/index.rs | 178 ++ .../baml_lsp2_actions_tests/src/runner.rs | 8 +- .../semantic_tokens/array_pattern.baml | 37 + .../semantic_tokens/attributes.baml | 24 + .../semantic_tokens/backtick_string.baml | 29 + .../semantic_tokens/block_attributes.baml | 128 ++ .../semantic_tokens/break_continue.baml | 26 +- .../semantic_tokens/byte_strings.baml | 197 ++ .../semantic_tokens/cancel_token.baml | 224 ++ .../semantic_tokens/catch_all_keyword.baml | 108 + .../semantic_tokens/catch_throw.baml | 40 + .../test_files/semantic_tokens/class.baml | 135 +- .../test_files/semantic_tokens/client.baml | 14 +- .../semantic_tokens/config_dictionary.baml | 165 ++ .../semantic_tokens/const_binding.baml | 9 +- .../semantic_tokens/const_let_else_defer.baml | 220 ++ .../semantic_tokens/constructor_spread.baml | 66 + .../semantic_tokens/deep_method_call.baml | 83 + .../semantic_tokens/dynamic_type_builder.baml | 191 ++ .../semantic_tokens/enum_decls.baml | 525 +++++ .../semantic_tokens/enum_member_access.baml | 75 + .../semantic_tokens/exhaustive.baml | 188 ++ .../semantic_tokens/extends_chain.baml | 80 + .../semantic_tokens/field_alias.baml | 49 + .../test_files/semantic_tokens/for_loops.baml | 26 +- .../test_files/semantic_tokens/function.baml | 13 +- .../semantic_tokens/generators.baml | 99 + .../semantic_tokens/generic_field_chain.baml | 97 + .../generic_function_call.baml | 43 + .../semantic_tokens/header_comments.baml | 103 + .../semantic_tokens/http_config.baml | 106 + .../test_files/semantic_tokens/if_else.baml | 25 +- .../semantic_tokens/if_expression.baml | 59 + .../semantic_tokens/if_let_chain.baml | 152 ++ .../semantic_tokens/implements_for.baml | 43 + .../semantic_tokens/index_access.baml | 121 ++ .../semantic_tokens/interface_impl.baml | 43 + ...interfaces_inferred_generic_type_args.baml | 1657 ++++++++++++++ .../semantic_tokens/interfaces_iter_core.baml | 1929 +++++++++++++++++ .../interfaces_sort_comparable.baml | 1377 ++++++++++++ .../semantic_tokens/is_operator.baml | 122 ++ .../test_files/semantic_tokens/iterator.baml | 67 + .../semantic_tokens/jinja_control_prompt.baml | 90 + .../semantic_tokens/json_map_literal.baml | 25 + .../json_parse_stringify_intrinsics.baml | 118 + .../semantic_tokens/lambda_advanced.baml | 1003 +++++++++ .../semantic_tokens/literal_types.baml | 52 + .../semantic_tokens/llm_function.baml | 28 +- .../semantic_tokens/map_literal_keys.baml | 183 ++ .../semantic_tokens/map_type_and_methods.baml | 97 + .../semantic_tokens/match_expr.baml | 57 +- .../semantic_tokens/match_literal_types.baml | 74 + .../method_explicit_type_args.baml | 50 + .../semantic_tokens/multi_segment_path.baml | 36 +- .../semantic_tokens/ns_agent_clients.baml | 58 + .../test_files/semantic_tokens/ns_ansi.baml | 204 ++ .../semantic_tokens/ns_game_clients.baml | 345 +++ .../semantic_tokens/ns_images_pipeline.baml | 64 + .../semantic_tokens/ns_sentiment.baml | 133 ++ .../semantic_tokens/patterns_new.baml | 801 +++++++ .../semantic_tokens/remap_role.baml | 80 + .../semantic_tokens/requires_clause.baml | 98 + .../retry_policy_valid_retry.baml | 34 + .../semantic_tokens/self_qualified_call.baml | 78 + .../semantic_tokens/signature_variety.baml | 239 ++ .../stream_llm_inferred_typeargs.baml | 114 + .../semantic_tokens/task_group.baml | 358 +++ .../semantic_tokens/template_string.baml | 8 +- .../template_string_calls.baml | 56 + .../semantic_tokens/test_block.baml | 27 +- .../test_expr_throwing_body.baml | 23 + .../test_files/semantic_tokens/testset.baml | 66 + .../semantic_tokens/testset_vibes_nested.baml | 270 +++ .../semantic_tokens/throws_clause.baml | 86 + .../semantic_tokens/top_level_binding.baml | 26 + .../semantic_tokens/type_alias.baml | 14 +- .../semantic_tokens/type_aliases_jinja.baml | 270 +++ .../test_files/semantic_tokens/watch_let.baml | 306 +++ .../semantic_tokens/while_loop.baml | 23 +- .../semantic_tokens/with_keyword.baml | 68 + .../src/bex_lsp/multi_project/request.rs | 7 +- .../crates/tools_semantic_tokens/Cargo.toml | 30 + .../crates/tools_semantic_tokens/README.md | 40 + .../tools_semantic_tokens/src/analysis.rs | 272 +++ .../tools_semantic_tokens/src/index.html | 522 +++++ .../crates/tools_semantic_tokens/src/main.rs | 112 + .../tools_semantic_tokens/src/server.rs | 197 ++ .../tools_semantic_tokens/src/staleness.rs | 113 + 101 files changed, 16486 insertions(+), 819 deletions(-) create mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md create mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs create mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/index.rs create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/array_pattern.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/attributes.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/backtick_string.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/byte_strings.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_all_keyword.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_throw.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/config_dictionary.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/const_let_else_defer.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/constructor_spread.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/deep_method_call.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/dynamic_type_builder.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_decls.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/enum_member_access.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/exhaustive.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/extends_chain.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/field_alias.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generators.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_field_chain.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/generic_function_call.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/header_comments.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/http_config.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_expression.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/if_let_chain.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/implements_for.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/index_access.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interface_impl.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_inferred_generic_type_args.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_iter_core.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/is_operator.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/iterator.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/jinja_control_prompt.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_map_literal.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/json_parse_stringify_intrinsics.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/literal_types.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_literal_keys.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_type_and_methods.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/match_literal_types.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/method_explicit_type_args.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_agent_clients.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_ansi.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_game_clients.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_images_pipeline.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_sentiment.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/remap_role.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/requires_clause.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/retry_policy_valid_retry.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/self_qualified_call.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/signature_variety.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/stream_llm_inferred_typeargs.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/task_group.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/template_string_calls.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/test_expr_throwing_body.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset_vibes_nested.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/throws_clause.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/top_level_binding.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/type_aliases_jinja.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/watch_let.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/with_keyword.baml create mode 100644 baml_language/crates/tools_semantic_tokens/Cargo.toml create mode 100644 baml_language/crates/tools_semantic_tokens/README.md create mode 100644 baml_language/crates/tools_semantic_tokens/src/analysis.rs create mode 100644 baml_language/crates/tools_semantic_tokens/src/index.html create mode 100644 baml_language/crates/tools_semantic_tokens/src/main.rs create mode 100644 baml_language/crates/tools_semantic_tokens/src/server.rs create mode 100644 baml_language/crates/tools_semantic_tokens/src/staleness.rs diff --git a/baml_language/Cargo.lock b/baml_language/Cargo.lock index 20fc21059a..284416fa81 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", @@ -984,6 +985,7 @@ dependencies = [ "baml_compiler_parser", "baml_compiler_syntax", "baml_workspace", + "bitflags 2.11.1", "indexmap", "insta", "rowan 0.16.1", @@ -7637,6 +7639,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 80cbd9ff11..99e5f521fc 100644 --- a/baml_language/Cargo.toml +++ b/baml_language/Cargo.toml @@ -128,6 +128,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..344a1ce2e2 100644 --- a/baml_language/crates/baml_cli/src/paint.rs +++ b/baml_language/crates/baml_cli/src/paint.rs @@ -103,6 +103,7 @@ 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::EscapeSequence => Style::new().color256(214), T::Number => Style::new().yellow().bright(), T::Comment => Style::new().color256(244), T::Decorator => Style::new().color256(179), diff --git a/baml_language/crates/baml_compiler2_mir/src/lower.rs b/baml_language/crates/baml_compiler2_mir/src/lower.rs index 046cc2427c..aef939f554 100644 --- a/baml_language/crates/baml_compiler2_mir/src/lower.rs +++ b/baml_language/crates/baml_compiler2_mir/src/lower.rs @@ -1187,7 +1187,7 @@ fn resolution_to_item_ref( name: func_data.name.clone(), }) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, } } @@ -6013,6 +6013,13 @@ impl<'db> LoweringContext<'db> { Some(MemberResolution::Variant { .. }) => { // Handled by expr_types check below. } + Some( + MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. }, + ) => { + // Interface member on an interface-typed value: fall through + // to the runtime interface-dispatch path below. + } None => {} } } @@ -6081,6 +6088,11 @@ impl<'db> LoweringContext<'db> { self.lower_multi_segment_path_as_field_chain(expr_id, segments, dest); return; } + MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => { + // Interface member on an interface-typed value: fall through + // to the runtime interface-dispatch path below. + } } } // An interface method referenced as a *value* on a generic- or @@ -8556,7 +8568,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8570,7 +8582,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { None } }) @@ -8593,7 +8605,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8651,7 +8663,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8665,7 +8677,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { None } }) @@ -8688,7 +8700,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8741,7 +8753,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8755,7 +8767,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { None } }) @@ -8778,7 +8790,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8852,7 +8864,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8866,7 +8878,7 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { None } }) @@ -8951,7 +8963,7 @@ impl LoweringContext<'_> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => None, + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8965,7 +8977,7 @@ impl LoweringContext<'_> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { None } }) @@ -9790,7 +9802,7 @@ impl<'db> LoweringContext<'db> { return; } } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { // Fall through — handled by the existing field/enum-variant lowering below } } diff --git a/baml_language/crates/baml_compiler2_tir/src/builder.rs b/baml_language/crates/baml_compiler2_tir/src/builder.rs index 5977f89050..c3cce86884 100644 --- a/baml_language/crates/baml_compiler2_tir/src/builder.rs +++ b/baml_language/crates/baml_compiler2_tir/src/builder.rs @@ -2487,7 +2487,10 @@ impl<'db> TypeInferenceBuilder<'db> { | MemberResolution::BoundMethod { func_loc, .. } | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => func_loc, - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => { return callee_generic_params.to_vec(); } }; @@ -2501,9 +2504,10 @@ impl<'db> TypeInferenceBuilder<'db> { MemberResolution::InterfaceDefaultMethod { .. } => { owner_params.into_iter().chain(fn_params).collect() } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } => { - callee_generic_params.to_vec() - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => callee_generic_params.to_vec(), } } @@ -12333,6 +12337,13 @@ impl<'db> TypeInferenceBuilder<'db> { attr: TyAttr::default(), }); } + self.resolutions.insert( + at, + crate::inference::MemberResolution::InterfaceField { + iface_loc, + field_name: member.clone(), + }, + ); let ty = field .type_expr .as_ref() @@ -12383,6 +12394,15 @@ impl<'db> TypeInferenceBuilder<'db> { continue; } let func_loc = baml_compiler2_hir::loc::FunctionLoc::new(db, file, fn_id); + if bound { + self.resolutions.insert( + at, + crate::inference::MemberResolution::InterfaceMethod { + iface_loc, + method_name: member.clone(), + }, + ); + } let sig = baml_compiler2_ppir::elaborated_function_signature(db, func_loc); // An exact receiver pins `Self` to its own type, not to a fresh // method generic, so suppress the unbound-reference generic there. @@ -12679,6 +12699,15 @@ impl<'db> TypeInferenceBuilder<'db> { if sig.name != *member { continue; } + if bound { + self.resolutions.insert( + at, + crate::inference::MemberResolution::InterfaceMethod { + iface_loc, + method_name: member.clone(), + }, + ); + } // An exact receiver pins `Self` to its own type, not to a fresh // method generic, so suppress the unbound-reference generic there. let receiver_generic = (!bound && !matches!(self_recv, SelfReceiver::ExactTy(_))) diff --git a/baml_language/crates/baml_compiler2_tir/src/inference.rs b/baml_language/crates/baml_compiler2_tir/src/inference.rs index 666a8a365a..c14fde709d 100644 --- a/baml_language/crates/baml_compiler2_tir/src/inference.rs +++ b/baml_language/crates/baml_compiler2_tir/src/inference.rs @@ -131,6 +131,96 @@ 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, + }) +} + +/// 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( db: &dyn crate::Db, file: SourceFile, @@ -624,6 +714,20 @@ pub enum MemberResolution<'db> { iface_loc: InterfaceLoc<'db>, func_loc: FunctionLoc<'db>, }, + /// A required (signature-only) interface method, accessed on an + /// interface-typed value (`x.as.greet()`, `self.next()` in a + /// default method). It has no body `FunctionLoc` — only the declaring + /// interface. + InterfaceMethod { + iface_loc: InterfaceLoc<'db>, + method_name: Name, + }, + /// An interface field, accessed on an interface-typed value + /// (`x.as.name`). + InterfaceField { + iface_loc: InterfaceLoc<'db>, + field_name: Name, + }, } // ── Per-Scope Inference Result ───────────────────────────────────────────── 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 dc1f2a28ca..959da0231b 100644 --- a/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs +++ b/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs @@ -530,6 +530,7 @@ impl SyntaxKind { | Self::KW_LET | Self::KW_CONST | Self::KW_IN + | Self::KW_IS | Self::KW_BREAK | Self::KW_CONTINUE | Self::KW_RETURN @@ -544,6 +545,7 @@ impl SyntaxKind { | Self::KW_WATCH | Self::KW_INSTANCEOF | Self::KW_DYNAMIC + | Self::KW_WITH ) } } 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/definition.rs b/baml_language/crates/baml_lsp2_actions/src/definition.rs index bf2719e49f..5735e38a78 100644 --- a/baml_language/crates/baml_lsp2_actions/src/definition.rs +++ b/baml_language/crates/baml_lsp2_actions/src/definition.rs @@ -423,6 +423,17 @@ fn resolve_field_access_at( range: *name_range, }) } + MemberResolution::InterfaceMethod { iface_loc, .. } + | MemberResolution::InterfaceField { iface_loc, .. } => { + // An interface member accessed on an interface-typed value: navigate + // to the declaring interface. + let def = baml_compiler2_hir::contributions::Definition::Interface(*iface_loc); + let (def_file, range) = utils::definition_span(db, def)?; + Some(Location { + file: def_file, + range, + }) + } } } 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..99934fc725 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -1,36 +1,33 @@ //! 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). +//! - **Declaration names** are classified by their declaring node and carry the +//! `declaration` modifier; a reference is classified the same way as its +//! definition. -use std::collections::HashMap; - -use baml_base::SourceFile; +use baml_base::{Name, 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, -}; -use baml_compiler2_tir::ty::Ty; +use baml_compiler2_tir::resolve::{resolve_name_at, resolve_path_at}; use rowan::NodeOrToken; -use text_size::TextRange; +use text_size::{TextRange, TextSize}; use crate::Db; +mod classify; +mod index; + // ── SemanticTokenType ───────────────────────────────────────────────────────── /// The semantic token type for a BAML file. @@ -63,6 +60,7 @@ pub enum SemanticTokenType { Regexp, Operator, Decorator, + EscapeSequence, } /// Token type legend — order determines the LSP legend index. @@ -92,6 +90,7 @@ pub const TOKEN_TYPES: &[SemanticTokenType] = &[ SemanticTokenType::Regexp, SemanticTokenType::Operator, SemanticTokenType::Decorator, + SemanticTokenType::EscapeSequence, ]; impl SemanticTokenType { @@ -132,672 +131,570 @@ impl SemanticTokenType { Self::Regexp => "regexp", Self::Operator => "operator", Self::Decorator => "decorator", + Self::EscapeSequence => "escapeSequence", } } } +// ── 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 ──────────────────────────────────────────────────────── +/// A token type paired with its modifiers — the unit a classifier produces. +type Class = (SemanticTokenType, ModifierSet); -/// 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 +/// The class for a declaration name: `ty` + the `declaration` modifier. +fn decl(ty: SemanticTokenType) -> Class { + (ty, ModifierSet::DECLARATION) } -// ── CST walker ─────────────────────────────────────────────────────────────── - -/// 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, - }); - } -} - -/// 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), - }, - } - } -} - -/// 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), - }, - } + if text_start < bytes.len() { + emit( + span(base + text_start, base + bytes.len()), + plain(SemanticTokenType::String), + out, + ); } } -/// 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), - }, - } +/// 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 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, - } -} - -/// 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), - }, - } - } -} +// ── Public entry point ──────────────────────────────────────────────────────── -/// Visit a `FUNCTION_DEF` node. +/// Compute semantic tokens for a file. /// -/// 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( - 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), - }, - } - } +/// 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); + let walk = Walk { + db, + file, + index: index::build(db, file), + }; + let mut out = Vec::new(); + walk.node(&root, &mut out); + 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> { +/// Holds the resolution index so the structural dispatch never threads it; an +/// identifier inside an expression body is looked up there, a declaration name is +/// classified by its declaring node, and every other token is syntactic. +struct Walk<'db> { db: &'db dyn Db, file: SourceFile, - resolution_map: HashMap, + index: index::ResolutionIndex, } -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, - }) - } - - /// Dispatch a single node inside an expression body. - fn visit_node(&self, node: &SyntaxNode, out: &mut Vec) { +impl Walk<'_> { + /// Dispatch a node to its classifier. + fn node(&self, node: &SyntaxNode, out: &mut Vec) { match node.kind() { ref n if n.is_comment() => emit_node(node, SemanticTokenType::Comment, out), - SyntaxKind::STRING_LITERAL | SyntaxKind::RAW_STRING_LITERAL => { + // Escape-processing literals: split out `\n`, `\xNN`, `\u{..}`, ... + SyntaxKind::STRING_LITERAL | SyntaxKind::BYTE_STRING_LITERAL => { + string_with_escapes(node, out); + } + // Raw / unquoted strings do not process escapes. + SyntaxKind::RAW_STRING_LITERAL | SyntaxKind::UNQUOTED_STRING => { 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); + SyntaxKind::BACKTICK_STRING_LITERAL => self.backtick_string(node, out), + SyntaxKind::ATTRIBUTE | SyntaxKind::BLOCK_ATTRIBUTE => self.tokens(node, out, |t| { + (matches!(t.kind(), SyntaxKind::AT_AT | SyntaxKind::AT | SyntaxKind::WORD) + || t.kind().is_keyword()) + .then_some(plain(SemanticTokenType::Decorator)) + }), + SyntaxKind::TYPE_ALIAS_DEF | SyntaxKind::ASSOCIATED_TYPE_DECL => { + self.type_decl(node, out); + } + SyntaxKind::ENUM_DEF => self.decl_name(node, SemanticTokenType::Enum, out), + SyntaxKind::ENUM_VARIANT => self.decl_name(node, SemanticTokenType::EnumMember, out), + SyntaxKind::CLASS_DEF => self.decl_name(node, SemanticTokenType::Class, out), + SyntaxKind::INTERFACE_DEF => self.decl_name(node, SemanticTokenType::Interface, out), + SyntaxKind::FIELD => self.decl_name(node, SemanticTokenType::Property, out), + SyntaxKind::FUNCTION_DEF | SyntaxKind::METHOD_SIG => self.function_def(node, out), + SyntaxKind::PARAMETER => self.decl_name(node, SemanticTokenType::Parameter, out), + SyntaxKind::TYPE_EXPR => self.type_expr(node, out), + // `let x`, match-arm bindings, etc.: the bound name is a declaration. + SyntaxKind::BINDING_PATTERN => self.decl_name(node, SemanticTokenType::Variable, out), + SyntaxKind::CLIENT_TYPE => self.tokens(node, out, |t| { + (t.kind() == SyntaxKind::WORD).then_some(plain(SemanticTokenType::Type)) + }), + SyntaxKind::CONFIG_ITEM => self.tokens(node, out, |t| { + (t.kind().is_keyword() || t.kind() == SyntaxKind::WORD) + .then_some(plain(SemanticTokenType::Property)) + }), + SyntaxKind::CLIENT_DEF | SyntaxKind::RETRY_POLICY_DEF => { + self.decl_name(node, SemanticTokenType::Struct, out); } - SyntaxKind::OBJECT_FIELD | SyntaxKind::OBJECT_LITERAL => { - self.visit_children(node, out); + SyntaxKind::TEST_DEF => self.decl_name(node, SemanticTokenType::Struct, out), + SyntaxKind::TEMPLATE_STRING_DEF => { + self.decl_name(node, SemanticTokenType::Function, out); } - _ => self.visit_children(node, out), + SyntaxKind::PROMPT_FIELD => self.decl_name(node, SemanticTokenType::Property, out), + SyntaxKind::OBJECT_LITERAL => self.object_literal(node, out), + SyntaxKind::OBJECT_FIELD => self.object_field(node, out), + SyntaxKind::CLIENT_FIELD => self.tokens(node, out, |t| { + (t.kind() == SyntaxKind::KW_CLIENT).then_some(plain(SemanticTokenType::Property)) + }), + // `as` is a contextual keyword (lexed as a WORD) in `.as` casts + // and `field as field` interface field links. + SyntaxKind::UPCAST_EXPR | SyntaxKind::INTERFACE_FIELD_LINK => self.tokens(node, out, |t| { + (t.kind() == SyntaxKind::WORD && t.text() == "as") + .then_some(plain(SemanticTokenType::Keyword)) + }), + SyntaxKind::GENERATOR_DEF => self.generator_def(node, out), + // A generic parameter declaration (`T` in `class Box`, + // `function f()`, ``): the name as a `TypeParameter` + // declaration, any bound dispatched as a type. + SyntaxKind::GENERIC_PARAM => { + let mut named = false; + self.tokens(node, out, |t| { + (!named && t.kind() == SyntaxKind::WORD).then(|| { + named = true; + decl(SemanticTokenType::TypeParameter) + }) + }); + } + _ => self.children(node, out), } } - /// 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); - } + /// Walk all children with no special token classification. + fn children(&self, node: &SyntaxNode, out: &mut Vec) { + self.tokens(node, out, |_| None); } - /// 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), + /// 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; + } + if kind == SyntaxKind::WORD { + if let Some(class) = self.index.get(&token.text_range()).copied() { + emit(token.text_range(), class, out); + } else if matches!(token.text(), "true" | "false" | "null") { + // Boolean / null literals lex as words and lower to + // `Expr::Literal` / `Expr::Null`, so they never enter the + // expression index; classify them as the keyword-literals they are. + emit(token.text_range(), plain(SemanticTokenType::Keyword), 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) { + 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( + /// The one structural primitive: walk children, dispatching each node and + /// classifying each token by `classify`. A `None` result falls back to the + /// token's own syntactic classification ([`Self::token`]). Every node handler + /// below is a thin wrapper over this. + 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.node(&n, out), + NodeOrToken::Token(t) => match classify(&t) { + Some(class) => emit(t.text_range(), class, out), + None => self.token(&t, out), + }, } } } -} -// ── Resolution map builder ──────────────────────────────────────────────────── + /// Direct WORD children as a declaration of `ty` (class/enum/field/... names, + /// which never appear in the expression index). + fn decl_name(&self, node: &SyntaxNode, ty: SemanticTokenType, out: &mut Vec) { + self.tokens(node, out, |t| (t.kind() == SyntaxKind::WORD).then_some(decl(ty))); + } -/// 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, + /// A `TYPE_ALIAS_DEF` (`type X = …`), an associated-type *declaration* + /// (`type Item [extends Bound] [= Default]` in an interface/impl), or an + /// associated-type *binding* (`Item = string` inside `Iterator<…>`). All + /// three share `ASSOCIATED_TYPE_DECL`/`TYPE_ALIAS_DEF`. The leading `type` + /// keyword (a WORD in the grammar) is `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 and dispatch on their own. + fn type_decl(&self, node: &SyntaxNode, out: &mut Vec) { + let mut saw_type_kw = false; + let mut named = false; + self.tokens(node, out, |t| { + if t.kind() != SyntaxKind::WORD { + return None; + } + if !named && t.text() == "type" { + saw_type_kw = true; + return Some(plain(SemanticTokenType::Keyword)); + } + if !named { + named = true; + let ty = SemanticTokenType::Type; + return Some(if saw_type_kw { decl(ty) } else { plain(ty) }); + } + 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.node(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; + /// 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`: prefix segments are namespaces; the leaf is the + // type the whole path resolves to. + let (leaf, prefix) = segments.split_last().expect("non-empty run"); + for seg in prefix { + emit(seg.text_range(), plain(SemanticTokenType::Namespace), out); + } + let names: Vec = segments.iter().map(|t| Name::new(t.text())).collect(); + let resolved = resolve_path_at(self.db, self.file, leaf.text_range().start(), &names, None); + // An unresolved qualified leaf is still a type, not a namespace. + let class = + classify::classify_resolved(&resolved).unwrap_or_else(|| plain(SemanticTokenType::Type)); + emit(leaf.text_range(), class, out); + } + + /// A `FUNCTION_DEF` or `METHOD_SIG` — the name as a `Function` (or `Method`, + /// inside a class/interface/implements) declaration; parameters, the return + /// type, and the body are dispatched as child nodes (the body's identifiers + /// resolve through the index). + fn function_def(&self, node: &SyntaxNode, out: &mut Vec) { + let name_type = if in_method_context(node) { + SemanticTokenType::Method + } else { + SemanticTokenType::Function + }; + self.decl_name(node, name_type, out); + } + + /// 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 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); - } + // `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.node(&n, out), + NodeOrToken::Token(t) => self.token(&t, 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; - } - 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); - } + /// 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) + }) + }); + } - // 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); - } - } + /// 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, + }); + } - _ => {} - } + /// An `OBJECT_FIELD` (`a: expr` or `"a": expr`) — a bare-word key (before the + /// `:`) as a `Property`; a string key and the value expression dispatched (so + /// a value like `null` / `true` isn't mistaken for the key). + fn object_field(&self, node: &SyntaxNode, out: &mut Vec) { + let mut seen_colon = false; + self.tokens(node, out, |t| match t.kind() { + SyntaxKind::COLON => { + seen_colon = true; + None + } + SyntaxKind::WORD if !seen_colon => Some(plain(SemanticTokenType::Property)), + _ => None, + }); } +} - // 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(); +// ── Type-name classification (annotations) ────────────────────────────────────── - let span = source_map.pattern_span(pat_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; - } - 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); - } - } +/// 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. +const PRIMITIVE_TYPES: &[&str] = &[ + "int", "bigint", "float", "string", "bool", "bytes", "uint8array", "null", "image", "audio", + "video", "pdf", "json", "map", "unknown", "never", +]; - map +/// 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 PRIMITIVE_TYPES.contains(&name) { + return (SemanticTokenType::Type, ModifierSet::DEFAULT_LIBRARY); + } + 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/GAPS.md b/baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md new file mode 100644 index 0000000000..3470c6d2f3 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md @@ -0,0 +1,69 @@ +# Semantic tokens — known gaps & next steps + +Status snapshot of the semantic-tokens classifier (`tokens.rs` + `tokens/index.rs` ++ `tokens/classify.rs`). Architecture mirrors rust-analyzer: walk the lossless +CST for token positions + syntactic tokens (keywords/operators/punctuation), +resolve identifier *meaning* through the HIR/inference. Keywords are a parser +concern (contextual keywords like `with` are re-lexed to `KW_*`, read by kind). + +## Scaling — "do what rust-analyzer does" (highest priority) + +Today the classifier always does **whole-file** work: `index::build` resolves +every scope in the file regardless of what's requested. That's the scaling gap, +not the recursive-vs-iterative traversal style. + +Levers, in order of impact: + +1. **On-demand per-token resolution.** Rebuild a `resolve_token(file, token)` + bridge on top of `baml_compiler2_tir::inference::scope_body` (still present) + and have the walker resolve each name lazily — RA's `Semantics::resolve` + model. Drops the prebuilt whole-file index so a range request only pays for + visible tokens. (We built `resolve_token` earlier this effort, then removed + it once the index covered the cases — bring it back for scale.) +2. **Range / viewport highlighting** (`semanticTokens/range`). Take a range, + skip subtrees whose `text_range()` doesn't intersect it, wire the request in + `bex_project`. Works in the current recursive shape (early `return` on + out-of-range nodes). Biggest single win on large files. +3. **Delta encoding** (`semanticTokens/full/delta`) — emit only the token diff. +4. **(Optional) iterative traversal shape.** Replace the recursive `node()` + dispatch with one `preorder_with_tokens()` loop + match-on-kind/parent, like + RA's `traverse`. Same asymptotics; only buys stack-depth robustness and + convergence with RA. Do last, or never. + +Already have: salsa-cached query, lossless rowan CST, typed AST accessors, +`scope_body` (uniform scope→body lookup), per-scope inference. + +## Remaining feature items (from the highlighting punch-list) + +- **Optional function parameters at call site** — not yet investigated. +- **Boolean literals** — `true`/`false` are currently `keyword`. RA uses a + custom `boolean` semantic-token type (beyond the standard legend); add it to + the legend + enum + paint.rs + viewer color map and classify there. + +## Known resolution gaps / limitations + +- **Test / testset bodies.** `testset` is not lowered into the compiler2 IR + (absent from tir/hir/ppir); body code is classified only insofar as the scope + iteration reaches it. Verify coverage; may need the testset lowering wired up. +- **Interface-member go-to-def** navigates to the *interface declaration*, not + the specific member span. `MemberResolution::InterfaceMethod`/`InterfaceField` + carry only `iface_loc` + name (no `func_loc` for required methods). Refine to + the member span when desired. +- **Generic param *usages*** (the `T` in `v: T`, `T[]`) classify as `type` + (fallback), while *declarations* (`class Box`) are `typeParameter`. To make + usages `typeParameter`, resolve the name to the in-scope generic param. +- **Backtick-string escapes** are not split into `escapeSequence` tokens (only + regular + byte strings are). +- **Generator bodies** are parsed opaquely (deprecated); classified by shape + (name→struct, key→property, value tokens→string), not via real structure. + +## Principled fixes landed this effort (context) + +- Interface members now resolve like class members: `resolve_interface_member` + records `MemberResolution::InterfaceMethod`/`InterfaceField` + (`builder.rs`), so casts / `Self` methods / chained interface calls classify + through the normal path; typos stay neutral. MIR-safe (new variants → `None` + item-ref, fall through to existing interface dispatch). +- `scope_body` (tir): uniform scope→`(ExprBody, source_map)` covering function / + let / lambda (and spawn/block bodies that lower to closures) — the index walks + every inference-bearing scope, not just top-level functions. 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..78afd81f09 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs @@ -0,0 +1,85 @@ +//! 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}; + +/// 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 { + Some(DefinitionSite::Parameter(_)) => 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::InterfaceField { .. } => T::Property, + M::Variant { .. } => T::EnumMember, + M::Free { .. } => T::Function, + M::BoundMethod { .. } + | M::UnboundMethod { .. } + | M::InterfaceDefaultMethod { .. } + | M::InterfaceMethod { .. } => 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..722b2d9ced --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs @@ -0,0 +1,178 @@ +//! 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; + +use baml_base::SourceFile; +use baml_compiler2_ast::{Expr, ExprBody, ExprId}; +use baml_compiler2_hir::scope::ScopeKind; +use baml_compiler2_tir::{ + inference::{ScopeInference, infer_scope_types, scope_body}, + resolve::{ResolvedName, resolve_name_at, 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); + } +} + +/// Build the resolution index over every inference-bearing scope in `file`. +/// +/// Iterates each `Function` / `Lambda` / `Let` scope and indexes its body via +/// the uniform [`scope_body`] lookup, so names inside lambdas, `spawn` blocks, +/// and other closures are classified with their own scope's inference — not +/// just top-level function bodies. Synthetic template-string bodies are skipped: +/// their expressions are typed inline in the enclosing scope and indexed there. +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; + } + let Some(body) = scope_body(db, sem_index.scope_ids[i]) else { + continue; + }; + let inference = infer_scope_types(db, body.scope); + index_function(db, file, &body.expr_body, &body.source_map, inference, &mut index); + } + + 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, +) { + let ns = (SemanticTokenType::Namespace, ModifierSet::empty()); + + 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), + // Unresolved root of a dotted path => a package/namespace. + None if segments.len() > 1 => record(index, root_span, ns), + 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), + None => record(index, span, (SemanticTokenType::Namespace, ModifierSet::empty())), + } + } +} 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/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/block_attributes.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml new file mode 100644 index 0000000000..b06d2d621b --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/block_attributes.baml @@ -0,0 +1,128 @@ +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 +// +// +//- 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 c0cf608565..0fd4dbc1b6 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,41 +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 (keyword) 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) len=3 "sum" +// 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) len=1 "i" +// 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/cancel_token.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml new file mode 100644 index 0000000000..b01b1444a6 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/cancel_token.baml @@ -0,0 +1,224 @@ +// 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) 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) 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:50 (operator) len=1 "=" +// cancel_token.baml:14:52 (variable) len=3 "tok" +// cancel_token.baml:15:9 (namespace) len=4 "baml" +// cancel_token.baml:15:14 (namespace) len=3 "sys" +// cancel_token.baml:15:18 (function) len=5 "sleep" +// cancel_token.baml:15:24 (namespace) len=4 "baml" +// cancel_token.baml:15:29 (namespace) 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: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:27 (namespace) len=4 "baml" +// cancel_token.baml:19:31 (operator) len=1 "." +// cancel_token.baml:19:32 (namespace) 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) len=6 "assert" +// cancel_token.baml:23:12 (function) len=7 "is_true" +// cancel_token.baml:23:20 (namespace) 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) 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) 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: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) len=6 "assert" +// cancel_token.baml:35:12 (function) len=7 "is_true" +// cancel_token.baml:35:20 (namespace) 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) 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) len=6 "assert" +// cancel_token.baml:49:12 (function) len=7 "is_true" +// cancel_token.baml:49:20 (namespace) 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 (keyword) len=5 "false" +// cancel_token.baml:49:83 (keyword) 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) 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:50 (operator) len=1 "=" +// cancel_token.baml:56:52 (keyword) 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) len=6 "assert" +// cancel_token.baml:61:12 (function) len=7 "is_true" +// cancel_token.baml:61:20 (namespace) 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..1907ad07b1 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_all_keyword.baml @@ -0,0 +1,108 @@ +// 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: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: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: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: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:38:14 (string) len=13 "\"caught rest\"" 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..e8728021bb --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_throw.baml @@ -0,0 +1,40 @@ +// `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: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 f1034b549a..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 @@ -57,104 +57,107 @@ function fo() -> int { // ╭─[ class.baml:44:29 ] // │ // 44 │ let first_red = colors[0].get_re(); -// │ ───┬── +// │ ───┬── // │ ╰──── type `Color` has no member `get_re` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `gree` // ╭─[ class.baml:45:32 ] // │ // 45 │ let second_green = colors[1].gree; -// │ ──┬─ +// │ ──┬─ // │ ╰─── type `Color` has no member `gree` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `re` // ╭─[ class.baml:47:23 ] // │ // 47 │ let sum = colors[0].re + colors[1].gree + colors[2].blu; -// │ ─┬ +// │ ─┬ // │ ╰── type `Color` has no member `re` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `gree` // ╭─[ class.baml:47:38 ] // │ // 47 │ let sum = colors[0].re + colors[1].gree + colors[2].blu; -// │ ──┬─ +// │ ──┬─ // │ ╰─── type `Color` has no member `gree` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `blu` // ╭─[ class.baml:47:55 ] // │ // 47 │ let sum = colors[0].re + colors[1].gree + colors[2].blu; -// │ ─┬─ +// │ ─┬─ // │ ╰─── type `Color` has no member `blu` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `get_re` // ╭─[ class.baml:49:27 ] // │ // 49 │ let nested = [colors[0].get_re(), colors[1].get_gree(), colors[2].get_blu()]; -// │ ───┬── +// │ ───┬── // │ ╰──── type `Color` has no member `get_re` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `get_gree` // ╭─[ class.baml:49:47 ] // │ // 49 │ let nested = [colors[0].get_re(), colors[1].get_gree(), colors[2].get_blu()]; -// │ ────┬─── +// │ ────┬─── // │ ╰───── type `Color` has no member `get_gree` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // error: type `Color` has no member `get_blu` // ╭─[ class.baml:49:69 ] // │ // 49 │ let nested = [colors[0].get_re(), colors[1].get_gree(), colors[2].get_blu()]; -// │ ───┬─── +// │ ───┬─── // │ ╰───── type `Color` has no member `get_blu` -// │ +// │ // │ Note: Error code: E0007 // ────╯ // //- 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) len=6 "colors" +// 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" @@ -178,47 +181,59 @@ function fo() -> int { // 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) len=9 "first_red" +// 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 (property) len=7 "get_red" +// class.baml:26:29 (method) len=7 "get_red" // class.baml:27:3 (keyword) len=3 "let" -// class.baml:27:7 (variable) len=12 "second_green" +// 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) len=3 "sum" +// 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) len=6 "nested" +// 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 (property) len=7 "get_red" +// 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 (property) len=9 "get_green" +// 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 (property) len=8 "get_blue" +// 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) len=6 "colors" +// 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" @@ -242,38 +257,42 @@ function fo() -> int { // 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) len=9 "first_red" +// 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:44:29 (property) len=6 "get_re" // class.baml:45:3 (keyword) len=3 "let" -// class.baml:45:7 (variable) len=12 "second_green" +// 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:45:32 (property) len=4 "gree" // class.baml:47:3 (keyword) len=3 "let" -// class.baml:47:7 (variable) len=3 "sum" +// 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:23 (property) len=2 "re" // 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:38 (property) len=4 "gree" // 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:47:55 (property) len=3 "blu" // class.baml:49:3 (keyword) len=3 "let" -// class.baml:49:7 (variable) len=6 "nested" +// 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:27 (property) len=6 "get_re" +// class.baml:49:37 (variable) len=6 "colors" // class.baml:49:44 (number) len=1 "1" -// class.baml:49:47 (property) len=8 "get_gree" +// class.baml:49:59 (variable) len=6 "colors" // class.baml:49:66 (number) len=1 "2" -// class.baml:49:69 (property) len=7 "get_blu" +// 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..b673c8f04e --- /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 (keyword) 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..40e9f954d6 --- /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 (namespace) len=9 "Direction" +// exhaustive.baml:12:14 (operator) len=1 "." +// exhaustive.baml:12:15 (type) len=5 "North" +// exhaustive.baml:12:24 (string) len=7 "\"north\"" +// exhaustive.baml:13:5 (namespace) len=9 "Direction" +// exhaustive.baml:13:14 (operator) len=1 "." +// exhaustive.baml:13:15 (type) len=5 "South" +// exhaustive.baml:13:24 (string) len=7 "\"south\"" +// exhaustive.baml:14:5 (namespace) len=9 "Direction" +// exhaustive.baml:14:14 (operator) len=1 "." +// exhaustive.baml:14:15 (type) len=4 "East" +// exhaustive.baml:14:23 (string) len=6 "\"east\"" +// exhaustive.baml:15:5 (namespace) len=9 "Direction" +// exhaustive.baml:15:14 (operator) len=1 "." +// exhaustive.baml:15:15 (type) 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 (namespace) len=9 "Direction" +// exhaustive.baml:22:14 (operator) len=1 "." +// exhaustive.baml:22:15 (type) 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 (namespace) len=9 "Direction" +// exhaustive.baml:30:14 (operator) len=1 "." +// exhaustive.baml:30:15 (type) 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..e49642c484 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/extends_chain.baml @@ -0,0 +1,80 @@ +// 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 +} + +interface Polite requires Greeter { + function farewell(self) -> string +} + +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: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: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..8d4008688e --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/field_alias.baml @@ -0,0 +1,49 @@ +// 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:10 (keyword) len=2 "as" +// 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 f81d1cebd9..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,36 +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) len=3 "sum" +// 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) len=1 "x" +// 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 d9ced7bddc..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,12 +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 c93ff0aedf..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,30 +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) len=6 "result" +// 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..1232e0070b --- /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:12 ] +// │ +// 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..cc1188f8ad --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/implements_for.baml @@ -0,0 +1,43 @@ +// Out-of-body implements: top-level `implements I for T { ... }` + +interface ToJson { + function to_json(self) -> string +} + +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: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..0eb5e7dc42 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interface_impl.baml @@ -0,0 +1,43 @@ +// Out-of-body implements: top-level `implements I for T { ... }` + +interface ToJson { + function to_json(self) -> string +} + +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: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..cb754171ea --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_inferred_generic_type_args.baml @@ -0,0 +1,1657 @@ +// 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 +} + +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 { + 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 { + return reflect.type_of().to_string() + } + function describe(self) -> string +} + +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 +} + +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 + function nested_self_type(self) -> string { + 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 +} + +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) 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: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) 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) 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:187:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:187:12 (namespace) 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) 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) 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:272:5 (keyword) len=6 "return" +// interfaces_inferred_generic_type_args.baml:272:12 (namespace) 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: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:20 (namespace) len=7 "default" +// 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) 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: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) 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) 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) 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) 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) 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 (keyword) 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 (keyword) 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) 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) 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: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: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) 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: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) 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) 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..ee4ed51ee6 --- /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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) len=4 "true" +// interfaces_iter_core.baml:86:5 (keyword) 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 (keyword) 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 (keyword) len=5 "false" +// interfaces_iter_core.baml:100:5 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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 (keyword) 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..0a5ee00b93 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml @@ -0,0 +1,1377 @@ +// 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) 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) 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) 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) 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) 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) 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) 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: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:43:5 (namespace) 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:36 (operator) len=1 ">" +// interfaces_sort_comparable.baml:43:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:44:5 (namespace) 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:36 (operator) len=1 "<" +// interfaces_sort_comparable.baml:44:38 (number) len=1 "0" +// interfaces_sort_comparable.baml:45:5 (namespace) 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: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) 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) 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) 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) 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 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:63:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:63:20 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:64:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:64:20 (namespace) 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 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:65:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:65:20 (namespace) 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 (namespace) 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) 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) 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) 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) 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) 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) 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: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 (keyword) 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:131:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:131:35 (variable) len=1 "e" +// interfaces_sort_comparable.baml:131:37 (property) len=7 "message" +// interfaces_sort_comparable.baml:133:5 (namespace) 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) 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) len=6 "assert" +// interfaces_sort_comparable.baml:158:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:158:20 (namespace) 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) 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) len=6 "assert" +// interfaces_sort_comparable.baml:166:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:166:20 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:173:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:173:20 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:180:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:180:20 (namespace) 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: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:187:5 (namespace) len=6 "assert" +// interfaces_sort_comparable.baml:187:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:187:20 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:199:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:199:20 (namespace) 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 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:207:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:207:20 (namespace) 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) 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) 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) len=6 "assert" +// interfaces_sort_comparable.baml:213:24 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:213:32 (keyword) 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) 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) 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) 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) len=6 "assert" +// interfaces_sort_comparable.baml:249:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:249:20 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:262:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:262:20 (namespace) 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 (keyword) 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:281:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:281:35 (variable) len=1 "e" +// interfaces_sort_comparable.baml:281:37 (property) len=7 "message" +// interfaces_sort_comparable.baml:283:5 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:289:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:289:20 (namespace) 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) 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 (keyword) len=5 "false" +// interfaces_sort_comparable.baml:304:7 (keyword) len=5 "catch" +// interfaces_sort_comparable.baml:305:9 (class) len=22 "ComparableCompareError" +// interfaces_sort_comparable.baml:305:35 (keyword) len=4 "true" +// interfaces_sort_comparable.baml:306:8 (operator) len=2 "==" +// interfaces_sort_comparable.baml:306:11 (keyword) 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) len=6 "assert" +// interfaces_sort_comparable.baml:311:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:311:20 (namespace) 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) 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 (namespace) 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) len=6 "assert" +// interfaces_sort_comparable.baml:331:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:331:20 (namespace) 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) 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) len=6 "assert" +// interfaces_sort_comparable.baml:361:12 (function) len=7 "is_true" +// interfaces_sort_comparable.baml:361:20 (namespace) 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..3201a29c9c --- /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) len=4 "baml" +// iterator.baml:2:33 (operator) len=1 "." +// iterator.baml:2:34 (namespace) 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) len=4 "baml" +// iterator.baml:6:29 (operator) len=1 "." +// iterator.baml:6:30 (namespace) 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) len=4 "baml" +// iterator.baml:7:8 (namespace) 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..941e03173a --- /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 (keyword) 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..a24009b7e8 --- /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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:5:22 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:6:8 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:10:22 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:11:8 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:15:22 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:17:29 (namespace) 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) len=4 "baml" +// json_parse_stringify_intrinsics.baml:18:38 (namespace) 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..468aee3ac4 --- /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 (keyword) 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 (keyword) 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..4ffbc2bba3 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/map_literal_keys.baml @@ -0,0 +1,183 @@ +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 +// +// +//- 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 a589dd774d..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,21 +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 (type) len=3 "pet" +// match_expr.baml:19:10 (parameter) len=3 "pet" // match_expr.baml:20:5 (keyword) len=3 "let" -// match_expr.baml:20:9 (variable) len=3 "cat" +// 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) len=3 "dog" +// match_expr.baml:21:9 (variable) [declaration] len=3 "dog" // match_expr.baml:21:14 (class) len=3 "Dog" +// 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=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: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..d1e9bbea6b --- /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 (keyword) 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 7eec73f273..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,36 +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:11 (class) len=4 "User" // multi_segment_path.baml:23:18 (property) len=4 "name" -// 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:24 (string) len=4 "\"hi\"" // multi_segment_path.baml:24:3 (keyword) len=3 "let" -// multi_segment_path.baml:24:7 (variable) len=1 "g" +// 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:13 (function) len=5 "greet" +// 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..94e1b99921 --- /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 (namespace) 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) len=4 "baml" +// ns_ansi.baml:16:17 (namespace) 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..b6667cd5d1 --- /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) 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) 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..2950378033 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml @@ -0,0 +1,801 @@ +// 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: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: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: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..0067071359 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/requires_clause.baml @@ -0,0 +1,98 @@ +// 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 { + return self.name + ", " + self.occupation + } +} + +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: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:14:1 (keyword) len=5 "class" +// requires_clause.baml:14:7 (class) [declaration] len=8 "Employee" +// requires_clause.baml:15:3 (property) [declaration] len=4 "name" +// requires_clause.baml:15:9 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:16:3 (property) [declaration] len=3 "age" +// requires_clause.baml:16:8 (type) [defaultLibrary] len=3 "int" +// requires_clause.baml:17:3 (property) [declaration] len=10 "occupation" +// requires_clause.baml:17:15 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:18:3 (property) [declaration] len=6 "salary" +// requires_clause.baml:18:11 (type) [defaultLibrary] len=5 "float" +// requires_clause.baml:20:3 (keyword) len=10 "implements" +// requires_clause.baml:20:14 (interface) len=5 "Named" +// requires_clause.baml:21:3 (keyword) len=10 "implements" +// requires_clause.baml:21:14 (interface) len=4 "Aged" +// requires_clause.baml:22:3 (keyword) len=10 "implements" +// requires_clause.baml:22:14 (interface) len=6 "Person" +// requires_clause.baml:25:1 (keyword) len=8 "function" +// requires_clause.baml:25:10 (function) [declaration] len=8 "get_name" +// requires_clause.baml:25:19 (parameter) [declaration] len=1 "e" +// requires_clause.baml:25:22 (class) len=8 "Employee" +// requires_clause.baml:25:35 (type) [defaultLibrary] len=6 "string" +// requires_clause.baml:26:3 (keyword) len=6 "return" +// requires_clause.baml:26:10 (parameter) len=1 "e" +// requires_clause.baml:26:12 (property) len=4 "name" +// requires_clause.baml:29:1 (keyword) len=8 "function" +// requires_clause.baml:29:10 (function) [declaration] len=7 "get_age" +// requires_clause.baml:29:18 (parameter) [declaration] len=1 "e" +// requires_clause.baml:29:21 (class) len=8 "Employee" +// requires_clause.baml:29:34 (type) [defaultLibrary] len=3 "int" +// 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=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..c7967fd2be --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/self_qualified_call.baml @@ -0,0 +1,78 @@ +// 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 +} + +interface Farewell { + function bye(self) -> string +} + +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: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: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..34ecbd94c7 --- /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) len=4 "baml" +// stream_llm_inferred_typeargs.baml:36:40 (operator) len=1 "." +// stream_llm_inferred_typeargs.baml:36:41 (namespace) 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) len=4 "baml" +// stream_llm_inferred_typeargs.baml:37:10 (namespace) 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..02f827f0cc --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/task_group.baml @@ -0,0 +1,358 @@ +// 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) 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) 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:49 (operator) len=1 "=" +// task_group.baml:13:51 (variable) len=1 "g" +// task_group.baml:13:56 (namespace) len=4 "baml" +// task_group.baml:13:61 (namespace) len=3 "sys" +// task_group.baml:13:65 (function) len=5 "sleep" +// task_group.baml:13:71 (namespace) len=4 "baml" +// task_group.baml:13:76 (namespace) 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: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) 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:49 (operator) len=1 "=" +// task_group.baml:14:51 (variable) len=1 "g" +// task_group.baml:14:56 (namespace) len=4 "baml" +// task_group.baml:14:61 (namespace) len=3 "sys" +// task_group.baml:14:65 (function) len=5 "sleep" +// task_group.baml:14:71 (namespace) len=4 "baml" +// task_group.baml:14:76 (namespace) 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: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) 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:49 (operator) len=1 "=" +// task_group.baml:15:51 (variable) len=1 "g" +// task_group.baml:15:56 (namespace) len=4 "baml" +// task_group.baml:15:61 (namespace) len=3 "sys" +// task_group.baml:15:65 (function) len=5 "sleep" +// task_group.baml:15:71 (namespace) len=4 "baml" +// task_group.baml:15:76 (namespace) 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: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) 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:49 (operator) len=1 "=" +// task_group.baml:16:51 (variable) len=1 "g" +// task_group.baml:16:56 (namespace) len=4 "baml" +// task_group.baml:16:61 (namespace) len=3 "sys" +// task_group.baml:16:65 (function) len=5 "sleep" +// task_group.baml:16:71 (namespace) len=4 "baml" +// task_group.baml:16:76 (namespace) 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: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) len=6 "assert" +// task_group.baml:23:12 (function) len=7 "is_true" +// task_group.baml:23:20 (namespace) 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) 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) 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: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) 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: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) 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: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) 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: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) 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: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) len=6 "assert" +// task_group.baml:38:12 (function) len=7 "is_true" +// task_group.baml:38:20 (namespace) 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) 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) 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:49 (operator) len=1 "=" +// task_group.baml:45:51 (variable) len=1 "g" +// task_group.baml:45:56 (namespace) len=4 "baml" +// task_group.baml:45:61 (namespace) len=3 "sys" +// task_group.baml:45:65 (function) len=5 "sleep" +// task_group.baml:45:71 (namespace) len=4 "baml" +// task_group.baml:45:76 (namespace) 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: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:27 (namespace) len=4 "baml" +// task_group.baml:47:31 (operator) len=1 "." +// task_group.baml:47:32 (namespace) 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) len=6 "assert" +// task_group.baml:51:12 (function) len=7 "is_true" +// task_group.baml:51:20 (namespace) 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) 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) len=6 "assert" +// task_group.baml:63:12 (function) len=7 "is_true" +// task_group.baml:63:20 (namespace) 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..f452506351 --- /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) 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..c7bc8cb95a --- /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) 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) 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..02f78b2b1a --- /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) len=4 "baml" +// testset_vibes_nested.baml:29:28 (namespace) 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) 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) 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..3d94e00b5f --- /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:51 ] +// │ +// 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..960d66f424 --- /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 (keyword) 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 (keyword) 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..8322d03c27 --- /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) 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) 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/bex_project/src/bex_lsp/multi_project/request.rs b/baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs index f283b75c13..6b6ed8d5a9 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,7 +44,10 @@ 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, @@ -344,7 +347,7 @@ impl BexLspRequest for BexMulitProject { delta_start, length, token_type: token.token_type.legend_index(), - token_modifiers_bitset: 0, + token_modifiers_bitset: token.modifiers.bits(), }); prev_line = pos.line; 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..6a1e2a9dc9 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/Cargo.toml @@ -0,0 +1,30 @@ +[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 } +# Reuses the inline-assertion test harness (parser / runner / updater) so the +# viewer computes the exact same token output the tests do, reads the committed +# `//- semantic_tokens` expectations, and "accepts" via the real UPDATE_EXPECT path. +baml_lsp2_actions_tests = { path = "../baml_lsp2_actions_tests" } +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..ac1c1f6c78 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/analysis.rs @@ -0,0 +1,272 @@ +//! 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()) + .unwrap_or_default(); + + 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, +/// added, or removed) — keyed by (line, col, len), matching the snapshot. +pub(crate) fn diff_count(current: &[Token], expected: &[Token]) -> usize { + let key = |t: &Token| (t.line, t.col, t.len); + // Signature = type + modifiers, so a modifier change registers as a diff. + let sig = |t: &Token| (t.ty.clone(), t.mods.clone()); + let cur: HashMap<_, _> = current.iter().map(|t| (key(t), sig(t))).collect(); + let exp: HashMap<_, _> = expected.iter().map(|t| (key(t), 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) -> Vec { + let mut names: Vec = fs::read_dir(dir) + .into_iter() + .flatten() + .flatten() + .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(); + 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..94990b3249 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/index.html @@ -0,0 +1,522 @@ + + + + + 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..d1bda610b4 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/main.rs @@ -0,0 +1,112 @@ +//! 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 offset in 0..50 { + let port = base + offset; + 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 + 50) +} + +/// 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..607d767500 --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/server.rs @@ -0,0 +1,197 @@ +//! 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) -> Json { + let dir = state.fixtures_dir.as_ref(); + let names = analysis::list_fixture_names(dir); + + // 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() + }); + + 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 path = dir.join(name); + if !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..2c93cc528e --- /dev/null +++ b/baml_language/crates/tools_semantic_tokens/src/staleness.rs @@ -0,0 +1,113 @@ +//! 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 classifier (`baml_lsp2_actions`) and viewer sources. +fn newest_source_mtime() -> Option { + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + let roots = [ + manifest.join("src"), + manifest.join("../baml_lsp2_actions/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); + } +} From ca0761d5a3100cf84fdcc1e1331c29f48a538ce6 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 01:46:56 -0700 Subject: [PATCH 02/17] feat(lsp): on-demand per-scope resolution + range/viewport tokens + boolean literals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the semantic-tokens classifier toward the rust-analyzer architecture: - scope_resolution_index: a per-ScopeId salsa-cached resolution index (RA's body-granularity memoization) — editing one scope only invalidates that scope's index, not the whole file. build() merges them for a full document; resolve_token_class resolves a single name on demand (RA's Semantics::resolve model), walking the scope chain. - semantic_tokens_in_range: viewport highlighting (RA's highlight_range) — a range-gated walk that skips out-of-range subtrees and resolves on demand, so only the scopes the viewport touches are ever indexed. Proven equal to the full result filtered to the range across every sub-range (new range_tokens_test). - boolean semantic-token type: true/false -> `boolean` (was keyword). The inert KW_TRUE/FALSE/NULL/AS/TYPE token kinds + is_ident_token/is_keyword updates are laid for the principled parser-token remap (deferred: it ripples into hover/formatter/CST snapshots — see tokens/DESIGN.md). - tokens/DESIGN.md + GAPS.md: target RA architecture, prerequisite parser/AST changes, and remaining phases (LSP range/delta wiring, flat traversal, parser-token remap, typed-AST accessors). --- baml_language/crates/baml_cli/src/paint.rs | 2 +- .../baml_compiler2_ast/src/lower_expr_body.rs | 8 + .../crates/baml_compiler_parser/src/parser.rs | 8 +- .../baml_compiler_syntax/src/syntax_kind.rs | 8 + .../crates/baml_lsp2_actions/src/tokens.rs | 88 +- .../baml_lsp2_actions/src/tokens/DESIGN.md | 125 ++ .../baml_lsp2_actions/src/tokens/index.rs | 76 +- .../crates/baml_lsp2_actions_tests/src/lib.rs | 1 + .../src/range_tokens_test.rs | 51 + .../semantic_tokens/break_continue.baml | 2 +- .../semantic_tokens/cancel_token.baml | 6 +- .../semantic_tokens/config_dictionary.baml | 2 +- ...interfaces_inferred_generic_type_args.baml | 4 +- .../semantic_tokens/interfaces_iter_core.baml | 42 +- .../interfaces_sort_comparable.baml | 8 +- .../test_files/semantic_tokens/watch_let.baml | 4 +- ...anned_expressions__05_diagnostics.snap.new | 490 +++++ ...s__bigint_literal__05_diagnostics.snap.new | 292 +++ ...e_string_literals__05_diagnostics.snap.new | 292 +++ ..._string_in_config__05_diagnostics.snap.new | 292 +++ ...nfig_model_string__05_diagnostics.snap.new | 292 +++ ...union_arithmetic__02_parser__main.snap.new | 261 +++ ..._union_arithmetic__05_diagnostics.snap.new | 292 +++ ...on_arithmetic__10_formatter__main.snap.new | 71 + ...al_union_widening__05_diagnostics.snap.new | 292 +++ ...xpressions__02_parser__precedence.snap.new | 92 + ...arser_expressions__05_diagnostics.snap.new | 292 +++ ...essions__10_formatter__precedence.snap.new | 19 + ...__test_expr_basic__05_diagnostics.snap.new | 292 +++ ...expr_name_concat__02_parser__main.snap.new | 64 + ...es__test_expr_name_concat__03_hir.snap.new | 8 + ..._expr_name_concat__05_diagnostics.snap.new | 292 +++ ...xpr_throwing_body__05_diagnostics.snap.new | 292 +++ ..._expr_with_runner__05_diagnostics.snap.new | 292 +++ ...ent_expr_position__05_diagnostics.snap.new | 313 +++ ...at_checks__02_parser__binary_expr.snap.new | 1246 +++++++++++ ...t_checks__02_parser__config_decls.snap.new | 1904 +++++++++++++++++ ...at_checks__02_parser__other_exprs.snap.new | 1615 ++++++++++++++ ...checks__10_formatter__binary_expr.snap.new | 227 ++ ..._name_type_error__02_parser__main.snap.new | 78 + ...test_expr_name_type_error__03_hir.snap.new | 8 + ...test_expr_name_type_error__04_tir.snap.new | 39 + ...r_name_type_error__05_diagnostics.snap.new | 322 +++ ...xpr_wrong_runner__02_parser__main.snap.new | 92 + ...expr_wrong_runner__05_diagnostics.snap.new | 322 +++ ..._wrong_runner__10_formatter__main.snap.new | 29 + 46 files changed, 10785 insertions(+), 62 deletions(-) create mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md create mode 100644 baml_language/crates/baml_lsp2_actions_tests/src/range_tokens_test.rs create mode 100644 baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new create mode 100644 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.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new create mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new diff --git a/baml_language/crates/baml_cli/src/paint.rs b/baml_language/crates/baml_cli/src/paint.rs index 344a1ce2e2..0e324bacb2 100644 --- a/baml_language/crates/baml_cli/src/paint.rs +++ b/baml_language/crates/baml_cli/src/paint.rs @@ -104,7 +104,7 @@ fn style_for(token_type: SemanticTokenType) -> Style { T::Namespace => Style::new().cyan().bright(), T::String | T::Regexp => Style::new().green(), T::EscapeSequence => Style::new().color256(214), - T::Number => Style::new().yellow().bright(), + 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 b43842f762..1bd3b7d3bc 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_compiler_parser/src/parser.rs b/baml_language/crates/baml_compiler_parser/src/parser.rs index e63b82f210..80af3cbc83 100644 --- a/baml_language/crates/baml_compiler_parser/src/parser.rs +++ b/baml_language/crates/baml_compiler_parser/src/parser.rs @@ -6188,10 +6188,14 @@ 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 + // Boolean literal. NOTE: re-lexing these as KW_TRUE/KW_FALSE (the + // principled form) ripples into hover/completions/formatter/CST + // snapshots — deferred until every token-kind consumer is mapped + // and updated. The highlighter classifies them as `boolean` via a + // transitional text match in `tokens.rs::token` for now. self.bump(); } else if text == "null" { - // Null literal + // Null literal (same KW_NULL deferral as above). self.bump(); } else { // Identifier or path (could be multi-segment like baml.HttpMethod.Get) 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 959da0231b..5643dc4e20 100644 --- a/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs +++ b/baml_language/crates/baml_compiler_syntax/src/syntax_kind.rs @@ -51,6 +51,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) @@ -546,6 +552,8 @@ impl SyntaxKind { | Self::KW_INSTANCEOF | Self::KW_DYNAMIC | Self::KW_WITH + | Self::KW_AS + | Self::KW_TYPE ) } } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index 99934fc725..4c278df684 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -61,6 +61,9 @@ pub enum SemanticTokenType { 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. @@ -91,6 +94,7 @@ pub const TOKEN_TYPES: &[SemanticTokenType] = &[ SemanticTokenType::Operator, SemanticTokenType::Decorator, SemanticTokenType::EscapeSequence, + SemanticTokenType::Boolean, ]; impl SemanticTokenType { @@ -132,6 +136,7 @@ impl SemanticTokenType { Self::Operator => "operator", Self::Decorator => "decorator", Self::EscapeSequence => "escapeSequence", + Self::Boolean => "boolean", } } } @@ -312,32 +317,73 @@ fn emit_node(node: &SyntaxNode, token_type: SemanticTokenType, out: &mut Vec 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, - index: index::build(db, file), + resolve: Box::new(move |range| index.get(&range).copied()), + range: None, }; let mut out = Vec::new(); walk.node(&root, &mut out); out } +/// 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, + range: TextRange, +) -> Vec { + 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.node(&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 +} + // ── Walker ───────────────────────────────────────────────────────────────────── /// A document-order CST walk that classifies each token exactly once. /// -/// Holds the resolution index so the structural dispatch never threads it; an -/// identifier inside an expression body is looked up there, a declaration name is -/// classified by its declaring node, and every other token is syntactic. +/// `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, - index: index::ResolutionIndex, + 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 Walk<'_> { /// Dispatch a node to its classifier. fn node(&self, node: &SyntaxNode, out: &mut Vec) { + // 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() { + return; + } + } match node.kind() { ref n if n.is_comment() => emit_node(node, SemanticTokenType::Comment, out), // Escape-processing literals: split out `\n`, `\xNN`, `\u{..}`, ... @@ -423,14 +469,34 @@ impl Walk<'_> { if kind.is_whitespace() { return; } + // Boolean / null literals: a dedicated `KW_TRUE`/`KW_FALSE`/`KW_NULL` + // token (value position, re-lexed by the parser). `true`/`false` -> + // `boolean`, `null` -> `keyword`. + match kind { + SyntaxKind::KW_TRUE | SyntaxKind::KW_FALSE => { + emit(token.text_range(), plain(SemanticTokenType::Boolean), out); + return; + } + SyntaxKind::KW_NULL => { + emit(token.text_range(), plain(SemanticTokenType::Keyword), out); + return; + } + _ => {} + } if kind == SyntaxKind::WORD { - if let Some(class) = self.index.get(&token.text_range()).copied() { + if let Some(class) = (self.resolve)(token.text_range()) { emit(token.text_range(), class, out); - } else if matches!(token.text(), "true" | "false" | "null") { - // Boolean / null literals lex as words and lower to - // `Expr::Literal` / `Expr::Null`, so they never enter the - // expression index; classify them as the keyword-literals they are. - emit(token.text_range(), plain(SemanticTokenType::Keyword), out); + } else { + // Transitional: type/config-position `true`/`false`/`null` are + // still bare WORDs until those parse sites are re-lexed too; give + // them the same classification as the `KW_*` value-position form. + match token.text() { + "true" | "false" => { + emit(token.text_range(), plain(SemanticTokenType::Boolean), out); + } + "null" => emit(token.text_range(), plain(SemanticTokenType::Keyword), out), + _ => {} + } } return; } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md new file mode 100644 index 0000000000..abafb19c35 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md @@ -0,0 +1,125 @@ +# Principled rust-analyzer-style semantic tokens — design & plan + +Target: the rust-analyzer highlighting architecture, faithfully, with the +prerequisite parser/AST changes it requires. No shortcuts. The 78 fixtures are +the behavior-preservation oracle at every step. + +## RA architecture (what we mirror) + +- `highlight(db, cfg, file, range: Option) -> Vec`. For a + range, root = `covering_element(range)`; else the whole file. +- `traverse`: one `preorder_with_tokens()` `WalkEvent::{Enter,Leave}` loop with a + small enter/leave **state stack**; per element, `range.intersect(elem).is_none() + -> continue`. Tokens classify **syntactically** (`highlight::token`: literals / + comments / punctuation(kind,parent_kind) / keyword(kind)). `ast::NameLike` nodes + classify **semantically** (`name_like -> NameClass/NameRefClass::classify -> + highlight_def`), then `skip_subtree()` so the inner ident token isn't re-done. +- Name bridge: `IdentClass::classify_token(token) = token.parent()` -> match + `ast::Name` (def site) | `ast::NameRef` (ref site). NameRef spine: `NameRef -> + PathSegment -> Path -> sema.resolve_path -> PathResolution -> Definition`. + `highlight_def(Definition) -> HlTag::Symbol(SymbolKind) + mods`. +- On-demand + memoized: each classify routes through `Semantics::analyze` (a + per-body `SourceAnalyzer`, source-to-def cache) and salsa-memoized + `InferenceResult::of(body)`. First token in a body pays inference; rest reuse. +- LSP: `full` (compute + cache by uri + result_id), `full/delta` (compute full + + diff token arrays), `range` (separate `highlight_range(frange)`). + +## Our analog (what we already have / map to) + +- Lossless CST (rowan) + `baml_compiler_syntax::ast` typed accessors = RA syntax + tree + `ast::*`. Event-buffer parser with `with_node`/`wrap_events_in_node`. +- `Semantics`/`SourceAnalyzer`/`InferenceResult::of` analog: `resolve_name_at` + (offset name res), `scope_body` (uniform scope->(ExprBody,source_map)), + `infer_scope_types` (salsa-memoized **per ScopeId** — our body-granularity + memo seam). No macros -> drop `descend_into_macros`/`Ranker` entirely. +- `Definition`/`highlight_def` = our `Resolution` + `classify.rs`. We do NOT copy + RA's 24-variant Definition; ours is small (class/enum/interface/function/method/ + field/variant/param/local/type-alias/assoc-type/client/test/...). + +## Prerequisite parser / AST changes (the foundation — do first, principled) + +These remove the corners the current classifier cuts (text-matching literals/ +keywords, positional structure recovery). + +**P1 — Real literal & contextual-keyword tokens (parser/lexer/SyntaxKind).** +- Add `KW_TRUE`, `KW_FALSE`, `KW_NULL` token kinds. `true`/`false`/`null` must be + syntactic, not text-matched (today bumped as WORD; recovered via `text==..` in + ast.rs:711/3906, parser.rs:6190/6024/7437). Mechanism: lexer keywords if BAML + reserves them, else uniform contextual remap at every literal site. Add to + `is_literal` (true/false/null) — they classify as `boolean`/`keyword`. +- Add a custom `boolean` semantic-token type (RA's `BoolLiteral`); `true`/`false` + -> `boolean`, `null` -> `keyword`/builtin. Wire legend + enum + paint.rs + viewer. +- Uniformly remap the remaining contextual keywords: `KW_AS` (`.as` cast, + `(T as I)`, `field as field`), `KW_TYPE` (assoc-type / type-alias) — today + bumped as plain WORD and re-detected by `text=="as"`/`"type"`. After remap, + `is_keyword` sees them and resolution stops string-matching. +- Reconcile `is_operator` (drop phantom `QUESTION_QUESTION`, add real compound + assigns / single `QUESTION` / etc. that the parser actually emits) and add + `HEADER_COMMENT` to `is_trivia`. + +**P2 — Typed AST union enums + wrappers (baml_compiler_syntax/src/ast.rs, +accessor-only; CST already supports unless noted).** The classifier must read +structure off `ast::*`, not positionally. +- `ast::Expr` union enum (the core RA pattern) + `ast::Pattern`, `ast::Type` + unions so child-expr accessors return typed nodes (today `FieldAccessExpr::base`, + control-flow accessors return raw `SyntaxNode`). +- Wrappers + accessors: `ObjectLiteral` (`type_name()`/`path()` + `fields()`), + `ObjectField` (`key()`/`value()`), `CallExpr` (`callee()`+`args()`) + `CallArgs`, + `BinaryExpr` (`lhs()`/`op_token()`/`rhs()`), `SpawnExpr` (`name_expr()`/`body()`), + `AwaitExpr`, give `UpcastExpr` real `base()`/`target_type()`, `GenericArgs`/ + `TypeArgs` (`args()`/`named_bindings()`), `TypeExpr::path_segments()` (mirror of + `PathExpr::segments`), `GeneratorDef`/`TestsetDef`/`TestExprDef` (`name()`) + + extend the `Item` enum, pattern wrappers (BINDING/DESTRUCTURE/FIELD/ARRAY/TYPE/ + WILDCARD/UNION/CHAIN). Lower-pri: Array/Map/Index/Lambda/Paren/Tagged/Is/Unary. +- Resolve the object-literal-generic-head mismatch: `Foo {}` head is emitted + as `PATH_EXPR` not `TYPE_ARGS` — normalize in parser or expose via ObjectLiteral. +- Def-vs-ref: our CST has no `ast::Name`/`ast::NameRef` split; classify by the + identifier token's **parent node kind** (decl node -> def site; path/member/type + -> ref site). No grammar change needed for this. +- (Lower-pri) `parse_generator` opaque body leaves interior strings un-noded. + +## P1 finding (2026-06): token-kind remap has a broad blast radius + +Re-lexing `true`/`false`/`null` from `WORD` to `KW_TRUE`/`KW_FALSE`/`KW_NULL` +(the principled form) compiles + passes the compiler logic tests, but ripples +into **every consumer keyed on the token kind**: hover (`on_hover` iterator +inference tests changed — hover resolves off the token), CST/parser/formatter +snapshots (`baml_tests` config_dictionary/json_map_literal), etc. So the +remap is NOT highlighter-local; it requires mapping and updating hover / +completions / definition / formatter / lowering and regenerating their +snapshots. **Deferred** until that full consumer map is done (a fan-out search). +For now the `boolean` token type is delivered via a transitional text match in +`tokens.rs::token` (true/false -> `boolean`, null -> `keyword`); the inert +`KW_*` kinds + `is_ident_token`/`is_keyword` additions are already in place, +ready for the proper remap. `as`/`type` highlighting already works via the +existing context handlers, so the remap is a *mechanism* upgrade, not a feature. + +## Revised sequencing: architecture first, parser-token remap as a mapped follow-up + +The RA *system* (Phases B/C/D) is LSP-only — no parser change, no broad +fallout — and is the high-value core. Do it first; do the broad parser-token +remap (P1 full) afterward as a carefully-mapped change. + +## Phases (each ends green: 78 fixtures unchanged unless the change is the point) + +- **A. Parser/AST prerequisites (P1 then P2).** Land literal/keyword tokens + + `is_*` fixes (update walker to read new kinds; output preserved except + true/false -> `boolean`). Then land typed-AST union enums + wrappers (additive; + no classifier change yet). +- **B. `Semantics` bridge (`resolve_token`).** token -> parent-kind dispatch -> + Resolution (root via `resolve_name_at`; member via `scope_body`+inference; + qualified via `resolve_path_at`; type via type res) -> classify. On-demand, + reusing `infer_scope_types` memo. Validate equals the current index per-token. +- **C. Flat traversal.** Replace recursive `node()`/handlers with one + `preorder_with_tokens()` loop: syntactic token classify + `resolve_token` for + names, reading context off the new typed-AST accessors; range-gate ready. Drop + `index::build`. Validate fixtures unchanged. +- **D. LSP scaling.** Range (`covering_element` + range-gated walk; advertise + + handler). Delta (stable `result_id` + per-uri encoded-token cache + prefix/ + suffix diff; advertise `Delta{delta:true}`). Unify position encoding. + +## Validation discipline +Every slice: `cargo check` the touched crates; run the 78 `semantic_tokens` +fixtures WITHOUT `UPDATE_EXPECT` (must stay green, except the deliberate +true/false->boolean change); run tir/mir + runtime interface tests after any +parser/inference change; clippy clean. Adversarial review at each phase boundary. diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs index 722b2d9ced..9afd30408d 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs @@ -17,10 +17,11 @@ //! handled by the walker from their `BINDING_PATTERN` CST nodes, not here. use std::collections::HashMap; +use std::sync::Arc; use baml_base::SourceFile; use baml_compiler2_ast::{Expr, ExprBody, ExprId}; -use baml_compiler2_hir::scope::ScopeKind; +use baml_compiler2_hir::scope::{ScopeId, ScopeKind}; use baml_compiler2_tir::{ inference::{ScopeInference, infer_scope_types, scope_body}, resolve::{ResolvedName, resolve_name_at, resolve_path_at}, @@ -41,17 +42,67 @@ fn record(index: &mut ResolutionIndex, span: TextRange, class: (SemanticTokenTyp } } -/// Build the resolution index over every inference-bearing scope in `file`. +/// On-demand classification of a single name token: which scope's inference +/// owns the expression at `range`, indexed lazily and cached per scope. /// -/// Iterates each `Function` / `Lambda` / `Let` scope and indexes its body via -/// the uniform [`scope_body`] lookup, so names inside lambdas, `spawn` blocks, -/// and other closures are classified with their own scope's inference — not -/// just top-level function bodies. Synthetic template-string bodies are skipped: -/// their expressions are typed inline in the enclosing scope and indexed there. +/// 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]; + if let Some(class) = scope_resolution_index(db, scope_id).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!( @@ -61,13 +112,10 @@ pub(super) fn build(db: &dyn Db, file: SourceFile) -> ResolutionIndex { { continue; } - let Some(body) = scope_body(db, sem_index.scope_ids[i]) else { - continue; - }; - let inference = infer_scope_types(db, body.scope); - index_function(db, file, &body.expr_body, &body.source_map, inference, &mut index); + for (&span, &class) in scope_resolution_index(db, sem_index.scope_ids[i]).iter() { + record(&mut index, span, class); + } } - index } 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..1e15520204 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,4 @@ pub mod updater; mod test_files { include!(concat!(env!("OUT_DIR"), "/generated_lsp2_tests.rs")); } +mod range_tokens_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..83d5da7df1 --- /dev/null +++ b/baml_language/crates/baml_lsp2_actions_tests/src/range_tokens_test.rs @@ -0,0 +1,51 @@ +//! 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 baml_lsp2_actions::tokens::{semantic_tokens, semantic_tokens_in_range}; + use baml_project::ProjectDatabase; + use std::path::Path; + + 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); + 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/test_files/semantic_tokens/break_continue.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/break_continue.baml index 0fd4dbc1b6..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 @@ -33,7 +33,7 @@ function SumOdds() -> int { // 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 (keyword) len=4 "true" +// 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 "==" 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 index b01b1444a6..693d10bf7a 100644 --- 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 @@ -193,8 +193,8 @@ test "detached_spawn_completes" { // cancel_token.baml:49:20 (namespace) 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 (keyword) len=5 "false" -// cancel_token.baml:49:83 (keyword) len=4 "true" +// 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)." @@ -210,7 +210,7 @@ test "detached_spawn_completes" { // cancel_token.baml:56:29 (keyword) len=5 "spawn" // cancel_token.baml:56:35 (function) len=7 "options" // cancel_token.baml:56:50 (operator) len=1 "=" -// cancel_token.baml:56:52 (keyword) len=4 "true" +// 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" 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 index b673c8f04e..a5ad499642 100644 --- 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 @@ -103,7 +103,7 @@ client MyClient { // 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 (keyword) len=4 "true" +// 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" 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 index cb754171ea..ac4c2bb83a 100644 --- 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 @@ -1368,7 +1368,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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 (keyword) len=4 "true" +// 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" @@ -1472,7 +1472,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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 (keyword) len=4 "true" +// 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" 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 index ee4ed51ee6..1e1c6e4491 100644 --- 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 @@ -636,7 +636,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -663,7 +663,7 @@ class Chain { // 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 (keyword) len=5 "false" +// 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" @@ -684,7 +684,7 @@ class Chain { // 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 (keyword) len=5 "false" +// 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" @@ -696,7 +696,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -735,7 +735,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -762,7 +762,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -792,7 +792,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -805,8 +805,8 @@ class Chain { // 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 (keyword) len=4 "true" -// interfaces_iter_core.baml:86:5 (keyword) len=5 "false" +// 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 "<" @@ -824,7 +824,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -838,8 +838,8 @@ class Chain { // 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 (keyword) len=5 "false" -// interfaces_iter_core.baml:100:5 (keyword) len=4 "true" +// 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 "<" @@ -857,7 +857,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1331,7 +1331,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1408,7 +1408,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1510,7 +1510,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1622,7 +1622,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1716,7 +1716,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" @@ -1764,7 +1764,7 @@ class Chain { // 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 (keyword) len=5 "false" +// 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" @@ -1823,7 +1823,7 @@ class Chain { // 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 (keyword) len=5 "false" +// 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" @@ -1918,7 +1918,7 @@ class Chain { // 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 (keyword) len=4 "true" +// 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" 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 index 0a5ee00b93..d7fb4fb459 100644 --- 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 @@ -966,7 +966,7 @@ test "sort_user_class_out_of_body_impl" { // interfaces_sort_comparable.baml:213:9 (type) [defaultLibrary] len=4 "null" // interfaces_sort_comparable.baml:213:17 (namespace) len=6 "assert" // interfaces_sort_comparable.baml:213:24 (function) len=7 "is_true" -// interfaces_sort_comparable.baml:213:32 (keyword) len=5 "false" +// 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" @@ -1212,12 +1212,12 @@ test "sort_user_class_out_of_body_impl" { // 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 (keyword) len=5 "false" +// interfaces_sort_comparable.baml:303:9 (boolean) len=5 "false" // interfaces_sort_comparable.baml:304:7 (keyword) len=5 "catch" // interfaces_sort_comparable.baml:305:9 (class) len=22 "ComparableCompareError" -// interfaces_sort_comparable.baml:305:35 (keyword) len=4 "true" +// 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 (keyword) len=5 "false" +// 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 "=" 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 index 960d66f424..86fea8675b 100644 --- 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 @@ -293,7 +293,7 @@ function while_body_restores_outer() -> int { // 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 (keyword) len=4 "true" +// 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" @@ -302,5 +302,5 @@ function while_body_restores_outer() -> int { // 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 (keyword) len=5 "false" +// 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_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new new file mode 100644 index 0000000000..5d2ae5c8a3 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new @@ -0,0 +1,490 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 131 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [parse] error: Expected expression, found let + ╭─[ banned_expressions.baml:3:11 ] + │ + 3 │ let a = let b = 42 + │ ─┬─ + │ ╰─── Expected expression, found let + │ + │ Note: Error code: E0010 +───╯ + + [type] error: unresolved name: b + ╭─[ banned_expressions.baml:3:15 ] + │ + 3 │ let a = let b = 42 + │ ┬ + │ ╰── unresolved name: b + │ + │ Note: Error code: E0003 +───╯ + + [type] error: unresolved name: a + ╭─[ banned_expressions.baml:4:3 ] + │ + 4 │ a + │ ┬ + │ ╰── unresolved name: a + │ + │ Note: Error code: E0003 +───╯ + + [type] error: missing return value of type int + ╭─[ banned_expressions.baml:8:22 ] + │ + 8 │ ╭─▶ function Bar() -> int { + ┆ ┆ + 10 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type int + │ + │ Note: Error code: E0029 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:22:4 ] + │ + 22 │ (x = 5) + │ ──┬── + │ ╰──── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:28:4 ] + │ + 28 │ (x += 5) + │ ───┬── + │ ╰──── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:33:14 ] + │ + 33 │ ╭─▶ let x = 10; + 34 │ ├─▶ let y = (x = 5); + │ │ + │ ╰──────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:34:12 ] + │ + 34 │ let y = (x = 5); + │ ──┬── + │ ╰──── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:63:56 ] + │ + 63 │ ╭─▶ function ParenSafeAssignField(user: User?) -> string? { + 64 │ ├─▶ let result = (user?.profile?.name = "new_name"); + │ │ + │ ╰──────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:64:17 ] + │ + 64 │ let result = (user?.profile?.name = "new_name"); + │ ────────────────┬─────────────── + │ ╰───────────────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:69:55 ] + │ + 69 │ ╭─▶ function ParenSafeAssignIndex(items: int[]?) -> int? { + 70 │ ├─▶ let result = (items?.[0] = 42); + │ │ + │ ╰─────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:70:17 ] + │ + 70 │ let result = (items?.[0] = 42); + │ ───────┬─────── + │ ╰───────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:75:56 ] + │ + 75 │ ╭─▶ function ParenSafeCompoundAssign(user: User?) -> int? { + 76 │ ├─▶ let result = (user?.id += 1); + │ │ + │ ╰───────────────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:76:17 ] + │ + 76 │ let result = (user?.id += 1); + │ ──────┬────── + │ ╰──────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:82:4 ] + │ + 82 │ (user?.profile?.name = "updated") + │ ───────────────┬─────────────── + │ ╰───────────────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:86:57 ] + │ + 86 │ ╭─▶ function ParenSafeAssignDeepChain(node: Node?) -> int? { + 87 │ ├─▶ let result = (node?.children?.[0].value = 99); + │ │ + │ ╰────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:87:17 ] + │ + 87 │ let result = (node?.children?.[0].value = 99); + │ ───────────────┬────────────── + │ ╰──────────────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ banned_expressions.baml:92:56 ] + │ + 92 │ ╭─▶ function ParenSafeAssignMapIndex(node: Node?) -> int? { + 93 │ ├─▶ let result = (node?.labels?.["main"].value = 50); + │ │ + │ ╰───────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +────╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ banned_expressions.baml:93:17 ] + │ + 93 │ let result = (node?.labels?.["main"].value = 50); + │ ────────────────┬──────────────── + │ ╰────────────────── assignment not allowed here + │ + │ Note: Error code: E0010 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new new file mode 100644 index 0000000000..188b893036 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 6146 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new new file mode 100644 index 0000000000..718a41e5f6 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 6491 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new new file mode 100644 index 0000000000..210d960f08 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 8216 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new new file mode 100644 index 0000000000..248dce15b5 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 9250 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new new file mode 100644 index 0000000000..e0da1ccb24 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new @@ -0,0 +1,261 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 16401 +--- +=== SYNTAX TREE === +SOURCE_FILE + FUNCTION_DEF + KW_FUNCTION "function" + WORD "ifElseAdd" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR + INTEGER_LITERAL "1" + PLUS "+" + IF_EXPR + KW_IF "if" + PAREN_EXPR "(true)" + L_PAREN "(" + KW_TRUE "true" + R_PAREN ")" + BLOCK_EXPR "{ 2 }" + L_BRACE "{" + INTEGER_LITERAL "2" + R_BRACE "}" + KW_ELSE "else" + BLOCK_EXPR "{ 3 }" + L_BRACE "{" + INTEGER_LITERAL "3" + R_BRACE "}" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "matchAdd" + PARAMETER_LIST + L_PAREN "(" + PARAMETER + WORD "x" + COLON ":" + TYPE_EXPR "int" + WORD "int" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR + MATCH_EXPR + KW_MATCH "match" + L_PAREN "(" + WORD "x" + R_PAREN ")" + L_BRACE "{" + MATCH_ARM + PATTERN + TYPE_PATTERN + TYPE_EXPR "1" + INTEGER_LITERAL "1" + FAT_ARROW "=>" + INTEGER_LITERAL "10" + COMMA "," + MATCH_ARM + PATTERN + TYPE_PATTERN + TYPE_EXPR "2" + INTEGER_LITERAL "2" + FAT_ARROW "=>" + INTEGER_LITERAL "20" + COMMA "," + MATCH_ARM + PATTERN + WILDCARD_PATTERN "_" + WORD "_" + FAT_ARROW "=>" + INTEGER_LITERAL "0" + R_BRACE "}" + PLUS "+" + INTEGER_LITERAL "1" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "bothSidesUnion" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + IF_EXPR + KW_IF "if" + PAREN_EXPR "(true)" + L_PAREN "(" + KW_TRUE "true" + R_PAREN ")" + BLOCK_EXPR "{ 1 }" + L_BRACE "{" + INTEGER_LITERAL "1" + R_BRACE "}" + KW_ELSE "else" + BLOCK_EXPR "{ 2 }" + L_BRACE "{" + INTEGER_LITERAL "2" + R_BRACE "}" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + IF_EXPR + KW_IF "if" + PAREN_EXPR "(false)" + L_PAREN "(" + KW_FALSE "false" + R_PAREN ")" + BLOCK_EXPR "{ 3 }" + L_BRACE "{" + INTEGER_LITERAL "3" + R_BRACE "}" + KW_ELSE "else" + BLOCK_EXPR "{ 4 }" + L_BRACE "{" + INTEGER_LITERAL "4" + R_BRACE "}" + R_PAREN ")" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "subtractUnion" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR + INTEGER_LITERAL "100" + MINUS "-" + IF_EXPR + KW_IF "if" + PAREN_EXPR "(true)" + L_PAREN "(" + KW_TRUE "true" + R_PAREN ")" + BLOCK_EXPR "{ 7 }" + L_BRACE "{" + INTEGER_LITERAL "7" + R_BRACE "}" + KW_ELSE "else" + BLOCK_EXPR "{ 3 }" + L_BRACE "{" + INTEGER_LITERAL "3" + R_BRACE "}" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "loopMatchAccum" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let sum" + KW_LET "let" + WORD "sum" + EQUALS "=" + INTEGER_LITERAL "0" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "let i" + KW_LET "let" + WORD "i" + EQUALS "=" + INTEGER_LITERAL "0" + SEMICOLON ";" + WHILE_STMT + KW_WHILE "while" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "i < 3" + WORD "i" + LESS "<" + INTEGER_LITERAL "3" + R_PAREN ")" + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR + WORD "sum" + EQUALS "=" + BINARY_EXPR + WORD "sum" + PLUS "+" + MATCH_EXPR + KW_MATCH "match" + L_PAREN "(" + WORD "i" + R_PAREN ")" + L_BRACE "{" + MATCH_ARM + PATTERN + TYPE_PATTERN + TYPE_EXPR "0" + INTEGER_LITERAL "0" + FAT_ARROW "=>" + INTEGER_LITERAL "10" + COMMA "," + MATCH_ARM + PATTERN + TYPE_PATTERN + TYPE_EXPR "1" + INTEGER_LITERAL "1" + FAT_ARROW "=>" + INTEGER_LITERAL "20" + COMMA "," + MATCH_ARM + PATTERN + WILDCARD_PATTERN "_" + WORD "_" + FAT_ARROW "=>" + INTEGER_LITERAL "30" + R_BRACE "}" + SEMICOLON ";" + BINARY_EXPR + WORD "i" + EQUALS "=" + BINARY_EXPR "i + 1" + WORD "i" + PLUS "+" + INTEGER_LITERAL "1" + SEMICOLON ";" + R_BRACE "}" + RETURN_STMT "return sum;" + KW_RETURN "return" + WORD "sum" + SEMICOLON ";" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new new file mode 100644 index 0000000000..4644b26444 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 16536 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new new file mode 100644 index 0000000000..9ca4e10b80 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new @@ -0,0 +1,71 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 16650 +--- +function ifElseAdd() -> int { + 1 + + if ( + true + ) { + 2 + } else { + 3 + } +} + +function matchAdd(x: int) -> int { + match (x) { + 1 => 10, + 2 => 20, + _ => 0, + } + + 1 +} + +function bothSidesUnion() -> int { + ( + if ( + true + ) { + 1 + } else { + 2 + } + ) + + ( + if ( + false + ) { + 3 + } else { + 4 + } + ) +} + +function subtractUnion() -> int { + 100 + - if ( + true + ) { + 7 + } else { + 3 + } +} + +function loopMatchAccum() -> int { + let sum = 0; + let i = 0; + while (i < 3) { + sum + = sum + + match (i) { + 0 => 10, + 1 => 20, + _ => 30, + }; + i = i + 1; + } + return sum; +} diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new new file mode 100644 index 0000000000..aa7a761737 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 16880 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new new file mode 100644 index 0000000000..87e602b8c1 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new @@ -0,0 +1,92 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 22169 +--- +=== SYNTAX TREE === +SOURCE_FILE + FUNCTION_DEF + KW_FUNCTION "function" + WORD "TestPrecedence" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "bool" + WORD "bool" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "// Multiplication before addition + let a" + KW_LET "let" + WORD "a" + EQUALS "=" + BINARY_EXPR + INTEGER_LITERAL "2" + PLUS "+" + BINARY_EXPR "3 * 4" + INTEGER_LITERAL "3" + STAR "*" + INTEGER_LITERAL "4" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "// Should be 14, not 20 + let c" + KW_LET "let" + WORD "c" + EQUALS "=" + BINARY_EXPR + BINARY_EXPR "2 * 3" + INTEGER_LITERAL "2" + STAR "*" + INTEGER_LITERAL "3" + PLUS "+" + INTEGER_LITERAL "4" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "// Should be 10, not 14 + + // Comparison after arithmetic + let b" + KW_LET "let" + WORD "b" + EQUALS "=" + BINARY_EXPR + WORD "a" + GREATER ">" + BINARY_EXPR "10 + 2" + INTEGER_LITERAL "10" + PLUS "+" + INTEGER_LITERAL "2" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "// Should be a > 12 + + // Logical operators + let d" + KW_LET "let" + WORD "d" + EQUALS "=" + BINARY_EXPR + KW_TRUE "true" + OR_OR "||" + BINARY_EXPR "false && false" + KW_FALSE "false" + AND_AND "&&" + KW_FALSE "false" + SEMICOLON ";" + RETURN_STMT "// Should be true (AND before OR) + + return d;" + KW_RETURN "return" + WORD "d" + SEMICOLON ";" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new new file mode 100644 index 0000000000..1890eb56b7 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 22400 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new new file mode 100644 index 0000000000..8d6288d587 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new @@ -0,0 +1,19 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 22695 +--- +function TestPrecedence() -> bool { + // Multiplication before addition + let a = 2 + 3 * 4; // Should be 14, not 20 + let c = 2 * 3 + 4; // Should be 10, not 14 + + // Comparison after arithmetic + let b = a > 10 + 2; // Should be a > 12 + + // Logical operators + let d = true + || false + && false; // Should be true (AND before OR) + + return d; +} diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new new file mode 100644 index 0000000000..60d6e7eedf --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 27523 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ 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.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new new file mode 100644 index 0000000000..e41a18604e --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new @@ -0,0 +1,64 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 27732 +--- +=== SYNTAX TREE === +SOURCE_FILE + TESTSET_DEF + KW_TESTSET "testset" + STRING_LITERAL "concat names" + QUOTE """ + WORD "concat" + WORD "names" + QUOTE """ + BLOCK_EXPR + L_BRACE "{" + TEST_EXPR_DEF + KW_TEST "test" + BINARY_EXPR + STRING_LITERAL "prefix_" + QUOTE """ + WORD "prefix_" + QUOTE """ + PLUS "+" + STRING_LITERAL "suffix" + QUOTE """ + WORD "suffix" + QUOTE """ + BLOCK_EXPR "{ + null + }" + L_BRACE "{" + KW_NULL "null" + R_BRACE "}" + TESTSET_DEF + KW_TESTSET "testset" + BINARY_EXPR + STRING_LITERAL "nested_" + QUOTE """ + WORD "nested_" + QUOTE """ + PLUS "+" + STRING_LITERAL "group" + QUOTE """ + WORD "group" + QUOTE """ + BLOCK_EXPR + L_BRACE "{" + TEST_EXPR_DEF + KW_TEST "test" + STRING_LITERAL "inner" + QUOTE """ + WORD "inner" + QUOTE """ + BLOCK_EXPR "{ + null + }" + L_BRACE "{" + KW_NULL "null" + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new new file mode 100644 index 0000000000..7822a4d9f7 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new @@ -0,0 +1,8 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 27756 +--- +=== HIR2 === +function user.$init_test_main(registry: testing.TestCollector) -> ? [expr] { + { registry.register_test_set("concat names", (testset: testing.TestCollector) -> void { { testset.register_test("prefix_" Add "suffix", () -> { { } }, null); testset.register_test_set("nested_" Add "group", (testset: testing.TestCollector) -> { { testset.register_test("inner", () -> { { } }, null) } null }, null) } null }, null) } null +} diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new new file mode 100644 index 0000000000..abdcad42aa --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 27867 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new new file mode 100644 index 0000000000..d16ac8c3fd --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 28211 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new new file mode 100644 index 0000000000..1cf804dd56 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new @@ -0,0 +1,292 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 28555 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new new file mode 100644 index 0000000000..3251413751 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new @@ -0,0 +1,313 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 33815 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] warning: unreachable code: 1 statement(s) after diverging statement + ╭─[ main.baml:7:16 ] + │ + 7 │ ╭─▶ let x = 10; + 8 │ ├─▶ let y = (x = 5); + │ │ + │ ╰────────────────────────── unreachable code: 1 statement(s) after diverging statement + │ + │ Note: Error code: E0001 +───╯ + + [hir] error: assignment is not allowed in expression position; assignment is a statement + ╭─[ main.baml:8:14 ] + │ + 8 │ let y = (x = 5); + │ ──┬── + │ ╰──── assignment not allowed here + │ + │ Note: Error code: E0010 +───╯ diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new new file mode 100644 index 0000000000..e1745b0e9d --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new @@ -0,0 +1,1246 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 39083 +--- +=== SYNTAX TREE === +SOURCE_FILE + FUNCTION_DEF + KW_FUNCTION "function" + WORD "BinaryExprs" + PARAMETER_LIST + L_PAREN "(" + PARAMETER + WORD "a" + COLON ":" + TYPE_EXPR "int" + WORD "int" + COMMA "," + PARAMETER + WORD "b" + COLON ":" + TYPE_EXPR "int" + WORD "int" + COMMA "," + PARAMETER + WORD "c" + COLON ":" + TYPE_EXPR "int" + WORD "int" + COMMA "," + PARAMETER + WORD "d" + COLON ":" + TYPE_EXPR "int" + WORD "int" + COMMA "," + PARAMETER + WORD "s" + COLON ":" + TYPE_EXPR "string" + WORD "string" + COMMA "," + PARAMETER + WORD "flag" + COLON ":" + TYPE_EXPR "bool" + WORD "bool" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a / b" + WORD "a" + SLASH "/" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a % b" + WORD "a" + PERCENT "%" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a == b" + WORD "a" + EQUALS_EQUALS "==" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a != b" + WORD "a" + NOT_EQUALS "!=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a < b" + WORD "a" + LESS "<" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a > b" + WORD "a" + GREATER ">" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a <= b" + WORD "a" + LESS_EQUALS "<=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a >= b" + WORD "a" + GREATER_EQUALS ">=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "flag && true" + WORD "flag" + AND_AND "&&" + KW_TRUE "true" + SEMICOLON ";" + BINARY_EXPR "flag || false" + WORD "flag" + OR_OR "||" + KW_FALSE "false" + SEMICOLON ";" + BINARY_EXPR "a & b" + WORD "a" + AND "&" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a | b" + WORD "a" + PIPE "|" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a ^ b" + WORD "a" + CARET "^" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a << b" + WORD "a" + LESS_LESS "<<" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a >> b" + WORD "a" + GREATER_GREATER ">>" + WORD "b" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "// ===== Assignment operators ===== + let mut_a" + KW_LET "let" + WORD "mut_a" + EQUALS "=" + WORD "a" + SEMICOLON ";" + BINARY_EXPR "mut_a += b" + WORD "mut_a" + PLUS_EQUALS "+=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a -= b" + WORD "mut_a" + MINUS_EQUALS "-=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a *= b" + WORD "mut_a" + STAR_EQUALS "*=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a /= b" + WORD "mut_a" + SLASH_EQUALS "/=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a %= b" + WORD "mut_a" + PERCENT_EQUALS "%=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a &= b" + WORD "mut_a" + AND_EQUALS "&=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a |= b" + WORD "mut_a" + PIPE_EQUALS "|=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a ^= b" + WORD "mut_a" + CARET_EQUALS "^=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a <<= b" + WORD "mut_a" + LESS_LESS_EQUALS "<<=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "mut_a >>= b" + WORD "mut_a" + GREATER_GREATER_EQUALS ">>=" + WORD "b" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + PLUS "+" + WORD "c" + MINUS "-" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + STAR "*" + WORD "c" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + SLASH "/" + WORD "c" + PERCENT "%" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + OR_OR "||" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "c > 0" + WORD "c" + GREATER ">" + INTEGER_LITERAL "0" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + OR_OR "||" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + OR_OR "||" + BINARY_EXPR "c > 0" + WORD "c" + GREATER ">" + INTEGER_LITERAL "0" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + OR_OR "||" + BINARY_EXPR "c > 0" + WORD "c" + GREATER ">" + INTEGER_LITERAL "0" + SEMICOLON ";" + BINARY_EXPR + WORD "a" + PLUS "+" + BINARY_EXPR "b * c" + WORD "b" + STAR "*" + WORD "c" + SEMICOLON ";" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + WORD "c" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + WORD "a" + PLUS "+" + BINARY_EXPR "b * c" + WORD "b" + STAR "*" + WORD "c" + PLUS "+" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c + d" + WORD "c" + PLUS "+" + WORD "d" + R_PAREN ")" + SEMICOLON ";" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + WORD "c" + R_PAREN ")" + PLUS "+" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + WORD "a" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + WORD "b" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c + d" + WORD "c" + PLUS "+" + WORD "d" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + WORD "c" + R_PAREN ")" + PLUS "+" + WORD "d" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + PLUS "+" + WORD "c" + R_PAREN ")" + MINUS "-" + WORD "d" + R_PAREN ")" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c + d" + WORD "c" + PLUS "+" + WORD "d" + R_PAREN ")" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c - d" + WORD "c" + MINUS "-" + WORD "d" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + BINARY_EXPR "a * c" + WORD "a" + STAR "*" + WORD "c" + STAR "*" + WORD "d" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + BINARY_EXPR "b * c" + WORD "b" + STAR "*" + WORD "c" + STAR "*" + WORD "d" + R_PAREN ")" + R_PAREN ")" + MINUS "-" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a * d" + WORD "a" + STAR "*" + WORD "d" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + BINARY_EXPR "b * c" + WORD "b" + STAR "*" + WORD "c" + STAR "*" + WORD "d" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + BINARY_EXPR "a // 2 left trailing + // 3 operator leading + + // 4 operator trailing + // 5 right leading + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a /* 2 left trailing */ + /* 3 operator leading */ + + /* 4 operator trailing */ + /* 5 right leading */ + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a // 2 first trailing + // 3 first op leading + + // 4 first op trailing + // 5 second leading + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "c > 0" + WORD "c" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "d > 0" + WORD "d" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "a != b" + WORD "a" + NOT_EQUALS "!=" + WORD "b" + AND_AND "&&" + BINARY_EXPR "b != c" + WORD "b" + NOT_EQUALS "!=" + WORD "c" + AND_AND "&&" + BINARY_EXPR "c != d" + WORD "c" + NOT_EQUALS "!=" + WORD "d" + AND_AND "&&" + BINARY_EXPR + WORD "a" + LESS "<" + BINARY_EXPR + BINARY_EXPR "1000 * 8" + INTEGER_LITERAL "1000" + STAR "*" + INTEGER_LITERAL "8" + PLUS "+" + BINARY_EXPR "1 * 2" + INTEGER_LITERAL "1" + STAR "*" + INTEGER_LITERAL "2" + AND_AND "&&" + BINARY_EXPR "b < 1000" + WORD "b" + LESS "<" + INTEGER_LITERAL "1000" + AND_AND "&&" + BINARY_EXPR "c < 1000" + WORD "c" + LESS "<" + INTEGER_LITERAL "1000" + AND_AND "&&" + BINARY_EXPR + WORD "d" + LESS "<" + BINARY_EXPR + BINARY_EXPR "1000 + 2" + INTEGER_LITERAL "1000" + PLUS "+" + INTEGER_LITERAL "2" + PLUS "+" + INTEGER_LITERAL "3" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + MINUS "-" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + STAR "*" + WORD "c" + STAR "*" + WORD "d" + LESS "<" + INTEGER_LITERAL "10000" + AND_AND "&&" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + MINUS "-" + WORD "c" + MINUS "-" + WORD "d" + NOT_EQUALS "!=" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "c + d" + WORD "c" + PLUS "+" + WORD "d" + R_PAREN ")" + GREATER_EQUALS ">=" + INTEGER_LITERAL "100" + OR_OR "||" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a * 1" + WORD "a" + STAR "*" + INTEGER_LITERAL "1" + LESS "<" + INTEGER_LITERAL "2" + AND_AND "&&" + BINARY_EXPR + STRING_LITERAL "aowiefjowiaj" + QUOTE """ + WORD "aowiefjowiaj" + QUOTE """ + EQUALS_EQUALS "==" + STRING_LITERAL "jfeiowajpwoeifj" + QUOTE """ + WORD "jfeiowajpwoeifj" + QUOTE """ + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + STRING_LITERAL "a very long string prefix that is already quite long" + QUOTE """ + WORD "a" + WORD "very" + WORD "long" + WORD "string" + WORD "prefix" + WORD "that" + KW_IS "is" + WORD "already" + WORD "quite" + WORD "long" + QUOTE """ + PLUS "+" + STRING_LITERAL " concatenated with " + QUOTE """ + WORD "concatenated" + WORD "with" + QUOTE """ + PLUS "+" + STRING_LITERAL "another very long string that together exceeds the line limit easily and comfortably" + QUOTE """ + WORD "another" + WORD "very" + WORD "long" + WORD "string" + WORD "that" + WORD "together" + WORD "exceeds" + WORD "the" + WORD "line" + WORD "limit" + WORD "easily" + WORD "and" + WORD "comfortably" + QUOTE """ + SEMICOLON ";" + BINARY_EXPR + WORD "mut_a" + PLUS_EQUALS "+=" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + PLUS "+" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + PLUS "+" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + PLUS "+" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + PLUS "+" + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + BINARY_EXPR "c * d" + WORD "c" + STAR "*" + WORD "d" + PLUS "+" + WORD "a" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a // 2 trailing + // 3 leading + + // 4 trailing + // 5 leading + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a /* 2 trailing */ + /* 3 leading */ + + /* 4 trailing */ + /* 5 leading */ + b" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + PLUS "+" + WORD "a" + PLUS "+" + WORD "b" + PLUS "+" + WORD "c" + PLUS "+" + WORD "d" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR + BINARY_EXPR "a > 0" + WORD "a" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "b > 0" + WORD "b" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "c > 0" + WORD "c" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "d > 0" + WORD "d" + GREATER ">" + INTEGER_LITERAL "0" + AND_AND "&&" + BINARY_EXPR "a != b" + WORD "a" + NOT_EQUALS "!=" + WORD "b" + AND_AND "&&" + BINARY_EXPR "b != c" + WORD "b" + NOT_EQUALS "!=" + WORD "c" + AND_AND "&&" + BINARY_EXPR "c != d" + WORD "c" + NOT_EQUALS "!=" + WORD "d" + SEMICOLON ";" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "1 + 2" + INTEGER_LITERAL "1" + PLUS "+" + INTEGER_LITERAL "2" + SEMICOLON ";" + BINARY_EXPR "a > b" + WORD "a" + GREATER ">" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a * b" + WORD "a" + STAR "*" + WORD "b" + PLUS "+" + WORD "c" + SEMICOLON ";" + BINARY_EXPR "a == b" + WORD "a" + EQUALS_EQUALS "==" + WORD "b" + SEMICOLON ";" + BINARY_EXPR + BINARY_EXPR "a == 2" + WORD "a" + EQUALS_EQUALS "==" + INTEGER_LITERAL "2" + AND_AND "&&" + BINARY_EXPR "b != 3" + WORD "b" + NOT_EQUALS "!=" + INTEGER_LITERAL "3" + SEMICOLON ";" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new new file mode 100644 index 0000000000..ece8b75b52 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new @@ -0,0 +1,1904 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 39200 +--- +=== SYNTAX TREE === +SOURCE_FILE + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "BasicClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + COMMA "," + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + COMMA "," + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "FullClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + KW_RETRY_POLICY "retry_policy" + CONFIG_VALUE "MyRetryPolicy" + WORD "MyRetryPolicy" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + COLON ":" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "max_tokens" + CONFIG_VALUE "100" + INTEGER_LITERAL "100" + CONFIG_ITEM + WORD "temperature" + CONFIG_VALUE "0.7" + FLOAT_LITERAL "0.7" + COMMA "," + CONFIG_ITEM + WORD "top_p" + CONFIG_VALUE "0.9" + FLOAT_LITERAL "0.9" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "StringProviderClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE + STRING_LITERAL "openai-generic" + QUOTE """ + WORD "openai-generic" + QUOTE """ + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://openrouter.ai/api/v1" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "openrouter" + DOT "." + WORD "ai" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v1" + QUOTE """ + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "mistralai/mistral-small-3.1-24b-instruct" + QUOTE """ + WORD "mistralai" + SLASH "/" + WORD "mistral-small-3" + DOT "." + INTEGER_LITERAL "1" + MINUS "-" + INTEGER_LITERAL "24" + WORD "b-instruct" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "NestedConfigClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "headers" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + STRING_LITERAL "X-API-Key" + QUOTE """ + WORD "X-API-Key" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "my-key" + QUOTE """ + WORD "my-key" + QUOTE """ + CONFIG_ITEM + STRING_LITERAL "Authorization" + QUOTE """ + WORD "Authorization" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "Bearer token" + QUOTE """ + WORD "Bearer" + WORD "token" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "ArrayConfigClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + COMMA "," + CONFIG_ITEM + WORD "stop_sequences" + COLON ":" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE + STRING_LITERAL "END" + QUOTE """ + WORD "END" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "STOP" + QUOTE """ + WORD "STOP" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "DONE" + QUOTE """ + WORD "DONE" + QUOTE """ + R_BRACKET "]" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "LongOptionClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "some-really-long-domain-name-for-testing" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v1" + SLASH "/" + WORD "chat" + SLASH "/" + WORD "completions" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TypedValuesClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "temperature" + COLON ":" + CONFIG_VALUE "0.5" + FLOAT_LITERAL "0.5" + CONFIG_ITEM + WORD "max_tokens" + CONFIG_VALUE "2048" + INTEGER_LITERAL "2048" + CONFIG_ITEM + WORD "stream" + CONFIG_VALUE "true" + KW_TRUE "true" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "EnvClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + COLON ":" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "api_key" + CONFIG_VALUE + ENV_ACCESS_EXPR "env.OPENAI_API_KEY" + WORD "env" + DOT "." + WORD "OPENAI_API_KEY" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "ArrayOfObjectsClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + COLON ":" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + COMMA "," + CONFIG_ITEM + WORD "tools" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "server_label" + CONFIG_VALUE + STRING_LITERAL "web_search" + QUOTE """ + WORD "web_search" + QUOTE """ + CONFIG_ITEM + WORD "server_url" + CONFIG_VALUE + STRING_LITERAL "https://example.com" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "example" + DOT "." + WORD "com" + QUOTE """ + CONFIG_ITEM + WORD "type" + CONFIG_VALUE + STRING_LITERAL "mcp" + QUOTE """ + WORD "mcp" + QUOTE """ + R_BRACE "}" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "server_label" + CONFIG_VALUE + STRING_LITERAL "calculator" + QUOTE """ + WORD "calculator" + QUOTE """ + CONFIG_ITEM + WORD "server_url" + CONFIG_VALUE + STRING_LITERAL "https://calc.example.com" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "calc" + DOT "." + WORD "example" + DOT "." + WORD "com" + QUOTE """ + R_BRACE "}" + R_BRACKET "]" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "RawStringConfigClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + COMMA "," + CONFIG_ITEM + WORD "options" + COLON ":" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + COLON ":" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "system_prompt" + CONFIG_VALUE + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "You are a helpful assistant. + Always be concise." + WORD "You" + WORD "are" + WORD "a" + WORD "helpful" + WORD "assistant" + DOT "." + WORD "Always" + WORD "be" + WORD "concise" + DOT "." + QUOTE """ + HASH "#" + R_BRACE "}" + COMMA "," + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "MixedValuesClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "max_tokens" + CONFIG_VALUE "100" + INTEGER_LITERAL "100" + CONFIG_ITEM + WORD "temperature" + CONFIG_VALUE "0.7" + FLOAT_LITERAL "0.7" + CONFIG_ITEM + WORD "stream" + CONFIG_VALUE "true" + KW_TRUE "true" + CONFIG_ITEM + WORD "stop" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE + STRING_LITERAL "END" + QUOTE """ + WORD "END" + QUOTE """ + R_BRACKET "]" + CONFIG_ITEM + WORD "inline_string" + CONFIG_VALUE + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "inline raw" + WORD "inline" + WORD "raw" + QUOTE """ + HASH "#" + CONFIG_ITEM + STRING_LITERAL "string key" + QUOTE """ + WORD "string" + WORD "key" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "value with spaces" + QUOTE """ + WORD "value" + WORD "with" + WORD "spaces" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "// 2 client keyword trailing +// 3 type angle leading +< // 4 open angle trailing +// 5 type leading +llm // 6 type trailing +// 7 close angle leading +>" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + COLON ":" + CONFIG_VALUE "// 14 provider key trailing + // 15 provider value leading + openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "/* 2 client keyword trailing */ +/* 3 type angle leading */ +< /* 4 open angle trailing */ +/* 5 type leading */ +llm /* 6 type trailing */ +/* 7 close angle leading */ +>" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaClientBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "/* 14 provider key trailing */ + /* 15 provider value leading */ + openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + COLON ":" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "ThisIsAnExtremelyLongClientNameThatDefinitelyExceedsTheDefaultLineLimitOfOneHundredColumns" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "DeeplyNestedClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "headers" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + STRING_LITERAL "X-API-Key" + QUOTE """ + WORD "X-API-Key" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "my-key" + QUOTE """ + WORD "my-key" + QUOTE """ + CONFIG_ITEM + STRING_LITERAL "Authorization" + QUOTE """ + WORD "Authorization" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "Bearer token" + QUOTE """ + WORD "Bearer" + WORD "token" + QUOTE """ + CONFIG_ITEM + WORD "custom_config" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "retry_on_failure" + CONFIG_VALUE "true" + KW_TRUE "true" + CONFIG_ITEM + WORD "timeout_ms" + CONFIG_VALUE "30000" + INTEGER_LITERAL "30000" + CONFIG_ITEM + WORD "metadata" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "team" + CONFIG_VALUE + STRING_LITERAL "platform" + QUOTE """ + WORD "platform" + QUOTE """ + CONFIG_ITEM + WORD "environment" + CONFIG_VALUE + STRING_LITERAL "production" + QUOTE """ + WORD "production" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "LongNestedValuesClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "anthropic/claude-3.5-sonnet-20250101-with-some-extremely-long-suffix-that-pushes-past-the-line-limit-easily" + QUOTE """ + WORD "anthropic" + SLASH "/" + WORD "claude-3" + DOT "." + INTEGER_LITERAL "5" + MINUS "-" + WORD "sonnet-20250101-with-some-extremely-long-suffix-that-pushes-past-the-line-limit-easily" + QUOTE """ + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://some-extremely-long-api-gateway-subdomain.internal.production.cluster.example.com/api/v2/chat/completions/streaming" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "some-extremely-long-api-gateway-subdomain" + DOT "." + WORD "internal" + DOT "." + WORD "production" + DOT "." + WORD "cluster" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v2" + SLASH "/" + WORD "chat" + SLASH "/" + WORD "completions" + SLASH "/" + WORD "streaming" + QUOTE """ + CONFIG_ITEM + WORD "headers" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + STRING_LITERAL "Authorization" + QUOTE """ + WORD "Authorization" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "Bearer some-extremely-long-api-token-value-that-is-used-for-authentication-and-exceeds-the-line-limit-easily-and-comfortably" + QUOTE """ + WORD "Bearer" + WORD "some-extremely-long-api-token-value-that-is-used-for-authentication-and-exceeds-the-line-limit-easily-and-comfortably" + QUOTE """ + CONFIG_ITEM + STRING_LITERAL "X-Custom-Header" + QUOTE """ + WORD "X-Custom-Header" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "another-very-long-header-value-that-also-pushes-past-one-hundred-columns-for-testing-purposes" + QUOTE """ + WORD "another-very-long-header-value-that-also-pushes-past-one-hundred-columns-for-testing-purposes" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "ManyOptionsClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "max_tokens" + CONFIG_VALUE "4096" + INTEGER_LITERAL "4096" + CONFIG_ITEM + WORD "temperature" + CONFIG_VALUE "0.7" + FLOAT_LITERAL "0.7" + CONFIG_ITEM + WORD "top_p" + CONFIG_VALUE "0.95" + FLOAT_LITERAL "0.95" + CONFIG_ITEM + WORD "frequency_penalty" + CONFIG_VALUE "0.5" + FLOAT_LITERAL "0.5" + CONFIG_ITEM + WORD "presence_penalty" + CONFIG_VALUE "0.3" + FLOAT_LITERAL "0.3" + CONFIG_ITEM + WORD "stream" + CONFIG_VALUE "true" + KW_TRUE "true" + CONFIG_ITEM + WORD "stop_sequences" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE + STRING_LITERAL "END" + QUOTE """ + WORD "END" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "STOP" + QUOTE """ + WORD "STOP" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "DONE" + QUOTE """ + WORD "DONE" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "COMPLETE" + QUOTE """ + WORD "COMPLETE" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "FINISHED" + QUOTE """ + WORD "FINISHED" + QUOTE """ + R_BRACKET "]" + CONFIG_ITEM + WORD "api_key" + CONFIG_VALUE + ENV_ACCESS_EXPR "env.OPENAI_API_KEY" + WORD "env" + DOT "." + WORD "OPENAI_API_KEY" + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://api.openai.com/v1" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "api" + DOT "." + WORD "openai" + DOT "." + WORD "com" + SLASH "/" + WORD "v1" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "LongArrayClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "stop_sequences" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE + STRING_LITERAL "STOP_GENERATION_NOW" + QUOTE """ + WORD "STOP_GENERATION_NOW" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "END_OF_RESPONSE_MARKER" + QUOTE """ + WORD "END_OF_RESPONSE_MARKER" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "COMPLETION_FINISHED_SIGNAL" + QUOTE """ + WORD "COMPLETION_FINISHED_SIGNAL" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "TERMINATE_OUTPUT_HERE" + QUOTE """ + WORD "TERMINATE_OUTPUT_HERE" + QUOTE """ + COMMA "," + CONFIG_VALUE + STRING_LITERAL "FINAL_ANSWER_DELIMITER" + QUOTE """ + WORD "FINAL_ANSWER_DELIMITER" + QUOTE """ + R_BRACKET "]" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "LongArrayOfObjectsClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "tools" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "server_label" + CONFIG_VALUE + STRING_LITERAL "this_is_a_very_long_server_label_that_exceeds_the_line_limit_when_combined_with_indentation" + QUOTE """ + WORD "this_is_a_very_long_server_label_that_exceeds_the_line_limit_when_combined_with_indentation" + QUOTE """ + CONFIG_ITEM + WORD "server_url" + CONFIG_VALUE + STRING_LITERAL "https://some-extremely-long-domain-name-for-the-mcp-server.internal.production.example.com/api/v2" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "some-extremely-long-domain-name-for-the-mcp-server" + DOT "." + WORD "internal" + DOT "." + WORD "production" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v2" + QUOTE """ + CONFIG_ITEM + WORD "type" + CONFIG_VALUE + STRING_LITERAL "mcp" + QUOTE """ + WORD "mcp" + QUOTE """ + CONFIG_ITEM + WORD "description" + CONFIG_VALUE + STRING_LITERAL "A very long description of the tool server that explains what it does and how it should be used by the model" + QUOTE """ + WORD "A" + WORD "very" + WORD "long" + WORD "description" + WORD "of" + WORD "the" + WORD "tool" + WORD "server" + WORD "that" + WORD "explains" + WORD "what" + WORD "it" + WORD "does" + WORD "and" + WORD "how" + WORD "it" + WORD "should" + WORD "be" + WORD "used" + WORD "by" + WORD "the" + WORD "model" + QUOTE """ + R_BRACE "}" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "server_label" + CONFIG_VALUE + STRING_LITERAL "another_long_server_label_for_testing_line_wrapping_behavior_in_nested_array_objects" + QUOTE """ + WORD "another_long_server_label_for_testing_line_wrapping_behavior_in_nested_array_objects" + QUOTE """ + CONFIG_ITEM + WORD "server_url" + CONFIG_VALUE + STRING_LITERAL "https://another-long-domain.internal.staging.example.com/tools/v1" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "another-long-domain" + DOT "." + WORD "internal" + DOT "." + WORD "staging" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "tools" + SLASH "/" + WORD "v1" + QUOTE """ + R_BRACE "}" + R_BRACKET "]" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "// 2 client trailing +< // 3 angle trailing +llm // 4 type trailing +>" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaDeeplyNestedClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "// 11 provider trailing + // 12 value leading + openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "headers" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + STRING_LITERAL "X-API-Key" + QUOTE """ + WORD "X-API-Key" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "my-key" + QUOTE """ + WORD "my-key" + QUOTE """ + CONFIG_ITEM + STRING_LITERAL "Authorization" + QUOTE """ + WORD "Authorization" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "Bearer token" + QUOTE """ + WORD "Bearer" + WORD "token" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "/* 2 client trailing */ +< /* 3 angle trailing */ +llm /* 4 type trailing */ +>" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaDeeplyNestedClientBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "/* 11 provider trailing */ + /* 12 value leading */ + openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + CONFIG_ITEM + WORD "headers" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + STRING_LITERAL "X-API-Key" + QUOTE """ + WORD "X-API-Key" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "my-key" + QUOTE """ + WORD "my-key" + QUOTE """ + CONFIG_ITEM + STRING_LITERAL "Authorization" + QUOTE """ + WORD "Authorization" + QUOTE """ + CONFIG_VALUE + STRING_LITERAL "Bearer token" + QUOTE """ + WORD "Bearer" + WORD "token" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + COMMA "," + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaLongValueClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "some-really-long-domain-name-for-testing" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v1" + SLASH "/" + WORD "chat" + SLASH "/" + WORD "completions" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "TriviaLongValueClientBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" + QUOTE """ + CONFIG_ITEM + WORD "base_url" + CONFIG_VALUE + STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" + QUOTE """ + WORD "https" + COLON ":" + SLASH "/" + SLASH "/" + WORD "some-really-long-domain-name-for-testing" + DOT "." + WORD "example" + DOT "." + WORD "com" + SLASH "/" + WORD "api" + SLASH "/" + WORD "v1" + SLASH "/" + WORD "chat" + SLASH "/" + WORD "completions" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "BasicRetry" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "3" + INTEGER_LITERAL "3" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "FullRetry" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "5" + INTEGER_LITERAL "5" + CONFIG_ITEM + WORD "backoff_multiplier" + CONFIG_VALUE "2.0" + FLOAT_LITERAL "2.0" + CONFIG_ITEM + WORD "initial_delay_ms" + CONFIG_VALUE "1000" + INTEGER_LITERAL "1000" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "ThisIsAnExtremelyLongRetryPolicyNameThatDefinitelyExceedsTheDefaultLineLimitOfOneHundredCols" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "10" + INTEGER_LITERAL "10" + CONFIG_ITEM + WORD "backoff_multiplier" + CONFIG_VALUE "3.0" + FLOAT_LITERAL "3.0" + CONFIG_ITEM + WORD "initial_delay_ms" + CONFIG_VALUE "5000" + INTEGER_LITERAL "5000" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "TriviaRetry" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "// 8 key trailing + // 9 value leading + 3" + INTEGER_LITERAL "3" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "TriviaRetryBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "/* 8 key trailing */ + /* 9 value leading */ + 3" + INTEGER_LITERAL "3" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "TestTarget" + PARAMETER_LIST "()" + L_PAREN "(" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "string" + WORD "string" + LLM_FUNCTION_BODY + L_BRACE "{" + CLIENT_FIELD "client BasicClient" + KW_CLIENT "client" + WORD "BasicClient" + PROMPT_FIELD + WORD "prompt" + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "Hello" + WORD "Hello" + QUOTE """ + HASH "#" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "BasicTest" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "{ + + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "TypeBuilderTest" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + TYPE_BUILDER_BLOCK + KW_TYPE_BUILDER "type_builder" + L_BRACE "{" + CLASS_DEF + KW_CLASS "class" + WORD "InnerClass" + L_BRACE "{" + FIELD + WORD "b" + TYPE_EXPR "int" + WORD "int" + R_BRACE "}" + DYNAMIC_TYPE_DEF + KW_DYNAMIC "dynamic" + CLASS_DEF + KW_CLASS "class" + WORD "DynamicInner" + L_BRACE "{" + FIELD + WORD "c" + TYPE_EXPR "string" + WORD "string" + R_BRACE "}" + ENUM_DEF + KW_ENUM "enum" + WORD "InnerEnum" + L_BRACE "{" + ENUM_VARIANT "X" + WORD "X" + ENUM_VARIANT "Y" + WORD "Y" + R_BRACE "}" + DYNAMIC_TYPE_DEF + KW_DYNAMIC "dynamic" + ENUM_DEF + KW_ENUM "enum" + WORD "DynamicInnerEnum" + L_BRACE "{" + ENUM_VARIANT "P" + WORD "P" + ENUM_VARIANT "Q" + WORD "Q" + R_BRACE "}" + TYPE_ALIAS_DEF + WORD "type" + WORD "InnerAlias" + EQUALS "=" + TYPE_EXPR "string | int" + WORD "string" + PIPE "|" + WORD "int" + R_BRACE "}" + COMMA "," + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "{ + + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "TriviaTest" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + COLON ":" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "// 12 args key trailing + // 13 args block leading + { // 14 args open brace trailing + // 15 args close brace leading + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "TriviaTestBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "/* 12 args key trailing */ + /* 13 args block leading */ + { /* 14 args open brace trailing */ + /* 15 args close brace leading */ + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "LongTypeBuilderTest" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + TYPE_BUILDER_BLOCK + KW_TYPE_BUILDER "type_builder" + L_BRACE "{" + CLASS_DEF + KW_CLASS "class" + WORD "VeryLongClassNameThatExceedsTheLineLimitWhenCombinedWithTheTypeBuilderIndentation" + L_BRACE "{" + FIELD + WORD "extremely_long_field_name_for_testing_wrapping" + TYPE_EXPR "int" + WORD "int" + FIELD + WORD "another_very_long_field_name" + TYPE_EXPR "string" + WORD "string" + R_BRACE "}" + ENUM_DEF + KW_ENUM "enum" + WORD "VeryLongEnumNameThatAlsoExceedsTheLineLimitWhenCombinedWithTheTypeBuilderIndentation" + L_BRACE "{" + ENUM_VARIANT "VeryLongVariantNameThatExceedsLimit" + WORD "VeryLongVariantNameThatExceedsLimit" + ENUM_VARIANT "AnotherVeryLongVariantName" + WORD "AnotherVeryLongVariantName" + R_BRACE "}" + TYPE_ALIAS_DEF + WORD "type" + WORD "VeryLongTypeAliasNameThatExceedsLimit" + EQUALS "=" + TYPE_EXPR "int | string | bool | float | null | int[] | string[]" + WORD "int" + PIPE "|" + WORD "string" + PIPE "|" + WORD "bool" + PIPE "|" + WORD "float" + PIPE "|" + WORD "null" + PIPE "|" + WORD "int" + L_BRACKET "[" + R_BRACKET "]" + PIPE "|" + WORD "string" + L_BRACKET "[" + R_BRACKET "]" + R_BRACE "}" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "{ + + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "TriviaTypeBuilderTest" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + TYPE_BUILDER_BLOCK + KW_TYPE_BUILDER "type_builder" + L_BRACE "{" + CLASS_DEF + KW_CLASS "class" + WORD "TbInnerClass" + L_BRACE "{" + FIELD + WORD "field_name" + COLON ":" + TYPE_EXPR "// 22 field name trailing + // 23 type leading + int" + WORD "int" + R_BRACE "}" + ENUM_DEF + KW_ENUM "enum" + WORD "TbInnerEnum" + L_BRACE "{" + ENUM_VARIANT "// 32 enum brace trailing + // 33 variant leading + X" + WORD "X" + R_BRACE "}" + TYPE_ALIAS_DEF + WORD "type" + WORD "TbAlias" + EQUALS "=" + TYPE_EXPR "// 42 equals trailing + // 43 rhs leading + string" + WORD "string" + R_BRACE "}" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "// 48 args trailing + // 49 args brace leading + { // 50 args brace trailing + // 51 args close leading + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + TEST_DEF + KW_TEST "test" + WORD "TriviaTypeBuilderTestBlock" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "functions" + CONFIG_VALUE + ARRAY_LITERAL + L_BRACKET "[" + CONFIG_VALUE "TestTarget" + WORD "TestTarget" + R_BRACKET "]" + TYPE_BUILDER_BLOCK + KW_TYPE_BUILDER "type_builder" + L_BRACE "{" + CLASS_DEF + KW_CLASS "class" + WORD "TbInnerClassBlock" + L_BRACE "{" + FIELD + WORD "field_name" + COLON ":" + TYPE_EXPR "/* 22 field name trailing */ + /* 23 type leading */ + int" + WORD "int" + R_BRACE "}" + ENUM_DEF + KW_ENUM "enum" + WORD "TbInnerEnumBlock" + L_BRACE "{" + ENUM_VARIANT "/* 32 enum brace trailing */ + /* 33 variant leading */ + X" + WORD "X" + R_BRACE "}" + TYPE_ALIAS_DEF + WORD "type" + WORD "TbAliasBlock" + EQUALS "=" + TYPE_EXPR "/* 42 equals trailing */ + /* 43 rhs leading */ + string" + WORD "string" + R_BRACE "}" + CONFIG_ITEM + WORD "args" + CONFIG_BLOCK "/* 48 args trailing */ + /* 49 args brace leading */ + { /* 50 args brace trailing */ + /* 51 args close leading */ + }" + L_BRACE "{" + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "C" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "R" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "1" + INTEGER_LITERAL "1" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "ExtraWhitespaceClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + RETRY_POLICY_DEF + KW_RETRY_POLICY "retry_policy" + WORD "ExtraWhitespaceRetry" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "max_retries" + CONFIG_VALUE "3" + INTEGER_LITERAL "3" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "CommaClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + COMMA "," + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + COMMA "," + CONFIG_ITEM + WORD "max_tokens" + CONFIG_VALUE "100" + INTEGER_LITERAL "100" + COMMA "," + R_BRACE "}" + R_BRACE "}" + CLIENT_DEF + KW_CLIENT "client" + CLIENT_TYPE "" + LESS "<" + WORD "llm" + GREATER ">" + WORD "SameLineClient" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "provider" + CONFIG_VALUE "openai" + WORD "openai" + CONFIG_ITEM + WORD "options" + CONFIG_BLOCK + L_BRACE "{" + CONFIG_ITEM + WORD "model" + CONFIG_VALUE + STRING_LITERAL "gpt-4" + QUOTE """ + WORD "gpt-4" + QUOTE """ + R_BRACE "}" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new new file mode 100644 index 0000000000..8d10a80fd9 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new @@ -0,0 +1,1615 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 39434 +--- +=== SYNTAX TREE === +SOURCE_FILE + CLASS_DEF + KW_CLASS "class" + WORD "OtherPoint" + L_BRACE "{" + FIELD + WORD "x" + TYPE_EXPR "int" + WORD "int" + FIELD + WORD "y" + TYPE_EXPR "int" + WORD "int" + R_BRACE "}" + CLASS_DEF + KW_CLASS "class" + WORD "OtherVec" + L_BRACE "{" + FIELD + WORD "p" + TYPE_EXPR "OtherPoint" + WORD "OtherPoint" + FIELD + WORD "q" + TYPE_EXPR "OtherPoint" + WORD "OtherPoint" + R_BRACE "}" + CLASS_DEF + KW_CLASS "class" + WORD "OtherTriple" + L_BRACE "{" + FIELD + WORD "a" + TYPE_EXPR "OtherVec" + WORD "OtherVec" + FIELD + WORD "b" + TYPE_EXPR "OtherVec" + WORD "OtherVec" + FIELD + WORD "c" + TYPE_EXPR "OtherVec" + WORD "OtherVec" + R_BRACE "}" + FUNCTION_DEF + KW_FUNCTION "function" + WORD "OtherExprs" + PARAMETER_LIST + L_PAREN "(" + PARAMETER + WORD "a" + COLON ":" + TYPE_EXPR "int" + WORD "int" + COMMA "," + PARAMETER + WORD "b" + COLON ":" + TYPE_EXPR "int" + WORD "int" + R_PAREN ")" + ARROW "->" + TYPE_EXPR "int" + WORD "int" + EXPR_FUNCTION_BODY + BLOCK_EXPR + L_BRACE "{" + INTEGER_LITERAL "0" + SEMICOLON ";" + INTEGER_LITERAL "1" + SEMICOLON ";" + INTEGER_LITERAL "42" + SEMICOLON ";" + INTEGER_LITERAL "999999" + SEMICOLON ";" + FLOAT_LITERAL "0.0" + SEMICOLON ";" + FLOAT_LITERAL "3.14" + SEMICOLON ";" + FLOAT_LITERAL "99.999" + SEMICOLON ";" + STRING_LITERAL "hello" + QUOTE """ + WORD "hello" + QUOTE """ + SEMICOLON ";" + STRING_LITERAL "a short string" + QUOTE """ + WORD "a" + WORD "short" + WORD "string" + QUOTE """ + SEMICOLON ";" + STRING_LITERAL "a much longer string that contains quite a lot of text and definitely exceeds one hundred characters to test how the formatter handles longer string literals in expressions" + QUOTE """ + WORD "a" + WORD "much" + WORD "longer" + WORD "string" + WORD "that" + WORD "contains" + WORD "quite" + WORD "a" + WORD "lot" + WORD "of" + WORD "text" + WORD "and" + WORD "definitely" + WORD "exceeds" + WORD "one" + WORD "hundred" + WORD "characters" + WORD "to" + KW_TEST "test" + WORD "how" + WORD "the" + WORD "formatter" + WORD "handles" + WORD "longer" + WORD "string" + WORD "literals" + KW_IN "in" + WORD "expressions" + QUOTE """ + SEMICOLON ";" + KW_TRUE "true" + SEMICOLON ";" + KW_FALSE "false" + SEMICOLON ";" + KW_NULL "null" + SEMICOLON ";" + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "raw string" + WORD "raw" + WORD "string" + QUOTE """ + HASH "#" + SEMICOLON ";" + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "raw string with "quotes" inside" + WORD "raw" + WORD "string" + WORD "with" + QUOTE """ + WORD "quotes" + QUOTE """ + WORD "inside" + QUOTE """ + HASH "#" + SEMICOLON ";" + RAW_STRING_LITERAL + HASH "#" + QUOTE """ + PROMPT_TEXT "multi-line raw string + with several lines + of content" + WORD "multi-line" + WORD "raw" + WORD "string" + WORD "with" + WORD "several" + WORD "lines" + WORD "of" + WORD "content" + QUOTE """ + HASH "#" + SEMICOLON ";" + PAREN_EXPR "// ===== Parenthesized expressions ===== + (a)" + L_PAREN "(" + WORD "a" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR + L_PAREN "(" + PAREN_EXPR "(a)" + L_PAREN "(" + WORD "a" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a * a" + WORD "a" + STAR "*" + WORD "a" + R_PAREN ")" + PLUS "+" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "b * b" + WORD "b" + STAR "*" + WORD "b" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_PAREN ")" + R_PAREN ")" + MINUS "-" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + STAR "*" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a - b" + WORD "a" + MINUS "-" + WORD "b" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR "// ===== Trivia in parens (line comments) ===== + // 1 open leading + ( // 2 open trailing + // 3 inner leading + a // 4 inner trailing + // 5 close leading + )" + L_PAREN "(" + WORD "a" + R_PAREN ")" + SEMICOLON ";" + PAREN_EXPR "// ===== Trivia in parens (block comments) ===== + /* 1 open leading */ + ( /* 2 open trailing */ + /* 3 inner leading */ + a /* 4 inner trailing */ + /* 5 close leading */ + )" + L_PAREN "(" + WORD "a" + R_PAREN ")" + SEMICOLON ";" + UNARY_EXPR "// ===== Unary expressions ===== + -a" + MINUS "-" + WORD "a" + SEMICOLON ";" + UNARY_EXPR "!true" + NOT "!" + KW_TRUE "true" + SEMICOLON ";" + UNARY_EXPR + MINUS "-" + PAREN_EXPR + L_PAREN "(" + UNARY_EXPR "-a" + MINUS "-" + WORD "a" + R_PAREN ")" + SEMICOLON ";" + UNARY_EXPR + NOT "!" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a > b" + WORD "a" + GREATER ">" + WORD "b" + R_PAREN ")" + SEMICOLON ";" + UNARY_EXPR "// ===== Trivia in unary (line comments) ===== + // 1 op leading + - // 2 op trailing + // 3 operand leading + a" + MINUS "-" + WORD "a" + SEMICOLON ";" + UNARY_EXPR "// ===== Trivia in unary (block comments) ===== + /* 1 op leading */ + - /* 2 op trailing */ + /* 3 operand leading */ + a" + MINUS "-" + WORD "a" + SEMICOLON ";" + ARRAY_LITERAL "// ===== Array initializers ===== + []" + L_BRACKET "[" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL "[1]" + L_BRACKET "[" + INTEGER_LITERAL "1" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL "[1, 2, 3]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + COMMA "," + INTEGER_LITERAL "3" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL "[1, 2, 3, 4, 5]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + COMMA "," + INTEGER_LITERAL "3" + COMMA "," + INTEGER_LITERAL "4" + COMMA "," + INTEGER_LITERAL "5" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "short" + QUOTE """ + WORD "short" + QUOTE """ + COMMA "," + STRING_LITERAL "array" + QUOTE """ + WORD "array" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "a" + QUOTE """ + WORD "a" + QUOTE """ + COMMA "," + STRING_LITERAL "b" + QUOTE """ + WORD "b" + QUOTE """ + COMMA "," + STRING_LITERAL "c" + QUOTE """ + WORD "c" + QUOTE """ + COMMA "," + STRING_LITERAL "d" + QUOTE """ + WORD "d" + QUOTE """ + COMMA "," + STRING_LITERAL "e" + QUOTE """ + WORD "e" + QUOTE """ + COMMA "," + STRING_LITERAL "f" + QUOTE """ + WORD "f" + QUOTE """ + COMMA "," + STRING_LITERAL "g" + QUOTE """ + WORD "g" + QUOTE """ + COMMA "," + STRING_LITERAL "h" + QUOTE """ + WORD "h" + QUOTE """ + COMMA "," + STRING_LITERAL "i" + QUOTE """ + WORD "i" + QUOTE """ + COMMA "," + STRING_LITERAL "j" + QUOTE """ + WORD "j" + QUOTE """ + COMMA "," + STRING_LITERAL "k" + QUOTE """ + WORD "k" + QUOTE """ + COMMA "," + STRING_LITERAL "l" + QUOTE """ + WORD "l" + QUOTE """ + COMMA "," + STRING_LITERAL "m" + QUOTE """ + WORD "m" + QUOTE """ + COMMA "," + STRING_LITERAL "n" + QUOTE """ + WORD "n" + QUOTE """ + COMMA "," + STRING_LITERAL "o" + QUOTE """ + WORD "o" + QUOTE """ + COMMA "," + STRING_LITERAL "p" + QUOTE """ + WORD "p" + QUOTE """ + COMMA "," + STRING_LITERAL "q" + QUOTE """ + WORD "q" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "this is a long string element" + QUOTE """ + WORD "this" + KW_IS "is" + WORD "a" + WORD "long" + WORD "string" + WORD "element" + QUOTE """ + COMMA "," + STRING_LITERAL "another long string value here" + QUOTE """ + WORD "another" + WORD "long" + WORD "string" + WORD "value" + WORD "here" + QUOTE """ + COMMA "," + STRING_LITERAL "yet another one that is quite long" + QUOTE """ + WORD "yet" + WORD "another" + WORD "one" + WORD "that" + KW_IS "is" + WORD "quite" + WORD "long" + QUOTE """ + COMMA "," + STRING_LITERAL "and one more string element here too" + QUOTE """ + WORD "and" + WORD "one" + WORD "more" + WORD "string" + WORD "element" + WORD "here" + WORD "too" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "alpha" + QUOTE """ + WORD "alpha" + QUOTE """ + COMMA "," + STRING_LITERAL "bravo" + QUOTE """ + WORD "bravo" + QUOTE """ + COMMA "," + STRING_LITERAL "charlie" + QUOTE """ + WORD "charlie" + QUOTE """ + COMMA "," + STRING_LITERAL "delta" + QUOTE """ + WORD "delta" + QUOTE """ + COMMA "," + STRING_LITERAL "echo" + QUOTE """ + WORD "echo" + QUOTE """ + COMMA "," + STRING_LITERAL "foxtrot" + QUOTE """ + WORD "foxtrot" + QUOTE """ + COMMA "," + STRING_LITERAL "golf" + QUOTE """ + WORD "golf" + QUOTE """ + COMMA "," + STRING_LITERAL "hotel" + QUOTE """ + WORD "hotel" + QUOTE """ + COMMA "," + STRING_LITERAL "india" + QUOTE """ + WORD "india" + QUOTE """ + COMMA "," + STRING_LITERAL "juliet" + QUOTE """ + WORD "juliet" + QUOTE """ + COMMA "," + STRING_LITERAL "kilo" + QUOTE """ + WORD "kilo" + QUOTE """ + COMMA "," + STRING_LITERAL "lima" + QUOTE """ + WORD "lima" + QUOTE """ + COMMA "," + STRING_LITERAL "mike" + QUOTE """ + WORD "mike" + QUOTE """ + COMMA "," + STRING_LITERAL "november" + QUOTE """ + WORD "november" + QUOTE """ + COMMA "," + STRING_LITERAL "oscar" + QUOTE """ + WORD "oscar" + QUOTE """ + COMMA "," + STRING_LITERAL "papa" + QUOTE """ + WORD "papa" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[1, 2]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[3, 4]" + L_BRACKET "[" + INTEGER_LITERAL "3" + COMMA "," + INTEGER_LITERAL "4" + R_BRACKET "]" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[1, 2, 3]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + COMMA "," + INTEGER_LITERAL "3" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[4, 5, 6]" + L_BRACKET "[" + INTEGER_LITERAL "4" + COMMA "," + INTEGER_LITERAL "5" + COMMA "," + INTEGER_LITERAL "6" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[7, 8, 9]" + L_BRACKET "[" + INTEGER_LITERAL "7" + COMMA "," + INTEGER_LITERAL "8" + COMMA "," + INTEGER_LITERAL "9" + R_BRACKET "]" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[1, 2]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[3, 4]" + L_BRACKET "[" + INTEGER_LITERAL "3" + COMMA "," + INTEGER_LITERAL "4" + R_BRACKET "]" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[5, 6]" + L_BRACKET "[" + INTEGER_LITERAL "5" + COMMA "," + INTEGER_LITERAL "6" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[7, 8]" + L_BRACKET "[" + INTEGER_LITERAL "7" + COMMA "," + INTEGER_LITERAL "8" + R_BRACKET "]" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[9, 10]" + L_BRACKET "[" + INTEGER_LITERAL "9" + COMMA "," + INTEGER_LITERAL "10" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[11, 12]" + L_BRACKET "[" + INTEGER_LITERAL "11" + COMMA "," + INTEGER_LITERAL "12" + R_BRACKET "]" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL + L_BRACKET "[" + ARRAY_LITERAL "[13, 14]" + L_BRACKET "[" + INTEGER_LITERAL "13" + COMMA "," + INTEGER_LITERAL "14" + R_BRACKET "]" + COMMA "," + ARRAY_LITERAL "[15, 16]" + L_BRACKET "[" + INTEGER_LITERAL "15" + COMMA "," + INTEGER_LITERAL "16" + R_BRACKET "]" + R_BRACKET "]" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL "// ===== Trivia in array (line comments) ===== + // 1 open bracket leading + [ // 2 open bracket trailing + // 3 first element leading + 1 // 4 first element trailing + , // 5 comma trailing + // 6 second element leading + 2 // 7 second element trailing + // 8 close bracket leading + ]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL "// ===== Trivia in array (block comments) ===== + /* 1 open bracket leading */ + [ /* 2 open bracket trailing */ + /* 3 first element leading */ + 1 /* 4 first element trailing */ + , /* 5 comma trailing */ + /* 6 second element leading */ + 2 /* 7 second element trailing */ + /* 8 close bracket leading */ + ]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "this is a long string" + QUOTE """ + WORD "this" + KW_IS "is" + WORD "a" + WORD "long" + WORD "string" + QUOTE """ + COMMA "," + STRING_LITERAL "another long string value" + QUOTE """ + WORD "another" + WORD "long" + WORD "string" + WORD "value" + QUOTE """ + COMMA "," + STRING_LITERAL "yet another that is quite long" + QUOTE """ + WORD "yet" + WORD "another" + WORD "that" + KW_IS "is" + WORD "quite" + WORD "long" + QUOTE """ + COMMA "," + STRING_LITERAL "and one more string element" + QUOTE """ + WORD "and" + WORD "one" + WORD "more" + WORD "string" + WORD "element" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + ARRAY_LITERAL + L_BRACKET "[" + STRING_LITERAL "this is a long string" + QUOTE """ + WORD "this" + KW_IS "is" + WORD "a" + WORD "long" + WORD "string" + QUOTE """ + COMMA "," + STRING_LITERAL "another long string value" + QUOTE """ + WORD "another" + WORD "long" + WORD "string" + WORD "value" + QUOTE """ + COMMA "," + STRING_LITERAL "yet another that is quite long" + QUOTE """ + WORD "yet" + WORD "another" + WORD "that" + KW_IS "is" + WORD "quite" + WORD "long" + QUOTE """ + COMMA "," + STRING_LITERAL "and one more string element" + QUOTE """ + WORD "and" + WORD "one" + WORD "more" + WORD "string" + WORD "element" + QUOTE """ + R_BRACKET "]" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "key" + QUOTE """ + WORD "key" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "a" + QUOTE """ + WORD "a" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "b" + QUOTE """ + WORD "b" + QUOTE """ + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "a" + QUOTE """ + WORD "a" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "b" + QUOTE """ + WORD "b" + QUOTE """ + COLON ":" + INTEGER_LITERAL "2" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "c" + QUOTE """ + WORD "c" + QUOTE """ + COLON ":" + INTEGER_LITERAL "3" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "d" + QUOTE """ + WORD "d" + QUOTE """ + COLON ":" + INTEGER_LITERAL "4" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "e" + QUOTE """ + WORD "e" + QUOTE """ + COLON ":" + INTEGER_LITERAL "5" + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "first_key" + QUOTE """ + WORD "first_key" + QUOTE """ + COLON ":" + STRING_LITERAL "first value" + QUOTE """ + WORD "first" + WORD "value" + QUOTE """ + COMMA "," + OBJECT_FIELD + STRING_LITERAL "second_key" + QUOTE """ + WORD "second_key" + QUOTE """ + COLON ":" + STRING_LITERAL "second value" + QUOTE """ + WORD "second" + WORD "value" + QUOTE """ + COMMA "," + OBJECT_FIELD + STRING_LITERAL "third_key" + QUOTE """ + WORD "third_key" + QUOTE """ + COLON ":" + STRING_LITERAL "third value" + QUOTE """ + WORD "third" + WORD "value" + QUOTE """ + COMMA "," + OBJECT_FIELD + STRING_LITERAL "fourth_key" + QUOTE """ + WORD "fourth_key" + QUOTE """ + COLON ":" + STRING_LITERAL "fourth value" + QUOTE """ + WORD "fourth" + WORD "value" + QUOTE """ + COMMA "," + OBJECT_FIELD + STRING_LITERAL "fifth_key" + QUOTE """ + WORD "fifth_key" + QUOTE """ + COLON ":" + STRING_LITERAL "fifth" + QUOTE """ + WORD "fifth" + QUOTE """ + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "outer" + QUOTE """ + WORD "outer" + QUOTE """ + COLON ":" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "inner_a" + QUOTE """ + WORD "inner_a" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "inner_b" + QUOTE """ + WORD "inner_b" + QUOTE """ + COLON ":" + INTEGER_LITERAL "2" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "inner_c" + QUOTE """ + WORD "inner_c" + QUOTE """ + COLON ":" + INTEGER_LITERAL "3" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "other" + QUOTE """ + WORD "other" + QUOTE """ + COLON ":" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "inner_d" + QUOTE """ + WORD "inner_d" + QUOTE """ + COLON ":" + INTEGER_LITERAL "4" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "inner_e" + QUOTE """ + WORD "inner_e" + QUOTE """ + COLON ":" + INTEGER_LITERAL "5" + COMMA "," + OBJECT_FIELD + STRING_LITERAL "inner_f" + QUOTE """ + WORD "inner_f" + QUOTE """ + COLON ":" + INTEGER_LITERAL "6" + R_BRACE "}" + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "k" + QUOTE """ + WORD "k" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + R_BRACE "}" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "k" + QUOTE """ + WORD "k" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "y: 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "y: 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 3" + WORD "x" + COLON ":" + INTEGER_LITERAL "3" + COMMA "," + OBJECT_FIELD "y: 4" + WORD "y" + COLON ":" + INTEGER_LITERAL "4" + R_BRACE "}" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 100000" + WORD "x" + COLON ":" + INTEGER_LITERAL "100000" + COMMA "," + OBJECT_FIELD "y: 200000" + WORD "y" + COLON ":" + INTEGER_LITERAL "200000" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 300000" + WORD "x" + COLON ":" + INTEGER_LITERAL "300000" + COMMA "," + OBJECT_FIELD "y: 400000" + WORD "y" + COLON ":" + INTEGER_LITERAL "400000" + R_BRACE "}" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherTriple" + L_BRACE "{" + OBJECT_FIELD + WORD "a" + COLON ":" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "y: 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 3" + WORD "x" + COLON ":" + INTEGER_LITERAL "3" + COMMA "," + OBJECT_FIELD "y: 4" + WORD "y" + COLON ":" + INTEGER_LITERAL "4" + R_BRACE "}" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "b" + COLON ":" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 5" + WORD "x" + COLON ":" + INTEGER_LITERAL "5" + COMMA "," + OBJECT_FIELD "y: 6" + WORD "y" + COLON ":" + INTEGER_LITERAL "6" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 7" + WORD "x" + COLON ":" + INTEGER_LITERAL "7" + COMMA "," + OBJECT_FIELD "y: 8" + WORD "y" + COLON ":" + INTEGER_LITERAL "8" + R_BRACE "}" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "c" + COLON ":" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 9" + WORD "x" + COLON ":" + INTEGER_LITERAL "9" + COMMA "," + OBJECT_FIELD "y: 10" + WORD "y" + COLON ":" + INTEGER_LITERAL "10" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x: 11" + WORD "x" + COLON ":" + INTEGER_LITERAL "11" + COMMA "," + OBJECT_FIELD "y: 12" + WORD "y" + COLON ":" + INTEGER_LITERAL "12" + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "// 4 open brace trailing + // 5 field name leading + x // 6 field name trailing + : // 7 colon trailing + // 8 value leading + 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "// 10 comma trailing + // 11 second field leading + y // 12 second name trailing + : // 13 second colon trailing + // 14 second value leading + 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "/* 4 open brace trailing */ + /* 5 field name leading */ + x /* 6 field name trailing */ + : /* 7 colon trailing */ + /* 8 value leading */ + 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "/* 10 comma trailing */ + /* 11 second field leading */ + y /* 12 second name trailing */ + : /* 13 second colon trailing */ + /* 14 second value leading */ + 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherVec" + L_BRACE "{" + OBJECT_FIELD + WORD "p" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "// 9 trailing + // 10 leading + x // 11 trailing + : // 12 trailing + // 13 leading + 100000" + WORD "x" + COLON ":" + INTEGER_LITERAL "100000" + COMMA "," + OBJECT_FIELD "// 15 trailing + // 16 leading + y // 17 trailing + : // 18 trailing + // 19 leading + 200000" + WORD "y" + COLON ":" + INTEGER_LITERAL "200000" + R_BRACE "}" + COMMA "," + OBJECT_FIELD + WORD "q" + COLON ":" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "// 28 trailing + // 29 leading + x // 30 trailing + : // 31 trailing + // 32 leading + 300000" + WORD "x" + COLON ":" + INTEGER_LITERAL "300000" + COMMA "," + OBJECT_FIELD "// 34 trailing + // 35 leading + y // 36 trailing + : // 37 trailing + // 38 leading + 400000" + WORD "y" + COLON ":" + INTEGER_LITERAL "400000" + R_BRACE "}" + R_BRACE "}" + SEMICOLON ";" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let x" + KW_LET "let" + WORD "x" + EQUALS "=" + INTEGER_LITERAL "1" + SEMICOLON ";" + BINARY_EXPR "x + 1" + WORD "x" + PLUS "+" + INTEGER_LITERAL "1" + R_BRACE "}" + SEMICOLON ";" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let x" + KW_LET "let" + WORD "x" + EQUALS "=" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + LET_STMT + PATTERN + BINDING_PATTERN "let y" + KW_LET "let" + WORD "y" + EQUALS "=" + BINARY_EXPR "x * 2" + WORD "x" + STAR "*" + INTEGER_LITERAL "2" + SEMICOLON ";" + WORD "y" + R_BRACE "}" + SEMICOLON ";" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let x" + KW_LET "let" + WORD "x" + EQUALS "=" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let y" + KW_LET "let" + WORD "y" + EQUALS "=" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let z" + KW_LET "let" + WORD "z" + EQUALS "=" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + SEMICOLON ";" + BINARY_EXPR "z * z" + WORD "z" + STAR "*" + WORD "z" + R_BRACE "}" + SEMICOLON ";" + BINARY_EXPR "y + y" + WORD "y" + PLUS "+" + WORD "y" + R_BRACE "}" + SEMICOLON ";" + BINARY_EXPR "x * x" + WORD "x" + STAR "*" + WORD "x" + R_BRACE "}" + SEMICOLON ";" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let x" + KW_LET "let" + WORD "x" + EQUALS "=" + IF_EXPR + KW_IF "if" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "a > b" + WORD "a" + GREATER ">" + WORD "b" + R_PAREN ")" + BLOCK_EXPR + L_BRACE "{" + MATCH_EXPR + KW_MATCH "match" + L_PAREN "(" + WORD "a" + R_PAREN ")" + L_BRACE "{" + MATCH_ARM + PATTERN + TYPE_PATTERN + TYPE_EXPR "0" + INTEGER_LITERAL "0" + FAT_ARROW "=>" + BLOCK_EXPR + L_BRACE "{" + LET_STMT + PATTERN + BINDING_PATTERN "let inner" + KW_LET "let" + WORD "inner" + EQUALS "=" + BINARY_EXPR "b * 2" + WORD "b" + STAR "*" + INTEGER_LITERAL "2" + SEMICOLON ";" + BINARY_EXPR "inner + 1" + WORD "inner" + PLUS "+" + INTEGER_LITERAL "1" + R_BRACE "}" + COMMA "," + MATCH_ARM + PATTERN + WILDCARD_PATTERN "_" + WORD "_" + FAT_ARROW "=>" + WORD "a" + R_BRACE "}" + R_BRACE "}" + KW_ELSE "else" + BLOCK_EXPR "{ + b + }" + L_BRACE "{" + WORD "b" + R_BRACE "}" + SEMICOLON ";" + WORD "x" + R_BRACE "}" + SEMICOLON ";" + ARRAY_LITERAL "// ===== Extraneous whitespace ===== + [ 1 , 2 , 3 ]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + COMMA "," + INTEGER_LITERAL "3" + R_BRACKET "]" + SEMICOLON ";" + MAP_LITERAL + L_BRACE "{" + OBJECT_FIELD + STRING_LITERAL "k" + QUOTE """ + WORD "k" + QUOTE """ + COLON ":" + INTEGER_LITERAL "1" + R_BRACE "}" + SEMICOLON ";" + OBJECT_LITERAL + WORD "OtherPoint" + L_BRACE "{" + OBJECT_FIELD "x : 1" + WORD "x" + COLON ":" + INTEGER_LITERAL "1" + COMMA "," + OBJECT_FIELD "y : 2" + WORD "y" + COLON ":" + INTEGER_LITERAL "2" + R_BRACE "}" + SEMICOLON ";" + BINARY_EXPR "a + b" + WORD "a" + PLUS "+" + WORD "b" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new new file mode 100644 index 0000000000..71d87ca021 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new @@ -0,0 +1,227 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 39957 +--- +// Testing all the formatter cases for binary expressions +// including chains and nested chains + +function BinaryExprs(a: int, b: int, c: int, d: int, s: string, flag: bool) -> int { + // ===== Basic arithmetic ===== + a + b; + a - b; + a * b; + a / b; + a % b; + + // ===== Comparison operators ===== + a == b; + a != b; + a < b; + a > b; + a <= b; + a >= b; + + // ===== Logical operators ===== + flag + && true; + flag + || false; + + // ===== Bitwise operators ===== + a & b; + a | b; + a ^ b; + a << b; + a >> b; + + // ===== Assignment operators ===== + let mut_a = a; + mut_a += b; + mut_a -= b; + mut_a *= b; + mut_a /= b; + mut_a %= b; + mut_a &= b; + mut_a |= b; + mut_a ^= b; + mut_a <<= b; + mut_a >>= b; + + // ===== Chained arithmetic (same precedence group) ===== + a + b + c; + a + b + c + d; + a - b + c - d; + a * b * c; + a * b / c % d; + + // ===== Chained comparisons with logical ===== + a > 0 && b > 0; + a > 0 || b > 0; + a > 0 && b > 0 && c > 0; + a > 0 || b > 0 || c > 0; + a > 0 && b > 0 || c > 0; + + // ===== Mixed precedence ===== + a + b * c; + (a + b) * c; + a * b + c * d; + a + b * c + d; + + // ===== Nested parenthesized ===== + (a + b) * (c + d); + ((a + b) * c) + d; + a + (b * (c + d)); + + // ===== Deeply nested parens ===== + ((((a + b) * c) + d) * (((a - b) + c) - d)) + ((a * b) + (c * d)); + (((a + b) * (c + d)) + ((a - b) * (c - d))) + * (((a * c * d) + (b * c * d)) - ((a * d) + (b * c * d))); + + // ===== Trivia between operands (line comments) ===== + // 1 left leading + a // 2 left trailing + + b; + + // ===== Trivia between operands (block comments) ===== + /* 1 left leading */ + a/* 2 left trailing *//* 3 operator leading */+/* 4 operator trailing *//* 5 right leading */b/* 6 right trailing */; + + // ===== Trivia in chained binary (line comments) ===== + // 1 first leading + a // 2 first trailing + + b // 6 second trailing + + c; + + // ===== Long arithmetic chain exceeding limit ===== + a + + b + + c + + d + + a + + b + + c + + d + + a + + b + + c + + d + + a + + b + + c + + d + + a + + b + + c + + d + + a + + b + + c + + d + + a + + b; + + // ===== Long logical chain exceeding limit ===== + a > 0 + && b > 0 + && c > 0 + && d > 0 + && a != b + && b != c + && c != d + && a < 1000 * 8 + 1 * 2 + && b < 1000 + && c < 1000 + && d < 1000 + 2 + 3; + + // ===== Long mixed precedence chain exceeding limit ===== + a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d + - a * b + + c * d; + + // ===== Long comparison chain exceeding limit ===== + a + b + c + d > 0 + && a * b * c * d < 10000 + && a - b - c - d != 0 + && (a + b) * (c + d) >= 100 + || a * 1 < 2 + && "aowiefjowiaj" == "jfeiowajpwoeifj"; + + // ===== Long string concatenation exceeding limit ===== + "a very long string prefix that is already quite long" + + " concatenated with " + + "another very long string that together exceeds the line limit easily and comfortably"; + + // ===== Long assignment expression exceeding limit ===== + mut_a += a * b + c * d + a * b + c * d + a * b + c * d + a * b + c * d + a * b + c * d + a; + + // ===== Trivia in long wrapping chain (line comments) ===== + // 1 leading + a // 2 trailing + + b // 6 trailing + + c // 10 trailing + + d // 14 trailing + + a // 18 trailing + + b // 22 trailing + + c // 26 trailing + + d // 30 trailing + + a // 34 trailing + + b // 38 trailing + + c // 42 trailing + + d; + + // ===== Trivia in long wrapping chain (block comments) ===== + /* 1 leading */ + a /* 2 trailing */ + + b /* 6 trailing */ + + c /* 10 trailing */ + + d /* 14 trailing */ + + a /* 18 trailing */ + + b /* 22 trailing */ + + c /* 26 trailing */ + + d /* 30 trailing */ + + a /* 34 trailing */ + + b /* 38 trailing */ + + c /* 42 trailing */ + + d/* 46 trailing */; + + // ===== Trivia in long wrapping logical chain (line comments) ===== + // 1 leading + a > 0 // 2 trailing + && b > 0 // 6 trailing + && c > 0 // 10 trailing + && d > 0 // 14 trailing + && a != b // 18 trailing + && b != c // 22 trailing + && c != d; + + // ===== Short expressions (should stay single line) ===== + a + b; + 1 + 2; + a > b; + + // ===== Extraneous whitespace ===== + a + b; + a * b + c; + a == b; + a == 2 && b != 3; + + // ===== Final expression ===== + a + b +} 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.new 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.new new file mode 100644 index 0000000000..77eca375a0 --- /dev/null +++ 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.new @@ -0,0 +1,78 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 50625 +--- +=== SYNTAX TREE === +SOURCE_FILE + TEST_EXPR_DEF + KW_TEST "test" + BINARY_EXPR + STRING_LITERAL "a" + QUOTE """ + WORD "a" + QUOTE """ + PLUS "+" + INTEGER_LITERAL "1" + BLOCK_EXPR "{ + null +}" + L_BRACE "{" + KW_NULL "null" + R_BRACE "}" + TEST_EXPR_DEF + KW_TEST "test" + INTEGER_LITERAL "42" + BLOCK_EXPR "{ + null +}" + L_BRACE "{" + KW_NULL "null" + R_BRACE "}" + TESTSET_DEF + KW_TESTSET "testset" + STRING_LITERAL "int_name" + QUOTE """ + WORD "int_name" + QUOTE """ + BLOCK_EXPR + L_BRACE "{" + FOR_EXPR + KW_FOR "for" + L_PAREN "(" + LET_STMT + PATTERN + BINDING_PATTERN "let i" + KW_LET "let" + WORD "i" + KW_IN "in" + ARRAY_LITERAL "[1, 2, 3]" + L_BRACKET "[" + INTEGER_LITERAL "1" + COMMA "," + INTEGER_LITERAL "2" + COMMA "," + INTEGER_LITERAL "3" + R_BRACKET "]" + R_PAREN ")" + BLOCK_EXPR + L_BRACE "{" + TEST_EXPR_DEF + KW_TEST "test" + PAREN_EXPR + L_PAREN "(" + BINARY_EXPR "5 + i" + INTEGER_LITERAL "5" + PLUS "+" + WORD "i" + R_PAREN ")" + BLOCK_EXPR "{ + null + }" + L_BRACE "{" + KW_NULL "null" + R_BRACE "}" + R_BRACE "}" + R_BRACE "}" + +=== ERRORS === +None 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__03_hir.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new new file mode 100644 index 0000000000..f1ccd920a9 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new @@ -0,0 +1,8 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 50649 +--- +=== HIR2 === +function user.$init_test_main(registry: testing.TestCollector) -> ? [expr] { + { registry.register_test("a" Add 1, () -> void { { } }, null); registry.register_test(42, () -> void { { } }, null); registry.register_test_set("int_name", (testset: testing.TestCollector) -> void { { for i in [1, 2, 3] { testset.register_test(5 Add i, () -> { { } }, null) } } null }, null) } null +} 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__04_tir.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new new file mode 100644 index 0000000000..7a57335620 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new @@ -0,0 +1,39 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 50673 +--- +=== TIR2 === +function user.$init_test_main(registry: testing.TestCollector) -> ? throws never { + { : null + registry.register_test("a" + 1, () -> void { ... }, null) : void + () -> void { ... } : () -> void throws unknown + { + } + registry.register_test(42, () -> void { ... }, null) : void + () -> void { ... } : () -> void throws unknown + { + } + registry.register_test_set("int_name", (testset: testing.TestCollector) -> void { ... }, null) : void + (testset: testing.TestCollector) -> void { ... } : (testset: testing.TestCollector) -> void throws unknown + { + for i in [1, 2, 3] + { + testset.register_test(5 + i, () -> { ... }, null) + } + null + } + null : null + } + !! 80..88: operator `+` cannot be applied to `"a"` and `1` + !! 106..108: type mismatch: expected string, got 42 + !! 181..186: type mismatch: expected string, got int +} +lambda user.$init_test_main { +} +lambda user.$init_test_main { +} +lambda user.$init_test_main { + !! 181..186: type mismatch: expected string, got int +} +lambda user.$init_test_main { +} 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__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new new file mode 100644 index 0000000000..c7371bcf99 --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new @@ -0,0 +1,322 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 50728 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: operator `+` cannot be applied to `"a"` and `1` + ╭─[ main.baml:3:5 ] + │ + 3 │ test "a" + 1 { + │ ────┬─── + │ ╰───── operator `+` cannot be applied to `"a"` and `1` + │ + │ Note: Error code: E0004 +───╯ + + [type] error: type mismatch: expected string, got 42 + ╭─[ main.baml:7:6 ] + │ + 7 │ test 42 { + │ ─┬ + │ ╰── type mismatch: expected string, got 42 + │ + │ Note: Error code: E0001 +───╯ + + [type] error: type mismatch: expected string, got int + ╭─[ main.baml:13:11 ] + │ + 13 │ test (5 + i) { + │ ──┬── + │ ╰──── type mismatch: expected string, got int + │ + │ Note: Error code: E0001 +────╯ 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.new 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.new new file mode 100644 index 0000000000..d35d9d54d6 --- /dev/null +++ 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.new @@ -0,0 +1,92 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 50900 +--- +=== SYNTAX TREE === +SOURCE_FILE + TEST_EXPR_DEF + KW_TEST "test" + STRING_LITERAL "wrong runner type" + QUOTE """ + WORD "wrong" + WORD "runner" + WORD "type" + QUOTE """ + KW_WITH "with" + INTEGER_LITERAL "42" + BLOCK_EXPR + L_BRACE "{" + CALL_EXPR + PATH_EXPR "assert.is_true" + WORD "assert" + DOT "." + WORD "is_true" + CALL_ARGS + L_PAREN "(" + CALL_ARG "true" + KW_TRUE "true" + R_PAREN ")" + R_BRACE "}" + TEST_EXPR_DEF + KW_TEST "test" + STRING_LITERAL "string as runner" + QUOTE """ + WORD "string" + WORD "as" + WORD "runner" + QUOTE """ + KW_WITH "with" + STRING_LITERAL "not a runner" + QUOTE """ + WORD "not" + WORD "a" + WORD "runner" + QUOTE """ + BLOCK_EXPR + L_BRACE "{" + CALL_EXPR + PATH_EXPR "assert.is_true" + WORD "assert" + DOT "." + WORD "is_true" + CALL_ARGS + L_PAREN "(" + CALL_ARG "true" + KW_TRUE "true" + R_PAREN ")" + R_BRACE "}" + TESTSET_DEF + KW_TESTSET "testset" + STRING_LITERAL "wrong testset runner" + QUOTE """ + WORD "wrong" + KW_TESTSET "testset" + WORD "runner" + QUOTE """ + KW_WITH "with" + INTEGER_LITERAL "42" + BLOCK_EXPR + L_BRACE "{" + TEST_EXPR_DEF + KW_TEST "test" + STRING_LITERAL "inner" + QUOTE """ + WORD "inner" + QUOTE """ + BLOCK_EXPR + L_BRACE "{" + CALL_EXPR + PATH_EXPR "assert.is_true" + WORD "assert" + DOT "." + WORD "is_true" + CALL_ARGS + L_PAREN "(" + CALL_ARG "true" + KW_TRUE "true" + R_PAREN ")" + R_BRACE "}" + R_BRACE "}" + +=== ERRORS === +None diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new new file mode 100644 index 0000000000..316f6ae81f --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new @@ -0,0 +1,322 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 51003 +--- +=== COMPILER2 DIAGNOSTICS === + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:343:31 ] + │ + 343 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:344:29 ] + │ + 344 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 348 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:396:14 ] + │ + 396 │ ╭─▶ null => { + ┆ ┆ + 399 │ ├─▶ }, + │ │ + │ ╰────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:408:33 ] + │ + 408 │ ╭─▶ if (chunk.length() == 0) { + ┆ ┆ + 410 │ ├─▶ } else { + │ │ + │ ╰────────────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:410:15 ] + │ + 410 │ ╭─▶ } else { + ┆ ┆ + 412 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:508:31 ] + │ + 508 │ ╭─▶ function flush(self) -> null { + ┆ ┆ + 510 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:521:31 ] + │ + 521 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:522:29 ] + │ + 522 │ ╭─▶ if (self._owns_file) { + ┆ ┆ + 526 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: `if` without `else` cannot be used as a value; add an `else` branch + ╭─[ csv.baml:561:31 ] + │ + 561 │ ╭─▶ let f: root.fs.File => { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch + │ + │ Note: Error code: E0001 +─────╯ + + [type] error: missing return value of type null + ╭─[ csv.baml:562:30 ] + │ + 562 │ ╭─▶ if (out.length() > 0) { + ┆ ┆ + 566 │ ├─▶ } + │ │ + │ ╰─────────────── missing return value of type null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:86:89 ] + │ + 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 98 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type bool + ╭─[ iter.baml:100:90 ] + │ + 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { + ┆ ┆ + 112 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type Self.Item | null + ╭─[ iter.baml:114:90 ] + │ + 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { + ┆ ┆ + 126 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type Self.Item | null + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:104:56 ] + │ + 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { + ┆ ┆ + 106 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ comparison.baml:107:57 ] + │ + 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { + ┆ ┆ + 109 │ ├─▶ } + │ │ + │ ╰─────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:298:63 ] + │ + 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { + ┆ ┆ + 307 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:309:75 ] + │ + 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { + ┆ ┆ + 319 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:490:62 ] + │ + 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { + ┆ ┆ + 513 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:517:18 ] + │ + 517 │ ╭─▶ if (expr == "") { + ┆ ┆ + 519 │ ├─▶ } else { + │ │ + │ ╰──────────────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type bool + ╭─[ registry.baml:524:98 ] + │ + 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { + ┆ ┆ + 531 │ ├─▶ } + │ │ + │ ╰─────── missing return value of type bool + │ + │ Note: Error code: E0029 +─────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:7:9 ] + │ + 7 │ ╭─▶ } else { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +───╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:16:9 ] + │ + 16 │ ╭─▶ } else { + ┆ ┆ + 18 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:44:9 ] + │ + 44 │ ╭─▶ } else { + ┆ ┆ + 46 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: missing return value of type null + ╭─[ assert.baml:53:9 ] + │ + 53 │ ╭─▶ } else { + ┆ ┆ + 55 │ ├─▶ } + │ │ + │ ╰───────── missing return value of type null + │ + │ Note: Error code: E0029 +────╯ + + [type] error: type mismatch: expected testing.TestRunner | null, got 42 + ╭─[ main.baml:4:31 ] + │ + 4 │ test "wrong runner type" with 42 { + │ ─┬ + │ ╰── type mismatch: expected testing.TestRunner | null, got 42 + │ + │ Note: Error code: E0001 +───╯ + + [type] error: type mismatch: expected testing.TestRunner | null, got "not a runner" + ╭─[ main.baml:8:30 ] + │ + 8 │ test "string as runner" with "not a runner" { + │ ───────┬────── + │ ╰──────── type mismatch: expected testing.TestRunner | null, got "not a runner" + │ + │ Note: Error code: E0001 +───╯ + + [type] error: type mismatch: expected testing.TestSetRunner | null, got 42 + ╭─[ main.baml:12:37 ] + │ + 12 │ testset "wrong testset runner" with 42 { + │ ─┬ + │ ╰── type mismatch: expected testing.TestSetRunner | null, got 42 + │ + │ Note: Error code: E0001 +────╯ diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new new file mode 100644 index 0000000000..35f0a3894b --- /dev/null +++ b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new @@ -0,0 +1,29 @@ +--- +source: crates/baml_tests/src/generated_tests.rs +assertion_line: 51080 +--- +// Runner expression is the wrong type — should produce a type diagnostic. +// Expected: diagnostics for type mismatch on 42 and "not a runner". + +test "wrong runner type" with 42 { + assert + .is_true( + true, + ) +} + +test "string as runner" with "not a runner" { + assert + .is_true( + true, + ) +} + +testset "wrong testset runner" with 42 { + test "inner" { + assert + .is_true( + true, + ) + } +} From c11b25524afe7634c98594f5d6f7eee9e99556bf Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 01:52:30 -0700 Subject: [PATCH 03/17] feat(lsp): wire textDocument/semanticTokens/range (viewport highlighting) Advertise and implement the range request: convert the LSP range to byte offsets, call semantic_tokens_in_range (on-demand, only resolves the scopes the viewport touches), and delta-encode via a shared encoder factored out of the full handler. Range query proven equal to full-filtered-to-range. --- .../crates/baml_lsp2_actions/src/tokens.rs | 4 +- .../src/range_tokens_test.rs | 3 +- .../src/bex_lsp/multi_project/request.rs | 106 ++++++++++++------ 3 files changed, 79 insertions(+), 34 deletions(-) diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index 4c278df684..c417da6257 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -340,8 +340,10 @@ pub fn semantic_tokens(db: &dyn Db, file: SourceFile) -> Vec { pub fn semantic_tokens_in_range( db: &dyn Db, file: SourceFile, - range: TextRange, + 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, 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 index 83d5da7df1..5da5cf6af5 100644 --- 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 @@ -25,7 +25,8 @@ mod tests { .filter(|t| range.intersect(t.range).is_some()) .cloned() .collect(); - let actual = semantic_tokens_in_range(&db, file, range); + 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:?}" 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 6b6ed8d5a9..fa196d3a2e 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 @@ -50,7 +50,7 @@ pub(super) fn server_capabilities() -> ServerCapabilities { .collect(), }, full: Some(SemanticTokensFullOptions::Bool(true)), - range: None, + range: Some(true), ..Default::default() }, )), @@ -319,42 +319,48 @@ 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); - // 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; - - let Some(pos) = line_index.offset_to_position(start_offset) else { - continue; - }; + Ok(Some(lsp_types::SemanticTokensResult::Tokens( + lsp_types::SemanticTokens { + result_id: None, + data: lsp_tokens, + }, + ))) + } - let delta_line = pos.line - prev_line; - let delta_start = if delta_line == 0 { - pos.character - prev_start - } else { - pos.character - }; + /// 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)?; - lsp_tokens.push(lsp_types::SemanticToken { - delta_line, - delta_start, - length, - token_type: token.token_type.legend_index(), - token_modifiers_bitset: token.modifiers.bits(), - }); + 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); - prev_line = pos.line; - prev_start = pos.character; - } + 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::SemanticTokensResult::Tokens( + Ok(Some(lsp_types::SemanticTokensRangeResult::Tokens( lsp_types::SemanticTokens { result_id: None, data: lsp_tokens, @@ -856,6 +862,42 @@ 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 +} + /// Convert a compiler2 `DefinitionKind` to an LSP `SymbolKind`. /// /// Used by the `textDocument/documentSymbol` and `workspace/symbol` handlers From 9474b5d4afbc3fa525ffee064fee74b53290e8ad Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 02:02:26 -0700 Subject: [PATCH 04/17] feat(lsp): wire textDocument/semanticTokens/full/delta (incremental tokens) Advertise Delta + cache the last-sent tokens per file under a monotonic result_id. The delta handler diffs the new token array against the cached one (common prefix/suffix trim at token granularity; offsets scaled by 5 since the LSP stream is 5 u32 per token) and returns just the edits, falling back to the full set on a result_id miss. The full handler now emits a result_id. Diff covered by unit tests (identical/middle/append/truncate). --- .../src/bex_lsp/multi_project/mod.rs | 18 +++ .../src/bex_lsp/multi_project/request.rs | 148 +++++++++++++++++- 2 files changed, 164 insertions(+), 2 deletions(-) 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 22166f34ec..70a51b2858 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 @@ -33,6 +33,13 @@ struct LiveProject { std::sync::Arc>>, } +/// 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: @@ -55,6 +62,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 { @@ -106,6 +120,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 fa196d3a2e..e1507bddcd 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 @@ -49,7 +49,7 @@ pub(super) fn server_capabilities() -> ServerCapabilities { .map(|name| lsp_types::SemanticTokenModifier::new(name)) .collect(), }, - full: Some(SemanticTokensFullOptions::Bool(true)), + full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }), range: Some(true), ..Default::default() }, @@ -320,15 +320,66 @@ impl BexLspRequest for BexMulitProject { // 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()); Ok(Some(lsp_types::SemanticTokensResult::Tokens( lsp_types::SemanticTokens { - result_id: None, + result_id: Some(result_id), data: lsp_tokens, }, ))) } + /// 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 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 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()); + + 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, + }, + ))), + } + } + /// Viewport semantic tokens — rust-analyzer's `highlight_range`. Resolves /// only the scopes the requested range touches. fn on_request_text_document_semantic_tokens_range( @@ -898,6 +949,81 @@ fn encode_semantic_tokens( 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 @@ -933,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, From 635d370ebce36e07a040befaa20d0cbb7147b2c3 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 02:33:51 -0700 Subject: [PATCH 05/17] refactor(lsp): flat preorder_with_tokens traversal + typed AST accessors Replace the recursive Walk::node dispatch with rust-analyzer's flat traverse shape: one preorder_with_tokens() loop (Walk::run) that range-gates each subtree, hands subtree-spanning nodes (strings, comments, type exprs, object literals, generators) to a wholesale handler then skip_subtree, and classifies every other token from its parent kind via the free fn classify_token (rust-analyzer's IdentClass::classify_token model). The stateful cases (type-alias type-kw/name, object-field key, generic-param name) read off typed ast accessors (ObjectField::key, GenericParam::name) instead of positional sibling scanning. Behavior-preserving: all 440 tests pass and the 78 semantic_tokens fixtures are byte-identical. --- .../crates/baml_compiler_syntax/src/ast.rs | 26 ++ .../crates/baml_lsp2_actions/src/tokens.rs | 302 ++++++++++-------- .../baml_lsp2_actions/src/tokens/DESIGN.md | 29 ++ 3 files changed, 219 insertions(+), 138 deletions(-) diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index 5226c23ae8..56cb0bebf7 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -186,6 +186,32 @@ 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 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| token.kind() == SyntaxKind::WORD) + } +} + +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. /// diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index c417da6257..dc1d117876 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -17,10 +17,14 @@ //! `declaration` modifier; a reference is classified the same way as its //! definition. +use std::cmp::Ordering; + use baml_base::{Name, SourceFile}; +use baml_compiler_syntax::ast::{GenericParam, ObjectField}; use baml_compiler_syntax::{SyntaxKind, SyntaxNode, SyntaxToken}; use baml_compiler2_tir::resolve::{resolve_name_at, resolve_path_at}; -use rowan::NodeOrToken; +use rowan::ast::AstNode; +use rowan::{NodeOrToken, WalkEvent}; use text_size::{TextRange, TextSize}; use crate::Db; @@ -327,7 +331,7 @@ pub fn semantic_tokens(db: &dyn Db, file: SourceFile) -> Vec { range: None, }; let mut out = Vec::new(); - walk.node(&root, &mut out); + walk.run(&root, &mut out); out } @@ -352,7 +356,7 @@ pub fn semantic_tokens_in_range( range: Some(range), }; let mut out = Vec::new(); - walk.node(&root, &mut out); + 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 @@ -377,17 +381,56 @@ struct Walk<'db> { } impl Walk<'_> { - /// Dispatch a node to its classifier. - fn node(&self, node: &SyntaxNode, out: &mut Vec) { - // 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() { - return; + /// 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(_) => {} } } + } + + /// 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), // Escape-processing literals: split out `\n`, `\xNN`, `\u{..}`, ... SyntaxKind::STRING_LITERAL | SyntaxKind::BYTE_STRING_LITERAL => { string_with_escapes(node, out); @@ -397,70 +440,12 @@ impl Walk<'_> { emit_node(node, SemanticTokenType::String, out); } SyntaxKind::BACKTICK_STRING_LITERAL => self.backtick_string(node, out), - SyntaxKind::ATTRIBUTE | SyntaxKind::BLOCK_ATTRIBUTE => self.tokens(node, out, |t| { - (matches!(t.kind(), SyntaxKind::AT_AT | SyntaxKind::AT | SyntaxKind::WORD) - || t.kind().is_keyword()) - .then_some(plain(SemanticTokenType::Decorator)) - }), - SyntaxKind::TYPE_ALIAS_DEF | SyntaxKind::ASSOCIATED_TYPE_DECL => { - self.type_decl(node, out); - } - SyntaxKind::ENUM_DEF => self.decl_name(node, SemanticTokenType::Enum, out), - SyntaxKind::ENUM_VARIANT => self.decl_name(node, SemanticTokenType::EnumMember, out), - SyntaxKind::CLASS_DEF => self.decl_name(node, SemanticTokenType::Class, out), - SyntaxKind::INTERFACE_DEF => self.decl_name(node, SemanticTokenType::Interface, out), - SyntaxKind::FIELD => self.decl_name(node, SemanticTokenType::Property, out), - SyntaxKind::FUNCTION_DEF | SyntaxKind::METHOD_SIG => self.function_def(node, out), - SyntaxKind::PARAMETER => self.decl_name(node, SemanticTokenType::Parameter, out), SyntaxKind::TYPE_EXPR => self.type_expr(node, out), - // `let x`, match-arm bindings, etc.: the bound name is a declaration. - SyntaxKind::BINDING_PATTERN => self.decl_name(node, SemanticTokenType::Variable, out), - SyntaxKind::CLIENT_TYPE => self.tokens(node, out, |t| { - (t.kind() == SyntaxKind::WORD).then_some(plain(SemanticTokenType::Type)) - }), - SyntaxKind::CONFIG_ITEM => self.tokens(node, out, |t| { - (t.kind().is_keyword() || t.kind() == SyntaxKind::WORD) - .then_some(plain(SemanticTokenType::Property)) - }), - SyntaxKind::CLIENT_DEF | SyntaxKind::RETRY_POLICY_DEF => { - self.decl_name(node, SemanticTokenType::Struct, out); - } - SyntaxKind::TEST_DEF => self.decl_name(node, SemanticTokenType::Struct, out), - SyntaxKind::TEMPLATE_STRING_DEF => { - self.decl_name(node, SemanticTokenType::Function, out); - } - SyntaxKind::PROMPT_FIELD => self.decl_name(node, SemanticTokenType::Property, out), SyntaxKind::OBJECT_LITERAL => self.object_literal(node, out), - SyntaxKind::OBJECT_FIELD => self.object_field(node, out), - SyntaxKind::CLIENT_FIELD => self.tokens(node, out, |t| { - (t.kind() == SyntaxKind::KW_CLIENT).then_some(plain(SemanticTokenType::Property)) - }), - // `as` is a contextual keyword (lexed as a WORD) in `.as` casts - // and `field as field` interface field links. - SyntaxKind::UPCAST_EXPR | SyntaxKind::INTERFACE_FIELD_LINK => self.tokens(node, out, |t| { - (t.kind() == SyntaxKind::WORD && t.text() == "as") - .then_some(plain(SemanticTokenType::Keyword)) - }), SyntaxKind::GENERATOR_DEF => self.generator_def(node, out), - // A generic parameter declaration (`T` in `class Box`, - // `function f()`, ``): the name as a `TypeParameter` - // declaration, any bound dispatched as a type. - SyntaxKind::GENERIC_PARAM => { - let mut named = false; - self.tokens(node, out, |t| { - (!named && t.kind() == SyntaxKind::WORD).then(|| { - named = true; - decl(SemanticTokenType::TypeParameter) - }) - }); - } - _ => self.children(node, out), + _ => return false, } - } - - /// Walk all children with no special token classification. - fn children(&self, node: &SyntaxNode, out: &mut Vec) { - self.tokens(node, out, |_| None); + true } /// Classify a single leaf token. A WORD consults the resolution index (an @@ -516,10 +501,10 @@ impl Walk<'_> { emit(token.text_range(), plain(token_type), out); } - /// The one structural primitive: walk children, dispatching each node and - /// classifying each token by `classify`. A `None` result falls back to the - /// token's own syntactic classification ([`Self::token`]). Every node handler - /// below is a thin wrapper over this. + /// 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, @@ -528,7 +513,7 @@ impl Walk<'_> { ) { for child in node.children_with_tokens() { match child { - NodeOrToken::Node(n) => self.node(&n, 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), @@ -537,40 +522,6 @@ impl Walk<'_> { } } - /// Direct WORD children as a declaration of `ty` (class/enum/field/... names, - /// which never appear in the expression index). - fn decl_name(&self, node: &SyntaxNode, ty: SemanticTokenType, out: &mut Vec) { - self.tokens(node, out, |t| (t.kind() == SyntaxKind::WORD).then_some(decl(ty))); - } - - /// A `TYPE_ALIAS_DEF` (`type X = …`), an associated-type *declaration* - /// (`type Item [extends Bound] [= Default]` in an interface/impl), or an - /// associated-type *binding* (`Item = string` inside `Iterator<…>`). All - /// three share `ASSOCIATED_TYPE_DECL`/`TYPE_ALIAS_DEF`. The leading `type` - /// keyword (a WORD in the grammar) is `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 and dispatch on their own. - fn type_decl(&self, node: &SyntaxNode, out: &mut Vec) { - let mut saw_type_kw = false; - let mut named = false; - self.tokens(node, out, |t| { - if t.kind() != SyntaxKind::WORD { - return None; - } - if !named && t.text() == "type" { - saw_type_kw = true; - return Some(plain(SemanticTokenType::Keyword)); - } - if !named { - named = true; - let ty = SemanticTokenType::Type; - return Some(if saw_type_kw { decl(ty) } else { plain(ty) }); - } - None - }); - } - /// 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 @@ -600,7 +551,7 @@ impl Walk<'_> { } } match &children[i] { - NodeOrToken::Node(n) => self.node(n, out), + NodeOrToken::Node(n) => self.run(n, out), NodeOrToken::Token(t) => self.token(t, out), } i += 1; @@ -629,19 +580,6 @@ impl Walk<'_> { emit(leaf.text_range(), class, out); } - /// A `FUNCTION_DEF` or `METHOD_SIG` — the name as a `Function` (or `Method`, - /// inside a class/interface/implements) declaration; parameters, the return - /// type, and the body are dispatched as child nodes (the body's identifiers - /// resolve through the index). - fn function_def(&self, node: &SyntaxNode, out: &mut Vec) { - let name_type = if in_method_context(node) { - SemanticTokenType::Method - } else { - SemanticTokenType::Function - }; - self.decl_name(node, name_type, out); - } - /// 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 @@ -659,7 +597,7 @@ impl Walk<'_> { typed = true; self.object_type_path(&n, out); } - NodeOrToken::Node(n) => self.node(&n, out), + NodeOrToken::Node(n) => self.run(&n, out), NodeOrToken::Token(t) => self.token(&t, out), } } @@ -724,20 +662,108 @@ impl Walk<'_> { _ => None, }); } +} - /// An `OBJECT_FIELD` (`a: expr` or `"a": expr`) — a bare-word key (before the - /// `:`) as a `Property`; a string key and the value expression dispatched (so - /// a value like `null` / `true` isn't mistaken for the key). - fn object_field(&self, node: &SyntaxNode, out: &mut Vec) { - let mut seen_colon = false; - self.tokens(node, out, |t| match t.kind() { - SyntaxKind::COLON => { - seen_colon = true; - None - } - SyntaxKind::WORD if !seen_colon => Some(plain(SemanticTokenType::Property)), - _ => None, - }); +/// 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)), + SyntaxKind::CLIENT_TYPE => word.then_some(plain(SemanticTokenType::Type)), + SyntaxKind::CONFIG_ITEM => { + (kind.is_keyword() || word).then_some(plain(SemanticTokenType::Property)) + } + SyntaxKind::CLIENT_FIELD => { + (kind == SyntaxKind::KW_CLIENT).then_some(plain(SemanticTokenType::Property)) + } + // `as` is a contextual keyword (lexed as a WORD) in `.as` casts and + // `field as field` interface field links. + SyntaxKind::UPCAST_EXPR | SyntaxKind::INTERFACE_FIELD_LINK => { + (word && token.text() == "as").then_some(plain(SemanticTokenType::Keyword)) + } + // 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)), + 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)), + _ => 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()?; + let words: Vec = parent + .children_with_tokens() + .filter_map(NodeOrToken::into_token) + .filter(|t| t.kind() == SyntaxKind::WORD) + .collect(); + // The leading run of `type` WORDs are keywords; the name is the first WORD + // after them. + let lead_type_kws = words.iter().take_while(|t| t.text() == "type").count(); + let index = words + .iter() + .position(|t| t.text_range() == token.text_range())?; + match index.cmp(&lead_type_kws) { + Ordering::Less => Some(plain(SemanticTokenType::Keyword)), + Ordering::Equal => { + let ty = SemanticTokenType::Type; + Some(if lead_type_kws > 0 { decl(ty) } else { plain(ty) }) + } + Ordering::Greater => None, } } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md index abafb19c35..e8a03fd894 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md @@ -100,6 +100,35 @@ The RA *system* (Phases B/C/D) is LSP-only — no parser change, no broad fallout — and is the high-value core. Do it first; do the broad parser-token remap (P1 full) afterward as a carefully-mapped change. +## Status (2026-06) + +DELIVERED + committed + validated (PR #3867): +- **B (on-demand resolution):** `scope_resolution_index` — per-`ScopeId` + salsa-cached resolution index (RA body-granularity memo; editing one scope + invalidates only its index). `build` merges them for a full document; + `resolve_token_class` resolves one name on demand (RA `Semantics::resolve`), + walking the scope chain. The `Walk` is parameterized by a `resolve` closure. +- **D (scaling):** `semantic_tokens_in_range` (RA `highlight_range`) — range-gated + walk, resolves only the scopes the viewport touches; proven equal to + full-filtered-to-range across every sub-range (`range_tokens_test`). LSP: + `semanticTokens/range` + `full/delta` advertised + wired (per-file token cache, + monotonic `result_id`, prefix/suffix token-granularity diff; diff unit-tested). +- **A1 (boolean):** `true`/`false` -> `boolean` token type; inert KW_* token + foundation laid. + +IN PROGRESS: +- **C (flat preorder traversal) + A2 (typed accessors):** rewriting the recursive + `Walk` into one `preorder_with_tokens()` loop + `classify_token` parent-kind + dispatch reading typed `ast::*` accessors. Behavior-preserving (78 fixtures + + range test are the oracle). + +DEFERRED (documented cost/benefit): +- **P1 broad remap (true/false/null -> KW_*):** ripples into hover/formatter/CST + snapshots for a highlighter-purity gain; the boolean output already ships via a + transitional text match. The contained `as`/`type` -> KW_AS/KW_TYPE remap is + worthwhile and smaller-radius; do it once C lands (it changes how `classify_token` + reads `as`/`type`). + ## Phases (each ends green: 78 fixtures unchanged unless the change is the point) - **A. Parser/AST prerequisites (P1 then P2).** Land literal/keyword tokens + From 860c2174e464b7da7d5a98a8d716a74f127b71e2 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 02:43:35 -0700 Subject: [PATCH 06/17] docs(lsp): record as/type remap blast-radius evidence (deferred) --- .../crates/baml_lsp2_actions/src/tokens/DESIGN.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md index e8a03fd894..16b5c50a22 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md @@ -94,6 +94,19 @@ For now the `boolean` token type is delivered via a transitional text match in ready for the proper remap. `as`/`type` highlighting already works via the existing context handlers, so the remap is a *mechanism* upgrade, not a feature. +**`as`/`type` remap also confirmed broad (attempted + reverted):** remapping the +5 `as`/`type` bump sites to `KW_AS`/`KW_TYPE` (and making `classify_token` read +the kinds) compiled and kept the 78 fixtures green, but broke compiler lowering +— `baml_compiler2_ast` `function_type_throws_preserves_omission_vs_explicit_never` +started emitting a spurious "type alias" diagnostic (the type-alias path keys on +the `type` token). So BOTH parser-token remaps (true/false/null AND as/type) are +deferred on the same evidence-based cost/benefit: they ripple into hover / +lowering / formatter / CST snapshots for a highlighter-purity-only gain, while +`classify_token`'s contextual disambiguation (the `as`/`type`/`true`/`false` +checks are scoped to a known parent node, not free substring scanning) is correct +and reasonable. Doing the remap properly means mapping + updating every +token-kind consumer first (a dedicated fan-out), not a highlighter-local change. + ## Revised sequencing: architecture first, parser-token remap as a mapped follow-up The RA *system* (Phases B/C/D) is LSP-only — no parser change, no broad From 7bf5aaaf04786b1a600c7ba98e672e876b293a97 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 03:38:23 -0700 Subject: [PATCH 07/17] feat(parser): re-lex `as`/`type` contextual keywords as KW_AS/KW_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the `as` cast/projection/field-link keyword and the `type` alias / associated-type keyword real tokens (KW_AS / KW_TYPE) instead of bare WORDs, so the semantic-tokens classifier reads them by kind rather than by text. Updates every token-kind consumer (the principled cleanup the remap enables): - ast.rs: TypeAliasDef::name no longer skips a leading `type` WORD (it's KW_TYPE now); the five `(WORD && text=="as")` checks read KW_AS. - baml_fmt: add TypeKw / As keyword tokens; TypeAliasDecl + AssociatedTypeDecl `keyword` and InterfaceFieldLink + AssociatedProjectionType `as_token` fields read them (drops the "type is just a WORD" workaround). - lsp classifier: `as` classifies via is_keyword (the text-match arm is gone); classify_type_decl_word detects KW_TYPE for the decl-vs-binding distinction. - 28 parser CST snapshots regenerated — purely mechanical WORD -> KW_AS/KW_TYPE (the meta-type value `type` correctly stays WORD). Validated: compiler2_ast 73/73, lsp 440/440, baml_tests 2661/2665 (the 4 generic_arg_soundness failures are pre-existing WIP red tests for a known TIR generics gap, confirmed failing on base too). --- .../crates/baml_compiler_parser/src/parser.rs | 10 +- .../crates/baml_compiler_syntax/src/ast.rs | 17 +- .../crates/baml_fmt/src/ast/declarations.rs | 9 +- .../crates/baml_fmt/src/ast/tokens.rs | 2 + .../crates/baml_fmt/src/ast/types.rs | 4 +- .../crates/baml_lsp2_actions/src/tokens.rs | 34 +- ...anned_expressions__05_diagnostics.snap.new | 490 ----- ...ts__02_parser__function_type_defaults.snap | 2 +- ...reaters_fix__02_parser__extra_greater.snap | 2 +- ...ion_errors__02_parser__type_malformed.snap | 4 +- ...s__bigint_literal__05_diagnostics.snap.new | 292 --- ...e_string_literals__05_diagnostics.snap.new | 292 --- ..._string_in_config__05_diagnostics.snap.new | 292 --- ...nfig_model_string__05_diagnostics.snap.new | 292 --- ...union_arithmetic__02_parser__main.snap.new | 261 --- ..._union_arithmetic__05_diagnostics.snap.new | 292 --- ...on_arithmetic__10_formatter__main.snap.new | 71 - ...al_union_widening__05_diagnostics.snap.new | 292 --- ...aces_type_resolution__02_parser__main.snap | 3 +- ...e_resolution__02_parser__ns_auth_auth.snap | 3 +- ..._resolution__02_parser__ns_llm_models.snap | 5 +- ..._function_parameters__02_parser__main.snap | 5 +- ...xpressions__02_parser__precedence.snap.new | 92 - ...arser_expressions__05_diagnostics.snap.new | 292 --- ...essions__10_formatter__precedence.snap.new | 19 - ...patterns_new__02_parser__patterns_new.snap | 2 +- ...__stream_crossfile__02_parser__file_a.snap | 2 +- ...__test_expr_basic__05_diagnostics.snap.new | 292 --- ...expr_name_concat__02_parser__main.snap.new | 64 - ...es__test_expr_name_concat__03_hir.snap.new | 8 - ..._expr_name_concat__05_diagnostics.snap.new | 292 --- ...xpr_throwing_body__05_diagnostics.snap.new | 292 --- ..._expr_with_runner__05_diagnostics.snap.new | 292 --- ...on__02_parser__type_alias_interaction.snap | 6 +- ...s__type_builder_test__02_parser__test.snap | 2 +- ...ent_expr_position__05_diagnostics.snap.new | 313 --- ..._disambiguation__02_parser__non_field.snap | 8 +- ...errors__basic_types__02_parser__types.snap | 20 +- ...uplicate_class_span__02_parser__repro.snap | 2 +- ...at_checks__02_parser__binary_expr.snap.new | 1246 ----------- ...ormat_checks__02_parser__config_decls.snap | 8 +- ...t_checks__02_parser__config_decls.snap.new | 1904 ----------------- ...format_checks__02_parser__match_exprs.snap | 2 +- ...at_checks__02_parser__other_exprs.snap.new | 1615 -------------- ...t_checks__02_parser__type_alias_decls.snap | 120 +- ...checks__10_formatter__binary_expr.snap.new | 227 -- ...tion_type_throws__02_parser__negative.snap | 2 +- ...tion_types__02_parser__function_types.snap | 18 +- ...ness__02_parser__match_exhaustiveness.snap | 32 +- ...ults__02_parser__unsupported_contexts.snap | 4 +- ...ors__stream_types__02_parser__complex.snap | 4 +- ...errors__stream_types__02_parser__main.snap | 16 +- ...02_parser__ns_foo_with_top_level_refs.snap | 2 +- ..._name_type_error__02_parser__main.snap.new | 78 - ...test_expr_name_type_error__03_hir.snap.new | 8 - ...test_expr_name_type_error__04_tir.snap.new | 39 - ...r_name_type_error__05_diagnostics.snap.new | 322 --- ...xpr_wrong_runner__02_parser__main.snap.new | 92 - ...expr_wrong_runner__05_diagnostics.snap.new | 322 --- ..._wrong_runner__10_formatter__main.snap.new | 29 - ...type_aliases__02_parser__type_aliases.snap | 6 +- ...aliases__02_parser__type_aliases_json.snap | 2 +- ...type__02_parser__function_type_throws.snap | 6 +- ...n_type__02_parser__void_function_type.snap | 2 +- 64 files changed, 176 insertions(+), 10602 deletions(-) delete mode 100644 baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new delete mode 100644 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.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__02_parser__main.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new delete mode 100644 baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new diff --git a/baml_language/crates/baml_compiler_parser/src/parser.rs b/baml_language/crates/baml_compiler_parser/src/parser.rs index 80af3cbc83..8109e88b6d 100644 --- a/baml_language/crates/baml_compiler_parser/src/parser.rs +++ b/baml_language/crates/baml_compiler_parser/src/parser.rs @@ -3011,7 +3011,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()); } @@ -3665,7 +3665,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()); } @@ -3758,7 +3758,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()); } @@ -5818,7 +5818,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 { @@ -7735,7 +7735,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 56cb0bebf7..27d85b426d 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -336,7 +336,7 @@ impl UnionMemberParts { if !self .tokens .iter() - .any(|t| t.kind() == SyntaxKind::WORD && t.text() == "as") + .any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } @@ -463,7 +463,7 @@ impl TypeExpr { } if !tokens .iter() - .any(|t| t.kind() == SyntaxKind::WORD && t.text() == "as") + .any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } @@ -2131,7 +2131,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) }) } @@ -2144,7 +2144,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; } @@ -2160,7 +2160,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) } } @@ -2754,16 +2754,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. diff --git a/baml_language/crates/baml_fmt/src/ast/declarations.rs b/baml_language/crates/baml_fmt/src/ast/declarations.rs index ce6b1b35f5..4251d53244 100644 --- a/baml_language/crates/baml_fmt/src/ast/declarations.rs +++ b/baml_language/crates/baml_fmt/src/ast/declarations.rs @@ -1333,7 +1333,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)>, @@ -1422,7 +1422,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, } @@ -3291,8 +3291,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, @@ -3306,7 +3305,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/tokens.rs b/baml_language/crates/baml_fmt/src/ast/tokens.rs index 420d2b6d8f..326bdf49a8 100644 --- a/baml_language/crates/baml_fmt/src/ast/tokens.rs +++ b/baml_language/crates/baml_fmt/src/ast/tokens.rs @@ -88,6 +88,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)] 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/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index dc1d117876..f6b6663d2d 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -17,7 +17,6 @@ //! `declaration` modifier; a reference is classified the same way as its //! definition. -use std::cmp::Ordering; use baml_base::{Name, SourceFile}; use baml_compiler_syntax::ast::{GenericParam, ObjectField}; @@ -686,11 +685,6 @@ fn classify_token(token: &SyntaxToken) -> Option { SyntaxKind::CLIENT_FIELD => { (kind == SyntaxKind::KW_CLIENT).then_some(plain(SemanticTokenType::Property)) } - // `as` is a contextual keyword (lexed as a WORD) in `.as` casts and - // `field as field` interface field links. - SyntaxKind::UPCAST_EXPR | SyntaxKind::INTERFACE_FIELD_LINK => { - (word && token.text() == "as").then_some(plain(SemanticTokenType::Keyword)) - } // 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. @@ -746,25 +740,21 @@ fn classify_type_decl_word(token: &SyntaxToken) -> Option { return None; } let parent = token.parent()?; - let words: Vec = 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) - .filter(|t| t.kind() == SyntaxKind::WORD) - .collect(); - // The leading run of `type` WORDs are keywords; the name is the first WORD - // after them. - let lead_type_kws = words.iter().take_while(|t| t.text() == "type").count(); - let index = words - .iter() - .position(|t| t.text_range() == token.text_range())?; - match index.cmp(&lead_type_kws) { - Ordering::Less => Some(plain(SemanticTokenType::Keyword)), - Ordering::Equal => { - let ty = SemanticTokenType::Type; - Some(if lead_type_kws > 0 { decl(ty) } else { plain(ty) }) - } - Ordering::Greater => None, + .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) }) } // ── Type-name classification (annotations) ────────────────────────────────────── diff --git a/baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new deleted file mode 100644 index 5d2ae5c8a3..0000000000 --- a/baml_language/crates/baml_tests/snapshots/broken_syntax/banned_expressions/baml_tests__broken_syntax__banned_expressions__05_diagnostics.snap.new +++ /dev/null @@ -1,490 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 131 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [parse] error: Expected expression, found let - ╭─[ banned_expressions.baml:3:11 ] - │ - 3 │ let a = let b = 42 - │ ─┬─ - │ ╰─── Expected expression, found let - │ - │ Note: Error code: E0010 -───╯ - - [type] error: unresolved name: b - ╭─[ banned_expressions.baml:3:15 ] - │ - 3 │ let a = let b = 42 - │ ┬ - │ ╰── unresolved name: b - │ - │ Note: Error code: E0003 -───╯ - - [type] error: unresolved name: a - ╭─[ banned_expressions.baml:4:3 ] - │ - 4 │ a - │ ┬ - │ ╰── unresolved name: a - │ - │ Note: Error code: E0003 -───╯ - - [type] error: missing return value of type int - ╭─[ banned_expressions.baml:8:22 ] - │ - 8 │ ╭─▶ function Bar() -> int { - ┆ ┆ - 10 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type int - │ - │ Note: Error code: E0029 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:22:4 ] - │ - 22 │ (x = 5) - │ ──┬── - │ ╰──── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:28:4 ] - │ - 28 │ (x += 5) - │ ───┬── - │ ╰──── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:33:14 ] - │ - 33 │ ╭─▶ let x = 10; - 34 │ ├─▶ let y = (x = 5); - │ │ - │ ╰──────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:34:12 ] - │ - 34 │ let y = (x = 5); - │ ──┬── - │ ╰──── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:63:56 ] - │ - 63 │ ╭─▶ function ParenSafeAssignField(user: User?) -> string? { - 64 │ ├─▶ let result = (user?.profile?.name = "new_name"); - │ │ - │ ╰──────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:64:17 ] - │ - 64 │ let result = (user?.profile?.name = "new_name"); - │ ────────────────┬─────────────── - │ ╰───────────────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:69:55 ] - │ - 69 │ ╭─▶ function ParenSafeAssignIndex(items: int[]?) -> int? { - 70 │ ├─▶ let result = (items?.[0] = 42); - │ │ - │ ╰─────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:70:17 ] - │ - 70 │ let result = (items?.[0] = 42); - │ ───────┬─────── - │ ╰───────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:75:56 ] - │ - 75 │ ╭─▶ function ParenSafeCompoundAssign(user: User?) -> int? { - 76 │ ├─▶ let result = (user?.id += 1); - │ │ - │ ╰───────────────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:76:17 ] - │ - 76 │ let result = (user?.id += 1); - │ ──────┬────── - │ ╰──────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:82:4 ] - │ - 82 │ (user?.profile?.name = "updated") - │ ───────────────┬─────────────── - │ ╰───────────────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:86:57 ] - │ - 86 │ ╭─▶ function ParenSafeAssignDeepChain(node: Node?) -> int? { - 87 │ ├─▶ let result = (node?.children?.[0].value = 99); - │ │ - │ ╰────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:87:17 ] - │ - 87 │ let result = (node?.children?.[0].value = 99); - │ ───────────────┬────────────── - │ ╰──────────────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ banned_expressions.baml:92:56 ] - │ - 92 │ ╭─▶ function ParenSafeAssignMapIndex(node: Node?) -> int? { - 93 │ ├─▶ let result = (node?.labels?.["main"].value = 50); - │ │ - │ ╰───────────────────────────────────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -────╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ banned_expressions.baml:93:17 ] - │ - 93 │ let result = (node?.labels?.["main"].value = 50); - │ ────────────────┬──────────────── - │ ╰────────────────── assignment not allowed here - │ - │ Note: Error code: E0010 -────╯ 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/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 a882b9a75d..46d2f056d6 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/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new deleted file mode 100644 index 188b893036..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/bigint_literal/baml_tests__compiles__bigint_literal__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 6146 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new deleted file mode 100644 index 718a41e5f6..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/byte_string_literals/baml_tests__compiles__byte_string_literals__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 6491 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new deleted file mode 100644 index 210d960f08..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/comment_after_string_in_config/baml_tests__compiles__comment_after_string_in_config__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 8216 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new deleted file mode 100644 index 248dce15b5..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/config_model_string/baml_tests__compiles__config_model_string__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 9250 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new deleted file mode 100644 index e0da1ccb24..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__02_parser__main.snap.new +++ /dev/null @@ -1,261 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 16401 ---- -=== SYNTAX TREE === -SOURCE_FILE - FUNCTION_DEF - KW_FUNCTION "function" - WORD "ifElseAdd" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR - INTEGER_LITERAL "1" - PLUS "+" - IF_EXPR - KW_IF "if" - PAREN_EXPR "(true)" - L_PAREN "(" - KW_TRUE "true" - R_PAREN ")" - BLOCK_EXPR "{ 2 }" - L_BRACE "{" - INTEGER_LITERAL "2" - R_BRACE "}" - KW_ELSE "else" - BLOCK_EXPR "{ 3 }" - L_BRACE "{" - INTEGER_LITERAL "3" - R_BRACE "}" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "matchAdd" - PARAMETER_LIST - L_PAREN "(" - PARAMETER - WORD "x" - COLON ":" - TYPE_EXPR "int" - WORD "int" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR - MATCH_EXPR - KW_MATCH "match" - L_PAREN "(" - WORD "x" - R_PAREN ")" - L_BRACE "{" - MATCH_ARM - PATTERN - TYPE_PATTERN - TYPE_EXPR "1" - INTEGER_LITERAL "1" - FAT_ARROW "=>" - INTEGER_LITERAL "10" - COMMA "," - MATCH_ARM - PATTERN - TYPE_PATTERN - TYPE_EXPR "2" - INTEGER_LITERAL "2" - FAT_ARROW "=>" - INTEGER_LITERAL "20" - COMMA "," - MATCH_ARM - PATTERN - WILDCARD_PATTERN "_" - WORD "_" - FAT_ARROW "=>" - INTEGER_LITERAL "0" - R_BRACE "}" - PLUS "+" - INTEGER_LITERAL "1" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "bothSidesUnion" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - IF_EXPR - KW_IF "if" - PAREN_EXPR "(true)" - L_PAREN "(" - KW_TRUE "true" - R_PAREN ")" - BLOCK_EXPR "{ 1 }" - L_BRACE "{" - INTEGER_LITERAL "1" - R_BRACE "}" - KW_ELSE "else" - BLOCK_EXPR "{ 2 }" - L_BRACE "{" - INTEGER_LITERAL "2" - R_BRACE "}" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - IF_EXPR - KW_IF "if" - PAREN_EXPR "(false)" - L_PAREN "(" - KW_FALSE "false" - R_PAREN ")" - BLOCK_EXPR "{ 3 }" - L_BRACE "{" - INTEGER_LITERAL "3" - R_BRACE "}" - KW_ELSE "else" - BLOCK_EXPR "{ 4 }" - L_BRACE "{" - INTEGER_LITERAL "4" - R_BRACE "}" - R_PAREN ")" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "subtractUnion" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR - INTEGER_LITERAL "100" - MINUS "-" - IF_EXPR - KW_IF "if" - PAREN_EXPR "(true)" - L_PAREN "(" - KW_TRUE "true" - R_PAREN ")" - BLOCK_EXPR "{ 7 }" - L_BRACE "{" - INTEGER_LITERAL "7" - R_BRACE "}" - KW_ELSE "else" - BLOCK_EXPR "{ 3 }" - L_BRACE "{" - INTEGER_LITERAL "3" - R_BRACE "}" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "loopMatchAccum" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let sum" - KW_LET "let" - WORD "sum" - EQUALS "=" - INTEGER_LITERAL "0" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "let i" - KW_LET "let" - WORD "i" - EQUALS "=" - INTEGER_LITERAL "0" - SEMICOLON ";" - WHILE_STMT - KW_WHILE "while" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "i < 3" - WORD "i" - LESS "<" - INTEGER_LITERAL "3" - R_PAREN ")" - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR - WORD "sum" - EQUALS "=" - BINARY_EXPR - WORD "sum" - PLUS "+" - MATCH_EXPR - KW_MATCH "match" - L_PAREN "(" - WORD "i" - R_PAREN ")" - L_BRACE "{" - MATCH_ARM - PATTERN - TYPE_PATTERN - TYPE_EXPR "0" - INTEGER_LITERAL "0" - FAT_ARROW "=>" - INTEGER_LITERAL "10" - COMMA "," - MATCH_ARM - PATTERN - TYPE_PATTERN - TYPE_EXPR "1" - INTEGER_LITERAL "1" - FAT_ARROW "=>" - INTEGER_LITERAL "20" - COMMA "," - MATCH_ARM - PATTERN - WILDCARD_PATTERN "_" - WORD "_" - FAT_ARROW "=>" - INTEGER_LITERAL "30" - R_BRACE "}" - SEMICOLON ";" - BINARY_EXPR - WORD "i" - EQUALS "=" - BINARY_EXPR "i + 1" - WORD "i" - PLUS "+" - INTEGER_LITERAL "1" - SEMICOLON ";" - R_BRACE "}" - RETURN_STMT "return sum;" - KW_RETURN "return" - WORD "sum" - SEMICOLON ";" - R_BRACE "}" - -=== ERRORS === -None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new deleted file mode 100644 index 4644b26444..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 16536 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new deleted file mode 100644 index 9ca4e10b80..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_arithmetic/baml_tests__compiles__literal_union_arithmetic__10_formatter__main.snap.new +++ /dev/null @@ -1,71 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 16650 ---- -function ifElseAdd() -> int { - 1 - + if ( - true - ) { - 2 - } else { - 3 - } -} - -function matchAdd(x: int) -> int { - match (x) { - 1 => 10, - 2 => 20, - _ => 0, - } - + 1 -} - -function bothSidesUnion() -> int { - ( - if ( - true - ) { - 1 - } else { - 2 - } - ) - + ( - if ( - false - ) { - 3 - } else { - 4 - } - ) -} - -function subtractUnion() -> int { - 100 - - if ( - true - ) { - 7 - } else { - 3 - } -} - -function loopMatchAccum() -> int { - let sum = 0; - let i = 0; - while (i < 3) { - sum - = sum - + match (i) { - 0 => 10, - 1 => 20, - _ => 30, - }; - i = i + 1; - } - return sum; -} diff --git a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new deleted file mode 100644 index aa7a761737..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/literal_union_widening/baml_tests__compiles__literal_union_widening__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 16880 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ 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..50c949871d 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" 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..3b36f9322d 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" 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..1b411d1ba6 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 diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new deleted file mode 100644 index 87e602b8c1..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__02_parser__precedence.snap.new +++ /dev/null @@ -1,92 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 22169 ---- -=== SYNTAX TREE === -SOURCE_FILE - FUNCTION_DEF - KW_FUNCTION "function" - WORD "TestPrecedence" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "bool" - WORD "bool" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "// Multiplication before addition - let a" - KW_LET "let" - WORD "a" - EQUALS "=" - BINARY_EXPR - INTEGER_LITERAL "2" - PLUS "+" - BINARY_EXPR "3 * 4" - INTEGER_LITERAL "3" - STAR "*" - INTEGER_LITERAL "4" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "// Should be 14, not 20 - let c" - KW_LET "let" - WORD "c" - EQUALS "=" - BINARY_EXPR - BINARY_EXPR "2 * 3" - INTEGER_LITERAL "2" - STAR "*" - INTEGER_LITERAL "3" - PLUS "+" - INTEGER_LITERAL "4" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "// Should be 10, not 14 - - // Comparison after arithmetic - let b" - KW_LET "let" - WORD "b" - EQUALS "=" - BINARY_EXPR - WORD "a" - GREATER ">" - BINARY_EXPR "10 + 2" - INTEGER_LITERAL "10" - PLUS "+" - INTEGER_LITERAL "2" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "// Should be a > 12 - - // Logical operators - let d" - KW_LET "let" - WORD "d" - EQUALS "=" - BINARY_EXPR - KW_TRUE "true" - OR_OR "||" - BINARY_EXPR "false && false" - KW_FALSE "false" - AND_AND "&&" - KW_FALSE "false" - SEMICOLON ";" - RETURN_STMT "// Should be true (AND before OR) - - return d;" - KW_RETURN "return" - WORD "d" - SEMICOLON ";" - R_BRACE "}" - -=== ERRORS === -None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new deleted file mode 100644 index 1890eb56b7..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 22400 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new deleted file mode 100644 index 8d6288d587..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/parser_expressions/baml_tests__compiles__parser_expressions__10_formatter__precedence.snap.new +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 22695 ---- -function TestPrecedence() -> bool { - // Multiplication before addition - let a = 2 + 3 * 4; // Should be 14, not 20 - let c = 2 * 3 + 4; // Should be 10, not 14 - - // Comparison after arithmetic - let b = a > 10 + 2; // Should be a > 12 - - // Logical operators - let d = true - || false - && false; // Should be true (AND before OR) - - return d; -} 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_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new deleted file mode 100644 index 60d6e7eedf..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_basic/baml_tests__compiles__test_expr_basic__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 27523 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ 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.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new deleted file mode 100644 index e41a18604e..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__02_parser__main.snap.new +++ /dev/null @@ -1,64 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 27732 ---- -=== SYNTAX TREE === -SOURCE_FILE - TESTSET_DEF - KW_TESTSET "testset" - STRING_LITERAL "concat names" - QUOTE """ - WORD "concat" - WORD "names" - QUOTE """ - BLOCK_EXPR - L_BRACE "{" - TEST_EXPR_DEF - KW_TEST "test" - BINARY_EXPR - STRING_LITERAL "prefix_" - QUOTE """ - WORD "prefix_" - QUOTE """ - PLUS "+" - STRING_LITERAL "suffix" - QUOTE """ - WORD "suffix" - QUOTE """ - BLOCK_EXPR "{ - null - }" - L_BRACE "{" - KW_NULL "null" - R_BRACE "}" - TESTSET_DEF - KW_TESTSET "testset" - BINARY_EXPR - STRING_LITERAL "nested_" - QUOTE """ - WORD "nested_" - QUOTE """ - PLUS "+" - STRING_LITERAL "group" - QUOTE """ - WORD "group" - QUOTE """ - BLOCK_EXPR - L_BRACE "{" - TEST_EXPR_DEF - KW_TEST "test" - STRING_LITERAL "inner" - QUOTE """ - WORD "inner" - QUOTE """ - BLOCK_EXPR "{ - null - }" - L_BRACE "{" - KW_NULL "null" - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - -=== ERRORS === -None diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new deleted file mode 100644 index 7822a4d9f7..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__03_hir.snap.new +++ /dev/null @@ -1,8 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 27756 ---- -=== HIR2 === -function user.$init_test_main(registry: testing.TestCollector) -> ? [expr] { - { registry.register_test_set("concat names", (testset: testing.TestCollector) -> void { { testset.register_test("prefix_" Add "suffix", () -> { { } }, null); testset.register_test_set("nested_" Add "group", (testset: testing.TestCollector) -> { { testset.register_test("inner", () -> { { } }, null) } null }, null) } null }, null) } null -} diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new deleted file mode 100644 index abdcad42aa..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_name_concat/baml_tests__compiles__test_expr_name_concat__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 27867 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new deleted file mode 100644 index d16ac8c3fd..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_throwing_body/baml_tests__compiles__test_expr_throwing_body__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 28211 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new deleted file mode 100644 index 1cf804dd56..0000000000 --- a/baml_language/crates/baml_tests/snapshots/compiles/test_expr_with_runner/baml_tests__compiles__test_expr_with_runner__05_diagnostics.snap.new +++ /dev/null @@ -1,292 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 28555 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ 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_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/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new deleted file mode 100644 index 3251413751..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/assignment_expr_position/baml_tests__diagnostic_errors__assignment_expr_position__05_diagnostics.snap.new +++ /dev/null @@ -1,313 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 33815 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] warning: unreachable code: 1 statement(s) after diverging statement - ╭─[ main.baml:7:16 ] - │ - 7 │ ╭─▶ let x = 10; - 8 │ ├─▶ let y = (x = 5); - │ │ - │ ╰────────────────────────── unreachable code: 1 statement(s) after diverging statement - │ - │ Note: Error code: E0001 -───╯ - - [hir] error: assignment is not allowed in expression position; assignment is a statement - ╭─[ main.baml:8:14 ] - │ - 8 │ let y = (x = 5); - │ ──┬── - │ ╰──── assignment not allowed here - │ - │ Note: Error code: E0010 -───╯ 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/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/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.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new deleted file mode 100644 index e1745b0e9d..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__binary_expr.snap.new +++ /dev/null @@ -1,1246 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 39083 ---- -=== SYNTAX TREE === -SOURCE_FILE - FUNCTION_DEF - KW_FUNCTION "function" - WORD "BinaryExprs" - PARAMETER_LIST - L_PAREN "(" - PARAMETER - WORD "a" - COLON ":" - TYPE_EXPR "int" - WORD "int" - COMMA "," - PARAMETER - WORD "b" - COLON ":" - TYPE_EXPR "int" - WORD "int" - COMMA "," - PARAMETER - WORD "c" - COLON ":" - TYPE_EXPR "int" - WORD "int" - COMMA "," - PARAMETER - WORD "d" - COLON ":" - TYPE_EXPR "int" - WORD "int" - COMMA "," - PARAMETER - WORD "s" - COLON ":" - TYPE_EXPR "string" - WORD "string" - COMMA "," - PARAMETER - WORD "flag" - COLON ":" - TYPE_EXPR "bool" - WORD "bool" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a / b" - WORD "a" - SLASH "/" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a % b" - WORD "a" - PERCENT "%" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a == b" - WORD "a" - EQUALS_EQUALS "==" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a != b" - WORD "a" - NOT_EQUALS "!=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a < b" - WORD "a" - LESS "<" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a > b" - WORD "a" - GREATER ">" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a <= b" - WORD "a" - LESS_EQUALS "<=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a >= b" - WORD "a" - GREATER_EQUALS ">=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "flag && true" - WORD "flag" - AND_AND "&&" - KW_TRUE "true" - SEMICOLON ";" - BINARY_EXPR "flag || false" - WORD "flag" - OR_OR "||" - KW_FALSE "false" - SEMICOLON ";" - BINARY_EXPR "a & b" - WORD "a" - AND "&" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a | b" - WORD "a" - PIPE "|" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a ^ b" - WORD "a" - CARET "^" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a << b" - WORD "a" - LESS_LESS "<<" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a >> b" - WORD "a" - GREATER_GREATER ">>" - WORD "b" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "// ===== Assignment operators ===== - let mut_a" - KW_LET "let" - WORD "mut_a" - EQUALS "=" - WORD "a" - SEMICOLON ";" - BINARY_EXPR "mut_a += b" - WORD "mut_a" - PLUS_EQUALS "+=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a -= b" - WORD "mut_a" - MINUS_EQUALS "-=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a *= b" - WORD "mut_a" - STAR_EQUALS "*=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a /= b" - WORD "mut_a" - SLASH_EQUALS "/=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a %= b" - WORD "mut_a" - PERCENT_EQUALS "%=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a &= b" - WORD "mut_a" - AND_EQUALS "&=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a |= b" - WORD "mut_a" - PIPE_EQUALS "|=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a ^= b" - WORD "mut_a" - CARET_EQUALS "^=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a <<= b" - WORD "mut_a" - LESS_LESS_EQUALS "<<=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "mut_a >>= b" - WORD "mut_a" - GREATER_GREATER_EQUALS ">>=" - WORD "b" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - PLUS "+" - WORD "c" - MINUS "-" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - STAR "*" - WORD "c" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - SLASH "/" - WORD "c" - PERCENT "%" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - OR_OR "||" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "c > 0" - WORD "c" - GREATER ">" - INTEGER_LITERAL "0" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - OR_OR "||" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - OR_OR "||" - BINARY_EXPR "c > 0" - WORD "c" - GREATER ">" - INTEGER_LITERAL "0" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - OR_OR "||" - BINARY_EXPR "c > 0" - WORD "c" - GREATER ">" - INTEGER_LITERAL "0" - SEMICOLON ";" - BINARY_EXPR - WORD "a" - PLUS "+" - BINARY_EXPR "b * c" - WORD "b" - STAR "*" - WORD "c" - SEMICOLON ";" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - WORD "c" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - WORD "a" - PLUS "+" - BINARY_EXPR "b * c" - WORD "b" - STAR "*" - WORD "c" - PLUS "+" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c + d" - WORD "c" - PLUS "+" - WORD "d" - R_PAREN ")" - SEMICOLON ";" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - WORD "c" - R_PAREN ")" - PLUS "+" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - WORD "a" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - WORD "b" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c + d" - WORD "c" - PLUS "+" - WORD "d" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - WORD "c" - R_PAREN ")" - PLUS "+" - WORD "d" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - PLUS "+" - WORD "c" - R_PAREN ")" - MINUS "-" - WORD "d" - R_PAREN ")" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c + d" - WORD "c" - PLUS "+" - WORD "d" - R_PAREN ")" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c - d" - WORD "c" - MINUS "-" - WORD "d" - R_PAREN ")" - R_PAREN ")" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - BINARY_EXPR "a * c" - WORD "a" - STAR "*" - WORD "c" - STAR "*" - WORD "d" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - BINARY_EXPR "b * c" - WORD "b" - STAR "*" - WORD "c" - STAR "*" - WORD "d" - R_PAREN ")" - R_PAREN ")" - MINUS "-" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a * d" - WORD "a" - STAR "*" - WORD "d" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - BINARY_EXPR "b * c" - WORD "b" - STAR "*" - WORD "c" - STAR "*" - WORD "d" - R_PAREN ")" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - BINARY_EXPR "a // 2 left trailing - // 3 operator leading - + // 4 operator trailing - // 5 right leading - b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a /* 2 left trailing */ - /* 3 operator leading */ - + /* 4 operator trailing */ - /* 5 right leading */ - b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a // 2 first trailing - // 3 first op leading - + // 4 first op trailing - // 5 second leading - b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "c > 0" - WORD "c" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "d > 0" - WORD "d" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "a != b" - WORD "a" - NOT_EQUALS "!=" - WORD "b" - AND_AND "&&" - BINARY_EXPR "b != c" - WORD "b" - NOT_EQUALS "!=" - WORD "c" - AND_AND "&&" - BINARY_EXPR "c != d" - WORD "c" - NOT_EQUALS "!=" - WORD "d" - AND_AND "&&" - BINARY_EXPR - WORD "a" - LESS "<" - BINARY_EXPR - BINARY_EXPR "1000 * 8" - INTEGER_LITERAL "1000" - STAR "*" - INTEGER_LITERAL "8" - PLUS "+" - BINARY_EXPR "1 * 2" - INTEGER_LITERAL "1" - STAR "*" - INTEGER_LITERAL "2" - AND_AND "&&" - BINARY_EXPR "b < 1000" - WORD "b" - LESS "<" - INTEGER_LITERAL "1000" - AND_AND "&&" - BINARY_EXPR "c < 1000" - WORD "c" - LESS "<" - INTEGER_LITERAL "1000" - AND_AND "&&" - BINARY_EXPR - WORD "d" - LESS "<" - BINARY_EXPR - BINARY_EXPR "1000 + 2" - INTEGER_LITERAL "1000" - PLUS "+" - INTEGER_LITERAL "2" - PLUS "+" - INTEGER_LITERAL "3" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - MINUS "-" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - STAR "*" - WORD "c" - STAR "*" - WORD "d" - LESS "<" - INTEGER_LITERAL "10000" - AND_AND "&&" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - MINUS "-" - WORD "c" - MINUS "-" - WORD "d" - NOT_EQUALS "!=" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "c + d" - WORD "c" - PLUS "+" - WORD "d" - R_PAREN ")" - GREATER_EQUALS ">=" - INTEGER_LITERAL "100" - OR_OR "||" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a * 1" - WORD "a" - STAR "*" - INTEGER_LITERAL "1" - LESS "<" - INTEGER_LITERAL "2" - AND_AND "&&" - BINARY_EXPR - STRING_LITERAL "aowiefjowiaj" - QUOTE """ - WORD "aowiefjowiaj" - QUOTE """ - EQUALS_EQUALS "==" - STRING_LITERAL "jfeiowajpwoeifj" - QUOTE """ - WORD "jfeiowajpwoeifj" - QUOTE """ - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - STRING_LITERAL "a very long string prefix that is already quite long" - QUOTE """ - WORD "a" - WORD "very" - WORD "long" - WORD "string" - WORD "prefix" - WORD "that" - KW_IS "is" - WORD "already" - WORD "quite" - WORD "long" - QUOTE """ - PLUS "+" - STRING_LITERAL " concatenated with " - QUOTE """ - WORD "concatenated" - WORD "with" - QUOTE """ - PLUS "+" - STRING_LITERAL "another very long string that together exceeds the line limit easily and comfortably" - QUOTE """ - WORD "another" - WORD "very" - WORD "long" - WORD "string" - WORD "that" - WORD "together" - WORD "exceeds" - WORD "the" - WORD "line" - WORD "limit" - WORD "easily" - WORD "and" - WORD "comfortably" - QUOTE """ - SEMICOLON ";" - BINARY_EXPR - WORD "mut_a" - PLUS_EQUALS "+=" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - PLUS "+" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - PLUS "+" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - PLUS "+" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - PLUS "+" - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - BINARY_EXPR "c * d" - WORD "c" - STAR "*" - WORD "d" - PLUS "+" - WORD "a" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a // 2 trailing - // 3 leading - + // 4 trailing - // 5 leading - b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a /* 2 trailing */ - /* 3 leading */ - + /* 4 trailing */ - /* 5 leading */ - b" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - PLUS "+" - WORD "a" - PLUS "+" - WORD "b" - PLUS "+" - WORD "c" - PLUS "+" - WORD "d" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR - BINARY_EXPR "a > 0" - WORD "a" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "b > 0" - WORD "b" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "c > 0" - WORD "c" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "d > 0" - WORD "d" - GREATER ">" - INTEGER_LITERAL "0" - AND_AND "&&" - BINARY_EXPR "a != b" - WORD "a" - NOT_EQUALS "!=" - WORD "b" - AND_AND "&&" - BINARY_EXPR "b != c" - WORD "b" - NOT_EQUALS "!=" - WORD "c" - AND_AND "&&" - BINARY_EXPR "c != d" - WORD "c" - NOT_EQUALS "!=" - WORD "d" - SEMICOLON ";" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "1 + 2" - INTEGER_LITERAL "1" - PLUS "+" - INTEGER_LITERAL "2" - SEMICOLON ";" - BINARY_EXPR "a > b" - WORD "a" - GREATER ">" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a * b" - WORD "a" - STAR "*" - WORD "b" - PLUS "+" - WORD "c" - SEMICOLON ";" - BINARY_EXPR "a == b" - WORD "a" - EQUALS_EQUALS "==" - WORD "b" - SEMICOLON ";" - BINARY_EXPR - BINARY_EXPR "a == 2" - WORD "a" - EQUALS_EQUALS "==" - INTEGER_LITERAL "2" - AND_AND "&&" - BINARY_EXPR "b != 3" - WORD "b" - NOT_EQUALS "!=" - INTEGER_LITERAL "3" - SEMICOLON ";" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_BRACE "}" - -=== ERRORS === -None 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..fff47ebcba 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 @@ -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__config_decls.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new deleted file mode 100644 index ece8b75b52..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__config_decls.snap.new +++ /dev/null @@ -1,1904 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 39200 ---- -=== SYNTAX TREE === -SOURCE_FILE - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "BasicClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - COMMA "," - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - COMMA "," - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "FullClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - KW_RETRY_POLICY "retry_policy" - CONFIG_VALUE "MyRetryPolicy" - WORD "MyRetryPolicy" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - COLON ":" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "max_tokens" - CONFIG_VALUE "100" - INTEGER_LITERAL "100" - CONFIG_ITEM - WORD "temperature" - CONFIG_VALUE "0.7" - FLOAT_LITERAL "0.7" - COMMA "," - CONFIG_ITEM - WORD "top_p" - CONFIG_VALUE "0.9" - FLOAT_LITERAL "0.9" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "StringProviderClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE - STRING_LITERAL "openai-generic" - QUOTE """ - WORD "openai-generic" - QUOTE """ - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://openrouter.ai/api/v1" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "openrouter" - DOT "." - WORD "ai" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v1" - QUOTE """ - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "mistralai/mistral-small-3.1-24b-instruct" - QUOTE """ - WORD "mistralai" - SLASH "/" - WORD "mistral-small-3" - DOT "." - INTEGER_LITERAL "1" - MINUS "-" - INTEGER_LITERAL "24" - WORD "b-instruct" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "NestedConfigClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "headers" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - STRING_LITERAL "X-API-Key" - QUOTE """ - WORD "X-API-Key" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "my-key" - QUOTE """ - WORD "my-key" - QUOTE """ - CONFIG_ITEM - STRING_LITERAL "Authorization" - QUOTE """ - WORD "Authorization" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "Bearer token" - QUOTE """ - WORD "Bearer" - WORD "token" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "ArrayConfigClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - COMMA "," - CONFIG_ITEM - WORD "stop_sequences" - COLON ":" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE - STRING_LITERAL "END" - QUOTE """ - WORD "END" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "STOP" - QUOTE """ - WORD "STOP" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "DONE" - QUOTE """ - WORD "DONE" - QUOTE """ - R_BRACKET "]" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "LongOptionClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "some-really-long-domain-name-for-testing" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v1" - SLASH "/" - WORD "chat" - SLASH "/" - WORD "completions" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TypedValuesClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "temperature" - COLON ":" - CONFIG_VALUE "0.5" - FLOAT_LITERAL "0.5" - CONFIG_ITEM - WORD "max_tokens" - CONFIG_VALUE "2048" - INTEGER_LITERAL "2048" - CONFIG_ITEM - WORD "stream" - CONFIG_VALUE "true" - KW_TRUE "true" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "EnvClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - COLON ":" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "api_key" - CONFIG_VALUE - ENV_ACCESS_EXPR "env.OPENAI_API_KEY" - WORD "env" - DOT "." - WORD "OPENAI_API_KEY" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "ArrayOfObjectsClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - COLON ":" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - COMMA "," - CONFIG_ITEM - WORD "tools" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "server_label" - CONFIG_VALUE - STRING_LITERAL "web_search" - QUOTE """ - WORD "web_search" - QUOTE """ - CONFIG_ITEM - WORD "server_url" - CONFIG_VALUE - STRING_LITERAL "https://example.com" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "example" - DOT "." - WORD "com" - QUOTE """ - CONFIG_ITEM - WORD "type" - CONFIG_VALUE - STRING_LITERAL "mcp" - QUOTE """ - WORD "mcp" - QUOTE """ - R_BRACE "}" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "server_label" - CONFIG_VALUE - STRING_LITERAL "calculator" - QUOTE """ - WORD "calculator" - QUOTE """ - CONFIG_ITEM - WORD "server_url" - CONFIG_VALUE - STRING_LITERAL "https://calc.example.com" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "calc" - DOT "." - WORD "example" - DOT "." - WORD "com" - QUOTE """ - R_BRACE "}" - R_BRACKET "]" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "RawStringConfigClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - COMMA "," - CONFIG_ITEM - WORD "options" - COLON ":" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - COLON ":" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "system_prompt" - CONFIG_VALUE - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "You are a helpful assistant. - Always be concise." - WORD "You" - WORD "are" - WORD "a" - WORD "helpful" - WORD "assistant" - DOT "." - WORD "Always" - WORD "be" - WORD "concise" - DOT "." - QUOTE """ - HASH "#" - R_BRACE "}" - COMMA "," - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "MixedValuesClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "max_tokens" - CONFIG_VALUE "100" - INTEGER_LITERAL "100" - CONFIG_ITEM - WORD "temperature" - CONFIG_VALUE "0.7" - FLOAT_LITERAL "0.7" - CONFIG_ITEM - WORD "stream" - CONFIG_VALUE "true" - KW_TRUE "true" - CONFIG_ITEM - WORD "stop" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE - STRING_LITERAL "END" - QUOTE """ - WORD "END" - QUOTE """ - R_BRACKET "]" - CONFIG_ITEM - WORD "inline_string" - CONFIG_VALUE - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "inline raw" - WORD "inline" - WORD "raw" - QUOTE """ - HASH "#" - CONFIG_ITEM - STRING_LITERAL "string key" - QUOTE """ - WORD "string" - WORD "key" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "value with spaces" - QUOTE """ - WORD "value" - WORD "with" - WORD "spaces" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "// 2 client keyword trailing -// 3 type angle leading -< // 4 open angle trailing -// 5 type leading -llm // 6 type trailing -// 7 close angle leading ->" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - COLON ":" - CONFIG_VALUE "// 14 provider key trailing - // 15 provider value leading - openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "/* 2 client keyword trailing */ -/* 3 type angle leading */ -< /* 4 open angle trailing */ -/* 5 type leading */ -llm /* 6 type trailing */ -/* 7 close angle leading */ ->" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaClientBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "/* 14 provider key trailing */ - /* 15 provider value leading */ - openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - COLON ":" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "ThisIsAnExtremelyLongClientNameThatDefinitelyExceedsTheDefaultLineLimitOfOneHundredColumns" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "DeeplyNestedClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "headers" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - STRING_LITERAL "X-API-Key" - QUOTE """ - WORD "X-API-Key" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "my-key" - QUOTE """ - WORD "my-key" - QUOTE """ - CONFIG_ITEM - STRING_LITERAL "Authorization" - QUOTE """ - WORD "Authorization" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "Bearer token" - QUOTE """ - WORD "Bearer" - WORD "token" - QUOTE """ - CONFIG_ITEM - WORD "custom_config" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "retry_on_failure" - CONFIG_VALUE "true" - KW_TRUE "true" - CONFIG_ITEM - WORD "timeout_ms" - CONFIG_VALUE "30000" - INTEGER_LITERAL "30000" - CONFIG_ITEM - WORD "metadata" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "team" - CONFIG_VALUE - STRING_LITERAL "platform" - QUOTE """ - WORD "platform" - QUOTE """ - CONFIG_ITEM - WORD "environment" - CONFIG_VALUE - STRING_LITERAL "production" - QUOTE """ - WORD "production" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "LongNestedValuesClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "anthropic/claude-3.5-sonnet-20250101-with-some-extremely-long-suffix-that-pushes-past-the-line-limit-easily" - QUOTE """ - WORD "anthropic" - SLASH "/" - WORD "claude-3" - DOT "." - INTEGER_LITERAL "5" - MINUS "-" - WORD "sonnet-20250101-with-some-extremely-long-suffix-that-pushes-past-the-line-limit-easily" - QUOTE """ - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://some-extremely-long-api-gateway-subdomain.internal.production.cluster.example.com/api/v2/chat/completions/streaming" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "some-extremely-long-api-gateway-subdomain" - DOT "." - WORD "internal" - DOT "." - WORD "production" - DOT "." - WORD "cluster" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v2" - SLASH "/" - WORD "chat" - SLASH "/" - WORD "completions" - SLASH "/" - WORD "streaming" - QUOTE """ - CONFIG_ITEM - WORD "headers" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - STRING_LITERAL "Authorization" - QUOTE """ - WORD "Authorization" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "Bearer some-extremely-long-api-token-value-that-is-used-for-authentication-and-exceeds-the-line-limit-easily-and-comfortably" - QUOTE """ - WORD "Bearer" - WORD "some-extremely-long-api-token-value-that-is-used-for-authentication-and-exceeds-the-line-limit-easily-and-comfortably" - QUOTE """ - CONFIG_ITEM - STRING_LITERAL "X-Custom-Header" - QUOTE """ - WORD "X-Custom-Header" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "another-very-long-header-value-that-also-pushes-past-one-hundred-columns-for-testing-purposes" - QUOTE """ - WORD "another-very-long-header-value-that-also-pushes-past-one-hundred-columns-for-testing-purposes" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "ManyOptionsClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "max_tokens" - CONFIG_VALUE "4096" - INTEGER_LITERAL "4096" - CONFIG_ITEM - WORD "temperature" - CONFIG_VALUE "0.7" - FLOAT_LITERAL "0.7" - CONFIG_ITEM - WORD "top_p" - CONFIG_VALUE "0.95" - FLOAT_LITERAL "0.95" - CONFIG_ITEM - WORD "frequency_penalty" - CONFIG_VALUE "0.5" - FLOAT_LITERAL "0.5" - CONFIG_ITEM - WORD "presence_penalty" - CONFIG_VALUE "0.3" - FLOAT_LITERAL "0.3" - CONFIG_ITEM - WORD "stream" - CONFIG_VALUE "true" - KW_TRUE "true" - CONFIG_ITEM - WORD "stop_sequences" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE - STRING_LITERAL "END" - QUOTE """ - WORD "END" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "STOP" - QUOTE """ - WORD "STOP" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "DONE" - QUOTE """ - WORD "DONE" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "COMPLETE" - QUOTE """ - WORD "COMPLETE" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "FINISHED" - QUOTE """ - WORD "FINISHED" - QUOTE """ - R_BRACKET "]" - CONFIG_ITEM - WORD "api_key" - CONFIG_VALUE - ENV_ACCESS_EXPR "env.OPENAI_API_KEY" - WORD "env" - DOT "." - WORD "OPENAI_API_KEY" - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://api.openai.com/v1" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "api" - DOT "." - WORD "openai" - DOT "." - WORD "com" - SLASH "/" - WORD "v1" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "LongArrayClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "stop_sequences" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE - STRING_LITERAL "STOP_GENERATION_NOW" - QUOTE """ - WORD "STOP_GENERATION_NOW" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "END_OF_RESPONSE_MARKER" - QUOTE """ - WORD "END_OF_RESPONSE_MARKER" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "COMPLETION_FINISHED_SIGNAL" - QUOTE """ - WORD "COMPLETION_FINISHED_SIGNAL" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "TERMINATE_OUTPUT_HERE" - QUOTE """ - WORD "TERMINATE_OUTPUT_HERE" - QUOTE """ - COMMA "," - CONFIG_VALUE - STRING_LITERAL "FINAL_ANSWER_DELIMITER" - QUOTE """ - WORD "FINAL_ANSWER_DELIMITER" - QUOTE """ - R_BRACKET "]" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "LongArrayOfObjectsClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "tools" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "server_label" - CONFIG_VALUE - STRING_LITERAL "this_is_a_very_long_server_label_that_exceeds_the_line_limit_when_combined_with_indentation" - QUOTE """ - WORD "this_is_a_very_long_server_label_that_exceeds_the_line_limit_when_combined_with_indentation" - QUOTE """ - CONFIG_ITEM - WORD "server_url" - CONFIG_VALUE - STRING_LITERAL "https://some-extremely-long-domain-name-for-the-mcp-server.internal.production.example.com/api/v2" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "some-extremely-long-domain-name-for-the-mcp-server" - DOT "." - WORD "internal" - DOT "." - WORD "production" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v2" - QUOTE """ - CONFIG_ITEM - WORD "type" - CONFIG_VALUE - STRING_LITERAL "mcp" - QUOTE """ - WORD "mcp" - QUOTE """ - CONFIG_ITEM - WORD "description" - CONFIG_VALUE - STRING_LITERAL "A very long description of the tool server that explains what it does and how it should be used by the model" - QUOTE """ - WORD "A" - WORD "very" - WORD "long" - WORD "description" - WORD "of" - WORD "the" - WORD "tool" - WORD "server" - WORD "that" - WORD "explains" - WORD "what" - WORD "it" - WORD "does" - WORD "and" - WORD "how" - WORD "it" - WORD "should" - WORD "be" - WORD "used" - WORD "by" - WORD "the" - WORD "model" - QUOTE """ - R_BRACE "}" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "server_label" - CONFIG_VALUE - STRING_LITERAL "another_long_server_label_for_testing_line_wrapping_behavior_in_nested_array_objects" - QUOTE """ - WORD "another_long_server_label_for_testing_line_wrapping_behavior_in_nested_array_objects" - QUOTE """ - CONFIG_ITEM - WORD "server_url" - CONFIG_VALUE - STRING_LITERAL "https://another-long-domain.internal.staging.example.com/tools/v1" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "another-long-domain" - DOT "." - WORD "internal" - DOT "." - WORD "staging" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "tools" - SLASH "/" - WORD "v1" - QUOTE """ - R_BRACE "}" - R_BRACKET "]" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "// 2 client trailing -< // 3 angle trailing -llm // 4 type trailing ->" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaDeeplyNestedClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "// 11 provider trailing - // 12 value leading - openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "headers" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - STRING_LITERAL "X-API-Key" - QUOTE """ - WORD "X-API-Key" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "my-key" - QUOTE """ - WORD "my-key" - QUOTE """ - CONFIG_ITEM - STRING_LITERAL "Authorization" - QUOTE """ - WORD "Authorization" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "Bearer token" - QUOTE """ - WORD "Bearer" - WORD "token" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "/* 2 client trailing */ -< /* 3 angle trailing */ -llm /* 4 type trailing */ ->" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaDeeplyNestedClientBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "/* 11 provider trailing */ - /* 12 value leading */ - openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - CONFIG_ITEM - WORD "headers" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - STRING_LITERAL "X-API-Key" - QUOTE """ - WORD "X-API-Key" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "my-key" - QUOTE """ - WORD "my-key" - QUOTE """ - CONFIG_ITEM - STRING_LITERAL "Authorization" - QUOTE """ - WORD "Authorization" - QUOTE """ - CONFIG_VALUE - STRING_LITERAL "Bearer token" - QUOTE """ - WORD "Bearer" - WORD "token" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - COMMA "," - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaLongValueClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "some-really-long-domain-name-for-testing" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v1" - SLASH "/" - WORD "chat" - SLASH "/" - WORD "completions" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "TriviaLongValueClientBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - WORD "some-extremely-long-model-name-that-goes-on-and-on-and-should-push-well-past-the-line-width-limit" - QUOTE """ - CONFIG_ITEM - WORD "base_url" - CONFIG_VALUE - STRING_LITERAL "https://some-really-long-domain-name-for-testing.example.com/api/v1/chat/completions" - QUOTE """ - WORD "https" - COLON ":" - SLASH "/" - SLASH "/" - WORD "some-really-long-domain-name-for-testing" - DOT "." - WORD "example" - DOT "." - WORD "com" - SLASH "/" - WORD "api" - SLASH "/" - WORD "v1" - SLASH "/" - WORD "chat" - SLASH "/" - WORD "completions" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "BasicRetry" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "3" - INTEGER_LITERAL "3" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "FullRetry" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "5" - INTEGER_LITERAL "5" - CONFIG_ITEM - WORD "backoff_multiplier" - CONFIG_VALUE "2.0" - FLOAT_LITERAL "2.0" - CONFIG_ITEM - WORD "initial_delay_ms" - CONFIG_VALUE "1000" - INTEGER_LITERAL "1000" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "ThisIsAnExtremelyLongRetryPolicyNameThatDefinitelyExceedsTheDefaultLineLimitOfOneHundredCols" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "10" - INTEGER_LITERAL "10" - CONFIG_ITEM - WORD "backoff_multiplier" - CONFIG_VALUE "3.0" - FLOAT_LITERAL "3.0" - CONFIG_ITEM - WORD "initial_delay_ms" - CONFIG_VALUE "5000" - INTEGER_LITERAL "5000" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "TriviaRetry" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "// 8 key trailing - // 9 value leading - 3" - INTEGER_LITERAL "3" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "TriviaRetryBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "/* 8 key trailing */ - /* 9 value leading */ - 3" - INTEGER_LITERAL "3" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "TestTarget" - PARAMETER_LIST "()" - L_PAREN "(" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "string" - WORD "string" - LLM_FUNCTION_BODY - L_BRACE "{" - CLIENT_FIELD "client BasicClient" - KW_CLIENT "client" - WORD "BasicClient" - PROMPT_FIELD - WORD "prompt" - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "Hello" - WORD "Hello" - QUOTE """ - HASH "#" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "BasicTest" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "{ - - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "TypeBuilderTest" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - TYPE_BUILDER_BLOCK - KW_TYPE_BUILDER "type_builder" - L_BRACE "{" - CLASS_DEF - KW_CLASS "class" - WORD "InnerClass" - L_BRACE "{" - FIELD - WORD "b" - TYPE_EXPR "int" - WORD "int" - R_BRACE "}" - DYNAMIC_TYPE_DEF - KW_DYNAMIC "dynamic" - CLASS_DEF - KW_CLASS "class" - WORD "DynamicInner" - L_BRACE "{" - FIELD - WORD "c" - TYPE_EXPR "string" - WORD "string" - R_BRACE "}" - ENUM_DEF - KW_ENUM "enum" - WORD "InnerEnum" - L_BRACE "{" - ENUM_VARIANT "X" - WORD "X" - ENUM_VARIANT "Y" - WORD "Y" - R_BRACE "}" - DYNAMIC_TYPE_DEF - KW_DYNAMIC "dynamic" - ENUM_DEF - KW_ENUM "enum" - WORD "DynamicInnerEnum" - L_BRACE "{" - ENUM_VARIANT "P" - WORD "P" - ENUM_VARIANT "Q" - WORD "Q" - R_BRACE "}" - TYPE_ALIAS_DEF - WORD "type" - WORD "InnerAlias" - EQUALS "=" - TYPE_EXPR "string | int" - WORD "string" - PIPE "|" - WORD "int" - R_BRACE "}" - COMMA "," - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "{ - - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "TriviaTest" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - COLON ":" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "// 12 args key trailing - // 13 args block leading - { // 14 args open brace trailing - // 15 args close brace leading - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "TriviaTestBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "/* 12 args key trailing */ - /* 13 args block leading */ - { /* 14 args open brace trailing */ - /* 15 args close brace leading */ - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "LongTypeBuilderTest" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - TYPE_BUILDER_BLOCK - KW_TYPE_BUILDER "type_builder" - L_BRACE "{" - CLASS_DEF - KW_CLASS "class" - WORD "VeryLongClassNameThatExceedsTheLineLimitWhenCombinedWithTheTypeBuilderIndentation" - L_BRACE "{" - FIELD - WORD "extremely_long_field_name_for_testing_wrapping" - TYPE_EXPR "int" - WORD "int" - FIELD - WORD "another_very_long_field_name" - TYPE_EXPR "string" - WORD "string" - R_BRACE "}" - ENUM_DEF - KW_ENUM "enum" - WORD "VeryLongEnumNameThatAlsoExceedsTheLineLimitWhenCombinedWithTheTypeBuilderIndentation" - L_BRACE "{" - ENUM_VARIANT "VeryLongVariantNameThatExceedsLimit" - WORD "VeryLongVariantNameThatExceedsLimit" - ENUM_VARIANT "AnotherVeryLongVariantName" - WORD "AnotherVeryLongVariantName" - R_BRACE "}" - TYPE_ALIAS_DEF - WORD "type" - WORD "VeryLongTypeAliasNameThatExceedsLimit" - EQUALS "=" - TYPE_EXPR "int | string | bool | float | null | int[] | string[]" - WORD "int" - PIPE "|" - WORD "string" - PIPE "|" - WORD "bool" - PIPE "|" - WORD "float" - PIPE "|" - WORD "null" - PIPE "|" - WORD "int" - L_BRACKET "[" - R_BRACKET "]" - PIPE "|" - WORD "string" - L_BRACKET "[" - R_BRACKET "]" - R_BRACE "}" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "{ - - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "TriviaTypeBuilderTest" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - TYPE_BUILDER_BLOCK - KW_TYPE_BUILDER "type_builder" - L_BRACE "{" - CLASS_DEF - KW_CLASS "class" - WORD "TbInnerClass" - L_BRACE "{" - FIELD - WORD "field_name" - COLON ":" - TYPE_EXPR "// 22 field name trailing - // 23 type leading - int" - WORD "int" - R_BRACE "}" - ENUM_DEF - KW_ENUM "enum" - WORD "TbInnerEnum" - L_BRACE "{" - ENUM_VARIANT "// 32 enum brace trailing - // 33 variant leading - X" - WORD "X" - R_BRACE "}" - TYPE_ALIAS_DEF - WORD "type" - WORD "TbAlias" - EQUALS "=" - TYPE_EXPR "// 42 equals trailing - // 43 rhs leading - string" - WORD "string" - R_BRACE "}" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "// 48 args trailing - // 49 args brace leading - { // 50 args brace trailing - // 51 args close leading - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - TEST_DEF - KW_TEST "test" - WORD "TriviaTypeBuilderTestBlock" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "functions" - CONFIG_VALUE - ARRAY_LITERAL - L_BRACKET "[" - CONFIG_VALUE "TestTarget" - WORD "TestTarget" - R_BRACKET "]" - TYPE_BUILDER_BLOCK - KW_TYPE_BUILDER "type_builder" - L_BRACE "{" - CLASS_DEF - KW_CLASS "class" - WORD "TbInnerClassBlock" - L_BRACE "{" - FIELD - WORD "field_name" - COLON ":" - TYPE_EXPR "/* 22 field name trailing */ - /* 23 type leading */ - int" - WORD "int" - R_BRACE "}" - ENUM_DEF - KW_ENUM "enum" - WORD "TbInnerEnumBlock" - L_BRACE "{" - ENUM_VARIANT "/* 32 enum brace trailing */ - /* 33 variant leading */ - X" - WORD "X" - R_BRACE "}" - TYPE_ALIAS_DEF - WORD "type" - WORD "TbAliasBlock" - EQUALS "=" - TYPE_EXPR "/* 42 equals trailing */ - /* 43 rhs leading */ - string" - WORD "string" - R_BRACE "}" - CONFIG_ITEM - WORD "args" - CONFIG_BLOCK "/* 48 args trailing */ - /* 49 args brace leading */ - { /* 50 args brace trailing */ - /* 51 args close leading */ - }" - L_BRACE "{" - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "C" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "R" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "1" - INTEGER_LITERAL "1" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "ExtraWhitespaceClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - RETRY_POLICY_DEF - KW_RETRY_POLICY "retry_policy" - WORD "ExtraWhitespaceRetry" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "max_retries" - CONFIG_VALUE "3" - INTEGER_LITERAL "3" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "CommaClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - COMMA "," - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - COMMA "," - CONFIG_ITEM - WORD "max_tokens" - CONFIG_VALUE "100" - INTEGER_LITERAL "100" - COMMA "," - R_BRACE "}" - R_BRACE "}" - CLIENT_DEF - KW_CLIENT "client" - CLIENT_TYPE "" - LESS "<" - WORD "llm" - GREATER ">" - WORD "SameLineClient" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "provider" - CONFIG_VALUE "openai" - WORD "openai" - CONFIG_ITEM - WORD "options" - CONFIG_BLOCK - L_BRACE "{" - CONFIG_ITEM - WORD "model" - CONFIG_VALUE - STRING_LITERAL "gpt-4" - QUOTE """ - WORD "gpt-4" - QUOTE """ - R_BRACE "}" - R_BRACE "}" - -=== ERRORS === -None 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.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new deleted file mode 100644 index 8d10a80fd9..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__other_exprs.snap.new +++ /dev/null @@ -1,1615 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 39434 ---- -=== SYNTAX TREE === -SOURCE_FILE - CLASS_DEF - KW_CLASS "class" - WORD "OtherPoint" - L_BRACE "{" - FIELD - WORD "x" - TYPE_EXPR "int" - WORD "int" - FIELD - WORD "y" - TYPE_EXPR "int" - WORD "int" - R_BRACE "}" - CLASS_DEF - KW_CLASS "class" - WORD "OtherVec" - L_BRACE "{" - FIELD - WORD "p" - TYPE_EXPR "OtherPoint" - WORD "OtherPoint" - FIELD - WORD "q" - TYPE_EXPR "OtherPoint" - WORD "OtherPoint" - R_BRACE "}" - CLASS_DEF - KW_CLASS "class" - WORD "OtherTriple" - L_BRACE "{" - FIELD - WORD "a" - TYPE_EXPR "OtherVec" - WORD "OtherVec" - FIELD - WORD "b" - TYPE_EXPR "OtherVec" - WORD "OtherVec" - FIELD - WORD "c" - TYPE_EXPR "OtherVec" - WORD "OtherVec" - R_BRACE "}" - FUNCTION_DEF - KW_FUNCTION "function" - WORD "OtherExprs" - PARAMETER_LIST - L_PAREN "(" - PARAMETER - WORD "a" - COLON ":" - TYPE_EXPR "int" - WORD "int" - COMMA "," - PARAMETER - WORD "b" - COLON ":" - TYPE_EXPR "int" - WORD "int" - R_PAREN ")" - ARROW "->" - TYPE_EXPR "int" - WORD "int" - EXPR_FUNCTION_BODY - BLOCK_EXPR - L_BRACE "{" - INTEGER_LITERAL "0" - SEMICOLON ";" - INTEGER_LITERAL "1" - SEMICOLON ";" - INTEGER_LITERAL "42" - SEMICOLON ";" - INTEGER_LITERAL "999999" - SEMICOLON ";" - FLOAT_LITERAL "0.0" - SEMICOLON ";" - FLOAT_LITERAL "3.14" - SEMICOLON ";" - FLOAT_LITERAL "99.999" - SEMICOLON ";" - STRING_LITERAL "hello" - QUOTE """ - WORD "hello" - QUOTE """ - SEMICOLON ";" - STRING_LITERAL "a short string" - QUOTE """ - WORD "a" - WORD "short" - WORD "string" - QUOTE """ - SEMICOLON ";" - STRING_LITERAL "a much longer string that contains quite a lot of text and definitely exceeds one hundred characters to test how the formatter handles longer string literals in expressions" - QUOTE """ - WORD "a" - WORD "much" - WORD "longer" - WORD "string" - WORD "that" - WORD "contains" - WORD "quite" - WORD "a" - WORD "lot" - WORD "of" - WORD "text" - WORD "and" - WORD "definitely" - WORD "exceeds" - WORD "one" - WORD "hundred" - WORD "characters" - WORD "to" - KW_TEST "test" - WORD "how" - WORD "the" - WORD "formatter" - WORD "handles" - WORD "longer" - WORD "string" - WORD "literals" - KW_IN "in" - WORD "expressions" - QUOTE """ - SEMICOLON ";" - KW_TRUE "true" - SEMICOLON ";" - KW_FALSE "false" - SEMICOLON ";" - KW_NULL "null" - SEMICOLON ";" - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "raw string" - WORD "raw" - WORD "string" - QUOTE """ - HASH "#" - SEMICOLON ";" - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "raw string with "quotes" inside" - WORD "raw" - WORD "string" - WORD "with" - QUOTE """ - WORD "quotes" - QUOTE """ - WORD "inside" - QUOTE """ - HASH "#" - SEMICOLON ";" - RAW_STRING_LITERAL - HASH "#" - QUOTE """ - PROMPT_TEXT "multi-line raw string - with several lines - of content" - WORD "multi-line" - WORD "raw" - WORD "string" - WORD "with" - WORD "several" - WORD "lines" - WORD "of" - WORD "content" - QUOTE """ - HASH "#" - SEMICOLON ";" - PAREN_EXPR "// ===== Parenthesized expressions ===== - (a)" - L_PAREN "(" - WORD "a" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR - L_PAREN "(" - PAREN_EXPR "(a)" - L_PAREN "(" - WORD "a" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a * a" - WORD "a" - STAR "*" - WORD "a" - R_PAREN ")" - PLUS "+" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "b * b" - WORD "b" - STAR "*" - WORD "b" - R_PAREN ")" - R_PAREN ")" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_PAREN ")" - R_PAREN ")" - MINUS "-" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - STAR "*" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a - b" - WORD "a" - MINUS "-" - WORD "b" - R_PAREN ")" - R_PAREN ")" - R_PAREN ")" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR "// ===== Trivia in parens (line comments) ===== - // 1 open leading - ( // 2 open trailing - // 3 inner leading - a // 4 inner trailing - // 5 close leading - )" - L_PAREN "(" - WORD "a" - R_PAREN ")" - SEMICOLON ";" - PAREN_EXPR "// ===== Trivia in parens (block comments) ===== - /* 1 open leading */ - ( /* 2 open trailing */ - /* 3 inner leading */ - a /* 4 inner trailing */ - /* 5 close leading */ - )" - L_PAREN "(" - WORD "a" - R_PAREN ")" - SEMICOLON ";" - UNARY_EXPR "// ===== Unary expressions ===== - -a" - MINUS "-" - WORD "a" - SEMICOLON ";" - UNARY_EXPR "!true" - NOT "!" - KW_TRUE "true" - SEMICOLON ";" - UNARY_EXPR - MINUS "-" - PAREN_EXPR - L_PAREN "(" - UNARY_EXPR "-a" - MINUS "-" - WORD "a" - R_PAREN ")" - SEMICOLON ";" - UNARY_EXPR - NOT "!" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a > b" - WORD "a" - GREATER ">" - WORD "b" - R_PAREN ")" - SEMICOLON ";" - UNARY_EXPR "// ===== Trivia in unary (line comments) ===== - // 1 op leading - - // 2 op trailing - // 3 operand leading - a" - MINUS "-" - WORD "a" - SEMICOLON ";" - UNARY_EXPR "// ===== Trivia in unary (block comments) ===== - /* 1 op leading */ - - /* 2 op trailing */ - /* 3 operand leading */ - a" - MINUS "-" - WORD "a" - SEMICOLON ";" - ARRAY_LITERAL "// ===== Array initializers ===== - []" - L_BRACKET "[" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL "[1]" - L_BRACKET "[" - INTEGER_LITERAL "1" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL "[1, 2, 3]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - COMMA "," - INTEGER_LITERAL "3" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL "[1, 2, 3, 4, 5]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - COMMA "," - INTEGER_LITERAL "3" - COMMA "," - INTEGER_LITERAL "4" - COMMA "," - INTEGER_LITERAL "5" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "short" - QUOTE """ - WORD "short" - QUOTE """ - COMMA "," - STRING_LITERAL "array" - QUOTE """ - WORD "array" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "a" - QUOTE """ - WORD "a" - QUOTE """ - COMMA "," - STRING_LITERAL "b" - QUOTE """ - WORD "b" - QUOTE """ - COMMA "," - STRING_LITERAL "c" - QUOTE """ - WORD "c" - QUOTE """ - COMMA "," - STRING_LITERAL "d" - QUOTE """ - WORD "d" - QUOTE """ - COMMA "," - STRING_LITERAL "e" - QUOTE """ - WORD "e" - QUOTE """ - COMMA "," - STRING_LITERAL "f" - QUOTE """ - WORD "f" - QUOTE """ - COMMA "," - STRING_LITERAL "g" - QUOTE """ - WORD "g" - QUOTE """ - COMMA "," - STRING_LITERAL "h" - QUOTE """ - WORD "h" - QUOTE """ - COMMA "," - STRING_LITERAL "i" - QUOTE """ - WORD "i" - QUOTE """ - COMMA "," - STRING_LITERAL "j" - QUOTE """ - WORD "j" - QUOTE """ - COMMA "," - STRING_LITERAL "k" - QUOTE """ - WORD "k" - QUOTE """ - COMMA "," - STRING_LITERAL "l" - QUOTE """ - WORD "l" - QUOTE """ - COMMA "," - STRING_LITERAL "m" - QUOTE """ - WORD "m" - QUOTE """ - COMMA "," - STRING_LITERAL "n" - QUOTE """ - WORD "n" - QUOTE """ - COMMA "," - STRING_LITERAL "o" - QUOTE """ - WORD "o" - QUOTE """ - COMMA "," - STRING_LITERAL "p" - QUOTE """ - WORD "p" - QUOTE """ - COMMA "," - STRING_LITERAL "q" - QUOTE """ - WORD "q" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "this is a long string element" - QUOTE """ - WORD "this" - KW_IS "is" - WORD "a" - WORD "long" - WORD "string" - WORD "element" - QUOTE """ - COMMA "," - STRING_LITERAL "another long string value here" - QUOTE """ - WORD "another" - WORD "long" - WORD "string" - WORD "value" - WORD "here" - QUOTE """ - COMMA "," - STRING_LITERAL "yet another one that is quite long" - QUOTE """ - WORD "yet" - WORD "another" - WORD "one" - WORD "that" - KW_IS "is" - WORD "quite" - WORD "long" - QUOTE """ - COMMA "," - STRING_LITERAL "and one more string element here too" - QUOTE """ - WORD "and" - WORD "one" - WORD "more" - WORD "string" - WORD "element" - WORD "here" - WORD "too" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "alpha" - QUOTE """ - WORD "alpha" - QUOTE """ - COMMA "," - STRING_LITERAL "bravo" - QUOTE """ - WORD "bravo" - QUOTE """ - COMMA "," - STRING_LITERAL "charlie" - QUOTE """ - WORD "charlie" - QUOTE """ - COMMA "," - STRING_LITERAL "delta" - QUOTE """ - WORD "delta" - QUOTE """ - COMMA "," - STRING_LITERAL "echo" - QUOTE """ - WORD "echo" - QUOTE """ - COMMA "," - STRING_LITERAL "foxtrot" - QUOTE """ - WORD "foxtrot" - QUOTE """ - COMMA "," - STRING_LITERAL "golf" - QUOTE """ - WORD "golf" - QUOTE """ - COMMA "," - STRING_LITERAL "hotel" - QUOTE """ - WORD "hotel" - QUOTE """ - COMMA "," - STRING_LITERAL "india" - QUOTE """ - WORD "india" - QUOTE """ - COMMA "," - STRING_LITERAL "juliet" - QUOTE """ - WORD "juliet" - QUOTE """ - COMMA "," - STRING_LITERAL "kilo" - QUOTE """ - WORD "kilo" - QUOTE """ - COMMA "," - STRING_LITERAL "lima" - QUOTE """ - WORD "lima" - QUOTE """ - COMMA "," - STRING_LITERAL "mike" - QUOTE """ - WORD "mike" - QUOTE """ - COMMA "," - STRING_LITERAL "november" - QUOTE """ - WORD "november" - QUOTE """ - COMMA "," - STRING_LITERAL "oscar" - QUOTE """ - WORD "oscar" - QUOTE """ - COMMA "," - STRING_LITERAL "papa" - QUOTE """ - WORD "papa" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[1, 2]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[3, 4]" - L_BRACKET "[" - INTEGER_LITERAL "3" - COMMA "," - INTEGER_LITERAL "4" - R_BRACKET "]" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[1, 2, 3]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - COMMA "," - INTEGER_LITERAL "3" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[4, 5, 6]" - L_BRACKET "[" - INTEGER_LITERAL "4" - COMMA "," - INTEGER_LITERAL "5" - COMMA "," - INTEGER_LITERAL "6" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[7, 8, 9]" - L_BRACKET "[" - INTEGER_LITERAL "7" - COMMA "," - INTEGER_LITERAL "8" - COMMA "," - INTEGER_LITERAL "9" - R_BRACKET "]" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[1, 2]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[3, 4]" - L_BRACKET "[" - INTEGER_LITERAL "3" - COMMA "," - INTEGER_LITERAL "4" - R_BRACKET "]" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[5, 6]" - L_BRACKET "[" - INTEGER_LITERAL "5" - COMMA "," - INTEGER_LITERAL "6" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[7, 8]" - L_BRACKET "[" - INTEGER_LITERAL "7" - COMMA "," - INTEGER_LITERAL "8" - R_BRACKET "]" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[9, 10]" - L_BRACKET "[" - INTEGER_LITERAL "9" - COMMA "," - INTEGER_LITERAL "10" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[11, 12]" - L_BRACKET "[" - INTEGER_LITERAL "11" - COMMA "," - INTEGER_LITERAL "12" - R_BRACKET "]" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL - L_BRACKET "[" - ARRAY_LITERAL "[13, 14]" - L_BRACKET "[" - INTEGER_LITERAL "13" - COMMA "," - INTEGER_LITERAL "14" - R_BRACKET "]" - COMMA "," - ARRAY_LITERAL "[15, 16]" - L_BRACKET "[" - INTEGER_LITERAL "15" - COMMA "," - INTEGER_LITERAL "16" - R_BRACKET "]" - R_BRACKET "]" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL "// ===== Trivia in array (line comments) ===== - // 1 open bracket leading - [ // 2 open bracket trailing - // 3 first element leading - 1 // 4 first element trailing - , // 5 comma trailing - // 6 second element leading - 2 // 7 second element trailing - // 8 close bracket leading - ]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL "// ===== Trivia in array (block comments) ===== - /* 1 open bracket leading */ - [ /* 2 open bracket trailing */ - /* 3 first element leading */ - 1 /* 4 first element trailing */ - , /* 5 comma trailing */ - /* 6 second element leading */ - 2 /* 7 second element trailing */ - /* 8 close bracket leading */ - ]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "this is a long string" - QUOTE """ - WORD "this" - KW_IS "is" - WORD "a" - WORD "long" - WORD "string" - QUOTE """ - COMMA "," - STRING_LITERAL "another long string value" - QUOTE """ - WORD "another" - WORD "long" - WORD "string" - WORD "value" - QUOTE """ - COMMA "," - STRING_LITERAL "yet another that is quite long" - QUOTE """ - WORD "yet" - WORD "another" - WORD "that" - KW_IS "is" - WORD "quite" - WORD "long" - QUOTE """ - COMMA "," - STRING_LITERAL "and one more string element" - QUOTE """ - WORD "and" - WORD "one" - WORD "more" - WORD "string" - WORD "element" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - ARRAY_LITERAL - L_BRACKET "[" - STRING_LITERAL "this is a long string" - QUOTE """ - WORD "this" - KW_IS "is" - WORD "a" - WORD "long" - WORD "string" - QUOTE """ - COMMA "," - STRING_LITERAL "another long string value" - QUOTE """ - WORD "another" - WORD "long" - WORD "string" - WORD "value" - QUOTE """ - COMMA "," - STRING_LITERAL "yet another that is quite long" - QUOTE """ - WORD "yet" - WORD "another" - WORD "that" - KW_IS "is" - WORD "quite" - WORD "long" - QUOTE """ - COMMA "," - STRING_LITERAL "and one more string element" - QUOTE """ - WORD "and" - WORD "one" - WORD "more" - WORD "string" - WORD "element" - QUOTE """ - R_BRACKET "]" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "key" - QUOTE """ - WORD "key" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "a" - QUOTE """ - WORD "a" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "b" - QUOTE """ - WORD "b" - QUOTE """ - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "a" - QUOTE """ - WORD "a" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "b" - QUOTE """ - WORD "b" - QUOTE """ - COLON ":" - INTEGER_LITERAL "2" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "c" - QUOTE """ - WORD "c" - QUOTE """ - COLON ":" - INTEGER_LITERAL "3" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "d" - QUOTE """ - WORD "d" - QUOTE """ - COLON ":" - INTEGER_LITERAL "4" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "e" - QUOTE """ - WORD "e" - QUOTE """ - COLON ":" - INTEGER_LITERAL "5" - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "first_key" - QUOTE """ - WORD "first_key" - QUOTE """ - COLON ":" - STRING_LITERAL "first value" - QUOTE """ - WORD "first" - WORD "value" - QUOTE """ - COMMA "," - OBJECT_FIELD - STRING_LITERAL "second_key" - QUOTE """ - WORD "second_key" - QUOTE """ - COLON ":" - STRING_LITERAL "second value" - QUOTE """ - WORD "second" - WORD "value" - QUOTE """ - COMMA "," - OBJECT_FIELD - STRING_LITERAL "third_key" - QUOTE """ - WORD "third_key" - QUOTE """ - COLON ":" - STRING_LITERAL "third value" - QUOTE """ - WORD "third" - WORD "value" - QUOTE """ - COMMA "," - OBJECT_FIELD - STRING_LITERAL "fourth_key" - QUOTE """ - WORD "fourth_key" - QUOTE """ - COLON ":" - STRING_LITERAL "fourth value" - QUOTE """ - WORD "fourth" - WORD "value" - QUOTE """ - COMMA "," - OBJECT_FIELD - STRING_LITERAL "fifth_key" - QUOTE """ - WORD "fifth_key" - QUOTE """ - COLON ":" - STRING_LITERAL "fifth" - QUOTE """ - WORD "fifth" - QUOTE """ - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "outer" - QUOTE """ - WORD "outer" - QUOTE """ - COLON ":" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "inner_a" - QUOTE """ - WORD "inner_a" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "inner_b" - QUOTE """ - WORD "inner_b" - QUOTE """ - COLON ":" - INTEGER_LITERAL "2" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "inner_c" - QUOTE """ - WORD "inner_c" - QUOTE """ - COLON ":" - INTEGER_LITERAL "3" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "other" - QUOTE """ - WORD "other" - QUOTE """ - COLON ":" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "inner_d" - QUOTE """ - WORD "inner_d" - QUOTE """ - COLON ":" - INTEGER_LITERAL "4" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "inner_e" - QUOTE """ - WORD "inner_e" - QUOTE """ - COLON ":" - INTEGER_LITERAL "5" - COMMA "," - OBJECT_FIELD - STRING_LITERAL "inner_f" - QUOTE """ - WORD "inner_f" - QUOTE """ - COLON ":" - INTEGER_LITERAL "6" - R_BRACE "}" - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "k" - QUOTE """ - WORD "k" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - R_BRACE "}" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "k" - QUOTE """ - WORD "k" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "y: 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "y: 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 3" - WORD "x" - COLON ":" - INTEGER_LITERAL "3" - COMMA "," - OBJECT_FIELD "y: 4" - WORD "y" - COLON ":" - INTEGER_LITERAL "4" - R_BRACE "}" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 100000" - WORD "x" - COLON ":" - INTEGER_LITERAL "100000" - COMMA "," - OBJECT_FIELD "y: 200000" - WORD "y" - COLON ":" - INTEGER_LITERAL "200000" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 300000" - WORD "x" - COLON ":" - INTEGER_LITERAL "300000" - COMMA "," - OBJECT_FIELD "y: 400000" - WORD "y" - COLON ":" - INTEGER_LITERAL "400000" - R_BRACE "}" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherTriple" - L_BRACE "{" - OBJECT_FIELD - WORD "a" - COLON ":" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "y: 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 3" - WORD "x" - COLON ":" - INTEGER_LITERAL "3" - COMMA "," - OBJECT_FIELD "y: 4" - WORD "y" - COLON ":" - INTEGER_LITERAL "4" - R_BRACE "}" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "b" - COLON ":" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 5" - WORD "x" - COLON ":" - INTEGER_LITERAL "5" - COMMA "," - OBJECT_FIELD "y: 6" - WORD "y" - COLON ":" - INTEGER_LITERAL "6" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 7" - WORD "x" - COLON ":" - INTEGER_LITERAL "7" - COMMA "," - OBJECT_FIELD "y: 8" - WORD "y" - COLON ":" - INTEGER_LITERAL "8" - R_BRACE "}" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "c" - COLON ":" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 9" - WORD "x" - COLON ":" - INTEGER_LITERAL "9" - COMMA "," - OBJECT_FIELD "y: 10" - WORD "y" - COLON ":" - INTEGER_LITERAL "10" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x: 11" - WORD "x" - COLON ":" - INTEGER_LITERAL "11" - COMMA "," - OBJECT_FIELD "y: 12" - WORD "y" - COLON ":" - INTEGER_LITERAL "12" - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "// 4 open brace trailing - // 5 field name leading - x // 6 field name trailing - : // 7 colon trailing - // 8 value leading - 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "// 10 comma trailing - // 11 second field leading - y // 12 second name trailing - : // 13 second colon trailing - // 14 second value leading - 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "/* 4 open brace trailing */ - /* 5 field name leading */ - x /* 6 field name trailing */ - : /* 7 colon trailing */ - /* 8 value leading */ - 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "/* 10 comma trailing */ - /* 11 second field leading */ - y /* 12 second name trailing */ - : /* 13 second colon trailing */ - /* 14 second value leading */ - 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherVec" - L_BRACE "{" - OBJECT_FIELD - WORD "p" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "// 9 trailing - // 10 leading - x // 11 trailing - : // 12 trailing - // 13 leading - 100000" - WORD "x" - COLON ":" - INTEGER_LITERAL "100000" - COMMA "," - OBJECT_FIELD "// 15 trailing - // 16 leading - y // 17 trailing - : // 18 trailing - // 19 leading - 200000" - WORD "y" - COLON ":" - INTEGER_LITERAL "200000" - R_BRACE "}" - COMMA "," - OBJECT_FIELD - WORD "q" - COLON ":" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "// 28 trailing - // 29 leading - x // 30 trailing - : // 31 trailing - // 32 leading - 300000" - WORD "x" - COLON ":" - INTEGER_LITERAL "300000" - COMMA "," - OBJECT_FIELD "// 34 trailing - // 35 leading - y // 36 trailing - : // 37 trailing - // 38 leading - 400000" - WORD "y" - COLON ":" - INTEGER_LITERAL "400000" - R_BRACE "}" - R_BRACE "}" - SEMICOLON ";" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let x" - KW_LET "let" - WORD "x" - EQUALS "=" - INTEGER_LITERAL "1" - SEMICOLON ";" - BINARY_EXPR "x + 1" - WORD "x" - PLUS "+" - INTEGER_LITERAL "1" - R_BRACE "}" - SEMICOLON ";" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let x" - KW_LET "let" - WORD "x" - EQUALS "=" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - LET_STMT - PATTERN - BINDING_PATTERN "let y" - KW_LET "let" - WORD "y" - EQUALS "=" - BINARY_EXPR "x * 2" - WORD "x" - STAR "*" - INTEGER_LITERAL "2" - SEMICOLON ";" - WORD "y" - R_BRACE "}" - SEMICOLON ";" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let x" - KW_LET "let" - WORD "x" - EQUALS "=" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let y" - KW_LET "let" - WORD "y" - EQUALS "=" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let z" - KW_LET "let" - WORD "z" - EQUALS "=" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - SEMICOLON ";" - BINARY_EXPR "z * z" - WORD "z" - STAR "*" - WORD "z" - R_BRACE "}" - SEMICOLON ";" - BINARY_EXPR "y + y" - WORD "y" - PLUS "+" - WORD "y" - R_BRACE "}" - SEMICOLON ";" - BINARY_EXPR "x * x" - WORD "x" - STAR "*" - WORD "x" - R_BRACE "}" - SEMICOLON ";" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let x" - KW_LET "let" - WORD "x" - EQUALS "=" - IF_EXPR - KW_IF "if" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "a > b" - WORD "a" - GREATER ">" - WORD "b" - R_PAREN ")" - BLOCK_EXPR - L_BRACE "{" - MATCH_EXPR - KW_MATCH "match" - L_PAREN "(" - WORD "a" - R_PAREN ")" - L_BRACE "{" - MATCH_ARM - PATTERN - TYPE_PATTERN - TYPE_EXPR "0" - INTEGER_LITERAL "0" - FAT_ARROW "=>" - BLOCK_EXPR - L_BRACE "{" - LET_STMT - PATTERN - BINDING_PATTERN "let inner" - KW_LET "let" - WORD "inner" - EQUALS "=" - BINARY_EXPR "b * 2" - WORD "b" - STAR "*" - INTEGER_LITERAL "2" - SEMICOLON ";" - BINARY_EXPR "inner + 1" - WORD "inner" - PLUS "+" - INTEGER_LITERAL "1" - R_BRACE "}" - COMMA "," - MATCH_ARM - PATTERN - WILDCARD_PATTERN "_" - WORD "_" - FAT_ARROW "=>" - WORD "a" - R_BRACE "}" - R_BRACE "}" - KW_ELSE "else" - BLOCK_EXPR "{ - b - }" - L_BRACE "{" - WORD "b" - R_BRACE "}" - SEMICOLON ";" - WORD "x" - R_BRACE "}" - SEMICOLON ";" - ARRAY_LITERAL "// ===== Extraneous whitespace ===== - [ 1 , 2 , 3 ]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - COMMA "," - INTEGER_LITERAL "3" - R_BRACKET "]" - SEMICOLON ";" - MAP_LITERAL - L_BRACE "{" - OBJECT_FIELD - STRING_LITERAL "k" - QUOTE """ - WORD "k" - QUOTE """ - COLON ":" - INTEGER_LITERAL "1" - R_BRACE "}" - SEMICOLON ";" - OBJECT_LITERAL - WORD "OtherPoint" - L_BRACE "{" - OBJECT_FIELD "x : 1" - WORD "x" - COLON ":" - INTEGER_LITERAL "1" - COMMA "," - OBJECT_FIELD "y : 2" - WORD "y" - COLON ":" - INTEGER_LITERAL "2" - R_BRACE "}" - SEMICOLON ";" - BINARY_EXPR "a + b" - WORD "a" - PLUS "+" - WORD "b" - R_BRACE "}" - -=== ERRORS === -None 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/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new deleted file mode 100644 index 71d87ca021..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__binary_expr.snap.new +++ /dev/null @@ -1,227 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 39957 ---- -// Testing all the formatter cases for binary expressions -// including chains and nested chains - -function BinaryExprs(a: int, b: int, c: int, d: int, s: string, flag: bool) -> int { - // ===== Basic arithmetic ===== - a + b; - a - b; - a * b; - a / b; - a % b; - - // ===== Comparison operators ===== - a == b; - a != b; - a < b; - a > b; - a <= b; - a >= b; - - // ===== Logical operators ===== - flag - && true; - flag - || false; - - // ===== Bitwise operators ===== - a & b; - a | b; - a ^ b; - a << b; - a >> b; - - // ===== Assignment operators ===== - let mut_a = a; - mut_a += b; - mut_a -= b; - mut_a *= b; - mut_a /= b; - mut_a %= b; - mut_a &= b; - mut_a |= b; - mut_a ^= b; - mut_a <<= b; - mut_a >>= b; - - // ===== Chained arithmetic (same precedence group) ===== - a + b + c; - a + b + c + d; - a - b + c - d; - a * b * c; - a * b / c % d; - - // ===== Chained comparisons with logical ===== - a > 0 && b > 0; - a > 0 || b > 0; - a > 0 && b > 0 && c > 0; - a > 0 || b > 0 || c > 0; - a > 0 && b > 0 || c > 0; - - // ===== Mixed precedence ===== - a + b * c; - (a + b) * c; - a * b + c * d; - a + b * c + d; - - // ===== Nested parenthesized ===== - (a + b) * (c + d); - ((a + b) * c) + d; - a + (b * (c + d)); - - // ===== Deeply nested parens ===== - ((((a + b) * c) + d) * (((a - b) + c) - d)) + ((a * b) + (c * d)); - (((a + b) * (c + d)) + ((a - b) * (c - d))) - * (((a * c * d) + (b * c * d)) - ((a * d) + (b * c * d))); - - // ===== Trivia between operands (line comments) ===== - // 1 left leading - a // 2 left trailing - + b; - - // ===== Trivia between operands (block comments) ===== - /* 1 left leading */ - a/* 2 left trailing *//* 3 operator leading */+/* 4 operator trailing *//* 5 right leading */b/* 6 right trailing */; - - // ===== Trivia in chained binary (line comments) ===== - // 1 first leading - a // 2 first trailing - + b // 6 second trailing - + c; - - // ===== Long arithmetic chain exceeding limit ===== - a - + b - + c - + d - + a - + b - + c - + d - + a - + b - + c - + d - + a - + b - + c - + d - + a - + b - + c - + d - + a - + b - + c - + d - + a - + b; - - // ===== Long logical chain exceeding limit ===== - a > 0 - && b > 0 - && c > 0 - && d > 0 - && a != b - && b != c - && c != d - && a < 1000 * 8 + 1 * 2 - && b < 1000 - && c < 1000 - && d < 1000 + 2 + 3; - - // ===== Long mixed precedence chain exceeding limit ===== - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d - - a * b - + c * d; - - // ===== Long comparison chain exceeding limit ===== - a + b + c + d > 0 - && a * b * c * d < 10000 - && a - b - c - d != 0 - && (a + b) * (c + d) >= 100 - || a * 1 < 2 - && "aowiefjowiaj" == "jfeiowajpwoeifj"; - - // ===== Long string concatenation exceeding limit ===== - "a very long string prefix that is already quite long" - + " concatenated with " - + "another very long string that together exceeds the line limit easily and comfortably"; - - // ===== Long assignment expression exceeding limit ===== - mut_a += a * b + c * d + a * b + c * d + a * b + c * d + a * b + c * d + a * b + c * d + a; - - // ===== Trivia in long wrapping chain (line comments) ===== - // 1 leading - a // 2 trailing - + b // 6 trailing - + c // 10 trailing - + d // 14 trailing - + a // 18 trailing - + b // 22 trailing - + c // 26 trailing - + d // 30 trailing - + a // 34 trailing - + b // 38 trailing - + c // 42 trailing - + d; - - // ===== Trivia in long wrapping chain (block comments) ===== - /* 1 leading */ - a /* 2 trailing */ - + b /* 6 trailing */ - + c /* 10 trailing */ - + d /* 14 trailing */ - + a /* 18 trailing */ - + b /* 22 trailing */ - + c /* 26 trailing */ - + d /* 30 trailing */ - + a /* 34 trailing */ - + b /* 38 trailing */ - + c /* 42 trailing */ - + d/* 46 trailing */; - - // ===== Trivia in long wrapping logical chain (line comments) ===== - // 1 leading - a > 0 // 2 trailing - && b > 0 // 6 trailing - && c > 0 // 10 trailing - && d > 0 // 14 trailing - && a != b // 18 trailing - && b != c // 22 trailing - && c != d; - - // ===== Short expressions (should stay single line) ===== - a + b; - 1 + 2; - a > b; - - // ===== Extraneous whitespace ===== - a + b; - a * b + c; - a == b; - a == 2 && b != 3; - - // ===== Final expression ===== - a + b -} 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/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/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..77147ea451 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 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.new 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.new deleted file mode 100644 index 77eca375a0..0000000000 --- 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.new +++ /dev/null @@ -1,78 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 50625 ---- -=== SYNTAX TREE === -SOURCE_FILE - TEST_EXPR_DEF - KW_TEST "test" - BINARY_EXPR - STRING_LITERAL "a" - QUOTE """ - WORD "a" - QUOTE """ - PLUS "+" - INTEGER_LITERAL "1" - BLOCK_EXPR "{ - null -}" - L_BRACE "{" - KW_NULL "null" - R_BRACE "}" - TEST_EXPR_DEF - KW_TEST "test" - INTEGER_LITERAL "42" - BLOCK_EXPR "{ - null -}" - L_BRACE "{" - KW_NULL "null" - R_BRACE "}" - TESTSET_DEF - KW_TESTSET "testset" - STRING_LITERAL "int_name" - QUOTE """ - WORD "int_name" - QUOTE """ - BLOCK_EXPR - L_BRACE "{" - FOR_EXPR - KW_FOR "for" - L_PAREN "(" - LET_STMT - PATTERN - BINDING_PATTERN "let i" - KW_LET "let" - WORD "i" - KW_IN "in" - ARRAY_LITERAL "[1, 2, 3]" - L_BRACKET "[" - INTEGER_LITERAL "1" - COMMA "," - INTEGER_LITERAL "2" - COMMA "," - INTEGER_LITERAL "3" - R_BRACKET "]" - R_PAREN ")" - BLOCK_EXPR - L_BRACE "{" - TEST_EXPR_DEF - KW_TEST "test" - PAREN_EXPR - L_PAREN "(" - BINARY_EXPR "5 + i" - INTEGER_LITERAL "5" - PLUS "+" - WORD "i" - R_PAREN ")" - BLOCK_EXPR "{ - null - }" - L_BRACE "{" - KW_NULL "null" - R_BRACE "}" - R_BRACE "}" - R_BRACE "}" - -=== ERRORS === -None 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__03_hir.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new deleted file mode 100644 index f1ccd920a9..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__03_hir.snap.new +++ /dev/null @@ -1,8 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 50649 ---- -=== HIR2 === -function user.$init_test_main(registry: testing.TestCollector) -> ? [expr] { - { registry.register_test("a" Add 1, () -> void { { } }, null); registry.register_test(42, () -> void { { } }, null); registry.register_test_set("int_name", (testset: testing.TestCollector) -> void { { for i in [1, 2, 3] { testset.register_test(5 Add i, () -> { { } }, null) } } null }, null) } null -} 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__04_tir.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new deleted file mode 100644 index 7a57335620..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__04_tir.snap.new +++ /dev/null @@ -1,39 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 50673 ---- -=== TIR2 === -function user.$init_test_main(registry: testing.TestCollector) -> ? throws never { - { : null - registry.register_test("a" + 1, () -> void { ... }, null) : void - () -> void { ... } : () -> void throws unknown - { - } - registry.register_test(42, () -> void { ... }, null) : void - () -> void { ... } : () -> void throws unknown - { - } - registry.register_test_set("int_name", (testset: testing.TestCollector) -> void { ... }, null) : void - (testset: testing.TestCollector) -> void { ... } : (testset: testing.TestCollector) -> void throws unknown - { - for i in [1, 2, 3] - { - testset.register_test(5 + i, () -> { ... }, null) - } - null - } - null : null - } - !! 80..88: operator `+` cannot be applied to `"a"` and `1` - !! 106..108: type mismatch: expected string, got 42 - !! 181..186: type mismatch: expected string, got int -} -lambda user.$init_test_main { -} -lambda user.$init_test_main { -} -lambda user.$init_test_main { - !! 181..186: type mismatch: expected string, got int -} -lambda user.$init_test_main { -} 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__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new deleted file mode 100644 index c7371bcf99..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_name_type_error/baml_tests__diagnostic_errors__test_expr_name_type_error__05_diagnostics.snap.new +++ /dev/null @@ -1,322 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 50728 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: operator `+` cannot be applied to `"a"` and `1` - ╭─[ main.baml:3:5 ] - │ - 3 │ test "a" + 1 { - │ ────┬─── - │ ╰───── operator `+` cannot be applied to `"a"` and `1` - │ - │ Note: Error code: E0004 -───╯ - - [type] error: type mismatch: expected string, got 42 - ╭─[ main.baml:7:6 ] - │ - 7 │ test 42 { - │ ─┬ - │ ╰── type mismatch: expected string, got 42 - │ - │ Note: Error code: E0001 -───╯ - - [type] error: type mismatch: expected string, got int - ╭─[ main.baml:13:11 ] - │ - 13 │ test (5 + i) { - │ ──┬── - │ ╰──── type mismatch: expected string, got int - │ - │ Note: Error code: E0001 -────╯ 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.new 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.new deleted file mode 100644 index d35d9d54d6..0000000000 --- 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.new +++ /dev/null @@ -1,92 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 50900 ---- -=== SYNTAX TREE === -SOURCE_FILE - TEST_EXPR_DEF - KW_TEST "test" - STRING_LITERAL "wrong runner type" - QUOTE """ - WORD "wrong" - WORD "runner" - WORD "type" - QUOTE """ - KW_WITH "with" - INTEGER_LITERAL "42" - BLOCK_EXPR - L_BRACE "{" - CALL_EXPR - PATH_EXPR "assert.is_true" - WORD "assert" - DOT "." - WORD "is_true" - CALL_ARGS - L_PAREN "(" - CALL_ARG "true" - KW_TRUE "true" - R_PAREN ")" - R_BRACE "}" - TEST_EXPR_DEF - KW_TEST "test" - STRING_LITERAL "string as runner" - QUOTE """ - WORD "string" - WORD "as" - WORD "runner" - QUOTE """ - KW_WITH "with" - STRING_LITERAL "not a runner" - QUOTE """ - WORD "not" - WORD "a" - WORD "runner" - QUOTE """ - BLOCK_EXPR - L_BRACE "{" - CALL_EXPR - PATH_EXPR "assert.is_true" - WORD "assert" - DOT "." - WORD "is_true" - CALL_ARGS - L_PAREN "(" - CALL_ARG "true" - KW_TRUE "true" - R_PAREN ")" - R_BRACE "}" - TESTSET_DEF - KW_TESTSET "testset" - STRING_LITERAL "wrong testset runner" - QUOTE """ - WORD "wrong" - KW_TESTSET "testset" - WORD "runner" - QUOTE """ - KW_WITH "with" - INTEGER_LITERAL "42" - BLOCK_EXPR - L_BRACE "{" - TEST_EXPR_DEF - KW_TEST "test" - STRING_LITERAL "inner" - QUOTE """ - WORD "inner" - QUOTE """ - BLOCK_EXPR - L_BRACE "{" - CALL_EXPR - PATH_EXPR "assert.is_true" - WORD "assert" - DOT "." - WORD "is_true" - CALL_ARGS - L_PAREN "(" - CALL_ARG "true" - KW_TRUE "true" - R_PAREN ")" - R_BRACE "}" - R_BRACE "}" - -=== ERRORS === -None diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new deleted file mode 100644 index 316f6ae81f..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__05_diagnostics.snap.new +++ /dev/null @@ -1,322 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 51003 ---- -=== COMPILER2 DIAGNOSTICS === - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:343:31 ] - │ - 343 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:344:29 ] - │ - 344 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 348 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:396:14 ] - │ - 396 │ ╭─▶ null => { - ┆ ┆ - 399 │ ├─▶ }, - │ │ - │ ╰────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:408:33 ] - │ - 408 │ ╭─▶ if (chunk.length() == 0) { - ┆ ┆ - 410 │ ├─▶ } else { - │ │ - │ ╰────────────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:410:15 ] - │ - 410 │ ╭─▶ } else { - ┆ ┆ - 412 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:508:31 ] - │ - 508 │ ╭─▶ function flush(self) -> null { - ┆ ┆ - 510 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:521:31 ] - │ - 521 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:522:29 ] - │ - 522 │ ╭─▶ if (self._owns_file) { - ┆ ┆ - 526 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: `if` without `else` cannot be used as a value; add an `else` branch - ╭─[ csv.baml:561:31 ] - │ - 561 │ ╭─▶ let f: root.fs.File => { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── `if` without `else` cannot be used as a value; add an `else` branch - │ - │ Note: Error code: E0001 -─────╯ - - [type] error: missing return value of type null - ╭─[ csv.baml:562:30 ] - │ - 562 │ ╭─▶ if (out.length() > 0) { - ┆ ┆ - 566 │ ├─▶ } - │ │ - │ ╰─────────────── missing return value of type null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:86:89 ] - │ - 86 │ ╭─▶ function some(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 98 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type bool - ╭─[ iter.baml:100:90 ] - │ - 100 │ ╭─▶ function every(self, predicate: (Item) -> bool throws E2) -> bool throws Error | E2 { - ┆ ┆ - 112 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type Self.Item | null - ╭─[ iter.baml:114:90 ] - │ - 114 │ ╭─▶ function find(self, predicate: (Item) -> bool throws E2) -> Item? throws Error | E2 { - ┆ ┆ - 126 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type Self.Item | null - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:104:56 ] - │ - 104 │ ╭─▶ function eq(self, other: Self) -> bool throws never { - ┆ ┆ - 106 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ comparison.baml:107:57 ] - │ - 107 │ ╭─▶ function neq(self, other: Self) -> bool throws never { - ┆ ┆ - 109 │ ├─▶ } - │ │ - │ ╰─────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:298:63 ] - │ - 298 │ ╭─▶ function _name_selected(name: string, names: string[]) -> bool { - ┆ ┆ - 307 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:309:75 ] - │ - 309 │ ╭─▶ function _has_selected_descendant(prefix: string, names: string[]) -> bool { - ┆ ┆ - 319 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:490:62 ] - │ - 490 │ ╭─▶ function glob_match(subject: string, pattern: string) -> bool { - ┆ ┆ - 513 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:517:18 ] - │ - 517 │ ╭─▶ if (expr == "") { - ┆ ┆ - 519 │ ├─▶ } else { - │ │ - │ ╰──────────────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type bool - ╭─[ registry.baml:524:98 ] - │ - 524 │ ╭─▶ function any_pattern_matches(pats: FilterPat[], function_name: string, test_name: string) -> bool { - ┆ ┆ - 531 │ ├─▶ } - │ │ - │ ╰─────── missing return value of type bool - │ - │ Note: Error code: E0029 -─────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:7:9 ] - │ - 7 │ ╭─▶ } else { - ┆ ┆ - 9 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -───╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:16:9 ] - │ - 16 │ ╭─▶ } else { - ┆ ┆ - 18 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:44:9 ] - │ - 44 │ ╭─▶ } else { - ┆ ┆ - 46 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: missing return value of type null - ╭─[ assert.baml:53:9 ] - │ - 53 │ ╭─▶ } else { - ┆ ┆ - 55 │ ├─▶ } - │ │ - │ ╰───────── missing return value of type null - │ - │ Note: Error code: E0029 -────╯ - - [type] error: type mismatch: expected testing.TestRunner | null, got 42 - ╭─[ main.baml:4:31 ] - │ - 4 │ test "wrong runner type" with 42 { - │ ─┬ - │ ╰── type mismatch: expected testing.TestRunner | null, got 42 - │ - │ Note: Error code: E0001 -───╯ - - [type] error: type mismatch: expected testing.TestRunner | null, got "not a runner" - ╭─[ main.baml:8:30 ] - │ - 8 │ test "string as runner" with "not a runner" { - │ ───────┬────── - │ ╰──────── type mismatch: expected testing.TestRunner | null, got "not a runner" - │ - │ Note: Error code: E0001 -───╯ - - [type] error: type mismatch: expected testing.TestSetRunner | null, got 42 - ╭─[ main.baml:12:37 ] - │ - 12 │ testset "wrong testset runner" with 42 { - │ ─┬ - │ ╰── type mismatch: expected testing.TestSetRunner | null, got 42 - │ - │ Note: Error code: E0001 -────╯ diff --git a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new b/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new deleted file mode 100644 index 35f0a3894b..0000000000 --- a/baml_language/crates/baml_tests/snapshots/diagnostic_errors/test_expr_wrong_runner/baml_tests__diagnostic_errors__test_expr_wrong_runner__10_formatter__main.snap.new +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/baml_tests/src/generated_tests.rs -assertion_line: 51080 ---- -// Runner expression is the wrong type — should produce a type diagnostic. -// Expected: diagnostics for type mismatch on 42 and "not a runner". - -test "wrong runner type" with 42 { - assert - .is_true( - true, - ) -} - -test "string as runner" with "not a runner" { - assert - .is_true( - true, - ) -} - -testset "wrong testset runner" with 42 { - test "inner" { - assert - .is_true( - true, - ) - } -} 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..ea4cedf230 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" @@ -48,7 +48,7 @@ SOURCE_FILE WORD "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/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 From 48fb053e75229066a023fed999504f0c81ea6c80 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 04:08:35 -0700 Subject: [PATCH 08/17] feat(parser): re-lex `true`/`false`/`null` as KW_TRUE/KW_FALSE/KW_NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the boolean and null literals real tokens instead of bare WORDs, so the semantic-tokens classifier reads them by kind (the last text-match in the classifier's value-literal path is now backed by a real token). Updates the token-kind consumers the remap touches: - ast.rs: the block tail-expression accessor accepts KW_TRUE/FALSE/NULL (a trailing `false`/`true`/`null` is the block's value — without this a bool-returning function tripped E0029 "missing return value"). - baml_fmt: a KeywordLiteral token (spanning the three kinds) + a Literal::Keyword variant; Expression::from_cst routes the bare literal tokens to it (they were formatted as bare-WORD Paths before). - 39 parser CST snapshots regenerated — purely mechanical WORD -> KW_*. Validated: lsp 440/440, compiler2_ast 73/73, baml_tests 2661/2665 (the 4 generic_arg_soundness failures are pre-existing, fail on base). --- .../crates/baml_compiler_parser/src/parser.rs | 14 +++----- .../crates/baml_compiler_syntax/src/ast.rs | 6 +++- .../crates/baml_fmt/src/ast/expressions.rs | 14 +++++++- .../crates/baml_fmt/src/ast/tokens.rs | 34 +++++++++++++++++++ ...est_invalid_contexts__02_parser__main.snap | 8 ++--- ...ctionary__02_parser__valid_dictionary.snap | 2 +- ...as_basic__02_parser__json_alias_basic.snap | 6 ++-- ..._literal__02_parser__json_map_literal.snap | 2 +- ..._advanced__02_parser__lambda_advanced.snap | 4 +-- ...l_scoping__02_parser__lexical_scoping.snap | 4 +-- ...ral_union_arithmetic__02_parser__main.snap | 9 +++-- ..._02_parser__method_explicit_type_args.snap | 2 +- ...e_resolution__02_parser__ns_auth_auth.snap | 2 +- ..._resolution__02_parser__ns_llm_models.snap | 2 +- ..._function_parameters__02_parser__main.snap | 8 ++--- ...er_expressions__02_parser__precedence.snap | 7 ++-- ...statements__02_parser__break_continue.snap | 17 +++++----- ...est_expr_name_concat__02_parser__main.snap | 4 +-- ...test_raw_string_name__02_parser__main.snap | 6 ++-- ...piles__testset_basic__02_parser__main.snap | 4 +-- ...les__testset_dynamic__02_parser__main.snap | 6 ++-- ...iles__testset_nested__02_parser__main.snap | 4 +-- ...annotation__02_parser__type_positions.snap | 2 +- ...acktick_strict_types__02_parser__main.snap | 2 +- ...errors__builtin_io__02_parser__io_ops.snap | 2 +- ...ors__builtin_io__02_parser__shell_ops.snap | 16 ++++----- ...02_parser__catch_return_type_mismatch.snap | 3 +- ...format_checks__02_parser__binary_expr.snap | 4 +-- ...ormat_checks__02_parser__config_decls.snap | 8 ++--- ..._format_checks__02_parser__loop_stmts.snap | 2 +- ...format_checks__02_parser__other_exprs.snap | 8 ++--- ..._errors__generics__02_parser__classes.snap | 2 +- ...ers_edge_cases__02_parser__edge_cases.snap | 3 +- ...ll_handling__02_parser__null_handling.snap | 2 +- ...ults__02_parser__unsupported_contexts.snap | 4 +-- ...ructors__02_parser__array_constructor.snap | 6 ++-- ...structors__02_parser__map_constructor.snap | 4 +-- ...expr_name_type_error__02_parser__main.snap | 7 ++-- ...st_expr_wrong_runner__02_parser__main.snap | 6 ++-- ...ith_runner_ambiguity__02_parser__main.snap | 6 ++-- ...type_aliases__02_parser__type_aliases.snap | 2 +- ..._error__02_parser__unknown_type_error.snap | 2 +- ..._02_parser__void_type_position_errors.snap | 2 +- 43 files changed, 149 insertions(+), 109 deletions(-) diff --git a/baml_language/crates/baml_compiler_parser/src/parser.rs b/baml_language/crates/baml_compiler_parser/src/parser.rs index 8109e88b6d..75c7120cd8 100644 --- a/baml_language/crates/baml_compiler_parser/src/parser.rs +++ b/baml_language/crates/baml_compiler_parser/src/parser.rs @@ -6187,16 +6187,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. NOTE: re-lexing these as KW_TRUE/KW_FALSE (the - // principled form) ripples into hover/completions/formatter/CST - // snapshots — deferred until every token-kind consumer is mapped - // and updated. The highlighter classifies them as `boolean` via a - // transitional text match in `tokens.rs::token` for now. - 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 (same KW_NULL deferral as above). - 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(); diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index 27d85b426d..107ebb7f63 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -3700,7 +3700,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_fmt/src/ast/expressions.rs b/baml_language/crates/baml_fmt/src/ast/expressions.rs index 1d11b0446c..179508bc05 100644 --- a/baml_language/crates/baml_fmt/src/ast/expressions.rs +++ b/baml_language/crates/baml_fmt/src/ast/expressions.rs @@ -75,6 +75,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 @@ -298,6 +301,8 @@ pub enum Literal { String(t::QuotedString), Integer(t::IntegerLiteral), Float(t::FloatLiteral), + /// `true` / `false` / `null`. + Keyword(t::KeywordLiteral), } impl FromCST for Literal { @@ -306,8 +311,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(), }), @@ -329,6 +337,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())), } } } @@ -339,6 +348,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() } @@ -347,6 +357,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 { @@ -354,6 +365,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 326bdf49a8..f3dee519f2 100644 --- a/baml_language/crates/baml_fmt/src/ast/tokens.rs +++ b/baml_language/crates/baml_fmt/src/ast/tokens.rs @@ -522,6 +522,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_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/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/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__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 50c949871d..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 @@ -262,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 3b36f9322d..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 @@ -274,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 1b411d1ba6..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 @@ -147,7 +147,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" COMMA "," PARAMETER WORD "chunk_size" @@ -350,7 +350,7 @@ SOURCE_FILE WORD "string" QUESTION "?" EQUALS "=" - WORD "null" + KW_NULL "null" R_PAREN ")" ARROW "->" TYPE_EXPR "int" @@ -365,7 +365,7 @@ SOURCE_FILE BINARY_EXPR "filter == null" WORD "filter" EQUALS_EQUALS "==" - WORD "null" + KW_NULL "null" R_PAREN ")" BLOCK_EXPR "{ max_results @@ -527,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/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_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/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/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_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/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 fff47ebcba..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 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__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/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/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 77147ea451..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 @@ -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/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 ea4cedf230..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 @@ -45,7 +45,7 @@ SOURCE_FILE true }" L_BRACE "{" - WORD "true" + KW_TRUE "true" R_BRACE "}" TYPE_ALIAS_DEF KW_TYPE "type" 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__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" From c8cb7d1f97e27febcb6d70218d801d35bc29d94e Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 04:09:17 -0700 Subject: [PATCH 09/17] style: simplify KW_AS negation (clippy nonminimal_bool) --- baml_language/crates/baml_compiler_syntax/src/ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index 107ebb7f63..ff12e7e055 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -2131,7 +2131,7 @@ impl InterfaceFieldLink { .find(|token| { !token.kind().is_trivia() && is_member_name_token(token.kind()) - && !(token.kind() == SyntaxKind::KW_AS) + && token.kind() != SyntaxKind::KW_AS }) } From d80062f40f8bb99bea86f61541238158849e2ae0 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 04:12:54 -0700 Subject: [PATCH 10/17] refactor(lsp): drop dead true/false/null text-match fallback Value-position literals are now KW_TRUE/KW_FALSE/KW_NULL (classified by kind) and type-position ones go through type_run, so the transitional WORD text match in token() is unreachable. The classifier no longer text-matches any literal. --- baml_language/crates/baml_lsp2_actions/src/tokens.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index f6b6663d2d..0412edcfc9 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -472,17 +472,6 @@ impl Walk<'_> { if kind == SyntaxKind::WORD { if let Some(class) = (self.resolve)(token.text_range()) { emit(token.text_range(), class, out); - } else { - // Transitional: type/config-position `true`/`false`/`null` are - // still bare WORDs until those parse sites are re-lexed too; give - // them the same classification as the `KW_*` value-position form. - match token.text() { - "true" | "false" => { - emit(token.text_range(), plain(SemanticTokenType::Boolean), out); - } - "null" => emit(token.text_range(), plain(SemanticTokenType::Keyword), out), - _ => {} - } } return; } From 2f92e915d7af4ca68e6379bbc140f9ce7f2b17f8 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sat, 27 Jun 2026 04:13:49 -0700 Subject: [PATCH 11/17] docs(lsp): mark parser-token remaps delivered (both done) --- .../baml_lsp2_actions/src/tokens/DESIGN.md | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md index 16b5c50a22..fd867b8574 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md @@ -135,12 +135,25 @@ IN PROGRESS: dispatch reading typed `ast::*` accessors. Behavior-preserving (78 fixtures + range test are the oracle). -DEFERRED (documented cost/benefit): -- **P1 broad remap (true/false/null -> KW_*):** ripples into hover/formatter/CST - snapshots for a highlighter-purity gain; the boolean output already ships via a - transitional text match. The contained `as`/`type` -> KW_AS/KW_TYPE remap is - worthwhile and smaller-radius; do it once C lands (it changes how `classify_token` - reads `as`/`type`). +DELIVERED — parser-token remaps (both done, with every consumer updated): +- **`as`/`type` -> KW_AS/KW_TYPE** and **`true`/`false`/`null` -> + KW_TRUE/KW_FALSE/KW_NULL** at the value/decl parse sites. The classifier now + reads every literal and keyword by kind — there is NO remaining text match in + the classifier. Consumers updated: ast.rs (TypeAliasDef::name, the `as` + checks, the block tail-expression accessor — a trailing `false`/`true`/`null` + is the block value, else E0029), baml_fmt (TypeKw/As keyword tokens + + KeywordLiteral for bool/null), the lsp classifier (kind-based). 67 parser CST + snapshots regenerated (mechanical WORD -> KW_*; the meta-type value `type` and + type-position literal types correctly stay WORD, handled by `type_run`). + Validated end to end: lsp 440/440, compiler2_ast 73/73, baml_tests 2661/2665 + (the 4 generic_arg_soundness failures are a pre-existing TIR generics gap, + fail on base). The blast-radius cost (hover/lowering/formatter/snapshots) was + real but was the work, not a reason to defer — every consumer was mapped and + fixed. + +REMAINING (niche, reasonable as-is): type-position boolean/null literal *types* +(`x: true`) stay bare WORDs, classified by `type_run` as types — re-lexing them +would touch type-parsing + type-check consumers for a niche gain. ## Phases (each ends green: 78 fixtures unchanged unless the change is the point) From 2d5b70f802cfbeaaf895834625f961441d973889 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Sun, 28 Jun 2026 20:39:10 +0900 Subject: [PATCH 12/17] feat(lsp): unify semantic-token resolvers + typing-robustness tests - enum-variant (`Enum.Variant` patterns) and interface-field-link (`name as display_name`) resolve through the same package-resolution system as namespace/item lookup (resolve_enum_variant, resolve_field), verified against the type's actual variants/fields - builtin namespaces flagged defaultLibrary; primitives unified; named/ optional call args, bigint literals, and catch bindings classified - typing-robustness tests (never panic on incomplete/mid-edit input): curated + nested-scope always-run; full-fixture sweep #[ignore]d - parser: find_token_after_hashes returns None at EOF, fixing two index-out-of-bounds panics on incomplete raw strings --- .../crates/baml_compiler2_hir/src/builder.rs | 4 +- .../baml_compiler2_hir/src/semantic_index.rs | 6 +- .../crates/baml_compiler2_mir/src/lower.rs | 85 ++++--- .../crates/baml_compiler2_tir/src/resolve.rs | 116 ++++++++++ .../crates/baml_compiler_parser/src/parser.rs | 10 +- .../crates/baml_compiler_syntax/src/ast.rs | 28 ++- .../baml_lsp2_actions/src/completions.rs | 6 +- .../baml_lsp2_actions/src/definition.rs | 4 +- .../crates/baml_lsp2_actions/src/describe.rs | 3 + .../crates/baml_lsp2_actions/src/tokens.rs | 172 ++++++++++++--- .../baml_lsp2_actions/src/tokens/classify.rs | 48 +++- .../baml_lsp2_actions/src/tokens/index.rs | 35 ++- .../crates/baml_lsp2_actions/src/type_info.rs | 4 +- .../crates/baml_lsp2_actions_tests/src/lib.rs | 1 + .../src/range_tokens_test.rs | 3 +- .../src/typing_robustness_test.rs | 207 ++++++++++++++++++ .../semantic_tokens/bigint_literals.baml | 29 +++ .../semantic_tokens/call_named_args.baml | 41 ++++ .../semantic_tokens/cancel_token.baml | 45 ++-- .../semantic_tokens/catch_all_keyword.baml | 5 + .../semantic_tokens/catch_param.baml | 39 ++++ .../semantic_tokens/catch_throw.baml | 1 + .../semantic_tokens/exhaustive.baml | 24 +- .../semantic_tokens/field_alias.baml | 2 + ...interfaces_inferred_generic_type_args.baml | 37 ++-- .../interfaces_sort_comparable.baml | 159 ++++++++------ .../test_files/semantic_tokens/iterator.baml | 12 +- .../json_parse_stringify_intrinsics.baml | 28 +-- .../test_files/semantic_tokens/ns_ansi.baml | 6 +- .../semantic_tokens/ns_game_clients.baml | 2 +- .../semantic_tokens/patterns_new.baml | 3 + .../stream_llm_inferred_typeargs.baml | 8 +- .../semantic_tokens/task_group.baml | 104 +++++---- .../test_files/semantic_tokens/testset.baml | 4 +- .../semantic_tokens/testset_vibes_nested.baml | 8 +- .../semantic_tokens/with_keyword.baml | 4 +- .../src/bex_lsp/multi_project/request.rs | 18 +- .../tools_semantic_tokens/src/server.rs | 5 +- .../tools_semantic_tokens/src/staleness.rs | 10 +- 39 files changed, 1023 insertions(+), 303 deletions(-) create mode 100644 baml_language/crates/baml_lsp2_actions_tests/src/typing_robustness_test.rs create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/bigint_literals.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/call_named_args.baml create mode 100644 baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/catch_param.baml diff --git a/baml_language/crates/baml_compiler2_hir/src/builder.rs b/baml_language/crates/baml_compiler2_hir/src/builder.rs index de6402275f..8d5fbdd8a5 100644 --- a/baml_language/crates/baml_compiler2_hir/src/builder.rs +++ b/baml_language/crates/baml_compiler2_hir/src/builder.rs @@ -955,7 +955,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, @@ -964,7 +964,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, 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 aef939f554..347ef502ae 100644 --- a/baml_language/crates/baml_compiler2_mir/src/lower.rs +++ b/baml_language/crates/baml_compiler2_mir/src/lower.rs @@ -1187,7 +1187,10 @@ fn resolution_to_item_ref( name: func_data.name.clone(), }) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, } } @@ -8568,7 +8571,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8582,9 +8588,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { - None - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }) } }; @@ -8605,7 +8612,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8663,7 +8673,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8677,9 +8690,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { - None - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }) } }; @@ -8700,7 +8714,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8753,7 +8770,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8767,9 +8787,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { - None - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }) } }; @@ -8790,7 +8811,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::UnboundMethod { func_loc, .. } | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => Some(*func_loc), MemberResolution::Free { func_loc } => Some(*func_loc), - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }; if let Some(fl) = func_loc { let body = baml_compiler2_ppir::function_body(self.db, fl); @@ -8864,7 +8888,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8878,9 +8905,10 @@ impl<'db> LoweringContext<'db> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { - None - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }) } }; @@ -8963,7 +8991,10 @@ impl LoweringContext<'_> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => None, + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }); if from_pmr.is_some() { from_pmr @@ -8977,9 +9008,10 @@ impl LoweringContext<'_> { | MemberResolution::InterfaceDefaultMethod { func_loc, .. } => { Some(*func_loc) } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { - None - } + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => None, }) } } @@ -9802,7 +9834,10 @@ impl<'db> LoweringContext<'db> { return; } } - MemberResolution::Field { .. } | MemberResolution::Variant { .. } | MemberResolution::InterfaceMethod { .. } | MemberResolution::InterfaceField { .. } => { + MemberResolution::Field { .. } + | MemberResolution::Variant { .. } + | MemberResolution::InterfaceMethod { .. } + | MemberResolution::InterfaceField { .. } => { // Fall through — handled by the existing field/enum-variant lowering below } } 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 75c7120cd8..f4d4b6196e 100644 --- a/baml_language/crates/baml_compiler_parser/src/parser.rs +++ b/baml_language/crates/baml_compiler_parser/src/parser.rs @@ -1736,11 +1736,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; @@ -1903,7 +1905,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; } diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index ff12e7e055..5c7e04d58a 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -189,6 +189,23 @@ 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`). /// @@ -333,11 +350,7 @@ impl UnionMemberParts { { return None; } - if !self - .tokens - .iter() - .any(|t| t.kind() == SyntaxKind::KW_AS) - { + if !self.tokens.iter().any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } let dot_idx = self @@ -461,10 +474,7 @@ impl TypeExpr { { return None; } - if !tokens - .iter() - .any(|t| t.kind() == SyntaxKind::KW_AS) - { + if !tokens.iter().any(|t| t.kind() == SyntaxKind::KW_AS) { return None; } let dot_idx = tokens.iter().rposition(|t| t.kind() == SyntaxKind::DOT)?; diff --git a/baml_language/crates/baml_lsp2_actions/src/completions.rs b/baml_language/crates/baml_lsp2_actions/src/completions.rs index db1a13e62d..abcfd8844f 100644 --- a/baml_language/crates/baml_lsp2_actions/src/completions.rs +++ b/baml_language/crates/baml_lsp2_actions/src/completions.rs @@ -1316,7 +1316,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) } } @@ -1391,7 +1392,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 5735e38a78..e16558859f 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 }) diff --git a/baml_language/crates/baml_lsp2_actions/src/describe.rs b/baml_language/crates/baml_lsp2_actions/src/describe.rs index b04dfebb7f..3d2889fafe 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/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index 0412edcfc9..82239bc9e8 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -17,13 +17,18 @@ //! `declaration` modifier; a reference is classified the same way as its //! definition. - use baml_base::{Name, SourceFile}; -use baml_compiler_syntax::ast::{GenericParam, ObjectField}; -use baml_compiler_syntax::{SyntaxKind, SyntaxNode, SyntaxToken}; -use baml_compiler2_tir::resolve::{resolve_name_at, resolve_path_at}; -use rowan::ast::AstNode; -use rowan::{NodeOrToken, WalkEvent}; +use baml_compiler_syntax::{ + SyntaxKind, SyntaxNode, SyntaxToken, + ast::{ + CallArg, ClassDef, GenericParam, ImplementsBlock, ImplementsTarget, InterfaceFieldLink, + ObjectField, TypeExpr, + }, +}; +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; @@ -256,7 +261,11 @@ fn string_with_escapes(node: &SyntaxNode, out: &mut Vec) { 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); + emit( + span(base + text_start, base + i), + plain(SemanticTokenType::String), + out, + ); } let len = escape_len(&text[i..]); emit( @@ -442,6 +451,7 @@ impl Walk<'_> { 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 @@ -481,7 +491,10 @@ impl Walk<'_> { SemanticTokenType::Operator } else if kind.is_comment() { SemanticTokenType::Comment - } else if matches!(kind, SyntaxKind::INTEGER_LITERAL | SyntaxKind::FLOAT_LITERAL) { + } else if matches!( + kind, + SyntaxKind::INTEGER_LITERAL | SyntaxKind::FLOAT_LITERAL | SyntaxKind::BIGINT_LITERAL + ) { SemanticTokenType::Number } else { return; @@ -549,25 +562,99 @@ impl Walk<'_> { /// 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()); + 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`: prefix segments are namespaces; the leaf is the - // type the whole path resolves to. + // 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 seg in prefix { - emit(seg.text_range(), plain(SemanticTokenType::Namespace), out); + 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 names: Vec = segments.iter().map(|t| Name::new(t.text())).collect(); let resolved = resolve_path_at(self.db, self.file, leaf.text_range().start(), &names, None); - // An unresolved qualified leaf is still a type, not a namespace. - let class = - classify::classify_resolved(&resolved).unwrap_or_else(|| plain(SemanticTokenType::Type)); + 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); } + /// 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 @@ -652,6 +739,24 @@ impl Walk<'_> { } } +/// 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 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 @@ -662,11 +767,11 @@ fn classify_token(token: &SyntaxToken) -> Option { 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)), + SyntaxKind::ATTRIBUTE | SyntaxKind::BLOCK_ATTRIBUTE => { + (matches!(kind, SyntaxKind::AT_AT | SyntaxKind::AT | SyntaxKind::WORD) + || kind.is_keyword()) + .then_some(plain(SemanticTokenType::Decorator)) + } SyntaxKind::CLIENT_TYPE => word.then_some(plain(SemanticTokenType::Type)), SyntaxKind::CONFIG_ITEM => { (kind.is_keyword() || word).then_some(plain(SemanticTokenType::Property)) @@ -691,6 +796,12 @@ fn classify_token(token: &SyntaxToken) -> Option { 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)) } @@ -713,6 +824,12 @@ fn classify_token(token: &SyntaxToken) -> Option { .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, } } @@ -751,11 +868,6 @@ fn classify_type_decl_word(token: &SyntaxToken) -> Option { /// 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. -const PRIMITIVE_TYPES: &[&str] = &[ - "int", "bigint", "float", "string", "bool", "bytes", "uint8array", "null", "image", "audio", - "video", "pdf", "json", "map", "unknown", "never", -]; - /// Classify a type-expression name token. /// /// Resolves the name through the real resolver (the same path used by go-to-def), @@ -765,8 +877,8 @@ const PRIMITIVE_TYPES: &[&str] = &[ /// 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 PRIMITIVE_TYPES.contains(&name) { - return (SemanticTokenType::Type, ModifierSet::DEFAULT_LIBRARY); + 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 index 78afd81f09..ed1f8932cc 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs @@ -14,6 +14,49 @@ 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", + "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 @@ -48,7 +91,10 @@ pub(super) fn classify_resolved( definition_site, .. } => { let token_type = match definition_site { - Some(DefinitionSite::Parameter(_)) => SemanticTokenType::Parameter, + // 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, }; diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs index 9afd30408d..39876ae504 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs @@ -16,15 +16,14 @@ //! 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; -use std::sync::Arc; +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}, - resolve::{ResolvedName, resolve_name_at, resolve_path_at}, + resolve::{ResolvedName, resolve_name_at, resolve_namespace_prefix, resolve_path_at}, }; use text_size::{TextRange, TextSize}; @@ -128,8 +127,6 @@ fn index_function( inference: &ScopeInference<'_>, index: &mut ResolutionIndex, ) { - let ns = (SemanticTokenType::Namespace, ModifierSet::empty()); - for (expr_id, expr) in expr_body.exprs.iter() { match expr { Expr::Path(segments) if !segments.is_empty() => { @@ -137,13 +134,25 @@ fn index_function( // 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 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), - // Unresolved root of a dotted path => a package/namespace. - None if segments.len() > 1 => record(index, root_span, ns), + // 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 => {} } @@ -220,7 +229,13 @@ fn index_path_tail( let resolved = resolve_path_at(db, file, span.start(), &segments[0..=k], None); match classify::classify_resolved(&resolved) { Some(class) => record(index, span, class), - None => record(index, span, (SemanticTokenType::Namespace, ModifierSet::empty())), + // 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 d047483a29..8fb0ea383e 100644 --- a/baml_language/crates/baml_lsp2_actions/src/type_info.rs +++ b/baml_language/crates/baml_lsp2_actions/src/type_info.rs @@ -701,8 +701,8 @@ fn local_type_info( }) } - DefinitionSite::PatternBinding(_) => { - // Pattern bindings — report as local variable with unknown type for now. + DefinitionSite::PatternBinding(_) | DefinitionSite::CatchBinding(_) => { + // Pattern / catch bindings — report as local variable with unknown type for now. Some(TypeInfo::LocalVar { name: name.as_str().to_string(), ty: "unknown".to_string(), 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 1e15520204..be8110a31c 100644 --- a/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs +++ b/baml_language/crates/baml_lsp2_actions_tests/src/lib.rs @@ -7,3 +7,4 @@ 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 index 5da5cf6af5..83be845c7c 100644 --- 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 @@ -4,9 +4,10 @@ #[cfg(test)] mod tests { + use std::path::Path; + use baml_lsp2_actions::tokens::{semantic_tokens, semantic_tokens_in_range}; use baml_project::ProjectDatabase; - use std::path::Path; fn check(src: &str) { let mut db = ProjectDatabase::new(); 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/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/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 index 693d10bf7a..de376ef0b1 100644 --- 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 @@ -82,7 +82,7 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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" @@ -91,18 +91,20 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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) len=4 "baml" -// cancel_token.baml:15:14 (namespace) len=3 "sys" +// 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) len=4 "baml" -// cancel_token.baml:15:29 (namespace) len=4 "time" +// 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 "=" @@ -111,17 +113,18 @@ test "detached_spawn_completes" { // 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:27 (namespace) len=4 "baml" +// 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) len=6 "panics" +// 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -133,7 +136,7 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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" @@ -142,9 +145,10 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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" @@ -152,9 +156,9 @@ test "detached_spawn_completes" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -166,7 +170,7 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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" @@ -188,9 +192,9 @@ test "detached_spawn_completes" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -206,9 +210,10 @@ test "detached_spawn_completes" { // 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) len=4 "baml" +// 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" @@ -216,9 +221,9 @@ test "detached_spawn_completes" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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 index 1907ad07b1..7a6c2ac8ee 100644 --- 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 @@ -68,6 +68,7 @@ function CatchThenCatchAll(x: int) -> 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" @@ -79,6 +80,7 @@ function CatchThenCatchAll(x: int) -> 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" @@ -89,6 +91,7 @@ function CatchThenCatchAll(x: int) -> 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" @@ -102,7 +105,9 @@ function CatchThenCatchAll(x: int) -> 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 index e8728021bb..c2d5148a01 100644 --- 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 @@ -37,4 +37,5 @@ function Handled(x: int) -> 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/exhaustive.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/exhaustive.baml index 40e9f954d6..b460c1c3d4 100644 --- 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 @@ -84,21 +84,21 @@ function TypeAliasExhaustive(r: MyResult) -> string { // 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 (namespace) len=9 "Direction" +// exhaustive.baml:12:5 (enum) len=9 "Direction" // exhaustive.baml:12:14 (operator) len=1 "." -// exhaustive.baml:12:15 (type) len=5 "North" +// exhaustive.baml:12:15 (enumMember) len=5 "North" // exhaustive.baml:12:24 (string) len=7 "\"north\"" -// exhaustive.baml:13:5 (namespace) len=9 "Direction" +// exhaustive.baml:13:5 (enum) len=9 "Direction" // exhaustive.baml:13:14 (operator) len=1 "." -// exhaustive.baml:13:15 (type) len=5 "South" +// exhaustive.baml:13:15 (enumMember) len=5 "South" // exhaustive.baml:13:24 (string) len=7 "\"south\"" -// exhaustive.baml:14:5 (namespace) len=9 "Direction" +// exhaustive.baml:14:5 (enum) len=9 "Direction" // exhaustive.baml:14:14 (operator) len=1 "." -// exhaustive.baml:14:15 (type) len=4 "East" +// exhaustive.baml:14:15 (enumMember) len=4 "East" // exhaustive.baml:14:23 (string) len=6 "\"east\"" -// exhaustive.baml:15:5 (namespace) len=9 "Direction" +// exhaustive.baml:15:5 (enum) len=9 "Direction" // exhaustive.baml:15:14 (operator) len=1 "." -// exhaustive.baml:15:15 (type) len=4 "West" +// 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" @@ -108,9 +108,9 @@ function TypeAliasExhaustive(r: MyResult) -> string { // 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 (namespace) len=9 "Direction" +// exhaustive.baml:22:5 (enum) len=9 "Direction" // exhaustive.baml:22:14 (operator) len=1 "." -// exhaustive.baml:22:15 (type) len=5 "North" +// 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" @@ -121,9 +121,9 @@ function TypeAliasExhaustive(r: MyResult) -> string { // 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 (namespace) len=9 "Direction" +// exhaustive.baml:30:5 (enum) len=9 "Direction" // exhaustive.baml:30:14 (operator) len=1 "." -// exhaustive.baml:30:15 (type) len=5 "North" +// 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" 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 index 8d4008688e..27b22226f0 100644 --- 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 @@ -34,7 +34,9 @@ function read_name(p: Person) -> string { // 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" 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 index ac4c2bb83a..eca15b66cb 100644 --- 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 @@ -706,7 +706,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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" @@ -778,7 +778,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -880,7 +880,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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" @@ -901,7 +901,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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:187:5 (keyword) len=6 "return" -// interfaces_inferred_generic_type_args.baml:187:12 (namespace) len=7 "reflect" +// 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" @@ -980,7 +980,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -1096,7 +1096,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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" @@ -1116,7 +1116,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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:272:5 (keyword) len=6 "return" -// interfaces_inferred_generic_type_args.baml:272:12 (namespace) len=7 "reflect" +// 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" @@ -1144,7 +1144,6 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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:20 (namespace) len=7 "default" // 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" @@ -1184,7 +1183,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -1214,7 +1213,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=7 "reflect" +// 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" @@ -1249,7 +1248,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -1276,7 +1275,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=7 "reflect" +// 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" @@ -1292,7 +1291,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -1334,7 +1333,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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" @@ -1498,7 +1497,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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" @@ -1518,7 +1517,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=7 "reflect" +// 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" @@ -1580,7 +1579,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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\"" @@ -1612,7 +1611,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=7 "reflect" +// 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" @@ -1651,7 +1650,7 @@ test "interface_dispatch_sees_inferred_method_type_arg" { // 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) len=6 "assert" +// 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_sort_comparable.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/interfaces_sort_comparable.baml index d7fb4fb459..60269ff6f8 100644 --- 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 @@ -394,21 +394,21 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -435,28 +435,28 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -469,26 +469,31 @@ test "sort_user_class_out_of_body_impl" { // 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:43:5 (namespace) len=6 "assert" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -504,21 +509,21 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -535,37 +540,37 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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 (namespace) len=5 "float" +// 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) len=6 "assert" +// 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 (namespace) len=5 "float" +// 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) len=6 "assert" +// 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 (namespace) len=5 "float" +// 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 (namespace) len=5 "float" +// 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) len=6 "assert" +// 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 (namespace) len=5 "float" +// 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 (namespace) len=5 "float" +// 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" @@ -585,7 +590,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=4 "baml" +// 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" @@ -607,7 +612,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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" @@ -618,7 +623,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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" @@ -629,7 +634,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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" @@ -650,7 +655,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=4 "baml" +// 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" @@ -692,7 +697,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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" @@ -702,6 +707,7 @@ test "sort_user_class_out_of_body_impl" { // 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 "<" @@ -723,10 +729,11 @@ test "sort_user_class_out_of_body_impl" { // interfaces_sort_comparable.baml:128:79 (keyword) 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 (variable) len=1 "e" +// 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) len=6 "assert" +// 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" @@ -789,14 +796,14 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -815,14 +822,14 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -846,9 +853,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -868,9 +875,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -879,14 +886,20 @@ test "sort_user_class_out_of_body_impl" { // 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:187:5 (namespace) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -916,9 +929,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -930,25 +943,25 @@ test "sort_user_class_out_of_body_impl" { // 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 (namespace) len=5 "float" +// 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) len=6 "assert" +// 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) len=4 "baml" +// 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -964,13 +977,13 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=6 "assert" +// 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" @@ -983,7 +996,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=4 "baml" +// 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" @@ -1041,7 +1054,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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 "==" @@ -1062,9 +1075,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -1112,9 +1125,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -1150,10 +1163,11 @@ test "sort_user_class_out_of_body_impl" { // 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 (variable) len=1 "e" +// 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) len=6 "assert" +// 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" @@ -1185,9 +1199,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -1208,12 +1222,13 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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 "==" @@ -1243,9 +1258,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -1259,7 +1274,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=4 "baml" +// 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 ">" @@ -1267,7 +1282,7 @@ test "sort_user_class_out_of_body_impl" { // 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 (namespace) len=1 "U" +// 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" @@ -1297,9 +1312,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -1315,7 +1330,7 @@ test "sort_user_class_out_of_body_impl" { // 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) len=4 "baml" +// 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" @@ -1369,9 +1384,9 @@ test "sort_user_class_out_of_body_impl" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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/iterator.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/iterator.baml index 3201a29c9c..acea5406be 100644 --- 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 @@ -16,9 +16,9 @@ function DoubleAll() -> baml.iter.Iterator throws nev // 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) len=4 "baml" +// iterator.baml:2:29 (namespace) [defaultLibrary] len=4 "baml" // iterator.baml:2:33 (operator) len=1 "." -// iterator.baml:2:34 (namespace) len=4 "iter" +// 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 "<" @@ -36,9 +36,9 @@ function DoubleAll() -> baml.iter.Iterator throws nev // 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) len=4 "baml" +// iterator.baml:6:25 (namespace) [defaultLibrary] len=4 "baml" // iterator.baml:6:29 (operator) len=1 "." -// iterator.baml:6:30 (namespace) len=4 "iter" +// 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 "<" @@ -51,8 +51,8 @@ function DoubleAll() -> baml.iter.Iterator throws nev // 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) len=4 "baml" -// iterator.baml:7:8 (namespace) len=4 "iter" +// 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" 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 index a24009b7e8..75811bf3c0 100644 --- 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 @@ -40,12 +40,12 @@ function match_parsed(s: string) -> string { // 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:5:22 (namespace) len=4 "json" +// 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:6:8 (namespace) len=4 "json" +// 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" @@ -57,12 +57,12 @@ function match_parsed(s: string) -> string { // 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:10:22 (namespace) len=4 "json" +// 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:11:8 (namespace) len=4 "json" +// 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" @@ -74,8 +74,8 @@ function match_parsed(s: string) -> string { // 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:15:22 (namespace) len=4 "json" +// 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" @@ -83,8 +83,8 @@ function match_parsed(s: string) -> string { // 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:17:29 (namespace) 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" @@ -94,8 +94,8 @@ function match_parsed(s: string) -> string { // 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) len=4 "baml" -// json_parse_stringify_intrinsics.baml:18:38 (namespace) len=4 "json" +// 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" 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 index 94e1b99921..3fe05dc540 100644 --- 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 @@ -81,7 +81,7 @@ function gray(text: string) -> string { // 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 (namespace) 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." @@ -93,8 +93,8 @@ function gray(text: string) -> string { // 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) len=4 "baml" -// ns_ansi.baml:16:17 (namespace) len=3 "env" +// 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" 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 index b6667cd5d1..0e141e1a49 100644 --- 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 @@ -339,7 +339,7 @@ function double() -> void { // 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) len=3 "log" +// 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/patterns_new.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml index 2950378033..c1eb1b91a4 100644 --- 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 @@ -693,6 +693,7 @@ class PatternMatrix { // 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" @@ -706,6 +707,7 @@ class PatternMatrix { // 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" @@ -719,6 +721,7 @@ class PatternMatrix { // 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" 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 index 34ecbd94c7..4dc017c1e9 100644 --- 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 @@ -94,9 +94,9 @@ function call_stream_inferred() -> baml.llm.Stream { // 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) len=4 "baml" +// 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) len=3 "llm" +// 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 "<" @@ -105,8 +105,8 @@ function call_stream_inferred() -> baml.llm.Stream { // 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) len=4 "baml" -// stream_llm_inferred_typeargs.baml:37:10 (namespace) len=3 "llm" +// 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\"" 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 index 02f827f0cc..744bc42b8a 100644 --- 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 @@ -83,7 +83,7 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -93,72 +93,80 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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) len=4 "baml" -// task_group.baml:13:61 (namespace) len=3 "sys" +// 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) len=4 "baml" -// task_group.baml:13:76 (namespace) len=4 "time" +// 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) len=4 "baml" +// 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) len=4 "baml" -// task_group.baml:14:61 (namespace) len=3 "sys" +// 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) len=4 "baml" -// task_group.baml:14:76 (namespace) len=4 "time" +// 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) len=4 "baml" +// 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) len=4 "baml" -// task_group.baml:15:61 (namespace) len=3 "sys" +// 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) len=4 "baml" -// task_group.baml:15:76 (namespace) len=4 "time" +// 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) len=4 "baml" +// 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) len=4 "baml" -// task_group.baml:16:61 (namespace) len=3 "sys" +// 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) len=4 "baml" -// task_group.baml:16:76 (namespace) len=4 "time" +// 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" @@ -177,9 +185,9 @@ test "set_limit_updates_limit" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -190,7 +198,7 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -200,9 +208,10 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -211,9 +220,10 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -222,9 +232,10 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -233,9 +244,10 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -244,9 +256,10 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -266,9 +279,9 @@ test "set_limit_updates_limit" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -280,7 +293,7 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -290,18 +303,20 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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) len=4 "baml" -// task_group.baml:45:61 (namespace) len=3 "sys" +// 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) len=4 "baml" -// task_group.baml:45:76 (namespace) len=4 "time" +// 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 "=" @@ -310,17 +325,18 @@ test "set_limit_updates_limit" { // 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:27 (namespace) len=4 "baml" +// 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) len=6 "panics" +// 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) len=6 "assert" +// 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) len=4 "baml" +// 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" @@ -331,7 +347,7 @@ test "set_limit_updates_limit" { // 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) len=4 "baml" +// 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" @@ -350,9 +366,9 @@ test "set_limit_updates_limit" { // 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) len=6 "assert" +// 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) len=4 "baml" +// 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/testset.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/testset.baml index c7bc8cb95a..b9ee19914f 100644 --- 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 @@ -42,7 +42,7 @@ testset "doubling" { // 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) len=6 "assert" +// 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" @@ -59,7 +59,7 @@ testset "doubling" { // 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) len=6 "assert" +// 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" 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 index 02f78b2b1a..998d6a11b6 100644 --- 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 @@ -151,8 +151,8 @@ function ClassifySentiment2(text: string) -> string { // 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) len=4 "baml" -// testset_vibes_nested.baml:29:28 (namespace) len=4 "http" +// 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 "+" @@ -179,7 +179,7 @@ function ClassifySentiment2(text: string) -> string { // 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) len=6 "assert" +// 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" @@ -216,7 +216,7 @@ function ClassifySentiment2(text: string) -> string { // 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) len=6 "assert" +// 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" 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 index 8322d03c27..f7f94e55f8 100644 --- 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 @@ -33,7 +33,7 @@ function use_with_as_identifiers() -> int { // 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) len=7 "testing" +// 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" @@ -41,7 +41,7 @@ function use_with_as_identifiers() -> int { // 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) len=6 "assert" +// 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." 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 e1507bddcd..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 @@ -363,14 +363,12 @@ impl BexLspRequest for BexMulitProject { let result_id = self.cache_semantic_tokens(&path, new_tokens.clone()); 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), - }, - ), - )), + 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), @@ -962,7 +960,9 @@ fn diff_semantic_tokens( 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] + while s < prev.len() - p + && s < new.len() - p + && prev[prev.len() - 1 - s] == new[new.len() - 1 - s] { s += 1; } diff --git a/baml_language/crates/tools_semantic_tokens/src/server.rs b/baml_language/crates/tools_semantic_tokens/src/server.rs index 607d767500..c423517115 100644 --- a/baml_language/crates/tools_semantic_tokens/src/server.rs +++ b/baml_language/crates/tools_semantic_tokens/src/server.rs @@ -6,7 +6,10 @@ use std::{ path::{Path, PathBuf}, - sync::{Arc, atomic::{AtomicBool, Ordering}}, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, time::SystemTime, }; diff --git a/baml_language/crates/tools_semantic_tokens/src/staleness.rs b/baml_language/crates/tools_semantic_tokens/src/staleness.rs index 2c93cc528e..221ac6cc0a 100644 --- a/baml_language/crates/tools_semantic_tokens/src/staleness.rs +++ b/baml_language/crates/tools_semantic_tokens/src/staleness.rs @@ -8,7 +8,10 @@ use std::{ path::Path, - sync::{Arc, atomic::{AtomicBool, Ordering}}, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, time::{Duration, SystemTime, UNIX_EPOCH}, }; @@ -51,7 +54,10 @@ fn newest_under(dir: &Path, newest: &mut Option) { 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")) { + } 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); From beb3a0c5c8818088399b462d6da00d23aeddb072 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Mon, 29 Jun 2026 09:06:34 +0900 Subject: [PATCH 13/17] fix(lsp): address CodeRabbit review on PR #3867 - builder.rs (tir): drop redundant InterfaceMethod resolution that is always clobbered by InterfaceDefaultMethod in the same iteration - ast.rs: ObjectField::key() accepts KW_CLIENT (client-named object fields) - definition.rs + item_tree/builder (hir): interface member go-to-def jumps to the member, not the interface header (interface field/method span plumbing mirroring the class-field/enum-variant pattern) + regression tests - tokens/index.rs: normalize the range-path resolution cache key to the inference-owner scope so sibling block/template scopes share one entry - viewer (tools_semantic_tokens): surface fixture load failures instead of empty results; count text-only snapshot drift as a diff; escape fixture names in HTML attributes; discard stale /api/tokens responses; clear state on load failure; re-enable Accept after a failed save; clamp port scan to u16::MAX; reject symlinked fixtures; watch the compiler crates - requires_clause fixture: exercise the transitive requires-chain member Skipped 5 stale/incorrect comments (classifier emits no token for the cited positions, or the flagged sections are genuine auto-generated output). --- .../crates/baml_compiler2_hir/src/builder.rs | 1 + .../baml_compiler2_hir/src/item_tree.rs | 21 ++++++ .../crates/baml_compiler2_tir/src/builder.rs | 9 --- .../baml_compiler2_tir/src/inference.rs | 12 ++++ .../crates/baml_compiler_syntax/src/ast.rs | 2 +- .../baml_lsp2_actions/src/definition.rs | 46 ++++++++++--- .../src/definition_at_tests.rs | 64 +++++++++++++++++ .../baml_lsp2_actions/src/tokens/index.rs | 9 ++- .../semantic_tokens/requires_clause.baml | 69 +++++++++++-------- .../tools_semantic_tokens/src/analysis.rs | 40 +++++++---- .../tools_semantic_tokens/src/index.html | 66 +++++++++++++----- .../crates/tools_semantic_tokens/src/main.rs | 5 +- .../tools_semantic_tokens/src/server.rs | 22 ++++-- .../tools_semantic_tokens/src/staleness.rs | 5 +- 14 files changed, 283 insertions(+), 88 deletions(-) diff --git a/baml_language/crates/baml_compiler2_hir/src/builder.rs b/baml_language/crates/baml_compiler2_hir/src/builder.rs index 8d5fbdd8a5..2bc8916ac1 100644 --- a/baml_language/crates/baml_compiler2_hir/src/builder.rs +++ b/baml_language/crates/baml_compiler2_hir/src/builder.rs @@ -1429,6 +1429,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 30f361e127..7d264d46a1 100644 --- a/baml_language/crates/baml_compiler2_hir/src/item_tree.rs +++ b/baml_language/crates/baml_compiler2_hir/src/item_tree.rs @@ -408,6 +408,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 ───────────────────────────────────────────────────────────────── @@ -693,6 +698,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_tir/src/builder.rs b/baml_language/crates/baml_compiler2_tir/src/builder.rs index c3cce86884..1999dce694 100644 --- a/baml_language/crates/baml_compiler2_tir/src/builder.rs +++ b/baml_language/crates/baml_compiler2_tir/src/builder.rs @@ -12394,15 +12394,6 @@ impl<'db> TypeInferenceBuilder<'db> { continue; } let func_loc = baml_compiler2_hir::loc::FunctionLoc::new(db, file, fn_id); - if bound { - self.resolutions.insert( - at, - crate::inference::MemberResolution::InterfaceMethod { - iface_loc, - method_name: member.clone(), - }, - ); - } let sig = baml_compiler2_ppir::elaborated_function_signature(db, func_loc); // An exact receiver pins `Self` to its own type, not to a fresh // method generic, so suppress the unbound-reference generic there. diff --git a/baml_language/crates/baml_compiler2_tir/src/inference.rs b/baml_language/crates/baml_compiler2_tir/src/inference.rs index c14fde709d..7128457727 100644 --- a/baml_language/crates/baml_compiler2_tir/src/inference.rs +++ b/baml_language/crates/baml_compiler2_tir/src/inference.rs @@ -162,6 +162,18 @@ pub fn scope_body<'db>(db: &'db dyn crate::Db, scope_id: ScopeId<'db>) -> Option }) } +/// 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, diff --git a/baml_language/crates/baml_compiler_syntax/src/ast.rs b/baml_language/crates/baml_compiler_syntax/src/ast.rs index 5c7e04d58a..19150b377f 100644 --- a/baml_language/crates/baml_compiler_syntax/src/ast.rs +++ b/baml_language/crates/baml_compiler_syntax/src/ast.rs @@ -216,7 +216,7 @@ impl ObjectField { .children_with_tokens() .find(|element| !element.kind().is_trivia()) .and_then(rowan::NodeOrToken::into_token) - .filter(|token| token.kind() == SyntaxKind::WORD) + .filter(|token| matches!(token.kind(), SyntaxKind::WORD | SyntaxKind::KW_CLIENT)) } } diff --git a/baml_language/crates/baml_lsp2_actions/src/definition.rs b/baml_language/crates/baml_lsp2_actions/src/definition.rs index e16558859f..1514078fa0 100644 --- a/baml_language/crates/baml_lsp2_actions/src/definition.rs +++ b/baml_language/crates/baml_lsp2_actions/src/definition.rs @@ -423,15 +423,45 @@ fn resolve_field_access_at( range: *name_range, }) } - MemberResolution::InterfaceMethod { iface_loc, .. } - | MemberResolution::InterfaceField { iface_loc, .. } => { - // An interface member accessed on an interface-typed value: navigate - // to the declaring interface. - let def = baml_compiler2_hir::contributions::Definition::Interface(*iface_loc); - let (def_file, range) = utils::definition_span(db, def)?; + MemberResolution::InterfaceMethod { + iface_loc, + method_name, + } => { + // A required interface method accessed on an interface-typed value: + // navigate to the method signature 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 method_idx = iface + .required_methods + .iter() + .position(|m| m.name == *method_name)?; + let method_spans = target_source_map + .interface_method_spans + .get(&iface_loc.id(db))?; Some(Location { - file: def_file, - range, + file: target_file, + range: method_spans[method_idx], + }) + } + MemberResolution::InterfaceField { + iface_loc, + field_name, + } => { + // An interface field accessed on an interface-typed value: 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_name)?; + 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..491a93717d 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,68 @@ 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!( + desc.contains("-> fullname") && !desc.contains("-> Named"), + "Should navigate to interface field 'fullname', not the interface header, 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!( + desc.contains("-> encode") && !desc.contains("-> Serializer"), + "Should navigate to interface method 'encode', not the interface header, got: {desc}" + ); + } } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs index 39876ae504..a76bf3f30d 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/index.rs @@ -22,7 +22,7 @@ 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}, + 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}; @@ -60,7 +60,12 @@ pub(super) fn resolve_token_class( let mut fsi = sem_index.scope_at_offset(range.start(), None); loop { let scope_id = sem_index.scope_ids[fsi.index() as usize]; - if let Some(class) = scope_resolution_index(db, scope_id).get(&range).copied() { + // 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 { 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 index 0067071359..7d31b4c0a2 100644 --- 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 @@ -9,6 +9,10 @@ interface Person requires Named, Aged { function introduce(self) -> string { return self.name + ", " + self.occupation } + + function age_value(self) -> int { + return self.age + } } class Employee { @@ -64,35 +68,42 @@ function get_age(e: Employee) -> int { // 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:14:1 (keyword) len=5 "class" -// requires_clause.baml:14:7 (class) [declaration] len=8 "Employee" -// requires_clause.baml:15:3 (property) [declaration] len=4 "name" -// requires_clause.baml:15:9 (type) [defaultLibrary] len=6 "string" -// requires_clause.baml:16:3 (property) [declaration] len=3 "age" -// requires_clause.baml:16:8 (type) [defaultLibrary] len=3 "int" -// requires_clause.baml:17:3 (property) [declaration] len=10 "occupation" -// requires_clause.baml:17:15 (type) [defaultLibrary] len=6 "string" -// requires_clause.baml:18:3 (property) [declaration] len=6 "salary" -// requires_clause.baml:18:11 (type) [defaultLibrary] len=5 "float" -// requires_clause.baml:20:3 (keyword) len=10 "implements" -// requires_clause.baml:20:14 (interface) len=5 "Named" -// requires_clause.baml:21:3 (keyword) len=10 "implements" -// requires_clause.baml:21:14 (interface) len=4 "Aged" -// requires_clause.baml:22:3 (keyword) len=10 "implements" -// requires_clause.baml:22:14 (interface) len=6 "Person" -// requires_clause.baml:25:1 (keyword) len=8 "function" -// requires_clause.baml:25:10 (function) [declaration] len=8 "get_name" -// requires_clause.baml:25:19 (parameter) [declaration] len=1 "e" -// requires_clause.baml:25:22 (class) len=8 "Employee" -// requires_clause.baml:25:35 (type) [defaultLibrary] len=6 "string" -// requires_clause.baml:26:3 (keyword) len=6 "return" -// requires_clause.baml:26:10 (parameter) len=1 "e" -// requires_clause.baml:26:12 (property) len=4 "name" +// 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: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=7 "get_age" -// requires_clause.baml:29:18 (parameter) [declaration] len=1 "e" -// requires_clause.baml:29:21 (class) len=8 "Employee" -// requires_clause.baml:29:34 (type) [defaultLibrary] len=3 "int" +// 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=3 "age" +// 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/tools_semantic_tokens/src/analysis.rs b/baml_language/crates/tools_semantic_tokens/src/analysis.rs index ac1c1f6c78..19b8020021 100644 --- a/baml_language/crates/tools_semantic_tokens/src/analysis.rs +++ b/baml_language/crates/tools_semantic_tokens/src/analysis.rs @@ -204,7 +204,12 @@ pub(crate) fn load_fixture(path: &Path) -> std::io::Result { .values() .next() .map(|f| f.content.clone()) - .unwrap_or_default(); + .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 @@ -221,13 +226,26 @@ pub(crate) fn load_fixture(path: &Path) -> std::io::Result { } /// Number of tokens that differ between current and expected (changed type, -/// added, or removed) — keyed by (line, col, len), matching the snapshot. +/// 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); - // Signature = type + modifiers, so a modifier change registers as a diff. - let sig = |t: &Token| (t.ty.clone(), t.mods.clone()); - let cur: HashMap<_, _> = current.iter().map(|t| (key(t), sig(t))).collect(); - let exp: HashMap<_, _> = expected.iter().map(|t| (key(t), sig(t))).collect(); + // 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 { @@ -259,14 +277,12 @@ pub(crate) fn accept_fixture(path: &Path) -> anyhow::Result<()> { } /// List `*.baml` fixture file names in `dir`, sorted. -pub(crate) fn list_fixture_names(dir: &Path) -> Vec { - let mut names: Vec = fs::read_dir(dir) - .into_iter() - .flatten() - .flatten() +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(); - names + Ok(names) } diff --git a/baml_language/crates/tools_semantic_tokens/src/index.html b/baml_language/crates/tools_semantic_tokens/src/index.html index 94990b3249..7cb8ed5921 100644 --- a/baml_language/crates/tools_semantic_tokens/src/index.html +++ b/baml_language/crates/tools_semantic_tokens/src/index.html @@ -294,22 +294,37 @@ // ── sidebar ────────────────────────────────────────────────────────── function renderList() { - const scratchRow = - ``; - const rows = fixtures - .map((f) => { - const cls = f.diff_count === 0 ? "same" : "different"; - const label = f.diff_count === 0 ? "Same" : `Diff ${f.diff_count}`; - const sel = selected === f.name ? "selected" : ""; - return ( - `` - ); - }) - .join(""); - listEl.innerHTML = scratchRow + rows; + const makeRow = (dataName, label, badgeText, badgeClass, isSelected) => { + const button = document.createElement("button"); + button.type = "button"; + button.className = `row ${isSelected ? "selected" : ""}`.trim(); + button.dataset.name = dataName; + button.title = label; + + const nameEl = document.createElement("span"); + nameEl.className = "row-name"; + nameEl.textContent = label; + + const badge = document.createElement("span"); + badge.className = `badge ${badgeClass}`.trim(); + badge.textContent = badgeText; + + button.append(nameEl, badge); + return button; + }; + + listEl.replaceChildren( + makeRow(SCRATCH, "Scratchpad", "live", "", selected === SCRATCH), + ...fixtures.map((f) => + makeRow( + f.name, + f.name, + f.diff_count === 0 ? "Same" : `Diff ${f.diff_count}`, + f.diff_count === 0 ? "same" : "different", + selected === f.name, + ), + ), + ); } // ── inspector + legend ─────────────────────────────────────────────── @@ -411,20 +426,25 @@ clearTimeout(scratchTimer); scratchTimer = setTimeout(renderScratch, 250); } + let scratchRequestId = 0; async function renderScratch() { + const source = scratchText; + const requestId = ++scratchRequestId; try { const res = await getJson("/api/tokens", { method: "POST", headers: { "content-type": "application/json" }, - body: JSON.stringify({ source: scratchText }), + body: JSON.stringify({ source }), }); + if (requestId !== scratchRequestId || source !== scratchText) return; scratchTokens = res.tokens.map((t) => ({ ...t, diff: null })); } catch { + if (requestId !== scratchRequestId || source !== scratchText) return; scratchTokens = []; } if (selected !== SCRATCH) return; const out = document.getElementById("scratchOut"); - if (out) out.innerHTML = renderTokens(scratchText, scratchTokens, "scratch"); + if (out) out.innerHTML = renderTokens(source, scratchTokens, "scratch"); } // ── selection ──────────────────────────────────────────────────────── @@ -440,7 +460,16 @@ try { detail = await getJson(`/api/fixture?name=${encodeURIComponent(name)}`); } catch (e) { + if (selected !== name) return; + detail = null; + curMap = new Map(); + expMap = new Map(); + panesEl.className = "panes single"; panesEl.innerHTML = `
${esc(String(e))}
`; + statusEl.textContent = "Load failed"; + statusEl.className = "status"; + acceptEl.disabled = true; + renderInspect(null); return; } if (selected !== name) return; @@ -466,6 +495,7 @@ await select(selected); } catch (e) { statusEl.textContent = `Accept failed: ${e}`; + acceptEl.disabled = selected === SCRATCH; } }); diff --git a/baml_language/crates/tools_semantic_tokens/src/main.rs b/baml_language/crates/tools_semantic_tokens/src/main.rs index d1bda610b4..d782de3e80 100644 --- a/baml_language/crates/tools_semantic_tokens/src/main.rs +++ b/baml_language/crates/tools_semantic_tokens/src/main.rs @@ -85,14 +85,13 @@ async fn main() -> Result<()> { /// Bind to `base`, falling back to the next free port within a small range. async fn bind(base: u16) -> Result<(TcpListener, u16)> { - for offset in 0..50 { - let port = base + offset; + 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 + 50) + anyhow::bail!("no free port in {base}..={}", base.saturating_add(49)) } /// Best-effort open the default browser; failure is silently ignored. diff --git a/baml_language/crates/tools_semantic_tokens/src/server.rs b/baml_language/crates/tools_semantic_tokens/src/server.rs index c423517115..b898fabde9 100644 --- a/baml_language/crates/tools_semantic_tokens/src/server.rs +++ b/baml_language/crates/tools_semantic_tokens/src/server.rs @@ -88,9 +88,10 @@ struct FixturesResponse { fixtures: Vec, } -async fn fixtures(State(state): State) -> Json { +async fn fixtures(State(state): State) -> Result, ApiError> { let dir = state.fixtures_dir.as_ref(); - let names = analysis::list_fixture_names(dir); + 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. @@ -115,9 +116,9 @@ async fn fixtures(State(state): State) -> Json { .collect() }); - Json(FixturesResponse { + Ok(Json(FixturesResponse { fixtures: summaries, - }) + })) } #[derive(Deserialize)] @@ -192,8 +193,19 @@ fn resolve_fixture(dir: &Path, name: &str) -> Result { 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); - if !path.is_file() { + 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 index 221ac6cc0a..65b56d2b69 100644 --- a/baml_language/crates/tools_semantic_tokens/src/staleness.rs +++ b/baml_language/crates/tools_semantic_tokens/src/staleness.rs @@ -31,12 +31,15 @@ pub(crate) fn build_id(started: Option) -> u64 { .map_or(0, |d| u64::try_from(d.as_millis()).unwrap_or(u64::MAX)) } -/// Newest mtime among the classifier (`baml_lsp2_actions`) and viewer sources. +/// 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 { From 76dc3689d62b8fabae7230fd3e7920bef86ce9c2 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Tue, 30 Jun 2026 01:27:04 +0900 Subject: [PATCH 14/17] fix(lsp): address follow-up CodeRabbit review on PR #3867 - classify.rs: add `void` to PRIMITIVE_TYPES so it highlights as a defaultLibrary builtin type like the other primitives (`type` is the KW_TYPE keyword, not a builtin type, so it is intentionally not added) - type_info.rs: resolve catch/pattern binding types in hover via the shared inference lookup (was always "unknown"), so hover agrees with completions - definition_at_tests.rs: assert the exact interface-declaration location (3:3 / 3:12) so the go-to-def tests can't pass on the alias/impl site - regenerate ns_game_clients, test_expr_throwing_body (void) and the hover_catch_binding fixture (resolved error-union type) --- .../src/definition_at_tests.rs | 14 ++++++++++---- .../baml_lsp2_actions/src/tokens/classify.rs | 1 + .../crates/baml_lsp2_actions/src/type_info.rs | 18 +++++++++++++++--- .../semantic_tokens/ns_game_clients.baml | 2 +- .../test_expr_throwing_body.baml | 2 +- .../test_files/syntax/hover/catch_binding.baml | 2 +- 6 files changed, 29 insertions(+), 10 deletions(-) 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 491a93717d..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 @@ -456,9 +456,12 @@ function ReadName(p: Person) -> string { .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("-> fullname") && !desc.contains("-> Named"), - "Should navigate to interface field 'fullname', not the interface header, got: {desc}" + desc.contains(":3:3 -> fullname"), + "Should navigate to the interface field declaration Named.fullname (3:3), got: {desc}" ); } @@ -487,9 +490,12 @@ function PickText(d: Data) -> string { .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("-> encode") && !desc.contains("-> Serializer"), - "Should navigate to interface method 'encode', not the interface header, got: {desc}" + 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/tokens/classify.rs b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs index ed1f8932cc..2c233b48cf 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens/classify.rs @@ -24,6 +24,7 @@ const PRIMITIVE_TYPES: &[&str] = &[ "bytes", "uint8array", "null", + "void", "image", "audio", "video", 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 73861d40d9..d9d0d3b95e 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,23 @@ fn local_type_info( }) } - DefinitionSite::PatternBinding(_) | DefinitionSite::CatchBinding(_) => { - // Pattern / catch bindings — report as local variable with unknown type for now. + DefinitionSite::PatternBinding(pat_id) | DefinitionSite::CatchBinding(pat_id) => { + // Resolve the binding type from inference (the same shared local-type + // lookup completions uses) so hover agrees with completion type info, + // rather than always reporting "unknown". + let func_scope_id = index.scope_ids[enclosing_func_scope.index() as usize]; + let inference = baml_compiler2_tir::inference::infer_scope_types(db, func_scope_id); + let ty_str = inference + .binding_type(pat_id) + .map(|ty| display_local_binding_ty(db, file, ty)) + .or_else(|| { + 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/test_files/semantic_tokens/ns_game_clients.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/ns_game_clients.baml index 0e141e1a49..f5358ae762 100644 --- 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 @@ -330,7 +330,7 @@ function double() -> void { // 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) len=4 "void" +// 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 "=" 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 index f452506351..60a9a21959 100644 --- 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 @@ -13,7 +13,7 @@ test "throwing body becomes failure" { //- 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) len=4 "void" +// 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" 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 // ``` From ecc17a60f15fc123286e1c261ef538f8c2e00aac Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Tue, 30 Jun 2026 02:03:52 +0900 Subject: [PATCH 15/17] fix: stow/doc compliance + consistent builtin `null` highlighting - stow.toml: approve `semantic` prefix for the tools namespace - Cargo.toml: register baml_lsp2_actions_tests as a workspace dependency; tools_semantic_tokens uses `{ workspace = true }` (stow validation) - tokens.rs: fix two public->private intra-doc links so `cargo doc` passes under `-D warnings` - tokens.rs: classify value-position `null` through the shared builtin classification (defaultLibrary `type`) so it matches its type position and every other builtin instead of reading as a keyword - regenerate semantic_tokens fixtures for the null change --- baml_language/Cargo.toml | 1 + baml_language/crates/baml_lsp2_actions/src/tokens.rs | 12 ++++++++---- .../semantic_tokens/interfaces_iter_core.baml | 2 +- .../semantic_tokens/interfaces_sort_comparable.baml | 4 ++-- .../test_files/semantic_tokens/json_map_literal.baml | 2 +- .../test_files/semantic_tokens/lambda_advanced.baml | 4 ++-- .../semantic_tokens/method_explicit_type_args.baml | 2 +- .../crates/tools_semantic_tokens/Cargo.toml | 5 +---- baml_language/stow.toml | 2 +- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/baml_language/Cargo.toml b/baml_language/Cargo.toml index 99e5f521fc..f377105ec6 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" } diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens.rs b/baml_language/crates/baml_lsp2_actions/src/tokens.rs index 82239bc9e8..f8299b118b 100644 --- a/baml_language/crates/baml_lsp2_actions/src/tokens.rs +++ b/baml_language/crates/baml_lsp2_actions/src/tokens.rs @@ -8,7 +8,7 @@ //! positions and these non-name tokens. //! //! - **Identifiers inside expression bodies** are classified by what they -//! *resolve to*, via a pre-built resolution index ([`index`]) keyed by exact +//! *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. @@ -345,7 +345,7 @@ pub fn semantic_tokens(db: &dyn Db, file: SourceFile) -> Vec { /// 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 +/// `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. @@ -467,14 +467,18 @@ impl Walk<'_> { } // Boolean / null literals: a dedicated `KW_TRUE`/`KW_FALSE`/`KW_NULL` // token (value position, re-lexed by the parser). `true`/`false` -> - // `boolean`, `null` -> `keyword`. + // `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 => { - emit(token.text_range(), plain(SemanticTokenType::Keyword), out); + let class = classify::classify_primitive(token.text()) + .unwrap_or_else(|| plain(SemanticTokenType::Keyword)); + emit(token.text_range(), class, out); return; } _ => {} 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 index 1e1c6e4491..20d0408511 100644 --- 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 @@ -871,7 +871,7 @@ class Chain { // 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 (keyword) len=4 "null" +// 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 "<" 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 index 60269ff6f8..b0505d2473 100644 --- 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 @@ -726,7 +726,7 @@ test "sort_user_class_out_of_body_impl" { // 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 (keyword) len=4 "null" +// 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" @@ -1152,7 +1152,7 @@ test "sort_user_class_out_of_body_impl" { // 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 (keyword) len=4 "null" +// 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" 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 index 941e03173a..e376e42a0c 100644 --- 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 @@ -22,4 +22,4 @@ function NestedMapLiteral() -> json { // 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 (keyword) len=4 "null" +// 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/lambda_advanced.baml b/baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml index 468aee3ac4..5353802249 100644 --- 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 @@ -630,7 +630,7 @@ function test_iife_inferred() -> int { // 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 (keyword) len=4 "null" +// 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" @@ -957,7 +957,7 @@ function test_iife_inferred() -> int { // 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 (keyword) len=4 "null" +// 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" 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 index d1e9bbea6b..23cb10452f 100644 --- 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 @@ -27,7 +27,7 @@ function use_method_type_args() -> int { // 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 (keyword) len=4 "null" +// 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" diff --git a/baml_language/crates/tools_semantic_tokens/Cargo.toml b/baml_language/crates/tools_semantic_tokens/Cargo.toml index 6a1e2a9dc9..08e6ed2c00 100644 --- a/baml_language/crates/tools_semantic_tokens/Cargo.toml +++ b/baml_language/crates/tools_semantic_tokens/Cargo.toml @@ -11,10 +11,7 @@ path = "src/main.rs" [dependencies] baml_lsp2_actions = { workspace = true } -# Reuses the inline-assertion test harness (parser / runner / updater) so the -# viewer computes the exact same token output the tests do, reads the committed -# `//- semantic_tokens` expectations, and "accepts" via the real UPDATE_EXPECT path. -baml_lsp2_actions_tests = { path = "../baml_lsp2_actions_tests" } +baml_lsp2_actions_tests = { workspace = true } baml_project = { workspace = true } anyhow = { workspace = true } axum = { workspace = true, features = [ "json" ] } 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" } From 9ce8b57cbd58c4056d5cf7b5646966507d3aebc4 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Tue, 30 Jun 2026 02:10:02 +0900 Subject: [PATCH 16/17] chore: remove ephemeral semantic-tokens design/gaps notes DESIGN.md and GAPS.md were working notes for the semantic-tokens rework. validate-markdown only allows README.md or whitelisted long-term docs, so drop them rather than whitelist throwaway notes. --- .../baml_lsp2_actions/src/tokens/DESIGN.md | 180 ------------------ .../baml_lsp2_actions/src/tokens/GAPS.md | 69 ------- 2 files changed, 249 deletions(-) delete mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md delete mode 100644 baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md b/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md deleted file mode 100644 index fd867b8574..0000000000 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/DESIGN.md +++ /dev/null @@ -1,180 +0,0 @@ -# Principled rust-analyzer-style semantic tokens — design & plan - -Target: the rust-analyzer highlighting architecture, faithfully, with the -prerequisite parser/AST changes it requires. No shortcuts. The 78 fixtures are -the behavior-preservation oracle at every step. - -## RA architecture (what we mirror) - -- `highlight(db, cfg, file, range: Option) -> Vec`. For a - range, root = `covering_element(range)`; else the whole file. -- `traverse`: one `preorder_with_tokens()` `WalkEvent::{Enter,Leave}` loop with a - small enter/leave **state stack**; per element, `range.intersect(elem).is_none() - -> continue`. Tokens classify **syntactically** (`highlight::token`: literals / - comments / punctuation(kind,parent_kind) / keyword(kind)). `ast::NameLike` nodes - classify **semantically** (`name_like -> NameClass/NameRefClass::classify -> - highlight_def`), then `skip_subtree()` so the inner ident token isn't re-done. -- Name bridge: `IdentClass::classify_token(token) = token.parent()` -> match - `ast::Name` (def site) | `ast::NameRef` (ref site). NameRef spine: `NameRef -> - PathSegment -> Path -> sema.resolve_path -> PathResolution -> Definition`. - `highlight_def(Definition) -> HlTag::Symbol(SymbolKind) + mods`. -- On-demand + memoized: each classify routes through `Semantics::analyze` (a - per-body `SourceAnalyzer`, source-to-def cache) and salsa-memoized - `InferenceResult::of(body)`. First token in a body pays inference; rest reuse. -- LSP: `full` (compute + cache by uri + result_id), `full/delta` (compute full + - diff token arrays), `range` (separate `highlight_range(frange)`). - -## Our analog (what we already have / map to) - -- Lossless CST (rowan) + `baml_compiler_syntax::ast` typed accessors = RA syntax - tree + `ast::*`. Event-buffer parser with `with_node`/`wrap_events_in_node`. -- `Semantics`/`SourceAnalyzer`/`InferenceResult::of` analog: `resolve_name_at` - (offset name res), `scope_body` (uniform scope->(ExprBody,source_map)), - `infer_scope_types` (salsa-memoized **per ScopeId** — our body-granularity - memo seam). No macros -> drop `descend_into_macros`/`Ranker` entirely. -- `Definition`/`highlight_def` = our `Resolution` + `classify.rs`. We do NOT copy - RA's 24-variant Definition; ours is small (class/enum/interface/function/method/ - field/variant/param/local/type-alias/assoc-type/client/test/...). - -## Prerequisite parser / AST changes (the foundation — do first, principled) - -These remove the corners the current classifier cuts (text-matching literals/ -keywords, positional structure recovery). - -**P1 — Real literal & contextual-keyword tokens (parser/lexer/SyntaxKind).** -- Add `KW_TRUE`, `KW_FALSE`, `KW_NULL` token kinds. `true`/`false`/`null` must be - syntactic, not text-matched (today bumped as WORD; recovered via `text==..` in - ast.rs:711/3906, parser.rs:6190/6024/7437). Mechanism: lexer keywords if BAML - reserves them, else uniform contextual remap at every literal site. Add to - `is_literal` (true/false/null) — they classify as `boolean`/`keyword`. -- Add a custom `boolean` semantic-token type (RA's `BoolLiteral`); `true`/`false` - -> `boolean`, `null` -> `keyword`/builtin. Wire legend + enum + paint.rs + viewer. -- Uniformly remap the remaining contextual keywords: `KW_AS` (`.as` cast, - `(T as I)`, `field as field`), `KW_TYPE` (assoc-type / type-alias) — today - bumped as plain WORD and re-detected by `text=="as"`/`"type"`. After remap, - `is_keyword` sees them and resolution stops string-matching. -- Reconcile `is_operator` (drop phantom `QUESTION_QUESTION`, add real compound - assigns / single `QUESTION` / etc. that the parser actually emits) and add - `HEADER_COMMENT` to `is_trivia`. - -**P2 — Typed AST union enums + wrappers (baml_compiler_syntax/src/ast.rs, -accessor-only; CST already supports unless noted).** The classifier must read -structure off `ast::*`, not positionally. -- `ast::Expr` union enum (the core RA pattern) + `ast::Pattern`, `ast::Type` - unions so child-expr accessors return typed nodes (today `FieldAccessExpr::base`, - control-flow accessors return raw `SyntaxNode`). -- Wrappers + accessors: `ObjectLiteral` (`type_name()`/`path()` + `fields()`), - `ObjectField` (`key()`/`value()`), `CallExpr` (`callee()`+`args()`) + `CallArgs`, - `BinaryExpr` (`lhs()`/`op_token()`/`rhs()`), `SpawnExpr` (`name_expr()`/`body()`), - `AwaitExpr`, give `UpcastExpr` real `base()`/`target_type()`, `GenericArgs`/ - `TypeArgs` (`args()`/`named_bindings()`), `TypeExpr::path_segments()` (mirror of - `PathExpr::segments`), `GeneratorDef`/`TestsetDef`/`TestExprDef` (`name()`) + - extend the `Item` enum, pattern wrappers (BINDING/DESTRUCTURE/FIELD/ARRAY/TYPE/ - WILDCARD/UNION/CHAIN). Lower-pri: Array/Map/Index/Lambda/Paren/Tagged/Is/Unary. -- Resolve the object-literal-generic-head mismatch: `Foo {}` head is emitted - as `PATH_EXPR` not `TYPE_ARGS` — normalize in parser or expose via ObjectLiteral. -- Def-vs-ref: our CST has no `ast::Name`/`ast::NameRef` split; classify by the - identifier token's **parent node kind** (decl node -> def site; path/member/type - -> ref site). No grammar change needed for this. -- (Lower-pri) `parse_generator` opaque body leaves interior strings un-noded. - -## P1 finding (2026-06): token-kind remap has a broad blast radius - -Re-lexing `true`/`false`/`null` from `WORD` to `KW_TRUE`/`KW_FALSE`/`KW_NULL` -(the principled form) compiles + passes the compiler logic tests, but ripples -into **every consumer keyed on the token kind**: hover (`on_hover` iterator -inference tests changed — hover resolves off the token), CST/parser/formatter -snapshots (`baml_tests` config_dictionary/json_map_literal), etc. So the -remap is NOT highlighter-local; it requires mapping and updating hover / -completions / definition / formatter / lowering and regenerating their -snapshots. **Deferred** until that full consumer map is done (a fan-out search). -For now the `boolean` token type is delivered via a transitional text match in -`tokens.rs::token` (true/false -> `boolean`, null -> `keyword`); the inert -`KW_*` kinds + `is_ident_token`/`is_keyword` additions are already in place, -ready for the proper remap. `as`/`type` highlighting already works via the -existing context handlers, so the remap is a *mechanism* upgrade, not a feature. - -**`as`/`type` remap also confirmed broad (attempted + reverted):** remapping the -5 `as`/`type` bump sites to `KW_AS`/`KW_TYPE` (and making `classify_token` read -the kinds) compiled and kept the 78 fixtures green, but broke compiler lowering -— `baml_compiler2_ast` `function_type_throws_preserves_omission_vs_explicit_never` -started emitting a spurious "type alias" diagnostic (the type-alias path keys on -the `type` token). So BOTH parser-token remaps (true/false/null AND as/type) are -deferred on the same evidence-based cost/benefit: they ripple into hover / -lowering / formatter / CST snapshots for a highlighter-purity-only gain, while -`classify_token`'s contextual disambiguation (the `as`/`type`/`true`/`false` -checks are scoped to a known parent node, not free substring scanning) is correct -and reasonable. Doing the remap properly means mapping + updating every -token-kind consumer first (a dedicated fan-out), not a highlighter-local change. - -## Revised sequencing: architecture first, parser-token remap as a mapped follow-up - -The RA *system* (Phases B/C/D) is LSP-only — no parser change, no broad -fallout — and is the high-value core. Do it first; do the broad parser-token -remap (P1 full) afterward as a carefully-mapped change. - -## Status (2026-06) - -DELIVERED + committed + validated (PR #3867): -- **B (on-demand resolution):** `scope_resolution_index` — per-`ScopeId` - salsa-cached resolution index (RA body-granularity memo; editing one scope - invalidates only its index). `build` merges them for a full document; - `resolve_token_class` resolves one name on demand (RA `Semantics::resolve`), - walking the scope chain. The `Walk` is parameterized by a `resolve` closure. -- **D (scaling):** `semantic_tokens_in_range` (RA `highlight_range`) — range-gated - walk, resolves only the scopes the viewport touches; proven equal to - full-filtered-to-range across every sub-range (`range_tokens_test`). LSP: - `semanticTokens/range` + `full/delta` advertised + wired (per-file token cache, - monotonic `result_id`, prefix/suffix token-granularity diff; diff unit-tested). -- **A1 (boolean):** `true`/`false` -> `boolean` token type; inert KW_* token - foundation laid. - -IN PROGRESS: -- **C (flat preorder traversal) + A2 (typed accessors):** rewriting the recursive - `Walk` into one `preorder_with_tokens()` loop + `classify_token` parent-kind - dispatch reading typed `ast::*` accessors. Behavior-preserving (78 fixtures + - range test are the oracle). - -DELIVERED — parser-token remaps (both done, with every consumer updated): -- **`as`/`type` -> KW_AS/KW_TYPE** and **`true`/`false`/`null` -> - KW_TRUE/KW_FALSE/KW_NULL** at the value/decl parse sites. The classifier now - reads every literal and keyword by kind — there is NO remaining text match in - the classifier. Consumers updated: ast.rs (TypeAliasDef::name, the `as` - checks, the block tail-expression accessor — a trailing `false`/`true`/`null` - is the block value, else E0029), baml_fmt (TypeKw/As keyword tokens + - KeywordLiteral for bool/null), the lsp classifier (kind-based). 67 parser CST - snapshots regenerated (mechanical WORD -> KW_*; the meta-type value `type` and - type-position literal types correctly stay WORD, handled by `type_run`). - Validated end to end: lsp 440/440, compiler2_ast 73/73, baml_tests 2661/2665 - (the 4 generic_arg_soundness failures are a pre-existing TIR generics gap, - fail on base). The blast-radius cost (hover/lowering/formatter/snapshots) was - real but was the work, not a reason to defer — every consumer was mapped and - fixed. - -REMAINING (niche, reasonable as-is): type-position boolean/null literal *types* -(`x: true`) stay bare WORDs, classified by `type_run` as types — re-lexing them -would touch type-parsing + type-check consumers for a niche gain. - -## Phases (each ends green: 78 fixtures unchanged unless the change is the point) - -- **A. Parser/AST prerequisites (P1 then P2).** Land literal/keyword tokens + - `is_*` fixes (update walker to read new kinds; output preserved except - true/false -> `boolean`). Then land typed-AST union enums + wrappers (additive; - no classifier change yet). -- **B. `Semantics` bridge (`resolve_token`).** token -> parent-kind dispatch -> - Resolution (root via `resolve_name_at`; member via `scope_body`+inference; - qualified via `resolve_path_at`; type via type res) -> classify. On-demand, - reusing `infer_scope_types` memo. Validate equals the current index per-token. -- **C. Flat traversal.** Replace recursive `node()`/handlers with one - `preorder_with_tokens()` loop: syntactic token classify + `resolve_token` for - names, reading context off the new typed-AST accessors; range-gate ready. Drop - `index::build`. Validate fixtures unchanged. -- **D. LSP scaling.** Range (`covering_element` + range-gated walk; advertise + - handler). Delta (stable `result_id` + per-uri encoded-token cache + prefix/ - suffix diff; advertise `Delta{delta:true}`). Unify position encoding. - -## Validation discipline -Every slice: `cargo check` the touched crates; run the 78 `semantic_tokens` -fixtures WITHOUT `UPDATE_EXPECT` (must stay green, except the deliberate -true/false->boolean change); run tir/mir + runtime interface tests after any -parser/inference change; clippy clean. Adversarial review at each phase boundary. diff --git a/baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md b/baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md deleted file mode 100644 index 3470c6d2f3..0000000000 --- a/baml_language/crates/baml_lsp2_actions/src/tokens/GAPS.md +++ /dev/null @@ -1,69 +0,0 @@ -# Semantic tokens — known gaps & next steps - -Status snapshot of the semantic-tokens classifier (`tokens.rs` + `tokens/index.rs` -+ `tokens/classify.rs`). Architecture mirrors rust-analyzer: walk the lossless -CST for token positions + syntactic tokens (keywords/operators/punctuation), -resolve identifier *meaning* through the HIR/inference. Keywords are a parser -concern (contextual keywords like `with` are re-lexed to `KW_*`, read by kind). - -## Scaling — "do what rust-analyzer does" (highest priority) - -Today the classifier always does **whole-file** work: `index::build` resolves -every scope in the file regardless of what's requested. That's the scaling gap, -not the recursive-vs-iterative traversal style. - -Levers, in order of impact: - -1. **On-demand per-token resolution.** Rebuild a `resolve_token(file, token)` - bridge on top of `baml_compiler2_tir::inference::scope_body` (still present) - and have the walker resolve each name lazily — RA's `Semantics::resolve` - model. Drops the prebuilt whole-file index so a range request only pays for - visible tokens. (We built `resolve_token` earlier this effort, then removed - it once the index covered the cases — bring it back for scale.) -2. **Range / viewport highlighting** (`semanticTokens/range`). Take a range, - skip subtrees whose `text_range()` doesn't intersect it, wire the request in - `bex_project`. Works in the current recursive shape (early `return` on - out-of-range nodes). Biggest single win on large files. -3. **Delta encoding** (`semanticTokens/full/delta`) — emit only the token diff. -4. **(Optional) iterative traversal shape.** Replace the recursive `node()` - dispatch with one `preorder_with_tokens()` loop + match-on-kind/parent, like - RA's `traverse`. Same asymptotics; only buys stack-depth robustness and - convergence with RA. Do last, or never. - -Already have: salsa-cached query, lossless rowan CST, typed AST accessors, -`scope_body` (uniform scope→body lookup), per-scope inference. - -## Remaining feature items (from the highlighting punch-list) - -- **Optional function parameters at call site** — not yet investigated. -- **Boolean literals** — `true`/`false` are currently `keyword`. RA uses a - custom `boolean` semantic-token type (beyond the standard legend); add it to - the legend + enum + paint.rs + viewer color map and classify there. - -## Known resolution gaps / limitations - -- **Test / testset bodies.** `testset` is not lowered into the compiler2 IR - (absent from tir/hir/ppir); body code is classified only insofar as the scope - iteration reaches it. Verify coverage; may need the testset lowering wired up. -- **Interface-member go-to-def** navigates to the *interface declaration*, not - the specific member span. `MemberResolution::InterfaceMethod`/`InterfaceField` - carry only `iface_loc` + name (no `func_loc` for required methods). Refine to - the member span when desired. -- **Generic param *usages*** (the `T` in `v: T`, `T[]`) classify as `type` - (fallback), while *declarations* (`class Box`) are `typeParameter`. To make - usages `typeParameter`, resolve the name to the in-scope generic param. -- **Backtick-string escapes** are not split into `escapeSequence` tokens (only - regular + byte strings are). -- **Generator bodies** are parsed opaquely (deprecated); classified by shape - (name→struct, key→property, value tokens→string), not via real structure. - -## Principled fixes landed this effort (context) - -- Interface members now resolve like class members: `resolve_interface_member` - records `MemberResolution::InterfaceMethod`/`InterfaceField` - (`builder.rs`), so casts / `Self` methods / chained interface calls classify - through the normal path; typos stay neutral. MIR-safe (new variants → `None` - item-ref, fall through to existing interface dispatch). -- `scope_body` (tir): uniform scope→`(ExprBody, source_map)` covering function / - let / lambda (and spawn/block bodies that lower to closures) — the index walks - every inference-bearing scope, not just top-level functions. From 1d4bb1d01b5ebd2714d237d30236fa1196d6c5fc Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Tue, 30 Jun 2026 02:15:54 +0900 Subject: [PATCH 17/17] fix(lsp): resolve catch/pattern binding hover via the use-site scope chain CodeRabbit: PatId is body-local, so probing the enclosing function scope's inference first could pick up a same-index binding from another body for pattern/catch bindings inside closures or nested blocks, giving the wrong hover type. Use only the collision-safe find_binding_ty_in_scopes walk from the current scope chain. --- .../crates/baml_lsp2_actions/src/type_info.rs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) 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 d9d0d3b95e..0d60b1f4a5 100644 --- a/baml_language/crates/baml_lsp2_actions/src/type_info.rs +++ b/baml_language/crates/baml_lsp2_actions/src/type_info.rs @@ -702,18 +702,14 @@ fn local_type_info( } DefinitionSite::PatternBinding(pat_id) | DefinitionSite::CatchBinding(pat_id) => { - // Resolve the binding type from inference (the same shared local-type - // lookup completions uses) so hover agrees with completion type info, - // rather than always reporting "unknown". - let func_scope_id = index.scope_ids[enclosing_func_scope.index() as usize]; - let inference = baml_compiler2_tir::inference::infer_scope_types(db, func_scope_id); - let ty_str = inference - .binding_type(pat_id) - .map(|ty| display_local_binding_ty(db, file, ty)) - .or_else(|| { - find_binding_ty_in_scopes(db, index, scope_id, pat_id) - .map(|ty| display_local_binding_ty(db, file, &ty)) - }) + // 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(),