Skip to content

Commit

Permalink
Added support for int-mask, int-mask-of, non-falsy-string, truthy-string
Browse files Browse the repository at this point in the history
  • Loading branch information
vudaltsov committed Jan 19, 2024
1 parent d0e9305 commit 700ccbc
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Reflector/PhpDocTypeReflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ private function reflectIdentifier(string $name, array $genericTypes = []): Type
return $this->reflectInt($genericTypes);
}

if ($name === 'int-mask') {
return $this->reflectIntMask($genericTypes);
}

if ($name === 'int-mask-of') {
return $this->reflectIntMaskOf($genericTypes);
}

if ($name === 'list') {
return $this->reflectList($genericTypes);
}
Expand All @@ -121,6 +129,8 @@ private function reflectIdentifier(string $name, array $genericTypes = []): Type
return $this->reflectIterable($genericTypes);
}

// todo check no generics?
return match ($name) {
'null' => types::null,
'true' => types::true,
Expand All @@ -134,6 +144,7 @@ private function reflectIdentifier(string $name, array $genericTypes = []): Type
'numeric' => types::numeric,
'string' => types::string,
'non-empty-string' => types::nonEmptyString,
'non-falsy-string', 'truthy-string' => types::truthyString,
'numeric-string' => types::numericString,
'array-key' => types::arrayKey,
'literal-int' => types::literalInt,
Expand Down Expand Up @@ -203,6 +214,57 @@ private function reflectIntLimit(TypeNode $type, string $unlimitedName): ?int
throw new ReflectionException(sprintf('%s cannot be used as int range limit.', TypeStringifier::stringify($type)));
}

/**
* @param list<TypeNode> $templateArguments
*/
private function reflectIntMask(array $templateArguments): Type\IntMaskType
{
if ($templateArguments === []) {
throw new \LogicException();
}

return types::intMask(...array_map($this->reflectIntMaskInt(...), $templateArguments));
}

/**
* @return int<0, max>
*/
private function reflectIntMaskInt(TypeNode $node): int
{
if (!$node instanceof ConstTypeNode) {
throw new ReflectionException('TODO');
}

if (!$node->constExpr instanceof ConstExprIntegerNode) {
throw new ReflectionException('TODO');
}

$int = (int) $node->constExpr->value;

if ((string) $int !== $node->constExpr->value) {
throw new ReflectionException('TODO');
}

if ($int < 0) {
throw new ReflectionException('TODO');
}

return $int;
}

/**
* @param list<TypeNode> $templateArguments
*/
private function reflectIntMaskOf(array $templateArguments): Type\IntMaskOfType
{
if (\count($templateArguments) !== 1) {
throw new \LogicException();
}

/** @psalm-suppress MixedArgumentTypeCoercion */
return types::intMaskOf($this->doReflect($templateArguments[0]));
}

/**
* @param list<TypeNode> $templateArguments
*/
Expand Down

0 comments on commit 700ccbc

Please sign in to comment.