Skip to content

Commit

Permalink
Annotated arrays are no longer checked, only when in properties
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed May 30, 2018
1 parent d966431 commit ad01d80
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 169 deletions.
4 changes: 2 additions & 2 deletions src/Analyser/NodeScopeResolver.php
Expand Up @@ -1056,7 +1056,7 @@ private function lookForAssigns(
'file_get_contents',
], true)
) {
$scope = $scope->assignVariable('http_response_header', new ArrayType(new IntegerType(), new StringType(), false), $certainty);
$scope = $scope->assignVariable('http_response_header', new ArrayType(new IntegerType(), new StringType()), $certainty);
}

if (
Expand Down Expand Up @@ -1538,7 +1538,7 @@ private function assignVariable(
}

if ($valueToWrite instanceof ErrorType) {
$valueToWrite = new ArrayType(new MixedType(), new MixedType(), true);
$valueToWrite = new ArrayType(new MixedType(), new MixedType());
}

$scope = $scope->assignVariable(
Expand Down
5 changes: 2 additions & 3 deletions src/Analyser/Scope.php
Expand Up @@ -715,8 +715,7 @@ private function resolveType(Expr $node): Type
if ($leftType instanceof ArrayType && $rightType instanceof ArrayType) {
return new ArrayType(
TypeCombinator::union($leftType->getKeyType(), $rightType->getKeyType()),
TypeCombinator::union($leftType->getItemType(), $rightType->getItemType()),
$leftType->isItemTypeInferredFromLiteralArray() || $rightType->isItemTypeInferredFromLiteralArray()
TypeCombinator::union($leftType->getItemType(), $rightType->getItemType())
);
}
}
Expand Down Expand Up @@ -1692,7 +1691,7 @@ public function getFunctionType($type = null, bool $isNullable, bool $isVariadic
$type,
false,
false
), false);
));
}
if ($type === null) {
return new MixedType();
Expand Down
24 changes: 20 additions & 4 deletions src/Rules/Arrays/AppendedArrayItemTypeRule.php
Expand Up @@ -6,18 +6,26 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\AssignOp;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Rules\RuleLevelHelper;
use PHPStan\Type\ArrayType;
use PHPStan\Type\VerbosityLevel;

class AppendedArrayItemTypeRule implements \PHPStan\Rules\Rule
{

/** @var \PHPStan\Rules\Properties\PropertyReflectionFinder */
private $propertyReflectionFinder;

/** @var \PHPStan\Rules\RuleLevelHelper */
private $ruleLevelHelper;

public function __construct(RuleLevelHelper $ruleLevelHelper)
public function __construct(
PropertyReflectionFinder $propertyReflectionFinder,
RuleLevelHelper $ruleLevelHelper
)
{
$this->propertyReflectionFinder = $propertyReflectionFinder;
$this->ruleLevelHelper = $ruleLevelHelper;
}

Expand All @@ -44,12 +52,20 @@ public function processNode(\PhpParser\Node $node, Scope $scope): array
return [];
}

$assignedToType = $scope->getType($node->var->var);
if (!($assignedToType instanceof ArrayType)) {
if (
!$node->var->var instanceof \PhpParser\Node\Expr\PropertyFetch
&& !$node->var->var instanceof \PhpParser\Node\Expr\StaticPropertyFetch
) {
return [];
}

if ($assignedToType->isItemTypeInferredFromLiteralArray()) {
$propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope);
if ($propertyReflection === null) {
return [];
}

$assignedToType = $propertyReflection->getType();
if (!($assignedToType instanceof ArrayType)) {
return [];
}

Expand Down
24 changes: 20 additions & 4 deletions src/Rules/Arrays/AppendedArrayKeyTypeRule.php
Expand Up @@ -5,6 +5,7 @@
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Type\ArrayType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\UnionType;
Expand All @@ -13,11 +14,18 @@
class AppendedArrayKeyTypeRule implements \PHPStan\Rules\Rule
{

/** @var PropertyReflectionFinder */
private $propertyReflectionFinder;

/** @var bool */
private $checkUnionTypes;

public function __construct(bool $checkUnionTypes)
public function __construct(
PropertyReflectionFinder $propertyReflectionFinder,
bool $checkUnionTypes
)
{
$this->propertyReflectionFinder = $propertyReflectionFinder;
$this->checkUnionTypes = $checkUnionTypes;
}

Expand All @@ -37,12 +45,20 @@ public function processNode(\PhpParser\Node $node, Scope $scope): array
return [];
}

$arrayType = $scope->getType($node->var->var);
if (!$arrayType instanceof ArrayType) {
if (
!$node->var->var instanceof \PhpParser\Node\Expr\PropertyFetch
&& !$node->var->var instanceof \PhpParser\Node\Expr\StaticPropertyFetch
) {
return [];
}

$propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope);
if ($propertyReflection === null) {
return [];
}

if ($arrayType->isItemTypeInferredFromLiteralArray()) {
$arrayType = $propertyReflection->getType();
if (!$arrayType instanceof ArrayType) {
return [];
}

Expand Down
30 changes: 8 additions & 22 deletions src/Type/ArrayType.php
Expand Up @@ -24,14 +24,10 @@ class ArrayType implements StaticResolvableType
/** @var \PHPStan\Type\Type */
private $itemType;

/** @var bool */
private $itemTypeInferredFromLiteralArray;

public function __construct(Type $keyType, Type $itemType, bool $itemTypeInferredFromLiteralArray = false)
public function __construct(Type $keyType, Type $itemType)
{
$this->keyType = $keyType;
$this->itemType = $itemType;
$this->itemTypeInferredFromLiteralArray = $itemTypeInferredFromLiteralArray;
}

public function getKeyType(): Type
Expand All @@ -55,11 +51,6 @@ public function getReferencedClasses(): array
);
}

public function isItemTypeInferredFromLiteralArray(): bool
{
return $this->itemTypeInferredFromLiteralArray;
}

public function accepts(Type $type): bool
{
if ($type instanceof self) {
Expand Down Expand Up @@ -110,28 +101,26 @@ public function unionWith(self $otherArray): Type
{
return new self(
TypeCombinator::union($this->getKeyType(), $otherArray->getKeyType()),
TypeCombinator::union($this->getIterableValueType(), $otherArray->getIterableValueType()),
$this->isItemTypeInferredFromLiteralArray() || $otherArray->isItemTypeInferredFromLiteralArray()
TypeCombinator::union($this->getIterableValueType(), $otherArray->getIterableValueType())
);
}

public function getKeysArray(): self
{
return new self(new IntegerType(), $this->keyType, true);
return new self(new IntegerType(), $this->keyType);
}

public function getValuesArray(): self
{
return new self(new IntegerType(), $this->itemType, true);
return new self(new IntegerType(), $this->itemType);
}

public function resolveStatic(string $className): Type
{
if ($this->getItemType() instanceof StaticResolvableType) {
return new self(
$this->keyType,
$this->getItemType()->resolveStatic($className),
$this->isItemTypeInferredFromLiteralArray()
$this->getItemType()->resolveStatic($className)
);
}

Expand All @@ -143,8 +132,7 @@ public function changeBaseClass(string $className): StaticResolvableType
if ($this->getItemType() instanceof StaticResolvableType) {
return new self(
$this->keyType,
$this->getItemType()->changeBaseClass($className),
$this->isItemTypeInferredFromLiteralArray()
$this->getItemType()->changeBaseClass($className)
);
}

Expand Down Expand Up @@ -199,8 +187,7 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType): Type

return new ArrayType(
TypeCombinator::union($this->keyType, self::castToArrayKeyType($offsetType)),
TypeCombinator::union($this->itemType, $valueType),
$this->itemTypeInferredFromLiteralArray
TypeCombinator::union($this->itemType, $valueType)
);
}

Expand Down Expand Up @@ -295,8 +282,7 @@ public static function __set_state(array $properties): Type
{
return new self(
$properties['keyType'],
$properties['itemType'],
$properties['itemTypeInferredFromLiteralArray']
$properties['itemType']
);
}

Expand Down
6 changes: 2 additions & 4 deletions src/Type/Constant/ConstantArrayType.php
Expand Up @@ -50,8 +50,7 @@ public function __construct(array $keyTypes, array $valueTypes, int $nextAutoInd

parent::__construct(
count($keyTypes) > 0 ? TypeCombinator::union(...$keyTypes) : new NeverType(),
count($valueTypes) > 0 ? TypeCombinator::union(...$valueTypes) : new NeverType(),
true
count($valueTypes) > 0 ? TypeCombinator::union(...$valueTypes) : new NeverType()
);

$this->keyTypes = $keyTypes;
Expand Down Expand Up @@ -347,8 +346,7 @@ public function generalize(): Type
{
return new ArrayType(
TypeUtils::generalizeType($this->getKeyType()),
$this->getItemType(),
true
$this->getItemType()
);
}

Expand Down
3 changes: 1 addition & 2 deletions src/Type/Constant/ConstantArrayTypeBuilder.php
Expand Up @@ -94,8 +94,7 @@ public function getArray(): ArrayType

return new ArrayType(
TypeCombinator::union(...$this->keyTypes),
TypeCombinator::union(...$this->valueTypes),
true
TypeCombinator::union(...$this->valueTypes)
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Type/FileTypeMapper.php
Expand Up @@ -91,7 +91,7 @@ public function getResolvedPhpDoc(
private function getResolvedPhpDocMap(string $fileName): array
{
if (!isset($this->memoryCache[$fileName])) {
$cacheKey = sprintf('%s-%d-v42', $fileName, filemtime($fileName));
$cacheKey = sprintf('%s-%d-v43', $fileName, filemtime($fileName));
$map = $this->cache->load($cacheKey);

if ($map === null) {
Expand Down
3 changes: 1 addition & 2 deletions src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php
Expand Up @@ -36,8 +36,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,

return new ArrayType(
$argumentType->getIterableKeyType(),
$argumentType->getIterableValueType(),
true
$argumentType->getIterableValueType()
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Type/Php/ArrayFillFunctionReturnTypeExtension.php
Expand Up @@ -29,12 +29,12 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
$valueType = $scope->getType($functionCall->args[2]->value);
$startIndexType = $scope->getType($functionCall->args[0]->value);
if (!$startIndexType instanceof ConstantIntegerType) {
return new ArrayType(new IntegerType(), $valueType, true);
return new ArrayType(new IntegerType(), $valueType);
}

$numberType = $scope->getType($functionCall->args[1]->value);
if (!$numberType instanceof ConstantIntegerType) {
return new ArrayType(new IntegerType(), $valueType, true);
return new ArrayType(new IntegerType(), $valueType);
}

$arrayBuilder = ConstantArrayTypeBuilder::createEmpty();
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Php/ArrayFillKeysFunctionReturnTypeExtension.php
Expand Up @@ -30,7 +30,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
$keysType = $scope->getType($functionCall->args[0]->value);
$constantArrays = TypeUtils::getConstantArrays($keysType);
if (count($constantArrays) === 0) {
return new ArrayType($keysType->getIterableValueType(), $valueType, true);
return new ArrayType($keysType->getIterableValueType(), $valueType);
}

$arrayTypes = [];
Expand Down
Expand Up @@ -49,7 +49,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
$itemType = new MixedType();
}

return new ArrayType($keyType, $itemType, true);
return new ArrayType($keyType, $itemType);
}

}
3 changes: 1 addition & 2 deletions src/Type/Php/ArrayKeysFunctionDynamicReturnTypeExtension.php
Expand Up @@ -31,8 +31,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,

return new ArrayType(
new IntegerType(),
new UnionType([new StringType(), new IntegerType()]),
true
new UnionType([new StringType(), new IntegerType()])
);
}

Expand Down
Expand Up @@ -30,8 +30,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,

return new ArrayType(
new IntegerType(),
new MixedType(),
true
new MixedType()
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Type/Php/ExplodeFunctionDynamicReturnTypeExtension.php
Expand Up @@ -36,7 +36,7 @@ public function getTypeFromFunctionCall(
if ($isSuperset->yes()) {
return new ConstantBooleanType(false);
} elseif ($isSuperset->no()) {
return new ArrayType(new IntegerType(), new StringType(), true);
return new ArrayType(new IntegerType(), new StringType());
}

return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
Expand Down
2 changes: 1 addition & 1 deletion src/Type/Php/IsArrayFunctionTypeSpecifyingExtension.php
Expand Up @@ -32,7 +32,7 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
throw new \PHPStan\ShouldNotHappenException();
}

return $this->typeSpecifier->create($node->args[0]->value, new ArrayType(new MixedType(), new MixedType(), true), $context);
return $this->typeSpecifier->create($node->args[0]->value, new ArrayType(new MixedType(), new MixedType()), $context);
}

public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void
Expand Down

0 comments on commit ad01d80

Please sign in to comment.