File tree Expand file tree Collapse file tree 2 files changed +30
-0
lines changed Expand file tree Collapse file tree 2 files changed +30
-0
lines changed Original file line number Diff line number Diff line change @@ -162,6 +162,8 @@ public function filter(): Filter
162162 */
163163 public function getData (bool $ raw = false ): ProcessedCodeCoverageData
164164 {
165+ $ this ->data ->finalize ();
166+
165167 if (!$ raw ) {
166168 if ($ this ->processUncoveredFiles ) {
167169 $ this ->processUncoveredFilesFromFilter ();
Original file line number Diff line number Diff line change @@ -188,6 +188,34 @@ public function merge(self $newData): void
188188 }
189189 }
190190
191+ public function finalize (): void
192+ {
193+ $ this ->ensureEmptyLinesAreMarkedNonExecutable ();
194+ }
195+
196+ /**
197+ * At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has
198+ * e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine
199+ * implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines
200+ * are considered non-executable for coverage purposes.
201+ *
202+ * @see https://github.com/sebastianbergmann/php-code-coverage/issues/799
203+ */
204+ private function ensureEmptyLinesAreMarkedNonExecutable (): void
205+ {
206+ foreach ($ this ->lineCoverage as $ filename => $ coverage ) {
207+ if (is_file ($ filename )) {
208+ $ sourceLines = explode ("\n" , file_get_contents ($ filename ));
209+
210+ foreach ($ coverage as $ line => $ lineCoverage ) {
211+ if (is_array ($ lineCoverage ) && trim ($ sourceLines [$ line - 1 ]) === '' ) {
212+ $ this ->lineCoverage [$ filename ][$ line ] = null ;
213+ }
214+ }
215+ }
216+ }
217+ }
218+
191219 /**
192220 * Determine the priority for a line.
193221 *
You can’t perform that action at this time.
0 commit comments