Skip to content

Commit

Permalink
Do not depend on sebastian/code-unit-reverse-lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Dec 8, 2024
1 parent 951acfc commit 1ad8a2d
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 23 deletions.
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"nikic/php-parser": "^5.3.1",
"phpunit/php-file-iterator": "^5.1.0",
"phpunit/php-text-template": "^4.0.1",
"sebastian/code-unit-reverse-lookup": "^4.0.1",
"sebastian/complexity": "^4.0.1",
"sebastian/environment": "^7.2.0",
"sebastian/lines-of-code": "^3.0.1",
Expand Down
5 changes: 1 addition & 4 deletions src/CodeCoverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
use SebastianBergmann\CodeCoverage\Test\Target\ValidationResult;
use SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
use SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
use SebastianBergmann\CodeUnitReverseLookup\Wizard;

/**
* Provides collection functionality for PHP code coverage information.
Expand All @@ -50,7 +49,6 @@ final class CodeCoverage
private const string UNCOVERED_FILES = 'UNCOVERED_FILES';
private readonly Driver $driver;
private readonly Filter $filter;
private readonly Wizard $wizard;
private ?Mapper $targetMapper = null;
private bool $checkForUnintentionallyCoveredCode = false;
private bool $ignoreDeprecatedCode = false;
Expand All @@ -77,7 +75,6 @@ public function __construct(Driver $driver, Filter $filter)
$this->driver = $driver;
$this->filter = $filter;
$this->data = new ProcessedCodeCoverageData;
$this->wizard = new Wizard;
}

/**
Expand Down Expand Up @@ -499,7 +496,7 @@ private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $dat
foreach ($data->lineCoverage() as $file => $_data) {
foreach ($_data as $line => $flag) {
if ($flag === 1 && !isset($allowedLines[$file][$line])) {
$unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
$unintentionallyCoveredUnits[] = $this->targetMapper->lookup($file, $line);
}
}
}
Expand Down
22 changes: 20 additions & 2 deletions src/Target/MapBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function build(Filter $filter, FileAnalyser $analyser): array
$traits = [];
$methods = [];
$functions = [];
$reverseLookup = [];

foreach ($filter->files() as $file) {
foreach ($analyser->interfacesIn($file) as $interface) {
Expand All @@ -55,7 +56,13 @@ public function build(Filter $filter, FileAnalyser $analyser): array
$this->process($classes, $class->namespacedName(), $file, $class->startLine(), $class->endLine());

foreach ($class->methods() as $method) {
$this->process($methods, $class->namespacedName() . '::' . $method->name(), $file, $method->startLine(), $method->endLine());
$methodName = $class->namespacedName() . '::' . $method->name();

$this->process($methods, $methodName, $file, $method->startLine(), $method->endLine());

foreach (range($method->startLine(), $method->endLine()) as $line) {
$reverseLookup[$file . ':' . $line] = $methodName;
}
}

$classesThatExtendClass[$class->namespacedName()] = [];
Expand All @@ -70,7 +77,13 @@ public function build(Filter $filter, FileAnalyser $analyser): array
$this->process($traits, $trait->namespacedName(), $file, $trait->startLine(), $trait->endLine());

foreach ($trait->methods() as $method) {
$this->process($methods, $trait->namespacedName() . '::' . $method->name(), $file, $method->startLine(), $method->endLine());
$methodName = $trait->namespacedName() . '::' . $method->name();

$this->process($methods, $methodName, $file, $method->startLine(), $method->endLine());

foreach (range($method->startLine(), $method->endLine()) as $line) {
$reverseLookup[$file . ':' . $line] = $methodName;
}
}
}

Expand All @@ -80,6 +93,10 @@ public function build(Filter $filter, FileAnalyser $analyser): array
}

$this->process($functions, $function->namespacedName(), $file, $function->startLine(), $function->endLine());

foreach (range($function->startLine(), $function->endLine()) as $line) {
$reverseLookup[$file . ':' . $line] = $function->namespacedName();
}
}
}

Expand Down Expand Up @@ -135,6 +152,7 @@ public function build(Filter $filter, FileAnalyser $analyser): array
'traits' => $traits,
'methods' => $methods,
'functions' => $functions,
'reverseLookup' => $reverseLookup,
];
}

Expand Down
20 changes: 19 additions & 1 deletion src/Target/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
use function sort;

/**
* @phpstan-type TargetMap = array{namespaces: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, traits: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart}
* @phpstan-type TargetMap = array{namespaces: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, traits: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart, reverseLookup: ReverseLookup}
* @phpstan-type TargetMapPart = array<non-empty-string, array<non-empty-string, list<positive-int>>>
* @phpstan-type ReverseLookup = array<non-empty-string, non-empty-string>
*
* @immutable
*
Expand Down Expand Up @@ -75,4 +76,21 @@ public function mapTarget(Target $target): array

return $this->map[$target->key()][$target->target()];
}

/**
* @param non-empty-string $file
* @param positive-int $line
*
* @return non-empty-string
*/
public function lookup(string $file, int $line): string
{
$key = $file . ':' . $line;

if (isset($this->map['reverseLookup'][$key])) {
return $this->map['reverseLookup'][$key];
}

return $key;
}
}
55 changes: 40 additions & 15 deletions tests/tests/Target/MapBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ final class MapBuilderTest extends TestCase
{
public function testBuildsMap(): void
{
$file = realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php');

$this->assertSame(
[
'namespaces' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => array_merge(
$file => array_merge(
range(19, 24),
range(26, 31),
range(33, 52),
Expand All @@ -38,58 +40,81 @@ public function testBuildsMap(): void
],
'classes' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParentClass' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(26, 31),
$file => range(26, 31),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ChildClass' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(33, 52),
$file => range(33, 52),
],
],
'classesThatExtendClass' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParentClass' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(33, 52),
$file => range(33, 52),
],
],
'classesThatImplementInterface' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\A' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(33, 52),
$file => range(33, 52),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\B' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(33, 52),
$file => range(33, 52),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\C' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(26, 31),
$file => range(26, 31),
],
],
'traits' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\T' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(19, 24),
$file => range(19, 24),
],
],
'methods' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParentClass::five' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(28, 30),
$file => range(28, 30),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ChildClass::six' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(37, 39),
$file => range(37, 39),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ChildClass::one' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(41, 43),
$file => range(41, 43),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ChildClass::two' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(45, 47),
$file => range(45, 47),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ChildClass::three' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(49, 51),
$file => range(49, 51),
],
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\T::four' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(21, 23),
$file => range(21, 23),
],
],
'functions' => [
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\f' => [
realpath(__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php') => range(54, 56),
$file => range(54, 56),
],
],
'reverseLookup' => [
$file . ':28' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ParentClass::five',
$file . ':29' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ParentClass::five',
$file . ':30' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ParentClass::five',
$file . ':37' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::six',
$file . ':38' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::six',
$file . ':39' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::six',
$file . ':41' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::one',
$file . ':42' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::one',
$file . ':43' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::one',
$file . ':45' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::two',
$file . ':46' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::two',
$file . ':47' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::two',
$file . ':49' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::three',
$file . ':50' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::three',
$file . ':51' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\ChildClass::three',
$file . ':21' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\T::four',
$file . ':22' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\T::four',
$file . ':23' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\T::four',
$file . ':54' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\f',
$file . ':55' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\f',
$file . ':56' => 'SebastianBergmann\CodeCoverage\StaticAnalysis\f',
],
],
$this->map([__DIR__ . '/../../_files/source_with_interfaces_classes_traits_functions.php']),
);
Expand Down

0 comments on commit 1ad8a2d

Please sign in to comment.