On Sat, 2 Oct 2021 at 16:37, tyson andre <[email protected]> wrote: > > Hi Andreas, > > > Hello list, > > I would like to propose new methods for ReflectionType, that would > > allow treating ReflectionNamedType and ReflectionUnionType in a > > unified way. > > This would eliminate the need for if (.. instanceof) in many use cases. > > > > Some details can still be discussed, e.g. whether 'null' should be > > included in builtin type names, whether there should be a canonical > > ordering of type names, whether we should use class names as array > > keys, etc. > > ... > > What do you think? > > Relatedly, I also had different ideas lately about new methods for > ReflectionType, though of a different form. > > 1. To simplify code that would check `instanceof` for all current and future > types such as `never` and `mixed` and intersection types > `ReflectionType->allowsValue(mixed $value, bool $strict = true): bool` > > Maybe also `allowsClass(string $className, bool $strict = true): bool` to > avoid needing to instantiate values (weak casting allows Stringable->string).
Ok for me, why not. I would see it as a distinct PR, separate from my original proposal. The problem or limitation of these methods is that they don't reflect the full expressiveness of the type system. That is, the return values of these methods would not be sufficient to recreate an equivalent type. > 2. To simplify code generation, e.g. in mocking libraries for unit testing: > `ReflectionType->toFullyQualifiedString(): string` (e.g. `\A|\B`) (may need > to throw ReflectionType for types that can't be resolved, e.g. `parent` in > reflection of traits, keep `static` as is) > > (The raw output of `__toString()` isn't prefixed with `\` (e.g. `A&B`) > and can't be used in namespaces Again, if we iron out the details, it can be a good idea as a distinct standalone PR. > > The fact that both intersection and union types (and possibility of union > types of full intersection types) > make it hard for me to believe that getBuiltinTypes and getBuiltinClasses > would be used correctly when used. Just to mention it, my proposed names were getBuiltinNames() and getClassNames() to be super clear that the return value will be string[]. For future intersection types, there could be additional methods getBuiltinIntersectionTypes() and getClassIntersectionTypes(), or it would be a single method getIntersectionTypes(). Not sure yet which combos make sense. E.g. array&callable would combine two builtin types, Countable&callable would combine a class-like type and a builtin type. Every type would be broken into a normal form, where the top-level is treated as a union type, and each item can either be a pure builtin type, a pure class type, or an intersection of pure types. int|string|(A&(B|(C&D))) === int | string | (A&B) | (A&C&D) If we always use this normal form, then the ReflectionIntersectionType only needs to have getBuiltinNames() and getClassNames(), not getUnionTypes(). Not sure yet what to do with 'static' and '$this'. > > Thanks, > Tyson > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
