/** * SMI-1303: Language Router * SMI-1337: Added metrics integration * SMI-1339: Added factory pattern integration * SMI-1340: Added language detection for extensionless files * * Detects file language and dispatches to appropriate adapter. * Manages adapter registry and provides unified access to framework rules. * * @see docs/internal/architecture/multi-language-analysis.md * @module analysis/router */ import type { LanguageAdapter } from './adapters/base.js'; import type { SupportedLanguage, FrameworkRule, ParseResult } from './types.js'; import { type AnalysisMetrics } from './metrics.js'; import { type LanguageDetectionResult } from './language-detector.js'; /** * Options for LanguageRouter */ export interface LanguageRouterOptions { /** Whether to throw on unsupported files (default: false) */ throwOnUnsupported?: boolean; /** Custom metrics instance (uses default if not provided) */ metrics?: AnalysisMetrics; /** Languages to register adapters for (default: all) */ languages?: SupportedLanguage[]; /** Enable language detection for extensionless files (default: true) */ enableLanguageDetection?: boolean; /** Minimum confidence for language detection (default: 0.5) */ detectionMinConfidence?: number; } /** * Routes files to appropriate language adapters * * Manages a registry of language adapters and provides: * - File extension to adapter mapping * - Aggregated framework detection rules * - Unified parsing interface * * @example * ```typescript * const router = new LanguageRouter() * * // Register adapters * router.registerAdapter(new TypeScriptAdapter()) * router.registerAdapter(new PythonAdapter()) * * // Route files to appropriate adapter * const adapter = router.getAdapter('src/main.py') * const result = adapter.parseFile(content, 'src/main.py') * ``` */ export declare class LanguageRouter { private adapters; private extensionMap; private readonly throwOnUnsupported; private readonly metrics; private readonly languageDetector; private readonly enableLanguageDetection; constructor(options?: LanguageRouterOptions); /** * Create a LanguageRouter with all adapters pre-registered * * Uses AdapterFactory to create adapters for all supported languages. * * @param options - Router options * @returns Configured LanguageRouter * * @example * ```typescript * // Create router with all language adapters * const router = LanguageRouter.createWithAllAdapters() * * // Create router with specific languages only * const router2 = LanguageRouter.createWithAllAdapters({ * languages: ['typescript', 'python'] * }) * ``` */ static createWithAllAdapters(options?: LanguageRouterOptions): LanguageRouter; /** * Create a LanguageRouter using cached adapters from factory * * Reuses adapter instances from the factory cache for efficiency. * * @param options - Router options * @returns Configured LanguageRouter */ static createWithCachedAdapters(options?: LanguageRouterOptions): LanguageRouter; /** * Register a language adapter * * The adapter's extensions are mapped for fast lookup. * If an adapter for the same language exists, it is replaced. * * @param adapter - Adapter to register * * @example * ```typescript * router.registerAdapter(new PythonAdapter()) * // Now handles .py, .pyi, .pyw files * ``` */ registerAdapter(adapter: LanguageAdapter): void; /** * Unregister a language adapter * * @param language - Language to unregister * @returns True if adapter was found and removed */ unregisterAdapter(language: SupportedLanguage): boolean; /** * Get adapter for a file path * * @param filePath - Path to the file * @returns Adapter that can handle the file * @throws Error if no adapter found and throwOnUnsupported is true * * @example * ```typescript * const adapter = router.getAdapter('src/main.py') * // Returns PythonAdapter * * const adapter2 = router.getAdapter('unknown.xyz') * // Throws if throwOnUnsupported, otherwise returns null * ``` */ getAdapter(filePath: string): LanguageAdapter; /** * Try to get adapter for a file path (returns null instead of throwing) * * SMI-1340: For extensionless files, attempts language detection * from content if provided and detection is enabled. * * @param filePath - Path to the file * @param content - Optional file content for language detection * @returns Adapter or null if not supported * * @example * ```typescript * // With extension - uses extension mapping * const adapter = router.tryGetAdapter('main.py') * * // Without extension - attempts content detection * const adapter2 = router.tryGetAdapter('Makefile', 'package main\n...') * ``` */ tryGetAdapter(filePath: string, content?: string): LanguageAdapter | null; /** * Detect language from file content * * Uses heuristics to determine the language of a file: * - Shebang analysis (#!/usr/bin/python, etc.) * - Content patterns (import statements, syntax markers) * - Statistical keyword analysis * * @param content - File content to analyze * @returns Detection result with language and confidence * * @example * ```typescript * const result = router.detectLanguageFromContent('#!/usr/bin/env python3\nprint("hello")') * // { language: 'python', confidence: 1.0, method: 'shebang', evidence: [...] } * ``` */ detectLanguageFromContent(content: string): LanguageDetectionResult; /** * Try to get adapter using content detection * * Specifically for extensionless files where content-based * detection is required. * * @param content - File content to analyze * @returns Object with adapter and detection result */ tryGetAdapterFromContent(content: string): { adapter: LanguageAdapter | null; detection: LanguageDetectionResult; }; /** * Check if a file can be handled * * @param filePath - Path to check * @returns True if an adapter is registered for this file type * * @example * ```typescript * router.canHandle('main.py') // true (if Python adapter registered) * router.canHandle('main.xyz') // false * ``` */ canHandle(filePath: string): boolean; /** * Get language for a file path * * @param filePath - Path to check * @returns Language or null if not supported */ getLanguage(filePath: string): SupportedLanguage | null; /** * Parse a file using the appropriate adapter * * Convenience method that combines getAdapter and parseFile. * SMI-1337: Records metrics for file parsing. * * @param content - File content * @param filePath - Path to the file * @returns Parse result * @throws Error if no adapter for file type */ parseFile(content: string, filePath: string): ParseResult; /** * Get list of supported languages * * @returns Array of registered languages */ getSupportedLanguages(): SupportedLanguage[]; /** * Get list of supported file extensions * * @returns Array of extensions (with dot) */ getSupportedExtensions(): string[]; /** * Get adapter for a specific language * * @param language - Language to get adapter for * @returns Adapter or undefined if not registered */ getAdapterByLanguage(language: SupportedLanguage): LanguageAdapter | undefined; /** * Get all framework detection rules from all adapters * * Aggregates rules from all registered adapters for * comprehensive framework detection. * * @returns Combined array of framework rules * * @example * ```typescript * const rules = router.getAllFrameworkRules() * // Includes rules for React, Django, Gin, Actix, etc. * ``` */ getAllFrameworkRules(): FrameworkRule[]; /** * Get framework rules for a specific language * * @param language - Language to get rules for * @returns Framework rules or empty array */ getFrameworkRules(language: SupportedLanguage): FrameworkRule[]; /** * Get number of registered adapters */ get adapterCount(): number; /** * Clean up all adapters * * Disposes all registered adapters and clears the registry. */ dispose(): void; } //# sourceMappingURL=router.d.ts.map