Skip to content

Commit

Permalink
Implemented "new" in initializers
Browse files Browse the repository at this point in the history
  • Loading branch information
kukulich committed Oct 22, 2021
1 parent dce6176 commit 58f9ff2
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/NodeCompiler/CompileNodeToValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public function __invoke(Node $node, CompilerContext $context): CompiledValue
return $this->getClassConstantValue($node, $constantName, $context);
}

if ($node instanceof Node\Expr\New_) {
throw Exception\UnableToCompileNode::becauseOfInitializer($context, $node);
}

if ($node instanceof Node\Scalar\MagicConst\Dir) {
return $this->compileDirConstant($context);
}
Expand Down
15 changes: 14 additions & 1 deletion src/NodeCompiler/Exception/UnableToCompileNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node;
use Roave\BetterReflection\NodeCompiler\CompilerContext;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Roave\BetterReflection\Util\FileHelper;

use function assert;
use function sprintf;
Expand Down Expand Up @@ -70,9 +71,21 @@ public static function becauseOfNotFoundConstantReference(
return $exception;
}

public static function becauseOfInitializer(
CompilerContext $context,
Node\Expr\New_ $newNode,
): self {
return new self(sprintf(
'Unable to compile initializer in %s in file %s (line %d)',
self::compilerContextToContextDescription($context),
self::getFileName($context),
$newNode->getLine(),
));
}

private static function getFileName(CompilerContext $fetchContext): string
{
return $fetchContext->getFileName() ?? '""';
return $fetchContext->getFileName() !== null ? FileHelper::normalizeWindowsPath($fetchContext->getFileName()) : '""';
}

private static function compilerContextToContextDescription(CompilerContext $fetchContext): string
Expand Down
14 changes: 14 additions & 0 deletions test/unit/Fixture/NewInInitializers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Roave\BetterReflectionTest\Fixture;

use const PHP_VERSION_ID;

const SOME_CONSTANT = 'constant';

class ClassWithNewInInitializers
{
public function methodWithInitializer($parameterWithInitializer = new \ArrayObject(['a', 'b', SOME_CONSTANT, PHP_VERSION_ID, self::class, new \stdClass()]))
{
}
}
20 changes: 20 additions & 0 deletions test/unit/NodeCompiler/CompileNodeToValueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
use Roave\BetterReflection\Util\FileHelper;
use Roave\BetterReflectionTest\BetterReflectionSingleton;
use Roave\BetterReflectionTest\Fixture\ClassWithNewInInitializers;
use Roave\BetterReflectionTest\Fixture\MagicConstantsClass;
use Roave\BetterReflectionTest\Fixture\MagicConstantsTrait;

Expand Down Expand Up @@ -706,4 +707,23 @@ public function testMagicConstantsInFunction(string $parameterName, mixed $expec

self::assertSame($expectedValue, $parameter->getDefaultValue());
}

public function testThrowExceptionWhenValueContainsInitializer(): void
{
$file = FileHelper::normalizeWindowsPath(realpath(__DIR__ . '/../Fixture/NewInInitializers.php'));

$this->expectException(UnableToCompileNode::class);
$this->expectExceptionMessage(sprintf(
'Unable to compile initializer in method %s::methodWithInitializer() in file %s (line 11)',
ClassWithNewInInitializers::class,
$file,
));

$reflector = new DefaultReflector(new SingleFileSourceLocator($file, $this->astLocator));
$class = $reflector->reflectClass(ClassWithNewInInitializers::class);
$method = $class->getMethod('methodWithInitializer');
$parameter = $method->getParameter('parameterWithInitializer');

$parameter->getDefaultValue();
}
}
18 changes: 18 additions & 0 deletions test/unit/NodeCompiler/Exception/UnableToCompileNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\Yield_;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
Expand Down Expand Up @@ -34,6 +35,23 @@ public function testDefaults(): void
self::assertNull($exception->constantName());
}

/** @dataProvider supportedContextTypes */
public function testBecauseOfInitializer(CompilerContext $context, string $contextName): void
{
$exception = UnableToCompileNode::becauseOfInitializer(
$context,
new New_(new Name('SomeClass')),
);

self::assertSame(
sprintf(
'Unable to compile initializer in %s in file "" (line -1)',
$contextName,
),
$exception->getMessage(),
);
}

/** @dataProvider supportedContextTypes */
public function testBecauseOfNotFoundConstantReference(CompilerContext $context, string $contextName): void
{
Expand Down

0 comments on commit 58f9ff2

Please sign in to comment.