Skip to content

Commit

Permalink
refactor: Introduce a Prefix value object
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry committed Jun 16, 2024
1 parent fbbcac0 commit a786f9b
Show file tree
Hide file tree
Showing 24 changed files with 180 additions and 72 deletions.
31 changes: 7 additions & 24 deletions src/Configuration/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@

use Humbug\PhpScoper\Configuration\Throwable\InvalidConfigurationValue;
use Humbug\PhpScoper\Patcher\Patcher;
use function Safe\preg_match;

final class Configuration
{
private const PREFIX_PATTERN = '/^[\p{L}\d_\\\\]+$/u';

/**
* @var non-empty-string
*/
private readonly string $prefix;
private readonly Prefix $prefix;

/**
* @param non-empty-string|null $path Absolute canonical path to the configuration file loaded.
Expand All @@ -43,15 +37,15 @@ final class Configuration
public function __construct(
private ?string $path,
private ?string $outputDir,
string $prefix,
string|Prefix $prefix,
private array $filesWithContents,
private array $excludedFilesWithContents,
private Patcher $patcher,
private SymbolsConfiguration $symbolsConfiguration
) {
self::validatePrefix($prefix);

$this->prefix = $prefix;
$this->prefix = $prefix instanceof Prefix
? $prefix
: new Prefix($prefix);
}

/**
Expand Down Expand Up @@ -89,9 +83,9 @@ public function withPrefix(string $prefix): self
}

/**
* @return non-empty-string
* @return non-empty-string|Prefix
*/
public function getPrefix(): string
public function getPrefix(): string|Prefix
{
return $this->prefix;
}
Expand Down Expand Up @@ -150,15 +144,4 @@ public function getSymbolsConfiguration(): SymbolsConfiguration
{
return $this->symbolsConfiguration;
}

private static function validatePrefix(string $prefix): void
{
if (1 !== preg_match(self::PREFIX_PATTERN, $prefix)) {
throw InvalidConfigurationValue::forInvalidPrefixPattern($prefix);
}

if (preg_match('/\\\{2,}/', $prefix)) {
throw InvalidConfigurationValue::forInvalidNamespaceSeparator($prefix);
}
}
}
35 changes: 35 additions & 0 deletions src/Configuration/Prefix.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* This file is part of the humbug/php-scoper package.
*
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
* Pádraic Brady <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Humbug\PhpScoper\Configuration;

use Stringable;

final readonly class Prefix implements Stringable
{
public function __construct(private string $prefix)
{
PrefixValidator::validate($this->prefix);
}

public function __toString(): string
{
return $this->prefix;
}

public function toString(): string
{
return (string) $this;
}
}
39 changes: 39 additions & 0 deletions src/Configuration/PrefixValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

