analyzer = new DependencyAnalyzer($this->reflectionProvider, $this->logger); } /** * Get the name of this plugin */ public function getName(): string { return 'dependency_analysis'; } /** * Check if this plugin can process the given file */ public function canProcess(FilePath $file, FileContext $context): bool { // Process all PHP files that contain classes return $file->hasExtension('php') && !empty($context->getClassNames()); } /** * Process a file and collect dependency information */ public function processFile(FilePath $file, FileContext $context, DiscoveryDataCollector $collector): void { $classNames = $context->getClassNames(); foreach ($classNames as $className) { // Create a discovered attribute for each class to track it $attribute = DiscoveredAttribute::create( className: $className, attributeType: 'DependencyNode', instance: null, // Will be filled during analysis metadata: [ 'file' => $file->toString(), 'discovered_at' => date('Y-m-d H:i:s'), ] ); $collector->addAttribute($attribute); } $this->logger?->debug('Processed file for dependency analysis', LogContext::withData([ 'file' => $file->toString(), 'classes_found' => count($classNames), ])); } /** * Post-process the discovery results to perform dependency analysis */ public function postProcess(DiscoveryRegistry $registry): DiscoveryRegistry { $this->logger?->info('Starting post-processing dependency analysis'); // Extract all class names from the discovered attributes $classNames = []; foreach ($registry->getByType('DependencyNode') as $attribute) { $classNames[] = $attribute->className; } if (empty($classNames)) { $this->logger?->warning('No classes found for dependency analysis'); return $registry; } // Perform dependency analysis $analysisResult = $this->analyzer->analyzeWithCircularDetection($classNames); // Add analysis result to the registry $analysisAttribute = DiscoveredAttribute::create( className: 'DependencyAnalysisResult', attributeType: 'DependencyAnalysis', instance: $analysisResult, metadata: [ 'analysis_timestamp' => date('Y-m-d H:i:s'), 'classes_analyzed' => count($classNames), 'circular_dependencies' => $analysisResult->getCircularDependencyCount(), 'statistics' => $analysisResult->getStatistics(), ] ); $updatedRegistry = $registry->add($analysisAttribute); // Update individual class attributes with dependency information $graph = $analysisResult->getGraph(); foreach ($registry->getByType('DependencyNode') as $attribute) { $node = $graph->getNode(\App\Framework\Core\ValueObjects\ClassName::create($attribute->className)); if ($node !== null) { $updatedAttribute = DiscoveredAttribute::create( className: $attribute->className, attributeType: 'DependencyNode', instance: $node, metadata: array_merge($attribute->metadata, [ 'dependency_count' => $node->getDependencyCount(), 'dependent_count' => $node->getDependentCount(), 'complexity_score' => $node->getComplexityScore(), 'type' => $node->getType()->value, ]) ); $updatedRegistry = $updatedRegistry->replace($attribute, $updatedAttribute); } } $this->logger?->info('Dependency analysis completed', LogContext::withData([ 'classes_analyzed' => count($classNames), 'nodes_created' => $graph->getNodeCount(), 'edges_created' => $graph->getEdgeCount(), 'circular_dependencies' => $analysisResult->getCircularDependencyCount(), ])); return $updatedRegistry; } /** * Get the analysis result from the registry */ public function getAnalysisResult(DiscoveryRegistry $registry): ?DependencyAnalysisResult { $analysisAttributes = $registry->getByType('DependencyAnalysis'); if (empty($analysisAttributes)) { return null; } $attribute = reset($analysisAttributes); return $attribute->instance instanceof DependencyAnalysisResult ? $attribute->instance : null; } /** * Get recommendations based on the analysis * * @return array */ public function getRecommendations(DiscoveryRegistry $registry): array { $analysisResult = $this->getAnalysisResult($registry); if ($analysisResult === null) { return ['error' => 'No dependency analysis results found']; } return $this->analyzer->getRecommendations($analysisResult->getGraph()); } }