llmcc 0.2.19

llmcc: llm context compiler
Documentation
use std::error::Error;
use std::path::Path;

use llmcc_core::*;

/// Input options for building an LLMCC project.
pub struct LlmccOptions {
    pub files: Vec<String>,
    pub dir: Option<String>,
    pub print_ir: bool,
    pub print_graph: bool,
    pub query: Option<String>,
    pub recursive: bool,
    pub dependents: bool,
}

pub fn run_main<L: LanguageTrait>(opts: &LlmccOptions) -> Result<Option<String>, Box<dyn Error>> {
    let (cc, files) = if let Some(dir) = opts.dir.as_ref() {
        let ctx = CompileCtxt::from_dir::<_, L>(Path::new(dir))?;
        let file_paths = ctx.get_files();
        (ctx, file_paths)
    } else {
        let ctx = CompileCtxt::from_files::<L>(&opts.files)?;
        (ctx, opts.files.clone())
    };

    build_llmcc_ir::<L>(&cc)?;
    let globals = cc.create_globals();

    if opts.print_ir {
        for (index, _) in files.iter().enumerate() {
            let unit = cc.compile_unit(index);
            print_llmcc_ir(unit);
        }
    }

    for (index, _) in files.iter().enumerate() {
        let unit = cc.compile_unit(index);
        L::collect_symbols(unit, globals);
    }

    let mut pg = ProjectGraph::new(&cc);
    for (index, _) in files.iter().enumerate() {
        let unit = cc.compile_unit(index);
        L::bind_symbols(unit, globals);
        let unit_graph = build_llmcc_graph::<L>(unit, index)?;

        if opts.print_graph {
            print_llmcc_graph(unit_graph.root(), unit);
        }

        pg.add_child(unit_graph);
    }

    pg.link_units();

    if opts.recursive && opts.dependents {
        return Err("`--recursive` is not supported together with `--dependents`".into());
    }

    let result = opts.query.as_ref().map(|name| {
        let query = ProjectQuery::new(&pg);
        if opts.dependents {
            query.find_depended(name).format_for_llm()
        } else if opts.recursive {
            query.find_depends_recursive(name).format_for_llm()
        } else {
            query.find_depends(name).format_for_llm()
        }
    });

    Ok(result)
}