-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/1.3.x' into 1.4.x
- Loading branch information
Showing
22 changed files
with
372 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
src/Type/Symfony/ExtensionGetConfigurationReturnTypeExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Type\Symfony; | ||
|
||
use PhpParser\Node\Expr\MethodCall; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Reflection\ClassReflection; | ||
use PHPStan\Reflection\MethodReflection; | ||
use PHPStan\Reflection\ReflectionProvider; | ||
use PHPStan\Type\DynamicMethodReturnTypeExtension; | ||
use PHPStan\Type\NullType; | ||
use PHPStan\Type\ObjectType; | ||
use PHPStan\Type\Type; | ||
use PHPStan\Type\TypeCombinator; | ||
use function str_contains; | ||
use function strrpos; | ||
use function substr_replace; | ||
|
||
class ExtensionGetConfigurationReturnTypeExtension implements DynamicMethodReturnTypeExtension | ||
{ | ||
|
||
/** @var ReflectionProvider */ | ||
private $reflectionProvider; | ||
|
||
public function __construct(ReflectionProvider $reflectionProvider) | ||
{ | ||
$this->reflectionProvider = $reflectionProvider; | ||
} | ||
|
||
public function getClass(): string | ||
{ | ||
return 'Symfony\Component\DependencyInjection\Extension\Extension'; | ||
} | ||
|
||
public function isMethodSupported(MethodReflection $methodReflection): bool | ||
{ | ||
return $methodReflection->getName() === 'getConfiguration' | ||
&& $methodReflection->getDeclaringClass()->getName() === 'Symfony\Component\DependencyInjection\Extension\Extension'; | ||
} | ||
|
||
public function getTypeFromMethodCall( | ||
MethodReflection $methodReflection, | ||
MethodCall $methodCall, | ||
Scope $scope | ||
): ?Type | ||
{ | ||
$types = []; | ||
$extensionType = $scope->getType($methodCall->var); | ||
$classes = $extensionType->getObjectClassNames(); | ||
|
||
foreach ($classes as $extensionName) { | ||
if (str_contains($extensionName, "\0")) { | ||
$types[] = new NullType(); | ||
continue; | ||
} | ||
|
||
$lastBackslash = strrpos($extensionName, '\\'); | ||
if ($lastBackslash === false) { | ||
$types[] = new NullType(); | ||
continue; | ||
} | ||
|
||
$configurationName = substr_replace($extensionName, '\Configuration', $lastBackslash); | ||
if (!$this->reflectionProvider->hasClass($configurationName)) { | ||
$types[] = new NullType(); | ||
continue; | ||
} | ||
|
||
$reflection = $this->reflectionProvider->getClass($configurationName); | ||
if ($this->hasRequiredConstructor($reflection)) { | ||
$types[] = new NullType(); | ||
continue; | ||
} | ||
|
||
$types[] = new ObjectType($configurationName); | ||
} | ||
|
||
return TypeCombinator::union(...$types); | ||
} | ||
|
||
private function hasRequiredConstructor(ClassReflection $class): bool | ||
{ | ||
if (!$class->hasConstructor()) { | ||
return false; | ||
} | ||
|
||
$constructor = $class->getConstructor(); | ||
foreach ($constructor->getVariants() as $variant) { | ||
$anyRequired = false; | ||
foreach ($variant->getParameters() as $parameter) { | ||
if (!$parameter->isOptional()) { | ||
$anyRequired = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!$anyRequired) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
stubs/Symfony/Component/Form/FormConfigBuilderInterface.stub
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\Form; | ||
|
||
/** | ||
* @template TData | ||
* | ||
* @extends FormConfigInterface<TData> | ||
*/ | ||
interface FormConfigBuilderInterface extends FormConfigInterface | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\Form; | ||
|
||
/** | ||
* @template TData | ||
*/ | ||
interface FormConfigInterface | ||
{ | ||
|
||
/** | ||
* @return TData | ||
*/ | ||
public function getData(): mixed; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
tests/Type/Symfony/data/extension/anonymous/AnonymousExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\Anonymous; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Extension\Extension; | ||
|
||
new class extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container) | ||
{ | ||
\PHPStan\Testing\assertType( | ||
'null', | ||
$this->getConfiguration($configs, $container) | ||
); | ||
} | ||
}; |
23 changes: 23 additions & 0 deletions
23
tests/Type/Symfony/data/extension/ignore-implemented/IgnoreImplementedExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\IgnoreImplemented; | ||
|
||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use \Symfony\Component\DependencyInjection\Extension\Extension; | ||
|
||
class IgnoreImplementedExtension extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container): void | ||
{ | ||
\PHPStan\Testing\assertType( | ||
'Symfony\Component\Config\Definition\ConfigurationInterface|null', | ||
$this->getConfiguration($configs, $container) | ||
); | ||
} | ||
|
||
public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface | ||
{ | ||
return null; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
tests/Type/Symfony/data/extension/multiple-types/MultipleTypes.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\MultipleTypes; | ||
|
||
use PHPStan\Type\Symfony\Extension\WithConfiguration\WithConfigurationExtension; | ||
use PHPStan\Type\Symfony\Extension\WithoutConfiguration\WithoutConfigurationExtension; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
|
||
/** | ||
* @param WithConfigurationExtension|WithoutConfigurationExtension $extension | ||
*/ | ||
function test($extension, array $configs, ContainerBuilder $container) | ||
{ | ||
\PHPStan\Testing\assertType( | ||
'PHPStan\Type\Symfony\Extension\WithConfiguration\Configuration|null', | ||
$extension->getConfiguration($configs, $container) | ||
); | ||
} |
16 changes: 16 additions & 0 deletions
16
...fony/data/extension/with-configuration-with-constructor-optional-params/Configuration.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructorOptionalParams; | ||
|
||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
|
||
class Configuration implements ConfigurationInterface | ||
{ | ||
public function __construct($foo = null) | ||
{ | ||
} | ||
|
||
public function getConfigTreeBuilder() | ||
{ | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...h-constructor-optional-params/WithConfigurationWithConstructorOptionalParamsExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructorOptionalParams; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use \Symfony\Component\DependencyInjection\Extension\Extension; | ||
|
||
class WithConfigurationWithConstructorOptionalParamsExtension extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container): void | ||
{ | ||
\PHPStan\Testing\assertType( | ||
Configuration::class, | ||
$this->getConfiguration($configs, $container) | ||
); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...fony/data/extension/with-configuration-with-constructor-required-params/Configuration.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructorRequiredParams; | ||
|
||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
|
||
class Configuration implements ConfigurationInterface | ||
{ | ||
public function __construct($foo) | ||
{ | ||
} | ||
|
||
public function getConfigTreeBuilder() | ||
{ | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...h-constructor-required-params/WithConfigurationWithConstructorRequiredParamsExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructorRequiredParams; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use \Symfony\Component\DependencyInjection\Extension\Extension; | ||
|
||
class WithConfigurationWithConstructorRequiredParamsExtension extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container): void | ||
{ | ||
\PHPStan\Testing\assertType( | ||
'null', | ||
$this->getConfiguration($configs, $container) | ||
); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
tests/Type/Symfony/data/extension/with-configuration-with-constructor/Configuration.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructor; | ||
|
||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
|
||
class Configuration implements ConfigurationInterface | ||
{ | ||
public function __construct() | ||
{ | ||
} | ||
|
||
public function getConfigTreeBuilder() | ||
{ | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...tension/with-configuration-with-constructor/WithConfigurationWithConstructorExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace PHPStan\Type\Symfony\Extension\WithConfigurationWithConstructor; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use \Symfony\Component\DependencyInjection\Extension\Extension; | ||
|
||
class WithConfigurationWithConstructorExtension extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container): void | ||
{ | ||
\PHPStan\Testing\assertType( | ||
Configuration::class, | ||
$this->getConfiguration($configs, $container) | ||
); | ||
} | ||
} |
Oops, something went wrong.