big-code-analysis-ast 2.3.0

Parse and classification layer behind big-code-analysis (internal, version-locked)
Documentation
// Per-language metric and AST modules deliberately consume the macro-
// generated tree-sitter token enums via `use crate::*` and `use Foo::*`
// inside match expressions — explicit imports would list dozens of
// variants per arm and obscure the per-language token sets that are the
// point of these files. Allowed at the module level rather than per
// function so the per-language impl blocks stay readable.
#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]

//! [`ParserTrait`], [`LanguageInfo`], and [`Search`].

use std::path::Path;
use std::sync::Arc;

use crate::alterator::Alterator;
use crate::checker::Checker;
use crate::getter::Getter;
use crate::langs::*;
use crate::node::Ancestors;
use crate::node::Node;
use crate::parser::Filter;
use crate::preproc::PreprocResults;

/// Static identification of a language code tag.
///
/// Implemented by every `XxxCode` type generated by the internal
/// `mk_code!` macro. Crate-internal: reached only through the
/// `pub` `Parser<T>` plumbing behind the `big_code_analysis::Ast` seam.
pub trait LanguageInfo {
    /// Tree-sitter base language enum carried by this code tag.
    type BaseLang;

    /// Returns the workspace-level [`LANG`] variant for this code tag.
    fn lang() -> LANG;
}

/// A parsed source in one language: the tree, its bytes, and the
/// `Checker` / `Getter` classifiers that read it.
///
/// Implemented once, generically, by [`Parser<T>`](crate::parser::Parser)
/// for every `*Code` tag; the per-language `*Parser` aliases in
/// [`langs`](crate::langs) are its concrete forms. This is the *parse*
/// half of a language: `big-code-analysis` layers the per-metric
/// implementations on top through its own supertrait, so nothing here
/// depends on a metric (#1376). Not an extension contract — implement
/// nothing; match on [`AnyParser`] to reach one.
pub trait ParserTrait {
    /// The language's classification predicates.
    type Checker: Alterator + Checker;
    /// The language's naming / space-kind / Halstead-class accessors.
    type Getter: Getter;

    /// Parses `code` read from `path`. `pr` carries the C-family
    /// preprocessor results whose `#define`s are expanded before parsing;
    /// every other language ignores it.
    ///
    /// # Panics
    ///
    /// When the language's Cargo feature is disabled in this build —
    /// there is no grammar to parse with and the signature is
    /// infallible. Check [`LANG::is_enabled`](crate::LANG::is_enabled)
    /// first, or reach a parser through
    /// [`AnyParser::parse`](crate::langs::AnyParser::parse), which
    /// returns `Err(MetricsError::LanguageDisabled)` instead.
    fn new(code: Vec<u8>, path: &Path, pr: Option<Arc<PreprocResults>>) -> Self;
    /// The root node of the parsed tree.
    fn root(&self) -> Node<'_>;
    /// The bytes the tree was parsed from (after macro expansion, for
    /// the C family).
    fn code(&self) -> &[u8];
    /// The returned [`Filter`] borrows `self` — the `"function"` and
    /// `"string"` predicates read the source bytes (#1162, #1381).
    fn filters(&self, requested: &[String]) -> Filter<'_>;
}

/// Subtree traversal helpers implemented by [`Node`].
pub trait Search<'a> {
    /// Visits every node of the subtree in source order, handing the
    /// action each node's ancestor chain alongside it so a predicate it
    /// applies stays off `Node::parent` (#1088).
    fn act_on_node(&self, action: &mut dyn FnMut(&Node<'a>, Ancestors<'a, '_>));
    /// The first direct child whose `kind_id` satisfies `pred`.
    fn first_child(&self, pred: fn(u16) -> bool) -> Option<Node<'a>>;
    /// Visits each direct child in source order.
    fn act_on_child(&self, action: &mut dyn FnMut(&Node<'a>));
}