Skip to content

Commit

Permalink
Merge pull request #476 from Roave/fix/#400-#410-normalize-source-pat…
Browse files Browse the repository at this point in the history
…hs-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
  • Loading branch information
Ocramius authored Mar 23, 2022
2 parents c192c45 + b124173 commit 2e51abb
Show file tree
Hide file tree
Showing 8 changed files with 432 additions and 32 deletions.
36 changes: 7 additions & 29 deletions src/Command/AssertBackwardsCompatible.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,41 +33,19 @@

final class AssertBackwardsCompatible extends Command
{
private PerformCheckoutOfRevision $git;

private ComposerInstallationReflectorFactory $makeComposerInstallationReflector;

private ParseRevision $parseRevision;

private GetVersionCollection $getVersions;

private PickVersionFromVersionCollection $pickFromVersion;

private LocateDependencies $locateDependencies;

private CompareApi $compareApi;

/**
* @throws LogicException
*/
public function __construct(
PerformCheckoutOfRevision $git,
ComposerInstallationReflectorFactory $makeComposerInstallationReflector,
ParseRevision $parseRevision,
GetVersionCollection $getVersions,
PickVersionFromVersionCollection $pickFromVersion,
LocateDependencies $locateDependencies,
CompareApi $compareApi
private PerformCheckoutOfRevision $git,
private ComposerInstallationReflectorFactory $makeComposerInstallationReflector,
private ParseRevision $parseRevision,
private GetVersionCollection $getVersions,
private PickVersionFromVersionCollection $pickFromVersion,
private LocateDependencies $locateDependencies,
private CompareApi $compareApi
) {
parent::__construct();

$this->git = $git;
$this->makeComposerInstallationReflector = $makeComposerInstallationReflector;
$this->parseRevision = $parseRevision;
$this->getVersions = $getVersions;
$this->pickFromVersion = $pickFromVersion;
$this->locateDependencies = $locateDependencies;
$this->compareApi = $compareApi;
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/LocateDependencies/LocateDependenciesViaComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Psl;
use Psl\Env;
use Psl\Filesystem;
use Roave\BackwardCompatibility\SourceLocator\ReplaceSourcePathOfLocatedSources;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
Expand Down Expand Up @@ -55,9 +56,11 @@ public function __invoke(string $installationPath, bool $includeDevelopmentDepen
$installer->run();
}, $installationPath);

$astLocator = new ReplaceSourcePathOfLocatedSources($this->astLocator, $installationPath);

return new AggregateSourceLocator([
new PhpInternalSourceLocator($this->astLocator, new ReflectionSourceStubber()),
(new MakeLocatorForInstalledJson())($installationPath, $this->astLocator),
new PhpInternalSourceLocator($astLocator, new ReflectionSourceStubber()),
(new MakeLocatorForInstalledJson())($installationPath, $astLocator),
]);
}

Expand Down
9 changes: 8 additions & 1 deletion src/LocateSources/LocateSourcesViaComposerJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Roave\BackwardCompatibility\LocateSources;

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

public function __invoke(string $installationPath): SourceLocator
{
return (new MakeLocatorForComposerJson())($installationPath, $this->astLocator);
return (new MakeLocatorForComposerJson())(
$installationPath,
new ReplaceSourcePathOfLocatedSources(
$this->astLocator,
$installationPath
)
);
}
}
62 changes: 62 additions & 0 deletions src/SourceLocator/LocatedSourceWithStrippedSourcesDirectory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Roave\BackwardCompatibility\SourceLocator;

use Roave\BetterReflection\SourceLocator\Located\LocatedSource;

use function str_starts_with;
use function strlen;
use function substr_replace;

/** @internal */
final class LocatedSourceWithStrippedSourcesDirectory extends LocatedSource
{
public function __construct(
private LocatedSource $next,
private string $sourcesDirectory
) {
}

public function getSource(): string
{
return $this->next->getSource();
}

public function getName(): ?string
{
return $this->next->getName();
}

public function getFileName(): ?string
{
$fileName = $this->next->getFileName();

if ($fileName === null || ! str_starts_with($fileName, $this->sourcesDirectory)) {
return $fileName;
}

return substr_replace($fileName, '', 0, strlen($this->sourcesDirectory));
}

public function isInternal(): bool
{
return $this->next->isInternal();
}

public function getExtensionName(): ?string
{
return $this->next->getExtensionName();
}

public function isEvaled(): bool
{
return $this->next->isEvaled();
}

public function getAliasName(): ?string
{
return $this->next->getAliasName();
}
}
48 changes: 48 additions & 0 deletions src/SourceLocator/ReplaceSourcePathOfLocatedSources.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Roave\BackwardCompatibility\SourceLocator;

use Roave\BetterReflection\Identifier\Identifier;
use Roave\BetterReflection\Identifier\IdentifierType;
use Roave\BetterReflection\Reflection\Reflection;
use Roave\BetterReflection\Reflector\Reflector;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;

/** @internal */
final class ReplaceSourcePathOfLocatedSources extends Locator
{
public function __construct(
private Locator $next,
private string $sourcesDirectory
) {
}

/** {@inheritDoc} */
public function findReflection(
Reflector $reflector,
LocatedSource $locatedSource,
Identifier $identifier,
): Reflection {
return $this->next->findReflection(
$reflector,
new LocatedSourceWithStrippedSourcesDirectory($locatedSource, $this->sourcesDirectory),
$identifier
);
}

/** {@inheritDoc} */
public function findReflectionsOfType(
Reflector $reflector,
LocatedSource $locatedSource,
IdentifierType $identifierType,
): array {
return $this->next->findReflectionsOfType(
$reflector,
new LocatedSourceWithStrippedSourcesDirectory($locatedSource, $this->sourcesDirectory),
$identifierType
);
}
}
8 changes: 8 additions & 0 deletions test/e2e/Command/AssertBackwardsCompatibleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ interface C {}
final class TheClass
{
public const UNCHANGED_CONSTANT = __DIR__;
public function method(A $a)
{
}
Expand All @@ -61,6 +63,8 @@ interface C {}
final class TheClass
{
public const UNCHANGED_CONSTANT = __DIR__;
public function method(B $a)
{
}
Expand All @@ -79,6 +83,8 @@ interface C {}
final class TheClass
{
public const UNCHANGED_CONSTANT = __DIR__;
public function method(C $a)
{
}
Expand All @@ -98,6 +104,8 @@ interface C {}
final class TheClass
{
public const UNCHANGED_CONSTANT = __DIR__;
public function method(A $a)
{
}
Expand Down
Loading

0 comments on commit 2e51abb

Please sign in to comment.