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

Choose a common phpdoc tag to assert that a parameter is of a given union type #3

Open
TysonAndre opened this issue Oct 26, 2019 · 4 comments

Comments

@TysonAndre
Copy link
Member

@param-assert UnionType $paramName or @x-assert UnionType $paramName are my best ideas so far.

Phan has @phan-assert, Psalm has @psalm-assert, PHPStan has an open issue, and I haven't checked to see if any similar tags exist elsewhere.

Psalm also has @psalm-assert-if-true and @psalm-assert-if-false - https://github.com/vimeo/psalm/blob/master/docs/annotating_code/adding_assertions.md

  • Possibly document implemented extensions such as truthy that aren't union types
  • Tool authors may wish to emit warnings if non-union types such as truthy are used in the common tag instead of the tool-specific phpdoc annotations
  • Having a common annotation will make it much easier for IDEs and other tools to make use of annotations in libraries in the future (e.g. webmozart/assert)

Related to phpstan/phpstan#2223

cc @ondrejmirtes @muglug @staabm

@ondrejmirtes
Copy link

Why only about union types? One could also assert a single (simple type).

What's more interesting than the tag name is the syntax needed for the type itself. See these Psalm docs: https://github.com/vimeo/psalm/blob/master/docs/annotating_code/assertion_syntax.md There's also !int and =int.

This feature should also work with generics:

/**
 * @template T
 * @param class-string<T> $type
 * @param mixed $x
 * @param-assert T $x
 */
function foo(string $type, $x)
{
}

foo(Foo::class, $x); // $x is Foo after this call

@TysonAndre
Copy link
Member Author

Why only about union types? One could also assert a single (simple type).

By union type, I mean a union type with 1 or more types, which includes the case of "a single (simple type)"

This feature should also work with generics:

I'd agree - that should follow naturally in implementations from the way an analyzer already parses types/union types for other tags

There's also !int and =int.

Tool authors may wish to emit warnings if non-union types such as truthy are used in the common tag instead of the tool-specific phpdoc annotations

I haven't gotten around to implementing that, but it'd be easy enough to add a rule to Phan or other analyzers to parse it and ignore it if support for the prefix wasn't implemented.

@ondrejmirtes
Copy link

I'd describe it as a "type" then because the user might also want to assert an intersection type.

@TysonAndre
Copy link
Member Author

I'd describe it as a "type" then because the user might also want to assert an intersection type.

Intersection types would also be permissible (I planned to implement pretty much anything you could already put in a @return or @param tag, plus the assert-specific syntax)

  • Intersection types aren't implemented in Phan but are planned.

I was thinking of "type" as the things that union types (and intersection types) contain. I thought you were referring to "atomic types"

  • I'd say that "union types" contain both "intersection types" and "atomic types", as I think they're called in Psalm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants