From 83ef99aeaf74e1867c388f3169044a9cac4e73a1 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sun, 28 Jan 2024 02:14:41 +0300 Subject: [PATCH 1/2] Added StaticType::$declaredAtClass, TemplateType::$declaredAt, $constraint --- src/AtClass.php | 28 +++++++++++++++++++++++++++ src/AtFunction.php | 28 +++++++++++++++++++++++++++ src/AtMethod.php | 36 +++++++++++++++++++++++++++++++++++ src/StaticType.php | 8 ++++++++ src/TemplateType.php | 8 ++++++++ src/types.php | 36 +++++++++++++++++++++++++++++++---- tests/psalm/StaticType.phpt | 4 ++-- tests/psalm/TemplateType.phpt | 2 +- 8 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 src/AtClass.php create mode 100644 src/AtFunction.php create mode 100644 src/AtMethod.php diff --git a/src/AtClass.php b/src/AtClass.php new file mode 100644 index 0000000..9a3d84f --- /dev/null +++ b/src/AtClass.php @@ -0,0 +1,28 @@ +name = $name; + } +} diff --git a/src/AtFunction.php b/src/AtFunction.php new file mode 100644 index 0000000..c7b3e85 --- /dev/null +++ b/src/AtFunction.php @@ -0,0 +1,28 @@ +name = $name; + } +} diff --git a/src/AtMethod.php b/src/AtMethod.php new file mode 100644 index 0000000..132a190 --- /dev/null +++ b/src/AtMethod.php @@ -0,0 +1,36 @@ +class = $class; + $this->name = $name; + } +} diff --git a/src/StaticType.php b/src/StaticType.php index 10c94e9..b96c415 100644 --- a/src/StaticType.php +++ b/src/StaticType.php @@ -12,6 +12,11 @@ */ final class StaticType implements Type { + /** + * @var class-string + */ + public readonly string $declaredAtClass; + /** * @var list */ @@ -21,11 +26,14 @@ final class StaticType implements Type * @internal * @psalm-internal Typhoon\Type * @no-named-arguments + * @param class-string $declaredAtClass * @param list $templateArguments */ public function __construct( + string $declaredAtClass, array $templateArguments = [], ) { + $this->declaredAtClass = $declaredAtClass; $this->templateArguments = $templateArguments; } diff --git a/src/TemplateType.php b/src/TemplateType.php index 916cec7..81b811a 100644 --- a/src/TemplateType.php +++ b/src/TemplateType.php @@ -17,6 +17,10 @@ final class TemplateType implements Type */ public readonly string $name; + public readonly AtMethod|AtClass|AtFunction $declaredAt; + + public readonly Type $constraint; + /** * @internal * @psalm-internal Typhoon\Type @@ -24,8 +28,12 @@ final class TemplateType implements Type */ public function __construct( string $name, + AtFunction|AtClass|AtMethod $declaredAt, + Type $constraint, ) { $this->name = $name; + $this->declaredAt = $declaredAt; + $this->constraint = $constraint; } public function accept(TypeVisitor $visitor): mixed diff --git a/src/types.php b/src/types.php index 8ffaf18..68c7ec9 100644 --- a/src/types.php +++ b/src/types.php @@ -265,10 +265,13 @@ public static function object(string $class, Type ...$templateArguments): NamedO /** * @psalm-pure * @no-named-arguments + * @template TObject of object + * @param class-string $declaredAtClass + * @return StaticType */ - public static function static(Type ...$templateArguments): StaticType + public static function static(string $declaredAtClass, Type ...$templateArguments): StaticType { - return new StaticType($templateArguments); + return new StaticType($declaredAtClass, $templateArguments); } /** @@ -369,9 +372,34 @@ public static function valueOf(Type $type): ValueOfType * @psalm-pure * @param non-empty-string $name */ - public static function template(string $name): TemplateType + public static function template(string $name, AtMethod|AtClass|AtFunction $declaredAt, Type $constraint = self::mixed): TemplateType + { + return new TemplateType($name, $declaredAt, $constraint); + } + + /** + * @param callable-string $name + */ + public static function atFunction(string $name): AtFunction + { + return new AtFunction($name); + } + + /** + * @param class-string $name + */ + public static function atClass(string $name): AtClass + { + return new AtClass($name); + } + + /** + * @param class-string $class + * @param non-empty-string $name + */ + public static function atMethod(string $class, string $name): AtMethod { - return new TemplateType($name); + return new AtMethod($class, $name); } /** diff --git a/tests/psalm/StaticType.phpt b/tests/psalm/StaticType.phpt index a6ecbd8..af7b233 100644 --- a/tests/psalm/StaticType.phpt +++ b/tests/psalm/StaticType.phpt @@ -3,7 +3,7 @@ namespace Typhoon\Type; -$_type = PsalmTest::extractType(new StaticType()); -/** @psalm-check-type-exact $_type = \object */ +$_type = PsalmTest::extractType(new StaticType(\stdClass::class)); +/** @psalm-check-type-exact $_type = \stdClass */ --EXPECT-- diff --git a/tests/psalm/TemplateType.phpt b/tests/psalm/TemplateType.phpt index 501e025..256ebe9 100644 --- a/tests/psalm/TemplateType.phpt +++ b/tests/psalm/TemplateType.phpt @@ -3,7 +3,7 @@ namespace Typhoon\Type; -$_type = PsalmTest::extractType(new TemplateType('T')); +$_type = PsalmTest::extractType(new TemplateType('T', new AtFunction('trim'), MixedType::type)); /** @psalm-check-type-exact $_type = \mixed */ --EXPECT-- From 4c0ea2bedd58d296a23e47bf95bcf98caec92f21 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sun, 28 Jan 2024 13:06:57 +0300 Subject: [PATCH 2/2] Use Type to TemplateType::$constraint --- src/TemplateType.php | 4 ++++ src/types.php | 3 +++ tests/psalm/TemplateType.phpt | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/TemplateType.php b/src/TemplateType.php index 81b811a..43f4d34 100644 --- a/src/TemplateType.php +++ b/src/TemplateType.php @@ -19,12 +19,16 @@ final class TemplateType implements Type public readonly AtMethod|AtClass|AtFunction $declaredAt; + /** + * @var Type + */ public readonly Type $constraint; /** * @internal * @psalm-internal Typhoon\Type * @param non-empty-string $name + * @param Type $constraint */ public function __construct( string $name, diff --git a/src/types.php b/src/types.php index 68c7ec9..2055dd3 100644 --- a/src/types.php +++ b/src/types.php @@ -370,7 +370,10 @@ public static function valueOf(Type $type): ValueOfType /** * @psalm-pure + * @template TType * @param non-empty-string $name + * @param Type $constraint + * @return TemplateType */ public static function template(string $name, AtMethod|AtClass|AtFunction $declaredAt, Type $constraint = self::mixed): TemplateType { diff --git a/tests/psalm/TemplateType.phpt b/tests/psalm/TemplateType.phpt index 256ebe9..1042e36 100644 --- a/tests/psalm/TemplateType.phpt +++ b/tests/psalm/TemplateType.phpt @@ -3,7 +3,7 @@ namespace Typhoon\Type; -$_type = PsalmTest::extractType(new TemplateType('T', new AtFunction('trim'), MixedType::type)); -/** @psalm-check-type-exact $_type = \mixed */ +$_type = PsalmTest::extractType(new TemplateType('T', new AtFunction('trim'), ObjectType::type)); +/** @psalm-check-type-exact $_type = \object */ --EXPECT--