/*
* This file is part of the humbug/php-scoper package.
*
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
* Pádraic Brady <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Humbug\PhpScoper\Configuration;

use Humbug\PhpScoper\Configuration\Throwable\InvalidConfigurationValue;
use function Safe\preg_match;

final class PrefixValidator
{
private const PREFIX_PATTERN = '/^[\p{L}\d_\\\\]+$/u';

/**
* @phpstan-assert non-empty-string $prefix
*
* @throws InvalidConfigurationValue
*/
public static function validate(string $prefix): void
{
if (1 !== preg_match(self::PREFIX_PATTERN, $prefix)) {
throw InvalidConfigurationValue::forInvalidPrefixPattern($prefix);
}

if (preg_match('/\\\{2,}/', $prefix)) {
throw InvalidConfigurationValue::forInvalidNamespaceSeparator($prefix);
}
}
}
3 changes: 2 additions & 1 deletion src/Console/ScoperLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use Fidry\Console\Application\Application as FidryApplication;
use Fidry\Console\IO;
use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\Throwable\Exception\ParsingException;
use PHPUnit\Framework\Attributes\CodeCoverageIgnore;
use Symfony\Component\Console\Helper\ProgressBar;
Expand Down Expand Up @@ -49,7 +50,7 @@ public function __construct(
/**
* @param string[] $paths
*/
public function outputScopingStart(?string $prefix, array $paths): void
public function outputScopingStart(Prefix|string|null $prefix, array $paths): void
{
$this->io->writeln($this->application->getHelp());

Expand Down
3 changes: 3 additions & 0 deletions src/Patcher/Patcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

namespace Humbug\PhpScoper\Patcher;

/**
* @phpstan-type PatcherCallable callable(string, string, string): string
*/
interface Patcher
{
public function __invoke(string $filePath, string $prefix, string $contents): string;
Expand Down
5 changes: 4 additions & 1 deletion src/Patcher/PatcherChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@

use function array_reduce;

/**
* @phpstan-import-type PatcherCallable from Patcher
*/
final readonly class PatcherChain implements Patcher
{
/**
* @param array<(callable(string, string, string): string)|Patcher> $patchers
* @param array<PatcherCallable|Patcher> $patchers
*/
public function __construct(private array $patchers = [])
{
Expand Down
12 changes: 8 additions & 4 deletions src/PhpParser/Node/FullyQualifiedFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@
use InvalidArgumentException;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use Stringable;

final class FullyQualifiedFactory
{
use NotInstantiable;

/**
* @param string|Name|string[]|null $name1
* @param string|Name|string[]|null $name2
* @param string|Name|string[]|Stringable|null $name1
* @param string|Name|string[]|Stringable|null $name2
*/
public static function concat(
array|Name|string|null $name1,
array|Name|string|null $name2,
array|Name|string|Stringable|null $name1,
array|Name|string|Stringable|null $name2,
?array $attributes = null,
): FullyQualified {
if (null === $name1 && null === $name2) {
Expand All @@ -38,6 +39,9 @@ public static function concat(

$newAttributes = NameFactory::getConcatenatedNamesAttributes($name1, $name2, $attributes);

$name1 = $name1 instanceof Stringable ? (string) $name1 : $name1;
$name2 = $name2 instanceof Stringable ? (string) $name2 : $name2;

return FullyQualified::concat($name1, $name2, $newAttributes);
}
}
9 changes: 5 additions & 4 deletions src/PhpParser/Node/NameFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Humbug\PhpScoper\NotInstantiable;
use InvalidArgumentException;
use PhpParser\Node\Name;
use Stringable;

final class NameFactory
{
Expand All @@ -41,12 +42,12 @@ public static function concat(
}

/**
* @param string|string[]|Name|null $name1
* @param string|string[]|Name|null $name2
* @param string|Stringable|string[]|Name|null $name1
* @param string|Stringable|string[]|Name|null $name2
*/
public static function getConcatenatedNamesAttributes(
string|array|Name|null $name1,
string|array|Name|null $name2,
string|Stringable|array|Name|null $name1,
string|Stringable|array|Name|null $name2,
?array $attributes = null,
): array {
return match (true) {
Expand Down
3 changes: 2 additions & 1 deletion src/PhpParser/NodeVisitor/ClassIdentifierRecorder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Humbug\PhpScoper\PhpParser\NodeVisitor;

use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\PhpParser\Node\FullyQualifiedFactory;
use Humbug\PhpScoper\PhpParser\NodeVisitor\AttributeAppender\ParentNodeAppender;
use Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver\IdentifierResolver;
Expand All @@ -35,7 +36,7 @@
final class ClassIdentifierRecorder extends NodeVisitorAbstract
{
public function __construct(
private readonly string $prefix,
private readonly Prefix $prefix,
private readonly IdentifierResolver $identifierResolver,
private readonly SymbolsRegistry $symbolsRegistry,
private readonly EnrichedReflector $enrichedReflector,
Expand Down
11 changes: 6 additions & 5 deletions src/PhpParser/NodeVisitor/ExcludedFunctionExistsEnricher.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Humbug\PhpScoper\PhpParser\NodeVisitor;

use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\PhpParser\NodeVisitor\AttributeAppender\ParentNodeAppender;
use Humbug\PhpScoper\PhpParser\UnexpectedParsingScenario;
use PhpParser\Node\Arg;
Expand Down Expand Up @@ -57,7 +58,7 @@
final class ExcludedFunctionExistsEnricher extends NodeVisitorAbstract
{
public function __construct(
private readonly string $prefix,
private readonly Prefix $prefix,
private readonly ExcludedFunctionExistsStringNodeStack $excludedFunctionExistsStringNodeStack,
) {
}
Expand All @@ -76,7 +77,7 @@ public function afterTraverse(array $nodes): array
return $nodes;
}

private static function addScopedFunctionExistsCondition(string $prefix, String_ $string): void
private static function addScopedFunctionExistsCondition(Prefix $prefix, String_ $string): void
{
$parentNodes = self::findFlattenedParentIfStmt($string);

Expand Down Expand Up @@ -154,7 +155,7 @@ private static function findFlattenedParentIfStmt(String_ $string): ?array
}

private static function replaceCondition(
string $prefix,
Prefix $prefix,
If_ $ifStmt,
BooleanAnd|BooleanOr|null $ifCondition,
BooleanNot|Equal|Identical $boolExpr,
Expand Down Expand Up @@ -217,11 +218,11 @@ private static function createNewArgument(Arg $previous, String_ $string): Arg
return $newArg;
}

private static function prefixString(string $prefix, String_ $previous): String_
private static function prefixString(Prefix $prefix, String_ $previous): String_
{
return new String_(
(string) FullyQualified::concat(
$prefix,
$prefix->toString(),
$previous->value,
),
$previous->getAttributes(),
Expand Down
3 changes: 2 additions & 1 deletion src/PhpParser/NodeVisitor/FunctionIdentifierRecorder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Humbug\PhpScoper\PhpParser\NodeVisitor;

use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\PhpParser\Node\FullyQualifiedFactory;
use Humbug\PhpScoper\PhpParser\NodeVisitor\AttributeAppender\ParentNodeAppender;
use Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver\IdentifierResolver;
Expand All @@ -38,7 +39,7 @@
final class FunctionIdentifierRecorder extends NodeVisitorAbstract
{
public function __construct(
private readonly string $prefix,
private readonly Prefix $prefix,
private readonly IdentifierResolver $identifierResolver,
private readonly SymbolsRegistry $symbolsRegistry,
private readonly EnrichedReflector $enrichedReflector,
Expand Down
5 changes: 3 additions & 2 deletions src/PhpParser/NodeVisitor/NameStmtPrefixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Humbug\PhpScoper\PhpParser\NodeVisitor;

use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\PhpParser\Node\FullyQualifiedFactory;
use Humbug\PhpScoper\PhpParser\NodeVisitor\AttributeAppender\ParentNodeAppender;
use Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt\NamespaceStmtCollection;
Expand Down Expand Up @@ -95,7 +96,7 @@ final class NameStmtPrefixer extends NodeVisitorAbstract
];

public function __construct(
private readonly string $prefix,
private readonly Prefix $prefix,
private readonly NamespaceStmtCollection $namespaceStatements,
private readonly UseStmtCollection $useStatements,
private readonly EnrichedReflector $enrichedReflector,
Expand Down Expand Up @@ -233,7 +234,7 @@ private function isNamePrefixable(Name $resolvedName): bool
return false;
}

$isAlreadyPrefixed = $this->prefix === $resolvedName->getFirst();
$isAlreadyPrefixed = $this->prefix->toString() === $resolvedName->getFirst();

return (
$isAlreadyPrefixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt;

use Humbug\PhpScoper\Configuration\Prefix;
use Humbug\PhpScoper\Symbol\EnrichedReflector;
use PhpParser\Node;
use PhpParser\Node\Name;
Expand All @@ -38,7 +39,7 @@
final class NamespaceStmtPrefixer extends NodeVisitorAbstract
{
public function __construct(
private readonly string $prefix,
private readonly Prefix $prefix,
private readonly EnrichedReflector $enrichedReflector,
private readonly NamespaceStmtCollection $namespaceStatements,
) {
Expand Down Expand Up @@ -75,11 +76,11 @@ private function shouldPrefixStmt(Namespace_ $namespace): bool
return $this->prefix !== $nameFirstPart;
}

private static function prefixStmt(Namespace_ $namespace, string $prefix): void
private static function prefixStmt(Namespace_ $namespace, Prefix $prefix): void
{
$originalName = $namespace->name;

$namespace->name = Name::concat($prefix, $originalName);
$namespace->name = Name::concat($prefix->toString(), $originalName);

NamespaceManipulator::setOriginalName($namespace, $originalName);
}
Expand Down
Loading

0 comments on commit a786f9b

Please sign in to comment.