1pub mod anchor;
2pub mod outline;
3
4#[cfg(feature = "lang-c")]
5mod outline_c;
6#[cfg(feature = "lang-cpp")]
7mod outline_cpp;
8#[cfg(feature = "lang-go")]
9mod outline_go;
10#[cfg(feature = "lang-java")]
11mod outline_java;
12#[cfg(feature = "lang-objc")]
13mod outline_objc;
14#[cfg(feature = "lang-python")]
15mod outline_python;
16#[cfg(feature = "lang-ruby")]
17mod outline_ruby;
18#[cfg(feature = "lang-swift")]
19mod outline_swift;
20#[cfg(feature = "lang-typescript")]
21mod outline_typescript;
22
23pub use anchor::AnchorMatch;
24pub use outline::{OutlineEntry, SemanticKind};
25
26use crate::error::AstError;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub enum Language {
31 Rust,
32 TypeScript,
33 Tsx,
34 JavaScript,
35 Jsx,
36 Python,
37 Go,
38 Java,
39 C,
40 Cpp,
41 Ruby,
42 ObjC,
43 Swift,
44 Unsupported,
45}
46
47impl Language {
48 pub fn from_extension(ext: &str) -> Self {
50 match ext {
51 "rs" => Language::Rust,
52 "ts" | "mts" | "cts" => Language::TypeScript,
53 "tsx" => Language::Tsx,
54 "js" | "mjs" | "cjs" => Language::JavaScript,
55 "jsx" => Language::Jsx,
56 "py" | "pyi" => Language::Python,
57 "go" => Language::Go,
58 "java" => Language::Java,
59 "c" | "h" => Language::C,
60 "cc" | "cpp" | "cxx" | "hpp" | "hxx" | "hh" => Language::Cpp,
61 "rb" | "rake" | "gemspec" => Language::Ruby,
62 "m" | "mm" => Language::ObjC,
63 "swift" => Language::Swift,
64 _ => Language::Unsupported,
65 }
66 }
67
68 pub fn from_path(path: &str) -> Self {
70 path.rsplit('.')
71 .next()
72 .map(Self::from_extension)
73 .unwrap_or(Language::Unsupported)
74 }
75}
76
77pub fn extract_outline(source: &str, language: Language) -> Result<Vec<OutlineEntry>, AstError> {
79 match language {
80 #[cfg(feature = "lang-rust")]
81 Language::Rust => outline::extract_rust_outline(source),
82
83 #[cfg(feature = "lang-typescript")]
84 Language::TypeScript | Language::JavaScript => {
85 outline_typescript::extract_typescript_outline(source, false)
86 }
87 #[cfg(feature = "lang-typescript")]
88 Language::Tsx | Language::Jsx => {
89 outline_typescript::extract_typescript_outline(source, true)
90 }
91
92 #[cfg(feature = "lang-python")]
93 Language::Python => outline_python::extract_python_outline(source),
94
95 #[cfg(feature = "lang-go")]
96 Language::Go => outline_go::extract_go_outline(source),
97
98 #[cfg(feature = "lang-java")]
99 Language::Java => outline_java::extract_java_outline(source),
100
101 #[cfg(feature = "lang-c")]
102 Language::C => outline_c::extract_c_outline(source),
103
104 #[cfg(feature = "lang-cpp")]
105 Language::Cpp => outline_cpp::extract_cpp_outline(source),
106
107 #[cfg(feature = "lang-ruby")]
108 Language::Ruby => outline_ruby::extract_ruby_outline(source),
109
110 #[cfg(feature = "lang-objc")]
111 Language::ObjC => outline_objc::extract_objc_outline(source),
112
113 #[cfg(feature = "lang-swift")]
114 Language::Swift => outline_swift::extract_swift_outline(source),
115
116 Language::Unsupported => Err(AstError::UnsupportedLanguage {
117 extension: "unknown".to_string(),
118 location: snafu::Location::new(file!(), line!(), 0),
119 }),
120
121 #[allow(unreachable_patterns)]
123 _ => Err(AstError::UnsupportedLanguage {
124 extension: format!("{:?} (feature not enabled)", language),
125 location: snafu::Location::new(file!(), line!(), 0),
126 }),
127 }
128}
129
130pub fn resolve_anchor(
132 outline: &[OutlineEntry],
133 unit_type: &str,
134 name: &str,
135) -> Option<AnchorMatch> {
136 anchor::resolve(outline, unit_type, name)
137}