#[derive(Clone)]
pub struct JavaMapper {
base: BaseLanguageMapper,
}
impl JavaMapper {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
base: BaseLanguageMapper::new(Language::Java),
}
}
#[allow(dead_code)]
fn process_java_specific(&self, nodes: &mut [UnifiedNode]) {
for node in nodes.iter_mut() {
match node.kind {
NodeKind::Class => {
if node.has_modifier("interface") {
node.kind = NodeKind::Interface;
}
if node.has_modifier("record") {
node.kind = NodeKind::Record;
}
}
_ => {}
}
}
}
}
#[async_trait]
impl LanguageMapper for JavaMapper {
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>> {
#[cfg(feature = "java-ast")]
{
use crate::services::languages::java::JavaAstVisitor;
let visitor = JavaAstVisitor::new(_path);
match visitor.analyze_java_source(_source) {
Ok(items) => {
let mut nodes = self.convert_ast_items(&items, _path);
self.process_java_specific(&mut nodes);
Ok(nodes)
}
Err(e) => Err(anyhow!("Failed to analyze Java source: {}", e)),
}
}
#[cfg(not(feature = "java-ast"))]
{
Err(anyhow!(
"Java AST support not enabled (feature 'java-ast' required)"
))
}
}
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 KotlinMapper {
base: BaseLanguageMapper,
}
impl KotlinMapper {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
base: BaseLanguageMapper::new(Language::Kotlin),
}
}
#[allow(dead_code)]
fn process_kotlin_specific(&self, nodes: &mut [UnifiedNode]) {
for node in nodes.iter_mut() {
match node.kind {
NodeKind::Class => {
if node.has_modifier("data") {
node.kind = NodeKind::Record;
node.add_metadata("kotlin:isData", "true");
}
if node.has_modifier("sealed") {
node.add_metadata("kotlin:isSealed", "true");
}
}
_ => {}
}
}
}
}
#[async_trait]
impl LanguageMapper for KotlinMapper {
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>> {
self.base.map_source(source, path).await
}
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 ScalaMapper {
base: BaseLanguageMapper,
}
impl ScalaMapper {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
base: BaseLanguageMapper::new(Language::Scala),
}
}
#[allow(dead_code)]
fn process_scala_specific(&self, nodes: &mut [UnifiedNode]) {
for node in nodes.iter_mut() {
match node.kind {
NodeKind::Class => {
if node.has_modifier("case") {
node.kind = NodeKind::CaseClass;
}
}
NodeKind::Module => {
node.add_metadata("scala:isObject", "true");
}
_ => {}
}
}
}
}
#[async_trait]
impl LanguageMapper for ScalaMapper {
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>> {
#[cfg(feature = "scala-ast")]
{
use crate::services::languages::scala::ScalaAstVisitor;
let visitor = ScalaAstVisitor::new(_path);
match visitor.analyze_scala_source(_source) {
Ok(items) => {
let mut nodes = self.convert_ast_items(&items, _path);
self.process_scala_specific(&mut nodes);
Ok(nodes)
}
Err(e) => Err(anyhow!("Failed to analyze Scala source: {}", e)),
}
}
#[cfg(not(feature = "scala-ast"))]
{
Err(anyhow!(
"Scala AST support not enabled (feature 'scala-ast' required)"
))
}
}
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())
}
}