pub use crate::parse::bash::BashParser;
pub use crate::parse::c::CParser;
pub use crate::parse::cpp::CppParser;
pub use crate::parse::csharp::CSharpParser;
pub use crate::parse::dart::DartParser;
pub use crate::parse::docs::{DocFlavor, DocParser};
pub use crate::parse::generic::GenericParser;
pub use crate::parse::go::GoParser;
pub use crate::parse::java::JavaParser;
pub use crate::parse::javascript::{JavaScriptParser, TypeScriptParser};
pub use crate::parse::json::JsonParser;
pub use crate::parse::kotlin::KotlinParser;
pub use crate::parse::lua::LuaParser;
pub use crate::parse::php::PhpParser;
pub use crate::parse::python::PythonParser;
pub use crate::parse::ruby::RubyParser;
pub use crate::parse::rust::RustParser;
pub use crate::parse::scala::ScalaParser;
pub use crate::parse::swift::SwiftParser;
pub fn parser_for_language(
language: &str,
) -> Option<Box<dyn crate::parse::traits::CodeIntelligence>> {
match language.to_lowercase().as_str() {
"python" | "py" => Some(Box::new(PythonParser::new())),
"javascript" | "js" => Some(Box::new(JavaScriptParser::new())),
"typescript" | "ts" => Some(Box::new(TypeScriptParser::new())),
"rust" | "rs" => Some(Box::new(RustParser::new())),
"go" => Some(Box::new(GoParser::new())),
"java" => Some(Box::new(JavaParser::new())),
"cpp" | "c++" => Some(Box::new(CppParser::new())),
"csharp" | "c#" => Some(Box::new(CSharpParser::new())),
"ruby" | "rb" => Some(Box::new(RubyParser::new())),
"php" => Some(Box::new(PhpParser::new())),
"lua" => Some(Box::new(LuaParser::new())),
"scala" => Some(Box::new(ScalaParser::new())),
"c" => Some(Box::new(CParser::new())),
"bash" | "sh" => Some(Box::new(BashParser::new())),
"json" => Some(Box::new(JsonParser::new())),
"swift" => Some(Box::new(SwiftParser::new())),
"kotlin" | "kt" => Some(Box::new(KotlinParser::new())),
"dart" => Some(Box::new(DartParser::new())),
"html" | "htm" => Some(Box::new(GenericParser::new("html"))),
"css" => Some(Box::new(GenericParser::new("css"))),
"scss" => Some(Box::new(GenericParser::new("scss"))),
"yaml" | "yml" => Some(Box::new(GenericParser::new("yaml"))),
"cmake" => Some(Box::new(GenericParser::new("cmake"))),
"elixir" | "ex" | "exs" => Some(Box::new(GenericParser::new("elixir"))),
"erlang" | "erl" => Some(Box::new(GenericParser::new("erlang"))),
"haskell" | "hs" => Some(Box::new(GenericParser::new("haskell"))),
"perl" | "pl" | "pm" => Some(Box::new(GenericParser::new("perl"))),
"r" => Some(Box::new(GenericParser::new("r"))),
"zig" => Some(Box::new(GenericParser::new("zig"))),
"graphql" | "gql" => Some(Box::new(GenericParser::new("graphql"))),
"hcl" | "terraform" | "tf" => Some(Box::new(GenericParser::new("hcl"))),
"make" | "makefile" => Some(Box::new(GenericParser::new("make"))),
"elisp" | "emacs-lisp" | "emacs lisp" => Some(Box::new(GenericParser::new("elisp"))),
"julia" | "jl" => Some(Box::new(GenericParser::new("julia"))),
"d" => Some(Box::new(GenericParser::new("d"))),
"glsl" => Some(Box::new(GenericParser::new("glsl"))),
"embedded-template" | "embedded template" | "ejs" | "erb" | "liquid" => {
Some(Box::new(GenericParser::new("embedded_template")))
}
"markdown" | "md" => Some(Box::new(DocParser::new(DocFlavor::Markdown))),
"rst" | "restructuredtext" => Some(Box::new(DocParser::new(DocFlavor::Rst))),
"asciidoc" | "adoc" => Some(Box::new(DocParser::new(DocFlavor::Adoc))),
"text" | "txt" | "plaintext" | "plain text" | "plain" => {
Some(Box::new(DocParser::new(DocFlavor::Plain)))
}
_ => None,
}
}
pub fn active_language_count() -> usize {
[
"python",
"javascript",
"typescript",
"rust",
"go",
"java",
"cpp",
"csharp",
"ruby",
"php",
"lua",
"scala",
"c",
"bash",
"json",
"swift",
"kotlin",
"dart",
"html",
"css",
"scss",
"yaml",
"cmake",
"elixir",
"erlang",
"haskell",
"perl",
"r",
"zig",
"graphql",
"hcl",
"make",
"elisp",
"julia",
"d",
"glsl",
"embedded-template",
]
.iter()
.filter(|language| parser_for_language(language).is_some())
.count()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse::traits::CodeIntelligence;
#[test]
fn test_python_parser_creation() {
let parser = PythonParser::new();
let source = b"def hello(): pass";
let result = parser.get_signatures(source);
assert!(result.is_ok());
}
#[test]
fn test_parser_factory() {
let parser = parser_for_language("python");
assert!(parser.is_some());
let parser = parser_for_language("unknown");
assert!(parser.is_none());
}
#[test]
fn test_every_registered_extension_resolves_a_parser_via_display_name() {
let representative_extensions = [
"py", "js", "ts", "go", "rs", "java", "cpp", "hpp", "h", "c", "cs", "rb", "php", "lua",
"scala", "sh", "json", "swift", "kt", "dart", "html", "htm", "css", "scss", "yaml",
"yml", "cmake", "ex", "exs", "erl", "hrl", "hs", "pl", "pm", "r", "zig", "graphql",
"gql", "hcl", "tf", "tfvars", "makefile", "mak", "mk", "el", "jl", "d", "di", "glsl",
"vert", "frag", "comp", "ejs", "erb", "liquid", "md", "markdown", "rst", "adoc", "txt",
];
for ext in representative_extensions {
let id = crate::parse::grammar::LanguageId::from_extension(ext)
.unwrap_or_else(|| panic!("extension .{ext} has no LanguageId"));
let name = id.config().name.clone();
assert!(
parser_for_language(&name).is_some(),
"language display name {name:?} (from .{ext}) resolves to no parser"
);
}
}
}