Skip to content

Commit

Permalink
Some useful advanced PHPDoc types
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 4, 2023
1 parent 9850ea7 commit 387ebd5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/PhpDoc/TypeNodeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
case 'class-string':
case 'interface-string':
case 'trait-string':
case 'enum-string':
return new ClassStringType();

case 'callable-string':
Expand All @@ -215,6 +216,18 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco

return new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]);

case 'empty-scalar':
return TypeCombinator::intersect(
new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]),
StaticTypeFactory::falsey(),
);

case 'non-empty-scalar':
return TypeCombinator::remove(
new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]),
StaticTypeFactory::falsey(),
);

case 'number':
$type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope);

Expand Down Expand Up @@ -260,6 +273,13 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
new AccessoryNonFalsyStringType(),
]);

case 'non-empty-literal-string':
return new IntersectionType([
new StringType(),
new AccessoryNonEmptyStringType(),
new AccessoryLiteralStringType(),
]);

case 'bool':
return new BooleanType();

Expand Down Expand Up @@ -307,6 +327,7 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
return new IterableType(new MixedType(), new MixedType());

case 'callable':
case 'pure-callable':
return new CallableType();

case 'resource':
Expand All @@ -318,9 +339,15 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco

return new ResourceType();

case 'closed-resource':
return new ResourceType();

case 'mixed':
return new MixedType(true);

case 'non-empty-mixed':
return new MixedType(true, StaticTypeFactory::falsey());

case 'void':
return new VoidType();

Expand All @@ -330,6 +357,9 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
case 'callable-object':
return new IntersectionType([new ObjectWithoutClassType(), new CallableType()]);

case 'callable-array':
return new IntersectionType([new ArrayType(new MixedType(), new MixedType()), new CallableType()]);

case 'never':
case 'noreturn':
$type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope);
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-8609.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-8609-function.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9131.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/more-types.php');
}

/**
Expand Down
41 changes: 41 additions & 0 deletions tests/PHPStan/Analyser/data/more-types.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace MoreTypes;

use function PHPStan\Testing\assertType;

class Foo
{

/**
* @param pure-callable $pureCallable
* @param callable-array $callableArray
* @param closed-resource $closedResource
* @param enum-string $enumString
* @param non-empty-literal-string $nonEmptyLiteralString
* @param non-empty-scalar $nonEmptyScalar
* @param empty-scalar $emptyScalar
* @param non-empty-mixed $nonEmptyMixed
*/
public function doFoo(
$pureCallable,
$callableArray,
$closedResource,
$enumString,
$nonEmptyLiteralString,
$nonEmptyScalar,
$emptyScalar,
$nonEmptyMixed
): void
{
assertType('callable(): mixed', $pureCallable);
assertType('array&callable(): mixed', $callableArray);
assertType('resource', $closedResource);
assertType('class-string', $enumString);
assertType('literal-string&non-empty-string', $nonEmptyLiteralString);
assertType('float|int<min, -1>|int<1, max>|non-falsy-string|true', $nonEmptyScalar);
assertType("0|0.0|''|'0'|false", $emptyScalar);
assertType("mixed~0|0.0|''|'0'|array{}|false|null", $nonEmptyMixed);
}

}

0 comments on commit 387ebd5

Please sign in to comment.