prepare support for multi-types [ref #97]

This commit is contained in:
TomasVotruba 2017-10-25 11:18:48 +02:00
parent f37b1d3a7d
commit e80f408a75
7 changed files with 35 additions and 20 deletions

View File

@ -36,6 +36,6 @@ final class NodeTypeResolver
return $perNodeTypeResolver->resolve($node);
}
return null;
return [];
}
}

View File

@ -62,7 +62,10 @@ final class AssignTypeResolver implements PerNodeTypeResolverInterface, NodeType
$this->nodeTypeResolver = $nodeTypeResolver;
}
private function processAssignVariableNode(Assign $assignNode): ?string
/**
* @return string[]
*/
private function processAssignVariableNode(Assign $assignNode): array
{
if ($assignNode->var->name instanceof Variable) {
$name = $assignNode->var->name->name;
@ -75,7 +78,10 @@ final class AssignTypeResolver implements PerNodeTypeResolverInterface, NodeType
return $this->typeContext->getTypesForVariable($name);
}
private function resolveTypeForRightSide(Assign $assignNode): ?string
/**
* @return string[]
*/
private function resolveTypeForRightSide(Assign $assignNode): array
{
// $var = $anotherVar;
if ($assignNode->expr instanceof Variable) {
@ -92,6 +98,6 @@ final class AssignTypeResolver implements PerNodeTypeResolverInterface, NodeType
return $this->nodeTypeResolver->resolve($assignNode->expr);
}
return null;
return [];
}
}

View File

@ -52,15 +52,17 @@ final class MethodCallTypeResolver implements PerNodeTypeResolverInterface
$variableName = $variableNode->name;
$methodCallVariableType = $this->typeContext->getTypesForVariable($variableName);
$methodCallVariableTypes = $this->typeContext->getTypesForVariable($variableName);
$methodCallName = $this->resolveMethodCallName($methodCallNode);
// 2. get method() return type
if (! $methodCallVariableType || ! $methodCallName) {
if (! $methodCallVariableTypes || ! $methodCallName) {
return null;
}
$methodCallVariableType = array_pop($methodCallVariableTypes);
$variableType = $this->methodReflector->getMethodReturnType($methodCallVariableType, $methodCallName);
if ($variableType) {
$variableName = $this->getVariableToAssignTo($methodCallNode);
@ -68,7 +70,7 @@ final class MethodCallTypeResolver implements PerNodeTypeResolverInterface
return null;
}
$this->typeContext->addVariableWithType($variableName, $variableType);
$this->typeContext->addVariableWithType($variableName, [$variableType]);
}
return [$variableType];

View File

@ -31,22 +31,23 @@ final class NameTypeResolver implements PerNodeTypeResolverInterface
*/
public function resolve(Node $nameNode): array
{
$types = [];
/** @var Name|null $fqnName */
$fqnName = $nameNode->getAttribute(Attribute::RESOLVED_NAME);
if ($fqnName instanceof Name) {
$types = [];
if ($fqnName) {
$types[] = $fullyQualifiedName = $fqnName->toString();
}
$classLikeReflection = $this->smartClassReflector->reflect($fullyQualifiedName);
if ($fqnName instanceof Name) {
if ($fullyQualifiedName) {
$classLikeReflection = $this->smartClassReflector->reflect($fullyQualifiedName);
}
$types = array_merge($types, array_keys($classLikeReflection->getInterfaces()));
$types = array_merge($types, $classLikeReflection->getParentClassNames());
return $types;
}
return $nameNode->toString();
return $types;
}
}

View File

@ -57,7 +57,7 @@ final class PropertyTypeResolver implements PerNodeTypeResolverInterface
$propertyType = $this->namespaceAnalyzer->resolveTypeToFullyQualified($propertyType, $propertyNode);
$this->typeContext->addPropertyType($propertyName, $propertyType);
$this->typeContext->addPropertyTypes($propertyName, $propertyType);
return [$propertyType];
}

View File

@ -66,9 +66,12 @@ final class TypeContext
$this->classLikeNode = null;
}
public function addVariableWithType(string $variableName, string $variableType): void
/**
* @param string[] $variableTypes
*/
public function addVariableWithType(string $variableName, array $variableTypes): void
{
$this->variableTypes[$variableName] = $variableType;
$this->variableTypes[$variableName] = $variableTypes;
}
public function enterClassLike(ClassLike $classLikeNode): void
@ -117,9 +120,12 @@ final class TypeContext
$this->addVariableWithType($newVariable, $type);
}
public function addPropertyType(string $propertyName, string $propertyType): void
/**
* @param string[] $propertyTypes
*/
public function addPropertyTypes(string $propertyName, array $propertyTypes): void
{
$this->propertyTypes[$propertyName] = $propertyType;
$this->propertyTypes[$propertyName] = $propertyTypes;
}
/**

View File

@ -14,7 +14,7 @@ final class Test extends AbstractNodeTypeResolverTest
$variableNodes = $this->getNodesForFileOfType($file, Variable::class);
$this->assertSame(
'SomeNamespace\SomeClass_SomeNamespace\SomeInterface',
['SomeNamespace\SomeClass', 'SomeNamespace\SomeInterface'],
$variableNodes[0]->getAttribute(Attribute::TYPES)
);
}