Skip to content

Commit 2e51abb

Browse files
authored
Merge pull request #476 from Roave/fix/#400-#410-normalize-source-paths-to-prevent-__DIR__-and-__FILE__-bc-break-false-positives
Normalize `__DIR__` and `__FILE__` by changing the base path of `LocatedSource` instances, prevent false-positive BC breaks on those magic constants
2 parents c192c45 + b124173 commit 2e51abb

8 files changed

+432
-32
lines changed

src/Command/AssertBackwardsCompatible.php

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,41 +33,19 @@
3333

3434
final class AssertBackwardsCompatible extends Command
3535
{
36-
private PerformCheckoutOfRevision $git;
37-
38-
private ComposerInstallationReflectorFactory $makeComposerInstallationReflector;
39-
40-
private ParseRevision $parseRevision;
41-
42-
private GetVersionCollection $getVersions;
43-
44-
private PickVersionFromVersionCollection $pickFromVersion;
45-
46-
private LocateDependencies $locateDependencies;
47-
48-
private CompareApi $compareApi;
49-
5036
/**
5137
* @throws LogicException
5238
*/
5339
public function __construct(
54-
PerformCheckoutOfRevision $git,
55-
ComposerInstallationReflectorFactory $makeComposerInstallationReflector,
56-
ParseRevision $parseRevision,
57-
GetVersionCollection $getVersions,
58-
PickVersionFromVersionCollection $pickFromVersion,
59-
LocateDependencies $locateDependencies,
60-
CompareApi $compareApi
40+
private PerformCheckoutOfRevision $git,
41+
private ComposerInstallationReflectorFactory $makeComposerInstallationReflector,
42+
private ParseRevision $parseRevision,
43+
private GetVersionCollection $getVersions,
44+
private PickVersionFromVersionCollection $pickFromVersion,
45+
private LocateDependencies $locateDependencies,
46+
private CompareApi $compareApi
6147
) {
6248
parent::__construct();
63-
64-
$this->git = $git;
65-
$this->makeComposerInstallationReflector = $makeComposerInstallationReflector;
66-
$this->parseRevision = $parseRevision;
67-
$this->getVersions = $getVersions;
68-
$this->pickFromVersion = $pickFromVersion;
69-
$this->locateDependencies = $locateDependencies;
70-
$this->compareApi = $compareApi;
7149
}
7250

7351
/**

src/LocateDependencies/LocateDependenciesViaComposer.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Psl;
1010
use Psl\Env;
1111
use Psl\Filesystem;
12+
use Roave\BackwardCompatibility\SourceLocator\ReplaceSourcePathOfLocatedSources;
1213
use Roave\BetterReflection\SourceLocator\Ast\Locator;
1314
use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber;
1415
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
@@ -55,9 +56,11 @@ public function __invoke(string $installationPath, bool $includeDevelopmentDepen
5556
$installer->run();
5657
}, $installationPath);
5758

59+
$astLocator = new ReplaceSourcePathOfLocatedSources($this->astLocator, $installationPath);
60+
5861
return new AggregateSourceLocator([
59-
new PhpInternalSourceLocator($this->astLocator, new ReflectionSourceStubber()),
60-
(new MakeLocatorForInstalledJson())($installationPath, $this->astLocator),
62+
new PhpInternalSourceLocator($astLocator, new ReflectionSourceStubber()),
63+
(new MakeLocatorForInstalledJson())($installationPath, $astLocator),
6164
]);
6265
}
6366

src/LocateSources/LocateSourcesViaComposerJson.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Roave\BackwardCompatibility\LocateSources;
66

7+
use Roave\BackwardCompatibility\SourceLocator\ReplaceSourcePathOfLocatedSources;
78
use Roave\BetterReflection\SourceLocator\Ast\Locator;
89
use Roave\BetterReflection\SourceLocator\Type\Composer\Factory\MakeLocatorForComposerJson;
910
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
@@ -19,6 +20,12 @@ public function __construct(Locator $astLocator)
1920

2021
public function __invoke(string $installationPath): SourceLocator
2122
{
22-
return (new MakeLocatorForComposerJson())($installationPath, $this->astLocator);
23+
return (new MakeLocatorForComposerJson())(
24+
$installationPath,
25+
new ReplaceSourcePathOfLocatedSources(
26+
$this->astLocator,
27+
$installationPath
28+
)
29+
);
2330
}
2431
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Roave\BackwardCompatibility\SourceLocator;
6+
7+
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
8+
9+
use function str_starts_with;
10+
use function strlen;
11+
use function substr_replace;
12+
13+
/** @internal */
14+
final class LocatedSourceWithStrippedSourcesDirectory extends LocatedSource
15+
{
16+
public function __construct(
17+
private LocatedSource $next,
18+
private string $sourcesDirectory
19+
) {
20+
}
21+
22+
public function getSource(): string
23+
{
24+
return $this->next->getSource();
25+
}
26+
27+
public function getName(): ?string
28+
{
29+
return $this->next->getName();
30+
}
31+
32+
public function getFileName(): ?string
33+
{
34+
$fileName = $this->next->getFileName();
35+
36+
if ($fileName === null || ! str_starts_with($fileName, $this->sourcesDirectory)) {
37+
return $fileName;
38+
}
39+
40+
return substr_replace($fileName, '', 0, strlen($this->sourcesDirectory));
41+
}
42+
43+
public function isInternal(): bool
44+
{
45+
return $this->next->isInternal();
46+
}
47+
48+
public function getExtensionName(): ?string
49+
{
50+
return $this->next->getExtensionName();
51+
}
52+
53+
public function isEvaled(): bool
54+
{
55+
return $this->next->isEvaled();
56+
}
57+
58+
public function getAliasName(): ?string
59+
{
60+
return $this->next->getAliasName();
61+
}
62+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Roave\BackwardCompatibility\SourceLocator;
6+
7+
use Roave\BetterReflection\Identifier\Identifier;
8+
use Roave\BetterReflection\Identifier\IdentifierType;
9+
use Roave\BetterReflection\Reflection\Reflection;
10+
use Roave\BetterReflection\Reflector\Reflector;
11+
use Roave\BetterReflection\SourceLocator\Ast\Locator;
12+
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
13+
14+
/** @internal */
15+
final class ReplaceSourcePathOfLocatedSources extends Locator
16+
{
17+
public function __construct(
18+
private Locator $next,
19+
private string $sourcesDirectory
20+
) {
21+
}
22+
23+
/** {@inheritDoc} */
24+
public function findReflection(
25+
Reflector $reflector,
26+
LocatedSource $locatedSource,
27+
Identifier $identifier,
28+
): Reflection {
29+
return $this->next->findReflection(
30+
$reflector,
31+
new LocatedSourceWithStrippedSourcesDirectory($locatedSource, $this->sourcesDirectory),
32+
$identifier
33+
);
34+
}
35+
36+
/** {@inheritDoc} */
37+
public function findReflectionsOfType(
38+
Reflector $reflector,
39+
LocatedSource $locatedSource,
40+
IdentifierType $identifierType,
41+
): array {
42+
return $this->next->findReflectionsOfType(
43+
$reflector,
44+
new LocatedSourceWithStrippedSourcesDirectory($locatedSource, $this->sourcesDirectory),
45+
$identifierType
46+
);
47+
}
48+
}

test/e2e/Command/AssertBackwardsCompatibleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ interface C {}
4343
4444
final class TheClass
4545
{
46+
public const UNCHANGED_CONSTANT = __DIR__;
47+
4648
public function method(A $a)
4749
{
4850
}
@@ -61,6 +63,8 @@ interface C {}
6163
6264
final class TheClass
6365
{
66+
public const UNCHANGED_CONSTANT = __DIR__;
67+
6468
public function method(B $a)
6569
{
6670
}
@@ -79,6 +83,8 @@ interface C {}
7983
8084
final class TheClass
8185
{
86+
public const UNCHANGED_CONSTANT = __DIR__;
87+
8288
public function method(C $a)
8389
{
8490
}
@@ -98,6 +104,8 @@ interface C {}
98104
99105
final class TheClass
100106
{
107+
public const UNCHANGED_CONSTANT = __DIR__;
108+
101109
public function method(A $a)
102110
{
103111
}

0 commit comments

Comments
 (0)