Skip to content
Permalink
Browse files

Merge pull request #569 from PHP-DI/567-silence-some-errors-at-compil…

…ation

Fix #567 Ignore errors for invalid referenced definitions during compilation
  • Loading branch information...
mnapoli committed Jan 20, 2018
2 parents f1b7b11 + f2ddc11 commit e4c85d7533525b22cab96cb7d3e64daeec8c1434
Showing with 70 additions and 2 deletions.
  1. +16 −2 src/Compiler/Compiler.php
  2. +54 −0 tests/IntegrationTest/CompiledContainerTest.php
@@ -95,8 +95,13 @@ public function compile(
// We use an ArrayIterator so that we can keep adding new items to the list while we compile entries
foreach ($this->entriesToCompile as $entryName => $definition) {
$silenceErrors = false;
// This is an entry found by reference during autowiring
if (!$definition) {
$definition = $definitionSource->getDefinition($entryName);
// We silence errors for those entries because type-hints may reference interfaces/abstract classes
// which could later be defined, or even not used (we don't want to block the compilation for those)
$silenceErrors = true;
}
if (!$definition) {
// We do not throw a `NotFound` exception here because the dependency
@@ -108,7 +113,16 @@ public function compile(
if ($errorMessage !== true) {
continue;
}
$this->compileDefinition($entryName, $definition);
try {
$this->compileDefinition($entryName, $definition);
} catch (InvalidDefinition $e) {
if ($silenceErrors) {
// forget the entry
unset($this->entryToMethodMapping[$entryName]);
} else {
throw $e;
}
}
}
$this->containerClass = $className;
@@ -147,7 +161,7 @@ private function compileDefinition(string $entryName, Definition $definition) :
$targetEntryName = $definition->getTargetEntryName();
$code = 'return $this->delegateContainer->get(' . $this->compileValue($targetEntryName) . ');';
// If this method is not yet compiled we store it for compilation
if (!isset($this->entryToMethodMapping[$targetEntryName])) {
if (!isset($this->entriesToCompile[$targetEntryName])) {
$this->entriesToCompile[$targetEntryName] = null;
}
break;
@@ -4,8 +4,10 @@
namespace DI\Test\IntegrationTest;
use function DI\autowire;
use DI\ContainerBuilder;
use function DI\create;
use DI\Definition\Exception\InvalidDefinition;
use function DI\get;
/**
@@ -171,6 +173,46 @@ public function recursively_compiles_referenced_definitions_found()
// Dependency of a dependency
$this->assertEntryIsCompiled($builder->build(), CompiledContainerTest\ConstructorWithAnotherTypehint::class);
}
/**
* @test
* @see https://github.com/PHP-DI/PHP-DI/issues/567
*/
public function invalid_definitions_referenced_in_the_configuration_throw_an_error()
{
$message = <<<MESSAGE
Entry "DI\Test\IntegrationTest\CompiledContainerTest\AbstractClass" cannot be compiled: the class is not instantiable
Full definition:
Object (
class = #NOT INSTANTIABLE# DI\Test\IntegrationTest\CompiledContainerTest\AbstractClass
lazy = false
)
MESSAGE;
$this->expectException(InvalidDefinition::class);
$this->expectExceptionMessage($message);
$builder = new ContainerBuilder;
$builder->addDefinitions([
CompiledContainerTest\ConstructorWithAbstractClassTypehint::class => autowire(),
CompiledContainerTest\AbstractClass::class => autowire(),
]);
$builder->enableCompilation(self::COMPILATION_DIR, self::generateCompiledClassName());
$builder->build();
}
/**
* @test
* @see https://github.com/PHP-DI/PHP-DI/issues/567
*/
public function invalid_definitions_transitively_referenced_are_skipped_and_do_not_throw_an_error()
{
$builder = new ContainerBuilder;
$builder->addDefinitions([
CompiledContainerTest\ConstructorWithAbstractClassTypehint::class => autowire(),
]);
$builder->enableCompilation(self::COMPILATION_DIR, self::generateCompiledClassName());
$builder->build();
$this->assertEntryIsNotCompiled($builder->build(), CompiledContainerTest\AbstractClass::class);
}
}
namespace DI\Test\IntegrationTest\CompiledContainerTest;
@@ -199,3 +241,15 @@ public function __construct(\stdClass $param)
}
}
class ConstructorWithAbstractClassTypehint
{
public function __construct(AbstractClass $param)
{
}
}
abstract class AbstractClass
{
}

0 comments on commit e4c85d7

Please sign in to comment.
You can’t perform that action at this time.