Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Do not import every single class #117

Merged
merged 1 commit into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions src/Extension/ObjectProphecyRevealDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,29 @@
namespace JanGregor\Prophecy\Extension;

use JanGregor\Prophecy\Type\ObjectProphecyType;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;

class ObjectProphecyRevealDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
use PhpParser\Node;
use PHPStan\Analyser;
use PHPStan\Reflection;
use PHPStan\Type;

class ObjectProphecyRevealDynamicReturnTypeExtension implements Type\DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return 'Prophecy\Prophecy\ObjectProphecy';
}

public function isMethodSupported(MethodReflection $methodReflection): bool
public function isMethodSupported(Reflection\MethodReflection $methodReflection): bool
{
return 'reveal' === $methodReflection->getName();
}

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
{
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
public function getTypeFromMethodCall(
Reflection\MethodReflection $methodReflection,
Node\Expr\MethodCall $methodCall,
Analyser\Scope $scope
): Type\Type {
$parametersAcceptor = Reflection\ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());

$calledOnType = $scope->getType($methodCall->var);

Expand All @@ -47,12 +46,12 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $returnType;
}

$types = \array_map(static function (string $class): ObjectType {
return new ObjectType($class);
$types = \array_map(static function (string $class): Type\ObjectType {
return new Type\ObjectType($class);
}, $calledOnType->getProphesizedClasses());

$types[] = $returnType;

return TypeCombinator::intersect(...$types);
return Type\TypeCombinator::intersect(...$types);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,20 @@
namespace JanGregor\Prophecy\Extension;

use JanGregor\Prophecy\Type\ObjectProphecyType;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PhpParser\Node;
use PHPStan\Analyser;
use PHPStan\Reflection;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type;

class ObjectProphecyWillExtendOrImplementDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
class ObjectProphecyWillExtendOrImplementDynamicReturnTypeExtension implements Type\DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return 'Prophecy\Prophecy\ObjectProphecy';
}

public function isMethodSupported(MethodReflection $methodReflection): bool
public function isMethodSupported(Reflection\MethodReflection $methodReflection): bool
{
$methodNames = [
'willImplement',
Expand All @@ -45,9 +41,12 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
);
}

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
{
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
public function getTypeFromMethodCall(
Reflection\MethodReflection $methodReflection,
Node\Expr\MethodCall $methodCall,
Analyser\Scope $scope
): Type\Type {
$parametersAcceptor = Reflection\ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());

$calledOnType = $scope->getType($methodCall->var);

Expand All @@ -63,13 +62,13 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method

$argumentType = $scope->getType($methodCall->args[0]->value);

if (!$argumentType instanceof ConstantStringType) {
if (!$argumentType instanceof Type\Constant\ConstantStringType) {
return $returnType;
}

$className = $argumentType->getValue();

if (!$returnType instanceof TypeWithClassName) {
if (!$returnType instanceof Type\TypeWithClassName) {
throw new ShouldNotHappenException();
}

Expand Down
29 changes: 14 additions & 15 deletions src/Extension/ProphetProphesizeDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@
namespace JanGregor\Prophecy\Extension;

use JanGregor\Prophecy\Type\ObjectProphecyType;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PhpParser\Node;
use PHPStan\Analyser;
use PHPStan\Reflection;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type;

class ProphetProphesizeDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
class ProphetProphesizeDynamicReturnTypeExtension implements Type\DynamicMethodReturnTypeExtension
{
private $className;

Expand All @@ -38,14 +34,17 @@ public function getClass(): string
return $this->className;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
public function isMethodSupported(Reflection\MethodReflection $methodReflection): bool
{
return 'prophesize' === $methodReflection->getName();
}

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
{
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
public function getTypeFromMethodCall(
Reflection\MethodReflection $methodReflection,
Node\Expr\MethodCall $methodCall,
Analyser\Scope $scope
): Type\Type {
$parametersAcceptor = Reflection\ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());

$returnType = $parametersAcceptor->getReturnType();

Expand All @@ -55,13 +54,13 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method

$argumentType = $scope->getType($methodCall->args[0]->value);

if (!$argumentType instanceof ConstantStringType) {
if (!$argumentType instanceof Type\Constant\ConstantStringType) {
return $returnType;
}

$className = $argumentType->getValue();

if (!$returnType instanceof TypeWithClassName) {
if (!$returnType instanceof Type\TypeWithClassName) {
throw new ShouldNotHappenException();
}

Expand Down
23 changes: 10 additions & 13 deletions src/PhpDoc/TypeNodeResolverExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,20 @@
namespace JanGregor\Prophecy\PhpDoc;

use JanGregor\Prophecy\Type\ObjectProphecyType;
use PHPStan\Analyser\NameScope;
use PHPStan\PhpDoc\TypeNodeResolver;
use PHPStan\PhpDoc\TypeNodeResolverAwareExtension;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Analyser;
use PHPStan\PhpDoc;
use PHPStan\PhpDocParser;
use PHPStan\Type;
use Prophecy\Prophecy\ObjectProphecy;

class TypeNodeResolverExtension implements \PHPStan\PhpDoc\TypeNodeResolverExtension, TypeNodeResolverAwareExtension
class TypeNodeResolverExtension implements PhpDoc\TypeNodeResolverAwareExtension, PhpDoc\TypeNodeResolverExtension
{
/**
* @var TypeNodeResolver
* @var PhpDoc\TypeNodeResolver
*/
private $typeNodeResolver;

public function setTypeNodeResolver(TypeNodeResolver $typeNodeResolver): void
public function setTypeNodeResolver(PhpDoc\TypeNodeResolver $typeNodeResolver): void
{
$this->typeNodeResolver = $typeNodeResolver;
}
Expand All @@ -40,9 +37,9 @@ public function getCacheKey(): string
return 'prophecy-v1';
}

public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type
public function resolve(PhpDocParser\Ast\Type\TypeNode $typeNode, Analyser\NameScope $nameScope): ?Type\Type
{
if (!$typeNode instanceof UnionTypeNode) {
if (!$typeNode instanceof PhpDocParser\Ast\Type\UnionTypeNode) {
return null;
}

Expand All @@ -53,7 +50,7 @@ public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type
foreach ($typeNode->types as $innerType) {
$type = $this->typeNodeResolver->resolve($innerType, $nameScope);

if ($type instanceof TypeWithClassName) {
if ($type instanceof Type\TypeWithClassName) {
if (ObjectProphecy::class === $type->getClassName()) {
$objectProphecyType = $type;
} else {
Expand Down
27 changes: 11 additions & 16 deletions src/Reflection/ObjectProphecyMethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,24 @@

namespace JanGregor\Prophecy\Reflection;

use PHPStan\Reflection\ClassMemberReflection;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\FunctionVariant;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Prophecy\Prophecy\MethodProphecy;
use PHPStan\Type;
use Prophecy\Prophecy;

class ObjectProphecyMethodReflection implements MethodReflection
class ObjectProphecyMethodReflection implements Reflection\MethodReflection
{
private $declaringClass;

private $name;

public function __construct(ClassReflection $declaringClass, string $name)
public function __construct(Reflection\ClassReflection $declaringClass, string $name)
{
$this->declaringClass = $declaringClass;
$this->name = $name;
}

public function getDeclaringClass(): ClassReflection
public function getDeclaringClass(): Reflection\ClassReflection
{
return $this->declaringClass;
}
Expand Down Expand Up @@ -63,17 +58,17 @@ public function getName(): string
public function getVariants(): array
{
return [
new FunctionVariant(
TemplateTypeMap::createEmpty(),
new Reflection\FunctionVariant(
Type\Generic\TemplateTypeMap::createEmpty(),
null,
[],
true,
new ObjectType(MethodProphecy::class)
new Type\ObjectType(Prophecy\MethodProphecy::class)
),
];
}

public function getPrototype(): ClassMemberReflection
public function getPrototype(): Reflection\ClassMemberReflection
{
return $this;
}
Expand All @@ -98,7 +93,7 @@ public function isInternal(): TrinaryLogic
return TrinaryLogic::createNo();
}

public function getThrowType(): ?Type
public function getThrowType(): ?Type\Type
{
return null;
}
Expand Down
10 changes: 4 additions & 6 deletions src/Reflection/ProphecyMethodsClassReflectionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,18 @@

namespace JanGregor\Prophecy\Reflection;

use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
use PHPStan\Reflection;

class ProphecyMethodsClassReflectionExtension implements MethodsClassReflectionExtension
class ProphecyMethodsClassReflectionExtension implements Reflection\MethodsClassReflectionExtension
{
public function hasMethod(ClassReflection $classReflection, string $methodName): bool
public function hasMethod(Reflection\ClassReflection $classReflection, string $methodName): bool
{
// don't know which class is prophesized here, so let's say yes to every method
// must match class in MockBuilderType parent::__construct() equivalent
return 'Prophecy\Prophecy\ObjectProphecy' === $classReflection->getName();
}

public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
public function getMethod(Reflection\ClassReflection $classReflection, string $methodName): Reflection\MethodReflection
{
return new ObjectProphecyMethodReflection($classReflection, $methodName);
}
Expand Down
10 changes: 4 additions & 6 deletions src/Type/ObjectProphecyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@

namespace JanGregor\Prophecy\Type;

use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\VerbosityLevel;
use PHPStan\Type;

class ObjectProphecyType extends ObjectType
class ObjectProphecyType extends Type\ObjectType
{
/**
* @var string[]
Expand All @@ -31,12 +29,12 @@ public function __construct(string ...$prophesizedClasses)
parent::__construct('Prophecy\Prophecy\ObjectProphecy');
}

public static function __set_state(array $properties): Type
public static function __set_state(array $properties): Type\Type
{
return new self($properties['prophesizedClasses']);
}

public function describe(VerbosityLevel $level): string
public function describe(Type\VerbosityLevel $level): string
{
return \sprintf(
'%s<%s>',
Expand Down