package quality import ( "context" "path/filepath" ) // Detector interface defines the contract for code quality detectors type Detector interface { // Name returns the detector name Name() string // Detect runs the detector on the given path Detect(ctx context.Context, path string, config *Config) ([]Finding, error) // Severity returns the default severity for findings from this detector Severity() Severity } // LanguageDetector interface extends Detector for language-specific detectors type LanguageDetector interface { Detector // SupportedLanguages returns the languages this detector supports SupportedLanguages() []string // ExtractFunctions extracts function information from source files ExtractFunctions(ctx context.Context, files []string) ([]FunctionInfo, error) // ExtractClasses extracts class information from source files ExtractClasses(ctx context.Context, files []string) ([]ClassInfo, error) } // FileFinder interface for finding files of a specific language type FileFinder interface { // FindFiles returns source files for the given path and language FindFiles(path string, language string) ([]string, error) // IsSourceFile checks if a file is a source file for the language IsSourceFile(path string, language string) bool } // BaseDetector provides common functionality for detectors type BaseDetector struct { name string severity Severity finder FileFinder } // NewBaseDetector creates a new base detector func NewBaseDetector(name string, severity Severity, finder FileFinder) *BaseDetector { return &BaseDetector{ name: name, severity: severity, finder: finder, } } // Name returns the detector name func (d *BaseDetector) Name() string { return d.name } // Severity returns the default severity func (d *BaseDetector) Severity() Severity { return d.severity } // FindFiles finds source files using the file finder func (d *BaseDetector) FindFiles(path string, language string) ([]string, error) { if d.finder != nil { return d.finder.FindFiles(path, language) } return nil, nil } // ShouldExclude checks if a path should be excluded based on config func ShouldExclude(path string, excludes []string) bool { if len(excludes) == 0 { return false } for _, pattern := range excludes { matched, err := filepath.Match(pattern, path) if err == nil && matched { return true } // Check directory exclusion matched, err = filepath.Match(pattern, filepath.Base(path)) if err == nil && matched { return true } } return false }