Skip to main content

weavatrix_rust/language/tokenized/
mod.rs

1//! Lossless language adapters backed by `weavatrix-parse`.
2
3mod convert;
4mod domains;
5mod kinds;
6mod node_http;
7mod swift;
8#[cfg(test)]
9mod tests;
10
11use super::{FileFacts, Language, LanguageAdapter, SourceFile};
12use crate::model::Result;
13
14/// One language served by the lossless parser.
15pub struct TokenizedAdapter {
16    language: Language,
17    parse: weavatrix_parse::Language,
18    extensions: &'static [&'static str],
19}
20
21impl TokenizedAdapter {
22    /// Every language the lossless parser extracts structure from.
23    pub fn defaults() -> impl Iterator<Item = Self> {
24        use weavatrix_parse::Language as Parsed;
25        [
26            (
27                Language::JavaScript,
28                Parsed::JavaScript,
29                &["js", "jsx", "mjs", "cjs"][..],
30            ),
31            (
32                Language::TypeScript,
33                Parsed::TypeScript,
34                &["ts", "tsx", "mts", "cts"][..],
35            ),
36            // The syn adapter wins with `lang-rust`; this remains the
37            // dependency-light fallback for no-default-feature builds.
38            (Language::Rust, Parsed::Rust, &["rs"][..]),
39            (Language::Python, Parsed::Python, &["py", "pyi"][..]),
40            (Language::Go, Parsed::Go, &["go"][..]),
41            (Language::Java, Parsed::Java, &["java"][..]),
42            (Language::CSharp, Parsed::CSharp, &["cs"][..]),
43            (Language::C, Parsed::C, &["c", "h"][..]),
44            (
45                Language::Cpp,
46                Parsed::Cpp,
47                &["cc", "cpp", "cxx", "hh", "hpp", "hxx"][..],
48            ),
49            (Language::Sql, Parsed::Sql, &["sql", "psql"][..]),
50            (Language::Bash, Parsed::Bash, &["sh", "bash", "zsh"][..]),
51            (Language::Swift, Parsed::Swift, &["swift"][..]),
52            (
53                Language::Custom("solidity".to_owned()),
54                Parsed::Solidity,
55                &["sol"][..],
56            ),
57            (
58                Language::Custom("html".to_owned()),
59                Parsed::Html,
60                &["html", "htm", "xhtml", "vue", "svelte"][..],
61            ),
62            (
63                Language::Custom("css".to_owned()),
64                Parsed::Css,
65                &["css"][..],
66            ),
67            (
68                Language::Custom("css".to_owned()),
69                Parsed::Scss,
70                &["scss", "sass", "less"][..],
71            ),
72            (
73                Language::Custom("terraform".to_owned()),
74                Parsed::Terraform,
75                &["tf", "tfvars", "hcl"][..],
76            ),
77            (
78                Language::Custom("xml".to_owned()),
79                Parsed::Xml,
80                &[
81                    "xml", "xsd", "xsl", "xslt", "csproj", "props", "targets", "plist",
82                ][..],
83            ),
84            (
85                Language::Custom("markdown".to_owned()),
86                Parsed::Markdown,
87                &["md", "markdown", "mdown", "mkd", "mkdn"][..],
88            ),
89            (
90                Language::Custom("markdown".to_owned()),
91                Parsed::Mdx,
92                &["mdx"][..],
93            ),
94            (
95                Language::Custom("rst".to_owned()),
96                Parsed::ReStructuredText,
97                &["rst"][..],
98            ),
99            (
100                Language::Custom("asciidoc".to_owned()),
101                Parsed::AsciiDoc,
102                &["adoc", "asciidoc", "asc"][..],
103            ),
104        ]
105        .into_iter()
106        .map(|(language, parse, extensions)| Self {
107            language,
108            parse,
109            extensions,
110        })
111    }
112}
113
114impl LanguageAdapter for TokenizedAdapter {
115    fn language(&self) -> Language {
116        self.language.clone()
117    }
118
119    fn extensions(&self) -> &'static [&'static str] {
120        self.extensions
121    }
122
123    fn extractor(&self) -> &'static str {
124        "weavatrix.parse.tokens"
125    }
126
127    fn parse(&self, source: SourceFile<'_>) -> Result<FileFacts> {
128        let mut facts = convert::convert(
129            &weavatrix_parse::extract(source.text, self.parse),
130            source.path,
131            source.text,
132            self.parse,
133        );
134        if matches!(
135            self.parse,
136            weavatrix_parse::Language::Markdown | weavatrix_parse::Language::Mdx
137        ) {
138            if let Some(skill) = super::agent::analyze_skill(source.path, source.text) {
139                facts.symbols.extend(skill.symbols);
140                facts.domains.extend(skill.domains);
141                facts.diagnostics.extend(skill.diagnostics);
142                facts.references.extend(skill.references);
143                facts.bound_edges.extend(skill.bound_edges);
144            }
145            if let Some(diagram) = super::mermaid::analyze_markdown(source.path, source.text) {
146                facts.symbols.extend(diagram.symbols);
147                facts.domains.extend(diagram.domains);
148                facts.diagnostics.extend(diagram.diagnostics);
149                facts.references.extend(diagram.references);
150                facts.bound_edges.extend(diagram.bound_edges);
151            }
152        }
153        if matches!(
154            self.parse,
155            weavatrix_parse::Language::Python
156                | weavatrix_parse::Language::JavaScript
157                | weavatrix_parse::Language::TypeScript
158        ) && let Some(regs) = super::agent::analyze_sdk(source.path, source.text)
159        {
160            facts.symbols.extend(regs.symbols);
161            facts.domains.extend(regs.domains);
162            facts.diagnostics.extend(regs.diagnostics);
163        }
164        Ok(facts)
165    }
166}