| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Sub::Meta::Param; | 
| 2 | 36 |  |  | 36 |  | 2617000 | use 5.010; | 
|  | 36 |  |  |  |  | 201 |  | 
| 3 | 36 |  |  | 36 |  | 182 | use strict; | 
|  | 36 |  |  |  |  | 65 |  | 
|  | 36 |  |  |  |  | 879 |  | 
| 4 | 36 |  |  | 36 |  | 185 | use warnings; | 
|  | 36 |  |  |  |  | 68 |  | 
|  | 36 |  |  |  |  | 1972 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | our $VERSION = "0.13"; | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 36 |  |  | 36 |  | 248 | use Scalar::Util (); | 
|  | 36 |  |  |  |  | 83 |  | 
|  | 36 |  |  |  |  | 1572 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | use overload | 
| 11 | 36 |  |  |  |  | 398 | fallback => 1, | 
| 12 |  |  |  |  |  |  | eq       =>  \&is_same_interface, | 
| 13 | 36 |  |  | 36 |  | 266 | ; | 
|  | 36 |  |  |  |  | 67 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | my %DEFAULT = ( named => 0, optional => 0, invocant => 0 ); | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | sub new { | 
| 18 | 215 |  |  | 215 | 1 | 148803 | my ($class, @args) = @_; | 
| 19 | 215 |  |  |  |  | 354 | my $v = $args[0]; | 
| 20 | 215 | 100 | 100 |  |  | 925 | my %args = @args == 1 ? ref $v && (ref $v eq 'HASH') ? %{$v} | 
|  | 75 | 100 |  |  |  | 337 |  | 
| 21 |  |  |  |  |  |  | : ( type => $v ) | 
| 22 |  |  |  |  |  |  | : @args; | 
| 23 |  |  |  |  |  |  |  | 
| 24 | 215 | 100 |  |  |  | 599 | $args{optional} = !delete $args{required} if exists $args{required}; | 
| 25 | 215 | 100 |  |  |  | 460 | $args{named}    = !delete $args{positional} if exists $args{positional}; | 
| 26 | 215 | 100 |  |  |  | 424 | $args{type}     = delete $args{isa} if exists $args{isa}; | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 215 |  |  |  |  | 925 | %args = (%DEFAULT, %args); | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 215 |  |  |  |  | 1202 | return bless \%args => $class; | 
| 31 |  |  |  |  |  |  | } | 
| 32 |  |  |  |  |  |  |  | 
| 33 | 232 |  | 100 | 232 | 1 | 36843 | sub name()       { my $self = shift; return $self->{name} // '' } | 
|  | 232 |  |  |  |  | 1446 |  | 
| 34 | 554 |  |  | 554 | 1 | 22508 | sub type()       { my $self = shift; return $self->{type} } | 
|  | 554 |  |  |  |  | 3337 |  | 
| 35 | 61 |  |  | 61 | 1 | 9894 | sub default()    { my $self = shift; return $self->{default} } ## no critic (ProhibitBuiltinHomonyms) | 
|  | 61 |  |  |  |  | 147 |  | 
| 36 | 61 |  |  | 61 | 1 | 9595 | sub coerce()     { my $self = shift; return $self->{coerce} } | 
|  | 61 |  |  |  |  | 136 |  | 
| 37 | 543 |  |  | 543 | 1 | 11530 | sub optional()   { my $self = shift; return !!$self->{optional} } | 
|  | 543 |  |  |  |  | 3641 |  | 
| 38 | 144 |  |  | 144 | 1 | 11655 | sub required()   { my $self = shift; return !$self->{optional} } | 
|  | 144 |  |  |  |  | 526 |  | 
| 39 | 642 |  |  | 642 | 1 | 12334 | sub named()      { my $self = shift; return !!$self->{named} } | 
|  | 642 |  |  |  |  | 2653 |  | 
| 40 | 217 |  |  | 217 | 1 | 11532 | sub positional() { my $self = shift; return !$self->{named} } | 
|  | 217 |  |  |  |  | 776 |  | 
| 41 | 61 |  |  | 61 | 1 | 11277 | sub invocant()   { my $self = shift; return !!$self->{invocant} } | 
|  | 61 |  |  |  |  | 162 |  | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 449 |  |  | 449 | 1 | 12006 | sub has_name()    { my $self = shift; return defined $self->{name} } | 
|  | 449 |  |  |  |  | 2353 |  | 
| 44 | 334 |  |  | 334 | 1 | 11638 | sub has_type()    { my $self = shift; return defined $self->{type} } | 
|  | 334 |  |  |  |  | 1274 |  | 
| 45 | 61 |  |  | 61 | 1 | 11275 | sub has_default() { my $self = shift; return defined $self->{default} } | 
|  | 61 |  |  |  |  | 157 |  | 
| 46 | 61 |  |  | 61 | 1 | 11314 | sub has_coerce()  { my $self = shift; return defined $self->{coerce} } | 
|  | 61 |  |  |  |  | 174 |  | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 3 |  |  | 3 | 1 | 9969 | sub set_name      { my ($self, $v) = @_; $self->{name}     = $v; return $self } | 
|  | 3 |  |  |  |  | 39 |  | 
|  | 3 |  |  |  |  | 17 |  | 
| 49 | 4 |  |  | 4 | 1 | 11643 | sub set_type      { my ($self, $v) = @_; $self->{type}     = $v; return $self } | 
|  | 4 |  |  |  |  | 33 |  | 
|  | 4 |  |  |  |  | 28 |  | 
| 50 | 4 |  |  | 4 | 1 | 11336 | sub set_default   { my ($self, $v) = @_; $self->{default}  = $v; return $self } | 
|  | 4 |  |  |  |  | 35 |  | 
|  | 4 |  |  |  |  | 29 |  | 
| 51 | 4 |  |  | 4 | 1 | 11615 | sub set_coerce    { my ($self, $v) = @_; $self->{coerce}   = $v; return $self } | 
|  | 4 |  |  |  |  | 33 |  | 
|  | 4 |  |  |  |  | 26 |  | 
| 52 | 6 | 100 |  | 6 | 1 | 7994 | sub set_optional   { my ($self, $v) = @_; $self->{optional} = !!(defined $v ? $v : 1); return $self } | 
|  | 6 |  |  |  |  | 46 |  | 
|  | 6 |  |  |  |  | 30 |  | 
| 53 | 6 | 100 |  | 6 | 1 | 8398 | sub set_required   { my ($self, $v) = @_; $self->{optional} =  !(defined $v ? $v : 1); return $self } | 
|  | 6 |  |  |  |  | 19 |  | 
|  | 6 |  |  |  |  | 28 |  | 
| 54 | 6 | 100 |  | 6 | 1 | 8449 | sub set_named      { my ($self, $v) = @_; $self->{named}    = !!(defined $v ? $v : 1); return $self } | 
|  | 6 |  |  |  |  | 53 |  | 
|  | 6 |  |  |  |  | 33 |  | 
| 55 | 6 | 100 |  | 6 | 1 | 8031 | sub set_positional { my ($self, $v) = @_; $self->{named}    =  !(defined $v ? $v : 1); return $self } | 
|  | 6 |  |  |  |  | 21 |  | 
|  | 6 |  |  |  |  | 26 |  | 
| 56 | 58 | 100 |  | 58 | 1 | 18062 | sub set_invocant   { my ($self, $v) = @_; $self->{invocant} = !!(defined $v ? $v : 1); return $self } | 
|  | 58 |  |  |  |  | 268 |  | 
|  | 58 |  |  |  |  | 143 |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | # alias | 
| 59 |  |  |  |  |  |  | sub isa_() :method; # NOT isa | 
| 60 |  |  |  |  |  |  | *isa_ = \&type; | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | sub set_isa; | 
| 63 |  |  |  |  |  |  | *set_isa = \&set_type; | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | sub is_same_interface { | 
| 66 | 113 |  |  | 113 | 1 | 238 | my ($self, $other) = @_; | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 113 | 100 | 100 |  |  | 706 | return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param'); | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 103 | 100 |  |  |  | 267 | if ($self->has_name) { | 
| 71 | 16 | 100 |  |  |  | 40 | return unless $self->name eq $other->name | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  | else { | 
| 74 | 87 | 100 |  |  |  | 148 | return if $other->has_name | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 | 93 | 100 |  |  |  | 193 | if ($self->has_type) { | 
| 78 | 66 | 100 | 100 |  |  | 121 | return unless $self->type eq ($other->type // ''); | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  | else { | 
| 81 | 27 | 100 |  |  |  | 56 | return if $other->has_type | 
| 82 |  |  |  |  |  |  | } | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 71 | 100 |  |  |  | 160 | return unless $self->optional eq $other->optional; | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 66 | 100 |  |  |  | 140 | return unless $self->named eq $other->named; | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 61 |  |  |  |  | 219 | return !!1; | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | sub is_relaxed_same_interface { | 
| 92 | 94 |  |  | 94 | 1 | 176 | my ($self, $other) = @_; | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 94 | 100 | 100 |  |  | 464 | return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param'); | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 92 | 100 |  |  |  | 209 | if ($self->has_name) { | 
| 97 | 14 | 100 |  |  |  | 28 | return unless $self->name eq $other->name | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 87 | 100 |  |  |  | 164 | if ($self->has_type) { | 
| 101 | 55 | 100 | 100 |  |  | 105 | return unless $self->type eq ($other->type // ''); | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 | 69 | 100 |  |  |  | 136 | return unless $self->optional eq $other->optional; | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 64 | 100 |  |  |  | 172 | return unless $self->named eq $other->named; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 59 |  |  |  |  | 518 | return !!1; | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | sub is_same_interface_inlined { | 
| 112 | 21 |  |  | 21 | 1 | 49 | my ($self, $v) = @_; | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 21 |  |  |  |  | 32 | my @src; | 
| 115 | 21 |  |  |  |  | 83 | push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v); | 
| 116 |  |  |  |  |  |  |  | 
| 117 | 21 | 100 |  |  |  | 55 | push @src => $self->has_name ? sprintf("'%s' eq %s->name", $self->name, $v) | 
| 118 |  |  |  |  |  |  | : sprintf('!%s->has_name', $v); | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 21 | 100 |  |  |  | 59 | push @src => $self->has_type ? sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v) | 
|  | 13 |  |  |  |  | 33 |  | 
| 121 |  |  |  |  |  |  | : sprintf('!%s->has_type', $v); | 
| 122 |  |  |  |  |  |  |  | 
| 123 | 21 |  |  |  |  | 63 | push @src => sprintf("'%s' eq %s->optional", $self->optional, $v); | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 21 |  |  |  |  | 57 | push @src => sprintf("'%s' eq %s->named", $self->named, $v); | 
| 126 |  |  |  |  |  |  |  | 
| 127 | 21 |  |  |  |  | 1268 | return join "\n && ", @src; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | sub is_relaxed_same_interface_inlined { | 
| 131 | 21 |  |  | 21 | 1 | 60 | my ($self, $v) = @_; | 
| 132 |  |  |  |  |  |  |  | 
| 133 | 21 |  |  |  |  | 33 | my @src; | 
| 134 | 21 |  |  |  |  | 75 | push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v); | 
| 135 |  |  |  |  |  |  |  | 
| 136 | 21 | 100 |  |  |  | 45 | push @src => sprintf("'%s' eq %s->name", $self->name, $v) if $self->has_name; | 
| 137 |  |  |  |  |  |  |  | 
| 138 | 21 | 100 |  |  |  | 53 | push @src => sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v) if $self->has_type; | 
|  | 13 |  |  |  |  | 29 |  | 
| 139 |  |  |  |  |  |  |  | 
| 140 | 21 |  |  |  |  | 59 | push @src => sprintf("'%s' eq %s->optional", $self->optional, $v); | 
| 141 |  |  |  |  |  |  |  | 
| 142 | 21 |  |  |  |  | 63 | push @src => sprintf("'%s' eq %s->named", $self->named, $v); | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 21 |  |  |  |  | 835 | return join "\n && ", @src; | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | sub display { | 
| 148 | 36 |  |  | 36 | 1 | 49 | my $self = shift; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 36 |  |  |  |  | 48 | my $s = ''; | 
| 151 | 36 | 100 |  |  |  | 62 | $s .= $self->type if $self->type; | 
| 152 | 36 | 100 | 100 |  |  | 101 | $s .= ' ' if $s && $self->name; | 
| 153 | 36 | 100 |  |  |  | 78 | $s .= ':' if $self->named; | 
| 154 | 36 | 100 |  |  |  | 70 | $s .= $self->name if $self->name; | 
| 155 | 36 |  |  |  |  | 146 | return $s; | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | 1; | 
| 160 |  |  |  |  |  |  | __END__ |