44
55namespace Phauthentic \CognitiveCodeAnalysis \Business ;
66
7- use JsonException ;
87use Phauthentic \CognitiveCodeAnalysis \Business \Churn \ChangeCounter \ChangeCounterFactory ;
98use Phauthentic \CognitiveCodeAnalysis \Business \Churn \ChurnCalculator ;
109use Phauthentic \CognitiveCodeAnalysis \Business \Churn \Exporter \ChurnExporterFactory ;
1110use Phauthentic \CognitiveCodeAnalysis \Business \CodeCoverage \CoverageReportReaderInterface ;
11+ use Phauthentic \CognitiveCodeAnalysis \Business \Cognitive \CognitiveMetrics ;
1212use Phauthentic \CognitiveCodeAnalysis \Business \Cognitive \CognitiveMetricsCollection ;
1313use Phauthentic \CognitiveCodeAnalysis \Business \Cognitive \CognitiveMetricsCollector ;
1414use Phauthentic \CognitiveCodeAnalysis \Business \Cognitive \Exporter \CognitiveExporterFactory ;
1515use Phauthentic \CognitiveCodeAnalysis \Business \Cognitive \ScoreCalculator ;
16- use Phauthentic \CognitiveCodeAnalysis \CognitiveAnalysisException ;
1716use Phauthentic \CognitiveCodeAnalysis \Config \CognitiveConfig ;
1817use Phauthentic \CognitiveCodeAnalysis \Config \ConfigService ;
1918
@@ -81,14 +80,20 @@ public function getCognitiveMetrics(string $path): CognitiveMetricsCollection
8180 * Collects and returns cognitive metrics for multiple paths.
8281 *
8382 * @param array<string> $paths Array of file or directory paths to collect metrics from.
83+ * @param CoverageReportReaderInterface|null $coverageReader Optional coverage reader for coverage data.
8484 * @return CognitiveMetricsCollection The collected cognitive metrics from all paths.
8585 */
86- public function getCognitiveMetricsFromPaths (array $ paths ): CognitiveMetricsCollection
86+ public function getCognitiveMetricsFromPaths (array $ paths, ? CoverageReportReaderInterface $ coverageReader = null ): CognitiveMetricsCollection
8787 {
8888 $ metricsCollection = $ this ->cognitiveMetricsCollector ->collectFromPaths ($ paths , $ this ->configService ->getConfig ());
8989
9090 foreach ($ metricsCollection as $ metric ) {
9191 $ this ->scoreCalculator ->calculate ($ metric , $ this ->configService ->getConfig ());
92+
93+ // Add coverage data if reader is provided
94+ if ($ coverageReader !== null ) {
95+ $ this ->addCoverageToMetric ($ metric , $ coverageReader );
96+ }
9297 }
9398
9499 return $ metricsCollection ;
@@ -136,36 +141,6 @@ public function getConfig(): CognitiveConfig
136141 return $ this ->configService ->getConfig ();
137142 }
138143
139- /**
140- * Get all ignored classes and methods from the last metrics collection.
141- *
142- * @return array<string, array<string, string>> Array with 'classes' and 'methods' keys
143- */
144- public function getIgnored (): array
145- {
146- return $ this ->cognitiveMetricsCollector ->getIgnored ();
147- }
148-
149- /**
150- * Get ignored classes from the last metrics collection.
151- *
152- * @return array<string, string> Array of ignored class FQCNs
153- */
154- public function getIgnoredClasses (): array
155- {
156- return $ this ->cognitiveMetricsCollector ->getIgnoredClasses ();
157- }
158-
159- /**
160- * Get ignored methods from the last metrics collection.
161- *
162- * @return array<string, string> Array of ignored method keys (ClassName::methodName)
163- */
164- public function getIgnoredMethods (): array
165- {
166- return $ this ->cognitiveMetricsCollector ->getIgnoredMethods ();
167- }
168-
169144 /**
170145 * @param array<string, array<string, mixed>> $classes
171146 */
@@ -188,4 +163,48 @@ public function exportMetricsReport(
188163 $ exporter = $ this ->getCognitiveExporterFactory ()->create ($ reportType );
189164 $ exporter ->export ($ metricsCollection , $ filename );
190165 }
166+
167+ /**
168+ * Add coverage data to a metric
169+ */
170+ private function addCoverageToMetric (
171+ CognitiveMetrics $ metric ,
172+ CoverageReportReaderInterface $ coverageReader
173+ ): void {
174+ // Strip leading backslash from class name for coverage lookup
175+ $ className = ltrim ($ metric ->getClass (), '\\' );
176+
177+ // Try to get method-level coverage first
178+ $ coverageDetails = $ coverageReader ->getCoverageDetails ($ className );
179+ if ($ coverageDetails !== null ) {
180+ $ this ->addMethodLevelCoverage ($ metric , $ coverageDetails );
181+ return ;
182+ }
183+
184+ // Fall back to class-level coverage if details not available
185+ $ coverage = $ coverageReader ->getLineCoverage ($ className );
186+ if ($ coverage !== null ) {
187+ $ metric ->setCoverage ($ coverage );
188+ }
189+ }
190+
191+ /**
192+ * Add method-level coverage from coverage details
193+ */
194+ private function addMethodLevelCoverage (
195+ CognitiveMetrics $ metric ,
196+ CodeCoverage \CoverageDetails $ coverageDetails
197+ ): void {
198+ $ methods = $ coverageDetails ->getMethods ();
199+ $ methodName = $ metric ->getMethod ();
200+
201+ if (isset ($ methods [$ methodName ])) {
202+ $ methodCoverage = $ methods [$ methodName ];
203+ $ metric ->setCoverage ($ methodCoverage ->getLineRate ());
204+ return ;
205+ }
206+
207+ // Fall back to class-level coverage if method not found
208+ $ metric ->setCoverage ($ coverageDetails ->getLineRate ());
209+ }
191210}
0 commit comments