1pub mod capabilities;
8pub mod kit;
9mod parse_recovery;
10pub mod registry;
11mod storage;
12pub mod taxonomy;
13pub mod types;
14
15pub use capabilities::{
16 callable_reference_variants, CallTextPrefilter, CallableDeclarationFamily, CallableReferenceSyntax,
17 CapabilityLevel, LanguageCapabilities, ModulePathSyntax, ReceiverTypeSyntax, NO_CONSTRUCTOR_METHOD_NAMES,
18};
19pub use kit::{
20 alias_map_from_import_specs, alias_map_from_imports, apply_assign_call_result_types,
21 apply_call_receiver_types, apply_call_receiver_types_with_language_syntax,
22 apply_call_receiver_types_with_super_tokens, apply_class_field_type_aliases,
23 apply_constructor_result_type_aliases, apply_expression_value_kinds, apply_file_stem_semantic_identity,
24 apply_local_closure_captures, apply_module_path_semantic_identity, assignment_trace_message,
25 c_family_preproc_imports, collect_assign_targets, collect_constructor_result_type_aliases,
26 collect_modifier_visibility, collect_param_type_aliases, collect_receiver_field_initializers,
27 collect_return_spans, decl_index_from_tree_with_handler, decl_index_with_handler,
28 extend_alias_map_with_flow_events, extract_assignment_value_facts, extract_branch_condition_facts,
29 extract_call_argument_value_facts, extract_call_receiver_facts, extract_imports_via,
30 extract_runtime_type_narrowing_facts, for_each_flow_event, mark_namespace_call_receivers,
31 module_local_binding, normalize_call_result_assignment_sources, populate_decl_return_types,
32 qualify_implicit_member_assign_targets, qualify_implicit_member_reads_in_index,
33 qualify_receiver_field_expression_flows, rewrite_implicit_member_reads, tuple_result_projection_index,
34 AliasTarget, AssignmentNodeSemantics, CallTargetExtraction, ExpressionPlaceExtraction,
35 FunctionDefinitionExtraction, GrammarHandler, ImplicitMemberReadCall, ModifierVocabulary,
36 PatternBindingSite, PatternSourceProjection, ProjectedPatternBindingSite, SyntaxSpecialForm,
37 TypeAliasVocabulary, EMPTY_HANDLER, MODULE_DECL_NAME, WILDCARD_IMPORT_ALIAS_PREFIX,
38};
39pub use parse_recovery::{
40 branch_free_conditional_recovery_edits, c_family_declaration_macro_recovery_edits, syntax_damage_score,
41 ConditionalDirectiveSyntax, ParseRecoveryEdit,
42};
43pub use registry::{AdapterArc, LanguageRegistry};
44pub use taxonomy::{flow_edge_spec, FlowEdgeKind, FlowEdgeSpec, FlowEdgeSupport, FLOW_EDGE_TAXONOMY};
45pub use types::{
46 assignment_value_fact_for_span, assignment_value_rendering, branch_condition_fact_for_span,
47 call_argument_value_fact, call_receiver_fact_for_span, character_constraints_from_substitutions,
48 finite_literal_selection_for_assignment, operations_from_flow_events, AggregateLayout,
49 ArgumentPassingMode, AssignValueKind, AssignmentValueFact, AssignmentValueIndex, BranchConditionFact,
50 BranchConditionPolarity, CallArg, CallArgumentValueFact, CallKind, CallReceiverFact, CallReceiverRole,
51 CharacterClass, CharacterConstraintDomain, CharacterConstraintFact, CharacterConstraintOutput,
52 CharacterSubstitutionDomain, CharacterSubstitutionFact, Comment, CommentKind, CompilerAssignmentAlias,
53 CompilerAttribution, CompilerBrowseHeader, CompilerBrowseTermGroup, CompilerCallArgumentAttribution,
54 CompilerCallAttribution, CompilerCallHeader, CompilerFactoryCallAssignment, CompilerFunctionAttribution,
55 CompilerGuardFact, CompilerReturnHeader, CompilerSyntaxHeader, CompilerWriteAttribution,
56 ConditionEquality, ConditionExpressionFact, ConditionOperandFact, Decl, DeclIndex, DeclKind,
57 DynamicKeyFilterFact, ExpressionField, ExpressionFlow, ExpressionProjection, FieldWrite,
58 FiniteLiteralSelectionFact, FlowEvent, GuardedValueFilterFact, ImportIndex, ImportScope, ImportSpec,
59 LanguageId, LoopKind, MembershipConditionFact, ModulePath, Operation, OperationKind, OperationOperand,
60 OperationOperandRole, ReceiverFieldInitializer, Ref, RefKind, RuntimeTypeNarrowingFact,
61 SameOriginPathConstraintFact, StaticAggregateFieldValue, StaticScalarValue, StaticStringMapEntry,
62 StaticStringMapFact, StringCategory, StringCompositionFact, StringCompositionPart, StringLiteral,
63 TypeAliasBinding, UnsupportedConstruct, Visibility, WorkspaceRoot,
64 COMPILER_GUARD_RELATIVE_PATH_BOUNDARY_REJECTION,
65};
66
67use bonsai_common::FileId;
68use bonsai_diagnostics::DiagnosticSink;
69pub use bonsai_vfs::{FileSnapshot, Vfs};
70use parking_lot::RwLock;
71use std::sync::Arc;
72pub use tree_sitter::Tree as SyntaxTree;
73
74pub trait TreeProvider: Send + Sync {
81 fn tree_for_snapshot(&self, pack_name: &str, snapshot: &FileSnapshot) -> Option<Arc<SyntaxTree>>;
88}
89
90pub struct AdapterContext<'a> {
96 pub vfs: &'a Vfs,
97 pub diagnostics: &'a RwLock<DiagnosticSink>,
98 pub tree_provider: Option<&'a dyn TreeProvider>,
100 pub workspace_root: Option<&'a std::path::Path>,
107}
108
109impl<'a> AdapterContext<'a> {
110 pub fn emit(&self, diag: bonsai_diagnostics::Diagnostic) {
111 self.diagnostics.write().push(diag);
112 }
113
114 #[must_use]
119 pub fn workspace_relative_path(&self, file: bonsai_common::FileId) -> Option<std::path::PathBuf> {
120 let path = self.vfs.path(file).ok()?;
121 let root = self.workspace_root?;
122 path.strip_prefix(root).ok().map(std::path::Path::to_path_buf)
123 }
124}
125
126#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
130pub struct FragmentParseContext {
131 pub prefix: &'static str,
133 pub suffix: &'static str,
135}
136
137#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
140pub enum LanguageOwnershipEvidence {
141 Excluded,
144 #[default]
147 Unproven,
148 Proven,
151}
152
153impl LanguageOwnershipEvidence {
154 #[must_use]
155 pub const fn selection_rank(self) -> u8 {
156 match self {
157 Self::Excluded => 0,
158 Self::Unproven => 1,
159 Self::Proven => 2,
160 }
161 }
162}
163
164pub trait LanguageAdapter: Send + Sync + 'static {
169 fn language_id(&self) -> LanguageId;
172
173 fn display_name(&self) -> &'static str;
175
176 fn file_extensions(&self) -> &'static [&'static str];
178
179 fn tree_sitter_language(&self) -> Result<tree_sitter::Language, AdapterError>;
182
183 fn source_syntax_proves_language(
194 &self,
195 _snapshot: &FileSnapshot,
196 _tree: &SyntaxTree,
197 ) -> LanguageOwnershipEvidence {
198 LanguageOwnershipEvidence::Unproven
199 }
200
201 fn grammar_name_for_path(&self, _path: &std::path::Path) -> &'static str {
207 self.language_id().as_str()
208 }
209
210 fn tree_sitter_language_for_path(
214 &self,
215 path: &std::path::Path,
216 ) -> Result<tree_sitter::Language, AdapterError> {
217 let grammar = self.grammar_name_for_path(path);
218 if grammar == self.language_id().as_str() {
219 self.tree_sitter_language()
220 } else {
221 tree_sitter_language_pack::get_language(grammar)
222 .map_err(|error| AdapterError::GrammarUnavailable(format!("{grammar}: {error}")))
223 }
224 }
225
226 fn parse_recovery_edits(
238 &self,
239 _snapshot: &FileSnapshot,
240 _vfs: &Vfs,
241 _tree: &SyntaxTree,
242 ) -> Vec<ParseRecoveryEdit> {
243 Vec::new()
244 }
245
246 fn fragment_parse_context(&self) -> FragmentParseContext {
249 FragmentParseContext::default()
250 }
251
252 fn capabilities(&self) -> LanguageCapabilities;
255
256 fn discover_workspace_roots(&self, _files: &[FileId], _ctx: &AdapterContext<'_>) -> Vec<WorkspaceRoot> {
259 vec![WorkspaceRoot::default()]
260 }
261
262 fn extract_declarations(&self, file: FileId, ctx: &AdapterContext<'_>) -> DeclIndex;
264
265 fn extract_imports(&self, file: FileId, ctx: &AdapterContext<'_>) -> ImportIndex;
267
268 fn unsupported_constructs(&self, _file: FileId, _ctx: &AdapterContext<'_>) -> Vec<UnsupportedConstruct> {
270 Vec::new()
271 }
272}
273
274pub type DynAdapter = Arc<dyn LanguageAdapter>;
276
277#[derive(Debug, thiserror::Error)]
278pub enum AdapterError {
279 #[error("grammar not available: {0}")]
280 GrammarUnavailable(String),
281 #[error("parser setup failed: {0}")]
282 ParserSetup(String),
283 #[error("parse error: {0}")]
284 Parse(String),
285}