Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ New TypeString utility class #588

Merged
merged 1 commit into from
May 23, 2024
Merged

Conversation

jrfnl
Copy link
Member

@jrfnl jrfnl commented Apr 28, 2024

... to contain utilities methods for analysing typestrings as retrieved via the getParameters()/getProperties() methods.

Initially, the class comes with the following methods:

  • getKeywordTypes(): array to retrieve an array of all currently supported type keywords.
  • isKeyword(string $type): bool to determine whether a type is a keyword type.
  • normalizeCase(string $type): string to normalize the case of keyword types to lowercase, while leaving the case of OO-based types alone.
  • isSingular(string $typeString): bool to determine if a type is a purely singular type.
  • isNullable(string $typeString): bool to determine if a type is a nullable type, either by it having the nullable type operator or by including null as part of a union or DNF type.
  • isUnion(string $typeString): bool to determine if a type is a union type.
  • isIntersection(string $typeString): bool to determine if a type is an intersection type.
  • isDNF(string $typeString): bool to determine if a type is an intersection type.
  • toArray(string $typeString, bool $normalize = true): array to split a type string to its individual types and optionally normalize the case of the types.
  • toArrayUnique(string $typeString, bool $normalize = true): array to split a type string to its unique individual types and optionally normalize the case of the types.
  • filterKeywordTypes(array $types): array to filter an array with individual types as found in a type string down to only the keyword types.
  • filterOOTypes(array $types): array to filter an array with individual types as found in a type string down to only the OO-name based types.

Notes:

  • The methods in this class have limited or no handling for surrounding or internal whitespace as the type strings these methods are intended to be used with do not contain whitespace.
  • The behaviour with type strings not retrieved via the getParameters()/getProperties() methods, or non-type strings, is undefined. This includes type strings found in docblocks. Those are not typically supported by the methods in this class.
  • The is*() methods will not check if the type string provided is valid, as doing so would inhibit what sniffs can flag. The is*() methods will only look at the form of the type string to determine if it could be valid for a certain type. Use the PHPCSUtils\Utils\NamingConventions::isValidIdentifierName() method if additional validity checks are needed on the individual "types" seen in a type string. And, if needed, use token walking on the tokens of the type to determine whether a type string actually complies with the type rules as set by PHP.

Includes extensive unit tests.

@jrfnl jrfnl added this to the 1.1.0 milestone Apr 28, 2024
@jrfnl jrfnl mentioned this pull request Apr 28, 2024
28 tasks
@jrfnl jrfnl force-pushed the utils/new-types-utility-class branch 5 times, most recently from 181523f to b79838b Compare April 30, 2024 21:01
@jrfnl jrfnl force-pushed the utils/new-types-utility-class branch from b79838b to 3b72a79 Compare May 10, 2024 05:54
*
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException If passed $typeString is not a string.
*/
public static function toArrayUnique($typeString, $normalize = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrfnl please can you help me understand why this should be a separate method, rather than built-in functionality of toArray()? When would a consumer of this library want to have a list of types which are not unique?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When would a consumer of this library want to have a list of types which are not unique?

The most typical case is when a sniff wants to flag all uses of a certain class/interface name. If the name is used twice in the type, like (A&B)|(A&D), it should also be flagged twice.

More of an edge case would be an error prevention sniff flagging non-OO duplicates in a type, like https://3v4l.org/FFjpT, or OO type redundancy, like https://3v4l.org/1heQE.

@jrfnl jrfnl force-pushed the utils/new-types-utility-class branch from 5c9b44c to 2404514 Compare May 13, 2024 11:24
@jrfnl
Copy link
Member Author

jrfnl commented May 13, 2024

Rebased on top of #598 and added a commit to take advantage of the new exceptions. Moving to draft until #598 has been merged.

@jrfnl jrfnl changed the base branch from develop to feature/introduce-better-exceptions May 13, 2024 11:25
@jrfnl jrfnl marked this pull request as draft May 13, 2024 11:25
@jrfnl jrfnl force-pushed the utils/new-types-utility-class branch from 2404514 to 518d412 Compare May 13, 2024 11:28
@jrfnl jrfnl force-pushed the feature/introduce-better-exceptions branch from d06975f to 8b08c1e Compare May 20, 2024 18:18
Base automatically changed from feature/introduce-better-exceptions to develop May 20, 2024 18:24
... to contain utilities methods for analysing typestrings as retrieved via the `getParameters()`/`getProperties()` methods.

Initially, the class comes with the following methods:
* `getKeywordTypes(): array` to retrieve an array of all currently supported type keywords.
* `isKeyword(string $type): bool` to determine whether a type is a keyword type.
* `normalizeCase(string $type): string` to normalize the case of keyword types to lowercase, while leaving the case of OO-based types alone.
* `isSingular(string $typeString): bool` to determine if a type is a purely singular type.
* `isNullable(string $typeString): bool` to determine if a type is a nullable type, either by it having the nullable type operator or by including `null` as part of a union or DNF type.
* `isUnion(string $typeString): bool` to determine if a type is a union type.
* `isIntersection(string $typeString): bool` to determine if a type is an intersection type.
* `isDNF(string $typeString): bool` to determine if a type is an intersection type.
* `toArray(string $typeString, bool $normalize = true): array` to split a type string to its individual types and optionally normalize the case of the types.
* `toArrayUnique(string $typeString, bool $normalize = true): array` to split a type string to its unique individual types and optionally normalize the case of the types.
* `filterKeywordTypes(array $types): array` to filter an array with individual types as found in a type string down to only the keyword types.
* `filterOOTypes(array $types): array` to filter an array with individual types as found in a type string down to only the OO-name based types.

Notes:
* The methods in this class have limited or no handling for surrounding or internal whitespace as the type strings these methods are intended to be used with do not contain whitespace.
* The behaviour with type strings not retrieved via the `getParameters()`/`getProperties()` methods, or non-type strings, is undefined.
    This includes type strings found in docblocks. Those are not typically supported by the methods in this class.
* The `is*()` methods will **not** check if the type string provided is **_valid_**, as doing so would inhibit what sniffs can flag.
    The `is*()` methods will only look at the _form_ of the type string to determine if it _could_ be valid for a certain type.
    Use the {@see \PHPCSUtils\Utils\NamingConventions::isValidIdentifierName()} method if additional validity checks are needed on the individual "types" seen in a type string.
     And, if needed, use token walking on the tokens of the type to determine whether a type string actually complies with the type rules as set by PHP.

Includes extensive unit tests.
@jrfnl jrfnl force-pushed the utils/new-types-utility-class branch from 518d412 to 2b6d556 Compare May 23, 2024 20:29
@jrfnl
Copy link
Member Author

jrfnl commented May 23, 2024

Rebased without changes, other than squashing the commits.
Marking as ready as #598 has been merged now. Merging once the build passes.

@jrfnl jrfnl marked this pull request as ready for review May 23, 2024 20:30
@jrfnl jrfnl merged commit 8752e2b into develop May 23, 2024
54 checks passed
@jrfnl jrfnl deleted the utils/new-types-utility-class branch May 23, 2024 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants