205 lines
5.1 KiB
Python
205 lines
5.1 KiB
Python
"""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 |