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

Support psalm #208

Open
lstrojny opened this issue Dec 19, 2019 · 10 comments
Open

Support psalm #208

lstrojny opened this issue Dec 19, 2019 · 10 comments

Comments

@lstrojny
Copy link
Owner

lstrojny commented Dec 19, 2019

Add psalm annotations

  • Fix all issues found by psalm
  • Increase type specificity
  • Add @psalm-pure
  • Add @psalm-assert
  • Add proper support for more complex cases like compose

Type specificity

  • Average
  • ButLast
  • Capture
  • CompareObjectHashOn
  • CompareOn
  • Compose
  • Concat
  • ConstFunction
  • Contains
  • Converge
  • Curry
  • CurryN
  • Difference
  • DropFirst
  • DropLast
  • Each
  • Equal
  • ErrorToException
  • Every
  • Exceptions/InvalidArgumentException
  • Exceptions/MatchException
  • False
  • Falsy
  • Filter
  • First
  • FirstIndexOf
  • FlatMap
  • Flatten
  • Flip
  • Functional
  • GreaterThan
  • GreaterThanOrEqual
  • Group
  • Head
  • Id
  • Identical
  • IfElse
  • IndexesOf
  • Intersperse
  • Invoke
  • InvokeFirst
  • InvokeIf
  • InvokeLast
  • Invoker
  • Last
  • LastIndexOf
  • LessThan
  • LessThanOrEqual
  • LexicographicCompare
  • Map
  • Match
  • Maximum
  • Memoize
  • Minimum
  • None
  • Noop
  • Not
  • OmitKeys
  • PartialAny
  • PartialLeft
  • PartialMethod
  • PartialRight
  • Partition
  • Pick
  • Pluck
  • Poll
  • Product
  • Ratio
  • ReduceLeft
  • ReduceRight
  • Reindex
  • Reject
  • Repeat
  • Retry
  • Select
  • SelectKeys
  • SequenceConstant
  • SequenceExponential
  • SequenceLinear
  • Sequences/ExponentialSequence
  • Sequences/LinearSequence
  • Some
  • Sort
  • Sum
  • SuppressError
  • Tail
  • TailRecursion
  • TakeLeft
  • TakeRight
  • Tap
  • True
  • Truthy
  • Unique
  • With
  • Zip
  • ZipAll

Issues

lstrojny added a commit that referenced this issue Dec 19, 2019
@alexeyshockov
Copy link
Contributor

Nice to see that you decided to go with Psalm! I think this is the best choice for a lib like yours, where templates and @psalm- specific annotations can really help end users.

I would like to help with the integration, if you don't mind (and if it's really needed...). Can start from the end of the list, to not mess with you.

@alexeyshockov
Copy link
Contributor

@lstrojny, please take a look at #209

@lstrojny
Copy link
Owner Author

@alexeyshockov it would be terrific to collaborate on this topic. I've just pushed my current WIP, would you mind rebasing. Unfortunately it’s going to create a few conflicts, sorry about that.
How about we agree to mark an item before working on it, so we avoid duplicate work?

@jkuchar
Copy link

jkuchar commented Jan 2, 2020

@ondrejmirtes Could @phpstan 0.12 also benefit from this work to make this available to even broader user base?

@ondrejmirtes
Copy link

@jkuchar PHPStan can benefit from generics annotations, not from "pure" or "assert" yet. Instead of assert annotations, right now a TypeSpecifyingExtension has to be written. There are already extensions like that for PHPUnit, for beberlei/assert and webmozart/assert.

Of course, an extension like this can be written to interpret these phpDoc annotations but no one did that yet.

@foalford
Copy link

One little thing to add: comment of variable length argument need a fix

It should be mixed ...$arguments. Otherwise, psalm always reports an error.

InvalidArgument - src/test.php:151:56 - Argument 2 of Functional\partial_right expects array<array-key, mixed>, string(BASE) provided

@klimick
Copy link

klimick commented Jun 28, 2020

Hi @lstrojny! Since 3.11.3 Psalm supports func_num_args() for conditional types. You could use for compose but with compromises.

/**
 * @template A
 * @template B
 * @template C
 * @template D
 * @template F
 * @template G
 * @template H
 * @template I
 *
 * @param callable(A):B $aToB
 * @param callable(B):C $bToC
 * @param callable(C):D $cToD
 * @param callable(D):F $dToF
 * @param callable(F):G $fToG
 * @param callable(G):H $gToH
 * @param callable(H):I $hToI
 *
 * @return (func_num_args() is 2 ? callable(A):C : (
 *          func_num_args() is 3 ? callable(A):D : (
 *          func_num_args() is 4 ? callable(A):F : (
 *          func_num_args() is 5 ? callable(A):G : (
 *          func_num_args() is 6 ? callable(A):H : (
 *          func_num_args() is 7 ? callable(A):I : callable
 *         ))))))
 */
function compose(
    callable $aToB,
    callable $bToC,
    callable $cToD = null,
    callable $dToF = null,
    callable $fToG = null,
    callable $gToH = null,
    callable $hToI = null,
    callable ...$others
) {
    // impl here
}

In this case you can type limited arguments count.
After the limit compose will return just callable.

Unfortunately you can pass null value instead of one of callable.

A similar solution used by rxjs

Inference example:
image

Error example:
image

@lstrojny
Copy link
Owner Author

@klimick that’s a great idea, thank you!

lstrojny added a commit that referenced this issue Jun 30, 2020
@jkuchar
Copy link

jkuchar commented Dec 21, 2020

Isn't this ready to be merged? (even incomplete) :-)

@adrienbrault
Copy link
Contributor

Hey, for anyone interested in psalm/phpstan support, there is an alternative to this library that has generics: azjezz/psl.

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

7 participants