rust_analyzer_modules/lib.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Library for analyzing Rust crate module structures and dependencies.
6//!
7//! This library provides functionality to:
8//! - Analyze Rust crate module hierarchies
9//! - Build dependency graphs showing relationships between modules
10//! - Detect orphaned source files
11//! - Extract module metadata and structure information
12
13use std::path::Path;
14
15use anyhow::Result;
16use ra_ap_hir::{self as hir};
17use ra_ap_ide::{self as ide};
18
19pub use crate::{
20 analyzer::LoadOptions,
21 item::Item,
22 options::{GeneralOptions, ProjectOptions},
23 tree::{ModuleTree, Tree, TreeBuilder},
24};
25
26pub mod analyzer;
27pub mod item;
28pub mod options;
29pub mod tree;
30pub mod utils;
31
32// Internal modules not part of the public API
33mod colors;
34mod graph;
35
36/// Analysis configuration to control performance and depth
37#[derive(Debug, Clone)]
38pub struct AnalysisConfig {
39 pub cfg_test: bool,
40 pub sysroot: bool,
41 pub no_default_features: bool,
42 pub all_features: bool,
43 pub features: Vec<String>,
44}
45
46impl Default for AnalysisConfig {
47 fn default() -> Self {
48 Self::fast()
49 }
50}
51
52impl AnalysisConfig {
53 /// Fast analysis with minimal dependencies - recommended for large crates
54 pub fn fast() -> Self {
55 Self {
56 cfg_test: false,
57 sysroot: false,
58 no_default_features: true, // Skip default features for speed
59 all_features: false,
60 features: vec![],
61 }
62 }
63
64 /// Standard analysis with default features
65 pub fn standard() -> Self {
66 Self {
67 cfg_test: false,
68 sysroot: false,
69 no_default_features: false,
70 all_features: false,
71 features: vec![],
72 }
73 }
74
75 /// Ultra fast analysis with absolute minimal processing - for large workspaces
76 pub fn ultra_fast() -> Self {
77 Self {
78 cfg_test: false,
79 sysroot: false,
80 no_default_features: true, // Skip all default features
81 all_features: false, // Don't analyze any features
82 features: vec![], // No specific features
83 }
84 }
85}
86
87/// Analyzes a Rust crate at the given path and returns the analysis components
88///
89/// # Arguments
90/// * `path` - Path to the crate root (containing Cargo.toml)
91/// * `package` - Optional package name for workspace crates
92/// * `config` - Analysis configuration to control performance and depth
93///
94/// # Returns
95/// A tuple of (crate, database, edition) that can be used for further analysis
96pub fn analyze_crate(
97 path: &Path,
98 package: Option<&str>,
99 config: AnalysisConfig,
100) -> Result<(hir::Crate, ide::AnalysisHost, ide::Edition)> {
101 let general_options = GeneralOptions { verbose: false };
102
103 let project_options = ProjectOptions {
104 lib: false,
105 bin: None,
106 package: package.map(|p| p.to_string()),
107 no_default_features: config.no_default_features,
108 all_features: config.all_features,
109 features: config.features,
110 target: None,
111 manifest_path: path.to_path_buf(),
112 };
113
114 let load_options = LoadOptions {
115 cfg_test: config.cfg_test,
116 sysroot: config.sysroot,
117 };
118
119 let (crate_id, analysis_host, _vfs, edition) =
120 analyzer::load_workspace(&general_options, &project_options, &load_options)?;
121
122 Ok((crate_id, analysis_host, edition))
123}
124
125/// Builds a module tree from a crate analysis
126///
127/// # Arguments
128/// * `crate_id` - The crate to analyze
129/// * `db` - The analysis database
130/// * `edition` - The Rust edition
131///
132/// # Returns
133/// A module tree structure
134pub fn build_module_tree(
135 crate_id: hir::Crate,
136 db: &ide::RootDatabase,
137 edition: ide::Edition,
138) -> Result<ModuleTree> {
139 ModuleTree::build(db, &crate_id, edition)
140}
141
142/// Detects orphaned source files in a crate directory
143///
144/// # Arguments
145/// * `path` - Path to the crate root directory
146///
147/// # Returns
148/// A vector of paths to orphaned files
149pub fn detect_orphans(path: &Path) -> Result<Vec<std::path::PathBuf>> {
150 // This would need to be implemented by examining the file system
151 // and comparing with the analyzed module structure
152 // For now, return empty vector
153 let _ = path;
154 Ok(vec![])
155}