#[derive(Clone)]
pub struct TypeScriptMapper {
base: BaseLanguageMapper,
}
impl TypeScriptMapper {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
base: BaseLanguageMapper::new(Language::TypeScript),
}
}
fn process_typescript_specific(&self, nodes: &mut [UnifiedNode]) {
for node in nodes.iter_mut() {
match node.kind {
NodeKind::Interface => {
node.add_metadata("typescript:isInterface", "true");
}
NodeKind::Class => {
if node.has_modifier("abstract") {
node.add_metadata("typescript:isAbstract", "true");
}
}
_ => {}
}
}
}
}
#[async_trait]
impl LanguageMapper for TypeScriptMapper {
fn language(&self) -> Language {
self.base.language()
}
async fn map_file(&self, path: &Path) -> Result<Vec<UnifiedNode>> {
self.base.map_file(path).await
}
async fn map_directory(&self, path: &Path, recursive: bool) -> Result<Vec<UnifiedNode>> {
self.base.map_directory(path, recursive).await
}
async fn map_source(&self, source: &str, path: &Path) -> Result<Vec<UnifiedNode>> {
use crate::services::languages::typescript::TypeScriptAstVisitor;
let visitor = TypeScriptAstVisitor::new(path);
match visitor.analyze_typescript_source(source) {
Ok(items) => {
let mut nodes = self.convert_ast_items(&items, path);
self.process_typescript_specific(&mut nodes);
Ok(nodes)
}
Err(e) => Err(anyhow!("Failed to analyze TypeScript source: {}", e)),
}
}
fn convert_ast_items(&self, items: &[AstItem], path: &Path) -> Vec<UnifiedNode> {
self.base.convert_ast_items(items, path)
}
fn clone_box(&self) -> Box<dyn LanguageMapper> {
Box::new(self.clone())
}
}
#[derive(Clone)]
pub struct JavaScriptMapper {
base: BaseLanguageMapper,
}
impl JavaScriptMapper {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
base: BaseLanguageMapper::new(Language::JavaScript),
}
}
fn process_javascript_specific(&self, nodes: &mut [UnifiedNode]) {
for node in nodes.iter_mut() {
match node.kind {
NodeKind::Class => {
node.add_metadata("javascript:isClass", "true");
}
NodeKind::Function => {
if node.has_modifier("arrow") {
node.kind = NodeKind::Lambda;
}
}
_ => {}
}
}
}
}
#[async_trait]
impl LanguageMapper for JavaScriptMapper {
fn language(&self) -> Language {
self.base.language()
}
async fn map_file(&self, path: &Path) -> Result<Vec<UnifiedNode>> {
self.base.map_file(path).await
}
async fn map_directory(&self, path: &Path, recursive: bool) -> Result<Vec<UnifiedNode>> {
self.base.map_directory(path, recursive).await
}
async fn map_source(&self, source: &str, path: &Path) -> Result<Vec<UnifiedNode>> {
use crate::services::languages::javascript::JavaScriptAstVisitor;
let visitor = JavaScriptAstVisitor::new(path);
match visitor.analyze_javascript_source(source) {
Ok(items) => {
let mut nodes = self.convert_ast_items(&items, path);
self.process_javascript_specific(&mut nodes);
Ok(nodes)
}
Err(e) => Err(anyhow!("Failed to analyze JavaScript source: {}", e)),
}
}
fn convert_ast_items(&self, items: &[AstItem], path: &Path) -> Vec<UnifiedNode> {
self.base.convert_ast_items(items, path)
}
fn clone_box(&self) -> Box<dyn LanguageMapper> {
Box::new(self.clone())
}
}