pub mod capabilities;
pub mod kit;
mod parse_recovery;
pub mod registry;
mod storage;
pub mod taxonomy;
pub mod types;
pub use capabilities::{
callable_reference_variants, CallTextPrefilter, CallableDeclarationFamily, CallableReferenceSyntax,
CapabilityLevel, LanguageCapabilities, ModulePathSyntax, ReceiverTypeSyntax, NO_CONSTRUCTOR_METHOD_NAMES,
};
pub use kit::{
alias_map_from_import_specs, alias_map_from_imports, apply_assign_call_result_types,
apply_call_receiver_types, apply_call_receiver_types_with_language_syntax,
apply_call_receiver_types_with_super_tokens, apply_class_field_type_aliases,
apply_constructor_result_type_aliases, apply_expression_value_kinds, apply_file_stem_semantic_identity,
apply_local_closure_captures, apply_module_path_semantic_identity, assignment_trace_message,
c_family_preproc_imports, collect_assign_targets, collect_constructor_result_type_aliases,
collect_modifier_visibility, collect_param_type_aliases, collect_receiver_field_initializers,
collect_return_spans, decl_index_from_tree_with_handler, decl_index_with_handler,
extend_alias_map_with_flow_events, extract_assignment_value_facts, extract_branch_condition_facts,
extract_call_argument_value_facts, extract_call_receiver_facts, extract_imports_via,
extract_runtime_type_narrowing_facts, for_each_flow_event, mark_namespace_call_receivers,
module_local_binding, normalize_call_result_assignment_sources, populate_decl_return_types,
qualify_implicit_member_assign_targets, qualify_implicit_member_reads_in_index,
qualify_receiver_field_expression_flows, rewrite_implicit_member_reads, tuple_result_projection_index,
AliasTarget, AssignmentNodeSemantics, CallTargetExtraction, ExpressionPlaceExtraction,
FunctionDefinitionExtraction, GrammarHandler, ImplicitMemberReadCall, ModifierVocabulary,
PatternBindingSite, PatternSourceProjection, ProjectedPatternBindingSite, SyntaxSpecialForm,
TypeAliasVocabulary, EMPTY_HANDLER, MODULE_DECL_NAME, WILDCARD_IMPORT_ALIAS_PREFIX,
};
pub use parse_recovery::{
branch_free_conditional_recovery_edits, c_family_declaration_macro_recovery_edits, syntax_damage_score,
ConditionalDirectiveSyntax, ParseRecoveryEdit,
};
pub use registry::{AdapterArc, LanguageRegistry};
pub use taxonomy::{flow_edge_spec, FlowEdgeKind, FlowEdgeSpec, FlowEdgeSupport, FLOW_EDGE_TAXONOMY};
pub use types::{
assignment_value_fact_for_span, assignment_value_rendering, branch_condition_fact_for_span,
call_argument_value_fact, call_receiver_fact_for_span, character_constraints_from_substitutions,
finite_literal_selection_for_assignment, operations_from_flow_events, AggregateLayout,
ArgumentPassingMode, AssignValueKind, AssignmentValueFact, AssignmentValueIndex, BranchConditionFact,
BranchConditionPolarity, CallArg, CallArgumentValueFact, CallKind, CallReceiverFact, CallReceiverRole,
CharacterClass, CharacterConstraintDomain, CharacterConstraintFact, CharacterConstraintOutput,
CharacterSubstitutionDomain, CharacterSubstitutionFact, Comment, CommentKind, CompilerAssignmentAlias,
CompilerAttribution, CompilerBrowseHeader, CompilerBrowseTermGroup, CompilerCallArgumentAttribution,
CompilerCallAttribution, CompilerCallHeader, CompilerFactoryCallAssignment, CompilerFunctionAttribution,
CompilerGuardFact, CompilerReturnHeader, CompilerSyntaxHeader, CompilerWriteAttribution,
ConditionEquality, ConditionExpressionFact, ConditionOperandFact, Decl, DeclIndex, DeclKind,
DynamicKeyFilterFact, ExpressionField, ExpressionFlow, ExpressionProjection, FieldWrite,
FiniteLiteralSelectionFact, FlowEvent, GuardedValueFilterFact, ImportIndex, ImportScope, ImportSpec,
LanguageId, LoopKind, MembershipConditionFact, ModulePath, Operation, OperationKind, OperationOperand,
OperationOperandRole, ReceiverFieldInitializer, Ref, RefKind, RuntimeTypeNarrowingFact,
SameOriginPathConstraintFact, StaticAggregateFieldValue, StaticScalarValue, StaticStringMapEntry,
StaticStringMapFact, StringCategory, StringCompositionFact, StringCompositionPart, StringLiteral,
TypeAliasBinding, UnsupportedConstruct, Visibility, WorkspaceRoot,
COMPILER_GUARD_RELATIVE_PATH_BOUNDARY_REJECTION,
};
use bonsai_common::FileId;
use bonsai_diagnostics::DiagnosticSink;
pub use bonsai_vfs::{FileSnapshot, Vfs};
use parking_lot::RwLock;
use std::sync::Arc;
pub use tree_sitter::Tree as SyntaxTree;
pub trait TreeProvider: Send + Sync {
fn tree_for_snapshot(&self, pack_name: &str, snapshot: &FileSnapshot) -> Option<Arc<SyntaxTree>>;
}
pub struct AdapterContext<'a> {
pub vfs: &'a Vfs,
pub diagnostics: &'a RwLock<DiagnosticSink>,
pub tree_provider: Option<&'a dyn TreeProvider>,
pub workspace_root: Option<&'a std::path::Path>,
}
impl<'a> AdapterContext<'a> {
pub fn emit(&self, diag: bonsai_diagnostics::Diagnostic) {
self.diagnostics.write().push(diag);
}
#[must_use]
pub fn workspace_relative_path(&self, file: bonsai_common::FileId) -> Option<std::path::PathBuf> {
let path = self.vfs.path(file).ok()?;
let root = self.workspace_root?;
path.strip_prefix(root).ok().map(std::path::Path::to_path_buf)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct FragmentParseContext {
pub prefix: &'static str,
pub suffix: &'static str,
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub enum LanguageOwnershipEvidence {
Excluded,
#[default]
Unproven,
Proven,
}
impl LanguageOwnershipEvidence {
#[must_use]
pub const fn selection_rank(self) -> u8 {
match self {
Self::Excluded => 0,
Self::Unproven => 1,
Self::Proven => 2,
}
}
}
pub trait LanguageAdapter: Send + Sync + 'static {
fn language_id(&self) -> LanguageId;
fn display_name(&self) -> &'static str;
fn file_extensions(&self) -> &'static [&'static str];
fn tree_sitter_language(&self) -> Result<tree_sitter::Language, AdapterError>;
fn source_syntax_proves_language(
&self,
_snapshot: &FileSnapshot,
_tree: &SyntaxTree,
) -> LanguageOwnershipEvidence {
LanguageOwnershipEvidence::Unproven
}
fn grammar_name_for_path(&self, _path: &std::path::Path) -> &'static str {
self.language_id().as_str()
}
fn tree_sitter_language_for_path(
&self,
path: &std::path::Path,
) -> Result<tree_sitter::Language, AdapterError> {
let grammar = self.grammar_name_for_path(path);
if grammar == self.language_id().as_str() {
self.tree_sitter_language()
} else {
tree_sitter_language_pack::get_language(grammar)
.map_err(|error| AdapterError::GrammarUnavailable(format!("{grammar}: {error}")))
}
}
fn parse_recovery_edits(
&self,
_snapshot: &FileSnapshot,
_vfs: &Vfs,
_tree: &SyntaxTree,
) -> Vec<ParseRecoveryEdit> {
Vec::new()
}
fn fragment_parse_context(&self) -> FragmentParseContext {
FragmentParseContext::default()
}
fn capabilities(&self) -> LanguageCapabilities;
fn discover_workspace_roots(&self, _files: &[FileId], _ctx: &AdapterContext<'_>) -> Vec<WorkspaceRoot> {
vec![WorkspaceRoot::default()]
}
fn extract_declarations(&self, file: FileId, ctx: &AdapterContext<'_>) -> DeclIndex;
fn extract_imports(&self, file: FileId, ctx: &AdapterContext<'_>) -> ImportIndex;
fn unsupported_constructs(&self, _file: FileId, _ctx: &AdapterContext<'_>) -> Vec<UnsupportedConstruct> {
Vec::new()
}
}
pub type DynAdapter = Arc<dyn LanguageAdapter>;
#[derive(Debug, thiserror::Error)]
pub enum AdapterError {
#[error("grammar not available: {0}")]
GrammarUnavailable(String),
#[error("parser setup failed: {0}")]
ParserSetup(String),
#[error("parse error: {0}")]
Parse(String),
}