pub mod cfg_builder;
pub mod ecmascript;
pub mod function_body;
pub mod go;
pub mod java;
pub mod parser;
pub mod python;
pub mod rust;
pub mod span;
pub mod tree_sitter_utils;
use std::path::Path;
pub use cfg_builder::{get_builder_for_function, CfgBuilder};
pub use ecmascript::{ECMAScriptCfgBuilder, ECMAScriptParser, VueParser};
pub use function_body::FunctionBody;
pub use go::{GoCfgBuilder, GoParser};
pub use java::{JavaCfgBuilder, JavaParser};
pub use parser::{LanguageParser, ParsedModule};
pub use python::{PythonCfgBuilder, PythonParser};
pub use rust::{RustCfgBuilder, RustParser};
pub use span::SourceSpan;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Language {
TypeScript,
TypeScriptReact,
JavaScript,
JavaScriptReact,
Go,
Java,
Python,
Rust,
Vue,
}
impl Language {
pub fn from_extension(ext: &str) -> Option<Self> {
match ext {
"ts" | "mts" | "cts" => Some(Language::TypeScript),
"tsx" | "mtsx" | "ctsx" => Some(Language::TypeScriptReact),
"js" | "mjs" | "cjs" => Some(Language::JavaScript),
"jsx" | "mjsx" | "cjsx" => Some(Language::JavaScriptReact),
"go" => Some(Language::Go),
"java" => Some(Language::Java),
"py" | "pyw" => Some(Language::Python),
"rs" => Some(Language::Rust),
"vue" => Some(Language::Vue),
_ => None,
}
}
pub fn from_path(path: &Path) -> Option<Self> {
path.extension()
.and_then(|ext| ext.to_str())
.and_then(Self::from_extension)
}
pub fn name(&self) -> &'static str {
match self {
Language::TypeScript => "TypeScript",
Language::TypeScriptReact => "TypeScript React",
Language::JavaScript => "JavaScript",
Language::JavaScriptReact => "JavaScript React",
Language::Go => "Go",
Language::Java => "Java",
Language::Python => "Python",
Language::Rust => "Rust",
Language::Vue => "Vue",
}
}
pub fn is_typescript(&self) -> bool {
matches!(self, Language::TypeScript | Language::TypeScriptReact)
}
pub fn is_javascript(&self) -> bool {
matches!(self, Language::JavaScript | Language::JavaScriptReact)
}
pub fn is_ecmascript(&self) -> bool {
self.is_typescript() || self.is_javascript()
}
pub fn extensions(&self) -> &[&'static str] {
match self {
Language::TypeScript => &["ts", "mts", "cts"],
Language::TypeScriptReact => &["tsx", "mtsx", "ctsx"],
Language::JavaScript => &["js", "mjs", "cjs"],
Language::JavaScriptReact => &["jsx", "mjsx", "cjsx"],
Language::Go => &["go"],
Language::Java => &["java"],
Language::Python => &["py", "pyw"],
Language::Rust => &["rs"],
Language::Vue => &["vue"],
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_extension_typescript() {
assert_eq!(Language::from_extension("ts"), Some(Language::TypeScript));
assert_eq!(Language::from_extension("mts"), Some(Language::TypeScript));
assert_eq!(Language::from_extension("cts"), Some(Language::TypeScript));
assert_eq!(
Language::from_extension("tsx"),
Some(Language::TypeScriptReact)
);
}
#[test]
fn test_from_extension_javascript() {
assert_eq!(Language::from_extension("js"), Some(Language::JavaScript));
assert_eq!(Language::from_extension("mjs"), Some(Language::JavaScript));
assert_eq!(Language::from_extension("cjs"), Some(Language::JavaScript));
assert_eq!(
Language::from_extension("jsx"),
Some(Language::JavaScriptReact)
);
}
#[test]
fn test_from_extension_go() {
assert_eq!(Language::from_extension("go"), Some(Language::Go));
}
#[test]
fn test_from_extension_rust() {
assert_eq!(Language::from_extension("rs"), Some(Language::Rust));
}
#[test]
fn test_from_extension_java() {
assert_eq!(Language::from_extension("java"), Some(Language::Java));
}
#[test]
fn test_from_extension_unknown() {
assert_eq!(Language::from_extension("cpp"), None);
assert_eq!(Language::from_extension("c"), None);
assert_eq!(Language::from_extension(""), None);
}
#[test]
fn test_from_path() {
assert_eq!(
Language::from_path(Path::new("src/main.ts")),
Some(Language::TypeScript)
);
assert_eq!(
Language::from_path(Path::new("src/component.tsx")),
Some(Language::TypeScriptReact)
);
assert_eq!(
Language::from_path(Path::new("main.go")),
Some(Language::Go)
);
assert_eq!(
Language::from_path(Path::new("lib.rs")),
Some(Language::Rust)
);
assert_eq!(Language::from_path(Path::new("README.md")), None);
assert_eq!(Language::from_path(Path::new("Makefile")), None);
}
#[test]
fn test_name() {
assert_eq!(Language::TypeScript.name(), "TypeScript");
assert_eq!(Language::TypeScriptReact.name(), "TypeScript React");
assert_eq!(Language::JavaScript.name(), "JavaScript");
assert_eq!(Language::JavaScriptReact.name(), "JavaScript React");
assert_eq!(Language::Go.name(), "Go");
assert_eq!(Language::Rust.name(), "Rust");
}
#[test]
fn test_is_typescript() {
assert!(Language::TypeScript.is_typescript());
assert!(Language::TypeScriptReact.is_typescript());
assert!(!Language::JavaScript.is_typescript());
assert!(!Language::Go.is_typescript());
assert!(!Language::Rust.is_typescript());
}
#[test]
fn test_is_javascript() {
assert!(Language::JavaScript.is_javascript());
assert!(Language::JavaScriptReact.is_javascript());
assert!(!Language::TypeScript.is_javascript());
assert!(!Language::Go.is_javascript());
assert!(!Language::Rust.is_javascript());
}
#[test]
fn test_is_ecmascript() {
assert!(Language::TypeScript.is_ecmascript());
assert!(Language::TypeScriptReact.is_ecmascript());
assert!(Language::JavaScript.is_ecmascript());
assert!(Language::JavaScriptReact.is_ecmascript());
assert!(!Language::Go.is_ecmascript());
assert!(!Language::Rust.is_ecmascript());
}
#[test]
fn test_extensions() {
assert_eq!(Language::TypeScript.extensions(), &["ts", "mts", "cts"]);
assert_eq!(
Language::TypeScriptReact.extensions(),
&["tsx", "mtsx", "ctsx"]
);
assert_eq!(Language::Go.extensions(), &["go"]);
assert_eq!(Language::Rust.extensions(), &["rs"]);
}
}