Skip to content

Commit

Permalink
fix: Preserve heredoc/newdoc indentation (#1037)
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry authored Jun 10, 2024
1 parent f21ea1b commit ead99dc
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 15 deletions.
3 changes: 3 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@ parameters:
path: 'src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php'
- message: '#PhpVersion::fromComponents#'
path: 'tests/SpecFramework/SpecScenario.php'
# Fixed in https://github.com/nikic/PHP-Parser/pull/1003
- message: '#Standard constructor expects array#'
path: 'src/Container.php'
43 changes: 43 additions & 0 deletions specs/misc/nowdoc.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/

use Humbug\PhpScoper\SpecFramework\Config\Meta;
use Humbug\PhpScoper\SpecFramework\Config\SpecWithConfig;

return [
'meta' => new Meta(
Expand Down Expand Up @@ -171,4 +172,46 @@
PHP_HEREDOC;

PHP,

// As per the RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
'Nowdoc and Heredoc indentation' => SpecWithConfig::create(
phpVersionUsed: 70_200,
spec: <<<'PHP'
<?php
// no indentation
echo <<<END
a
b
c
END;
// 4 spaces of indentation
echo <<<END
a
b
c
END;
----
<?php
namespace Humbug;
// no indentation
echo <<<END
a
b
c
END;
// 4 spaces of indentation
echo <<<END
a
b
c
END
;

PHP,
),
];
39 changes: 25 additions & 14 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ final class Container
private Filesystem $filesystem;
private ConfigurationFactory $configFactory;
private Parser $parser;
private ?PhpVersion $phpVersion = null;
private ?PhpVersion $parserPhpVersion = null;
private ?PhpVersion $printerPhpVersion = null;
private Reflector $reflector;
private ScoperFactory $scoperFactory;
private EnrichedReflectorFactory $enrichedReflectorFactory;
Expand Down Expand Up @@ -82,20 +83,11 @@ public function getScoperFactory(?PhpVersion $phpVersion = null): ScoperFactory
public function getParser(?PhpVersion $phpVersion = null): Parser
{
if (!isset($this->parser)) {
$this->phpVersion = $phpVersion;
$this->parserPhpVersion = $phpVersion;
$this->parser = $this->createParser($phpVersion);
}

$parserVersion = $this->phpVersion;

$parserMessage = 'Cannot use the existing parser: its PHP version is different than the one requested.';

if (null === $parserVersion) {
Assert::null($phpVersion, $parserMessage);
} else {
Assert::notNull($phpVersion, $parserMessage);
Assert::true($parserVersion->equals($phpVersion), $parserMessage);
}
self::checkSamePhpVersion($this->parserPhpVersion, $phpVersion);

return $this->parser;
}
Expand Down Expand Up @@ -130,14 +122,33 @@ public function getEnrichedReflectorFactory(): EnrichedReflectorFactory
return $this->enrichedReflectorFactory;
}

public function getPrinter(): Printer
public function getPrinter(?PhpVersion $phpVersion = null): Printer
{
if (!isset($this->printer)) {
$this->printerPhpVersion = $phpVersion;
$this->printer = new StandardPrinter(
new Standard(),
new Standard([
'phpVersion' => $phpVersion,
]),
);
}

self::checkSamePhpVersion($this->printerPhpVersion, $phpVersion);

return $this->printer;
}

private static function checkSamePhpVersion(
?PhpVersion $versionUsed,
?PhpVersion $versionRequest,
): void {
$parserMessage = 'Cannot use the existing parser: its PHP version is different than the one requested.';

if (null === $versionUsed) {
Assert::null($versionRequest, $parserMessage);
} else {
Assert::notNull($versionRequest, $parserMessage);
Assert::true($versionUsed->equals($versionRequest), $parserMessage);
}
}
}
27 changes: 27 additions & 0 deletions tests/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ public function test_it_can_get_the_parser_if_the_version_does_not_change(
$this->addToAssertionCount(1);
}

#[DataProvider('samePhpVersionProvider')]
public function test_it_can_get_the_printer_if_the_version_does_not_change(
?PhpVersion $version1,
?PhpVersion $version2,
): void {
$container = new Container();

$container->getPrinter($version1);
$container->getPrinter($version2);

$this->addToAssertionCount(1);
}

public static function samePhpVersionProvider(): iterable
{
yield 'no PHP version configured' => [
Expand Down Expand Up @@ -108,6 +121,20 @@ public function test_it_cannot_create_two_different_versions_of_the_parser(
$container->getParser($version2);
}

#[DataProvider('differentPhpVersionProvider')]
public function test_it_cannot_create_two_different_versions_of_the_printer(
?PhpVersion $version1,
?PhpVersion $version2,
): void {
$container = new Container();

$container->getPrinter($version1);

$this->expectException(InvalidArgumentException::class);

$container->getPrinter($version2);
}

public static function differentPhpVersionProvider(): iterable
{
$phpVersion = PhpVersion::fromString('7.2');
Expand Down
2 changes: 1 addition & 1 deletion tests/Scoper/PhpScoperSpecTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private static function createScoper(
$prefix,
$symbolsRegistry,
),
$container->getPrinter(),
$container->getPrinter($phpVersionUsed),
);
}

Expand Down

0 comments on commit ead99dc

Please sign in to comment.