"""Language detection utilities for Local Code Assistant.""" from pathlib import Path from typing import Optional class LanguageSettings: """Language configuration settings.""" def __init__( self, extensions: list[str], patterns: list[str], comment: str, testing_framework: str, ): self.extensions = extensions self.patterns = patterns self.comment = comment self.testing_framework = testing_framework LANGUAGE_MAP: dict[str, LanguageSettings] = { "python": LanguageSettings( extensions=[".py", ".pyw", ".pyi"], patterns=["def ", "import ", "from ", "class ", "if __name__"], comment="#", testing_framework="pytest", ), "javascript": LanguageSettings( extensions=[".js", ".mjs", ".cjs"], patterns=["function ", "const ", "let ", "var ", "=>"], comment="//", testing_framework="jest", ), "typescript": LanguageSettings( extensions=[".ts", ".tsx"], patterns=[": string", ": number", "interface ", "type "], comment="//", testing_framework="jest", ), "go": LanguageSettings( extensions=[".go"], patterns=["func ", "package ", "import (", "type "], comment="//", testing_framework="testing", ), "rust": LanguageSettings( extensions=[".rs"], patterns=["fn ", "let ", "struct ", "impl ", "pub "], comment="//", testing_framework="test", ), "java": LanguageSettings( extensions=[".java"], patterns=["public class", "public static", "import java"], comment="//", testing_framework="junit", ), "cpp": LanguageSettings( extensions=[".cpp", ".cc", ".hpp", ".h"], patterns=["#include", "std::", "using namespace"], comment="//", testing_framework="catch2", ), "c": LanguageSettings( extensions=[".c", ".h"], patterns=["#include", "int main()", "struct "], comment="//", testing_framework="unity", ), } def detect_language_from_extension(file_path: Path) -> Optional[str]: """Detect programming language from file extension. Args: file_path: Path to the file. Returns: Detected language or None. """ suffix = file_path.suffix.lower() for language, config in LANGUAGE_MAP.items(): if suffix in config.extensions: return language return None def detect_language_from_content(content: str) -> Optional[str]: """Detect programming language from file content. Args: content: File content to analyze. Returns: Detected language or None. """ for language, config in LANGUAGE_MAP.items(): for pattern in config.patterns: if pattern in content: return language return None def detect_language(file_path: Path, content: Optional[str] = None) -> str: """Detect programming language from file path and optionally content. Args: file_path: Path to the file. content: Optional file content for additional detection. Returns: Detected language (defaults to 'python'). """ ext_lang = detect_language_from_extension(file_path) if ext_lang: return ext_lang if content: content_lang = detect_language_from_content(content) if content_lang: return content_lang return "python" def get_language_config(language: str) -> LanguageSettings: """Get configuration for a specific language. Args: language: Language name. Returns: Language configuration object. """ if language in LANGUAGE_MAP: return LANGUAGE_MAP[language] return LanguageSettings( extensions=[".txt"], patterns=[], comment="#", testing_framework="pytest", ) def get_supported_languages() -> list[str]: """Get list of supported programming languages. Returns: List of language names. """ return list(LANGUAGE_MAP.keys()) def is_language_supported(language: str) -> bool: """Check if a language is supported. Args: language: Language name to check. Returns: True if supported, False otherwise. """ return language.lower() in LANGUAGE_MAP def get_file_extension(language: str) -> str: """Get file extension for a language. Args: language: Language name. Returns: File extension with leading dot. """ config = get_language_config(language) return config.extensions[0] if config.extensions else ".txt" def get_comment_style(language: str) -> str: """Get comment style for a language. Args: language: Language name. Returns: Comment prefix string. """ config = get_language_config(language) return config.comment def get_testing_framework(language: str) -> str: """Get default testing framework for a language. Args: language: Language name. Returns: Testing framework name. """ config = get_language_config(language) return config.testing_framework