File Coverage

blib/lib/Sub/HandlesVia/Toolkit/Mouse.pm
Criterion Covered Total %
statement 93 101 92.0
branch 26 36 72.2
condition 10 24 41.6
subroutine 21 22 95.4
pod 0 5 0.0
total 150 188 79.7


line stmt bran cond sub pod time code
1 21     21   412 use 5.008;
  21         80  
2 21     21   112 use strict;
  21         46  
  21         474  
3 21     21   115 use warnings;
  21         52  
  21         1393  
4              
5              
6             our $AUTHORITY = 'cpan:TOBYINK';
7             our $VERSION = '0.045';
8              
9             use Sub::HandlesVia::Mite;
10 21     21   9975 extends 'Sub::HandlesVia::Toolkit';
  21         68  
  21         154  
11              
12             my $me = shift;
13             my ($target) = @_;
14 88     88 0 239
15 88         252 require Mouse::Util;
16             my $meta = Mouse::Util::find_meta($target);
17 88         409 $me->meta_hack( $meta );
18 88         402 }
19 88         1433  
20             my ( $me, $meta ) = ( shift, @_ );
21            
22             require Mouse::Util::MetaRole;
23 90     90 0 305
24             if ( $meta->isa('Mouse::Meta::Role') ) {
25 90         9428
26             return Mouse::Util::MetaRole::apply_metaroles(
27 90 100       20460 for => $meta,
28             role_metaroles => { role => [ $me->package_trait, $me->role_trait ] },
29 3         21 );
30             }
31             else {
32            
33             return Mouse::Util::MetaRole::apply_metaroles(
34             for => $meta,
35             class_metaroles => { class => [ $me->package_trait ] },
36 87         452 );
37             }
38             }
39              
40             __PACKAGE__ . "::PackageTrait";
41             }
42              
43             __PACKAGE__ . "::RoleTrait";
44 90     90 0 596 }
45              
46             my ($me, $target, $attrname) = (shift, @_);
47              
48 3     3 0 17 if (ref $attrname) {
49             @$attrname==1 or die;
50             ($attrname) = @$attrname;
51             }
52 101     101 0 386
53             my $meta;
54 101 50       412 if (ref $target) {
55 101 50       392 $meta = $target;
56 101         297 $target = $meta->name;
57             }
58             else {
59 101         221 require Mouse::Util;
60 101 50       398 $meta = Mouse::Util::find_meta($target);
61 0         0 }
62 0         0
63             my $attr = $meta->get_attribute($attrname);
64             my $spec = +{%$attr};
65 101         651
66 101         444 my $captures = {};
67            
68             my ($get, $set, $get_is_lvalue, $set_checks_isa);
69 101         1707 if (!$spec->{lazy} and !$spec->{traits} and !$spec->{auto_deref}) {
70 101         1412 require B;
71             my $slot = B::perlstring($attrname);
72 101         345 $get = sub {
73             my $self = shift->generate_self;
74 101         310 "$self\->{$slot}";
75 101 100 33     959 };
    100          
76 78         370 ++$get_is_lvalue;
77 78         395 }
78             elsif ($attr->has_read_method) {
79 1541     1541   3913 my $read_method = $attr->reader || $attr->accessor;
80 1541         10211 $get = sub {
81 78         482 my $self = shift->generate_self;
82 78         231 "scalar($self\->$read_method)";
83             };
84             }
85 17   66     642 else {
86             my $read_method = $attr->get_read_method_ref;
87 293     293   829 $captures->{'$shv_read_method'} = \$read_method;
88 293         1937 $get = sub {
89 17         137 my $self = shift->generate_self;
90             "scalar($self\->\$shv_read_method)";
91             };
92 6         50 }
93 6         220 if ($attr->has_write_method) {
94             my $write_method = $attr->writer || $attr->accessor;
95 12     12   33 $set = sub {
96 12         71 my ($gen, $val) = @_;
97 6         29 $gen->generate_self . "->$write_method\($val)"
98             };
99 101 100       529 ++$set_checks_isa;
100 77   66     1074 }
101             else {
102 616     616   2264 my $write_method = $attr->get_write_method_ref;
103 616         1616 $captures->{'$shv_write_method'} = \$write_method;
104 77         430 $set = sub {
105 77         197 my ($gen, $val) = @_;
106             $gen->generate_self . '->$shv_write_method('.$val.')';
107             };
108 24         221 ++$set_checks_isa;
109 24         872 }
110              
111 5     5   22 my $default;
112 5         20 if (exists $spec->{default}) {
113 24         102 $default = [ default => $spec->{default} ];
114 24         57 }
115             elsif (exists $spec->{builder}) {
116             $default = [ builder => $spec->{builder} ];
117 101         228 }
118 101 100       350  
    100          
119 80         284 if (ref $default->[1] eq 'CODE') {
120             $captures->{'$shv_default_for_reset'} = \$default->[1];
121             }
122 9         34  
123             require Sub::HandlesVia::CodeGenerator;
124             return 'Sub::HandlesVia::CodeGenerator'->new(
125 101 100       447 toolkit => $me,
126 39         141 target => $target,
127             attribute => $attrname,
128             attribute_spec => $spec,
129 101         12131 env => $captures,
130             isa => Types::TypeTiny::to_TypeTiny($attr->type_constraint),
131             coerce => !!$spec->{coerce},
132             generator_for_slot => sub { shift->generate_self.'->{'.B::perlstring($attrname).'}' }, # icky
133             generator_for_get => $get,
134             generator_for_set => $set,
135             get_is_lvalue => $get_is_lvalue,
136             set_checks_isa => $set_checks_isa,
137             set_strictly => !!0,
138 0     0   0 method_installer => sub { $meta->add_method(@_) },
139             generator_for_default => sub {
140             my ( $gen, $handler ) = @_ or die;
141             if ( !$default and $handler ) {
142             return $handler->default_for_reset->();
143             }
144 1292     1292   15264 elsif ( $default->[0] eq 'builder' ) {
145             return sprintf(
146 15 50   15   73 '(%s)->%s',
147 15 50 33     192 $gen->generate_self,
    100 33        
    50 33        
    50 33        
    50          
148 0         0 $default->[1],
149             );
150             }
151 4         10 elsif ( $default->[0] eq 'default' and ref $default->[1] eq 'CODE' ) {
152             return sprintf(
153             '(%s)->$shv_default_for_reset',
154             $gen->generate_self,
155             );
156             }
157             elsif ( $default->[0] eq 'default' and !defined $default->[1] ) {
158 0         0 return 'undef';
159             }
160             elsif ( $default->[0] eq 'default' and !ref $default->[1] ) {
161             require B;
162             return B::perlstring( $default->[1] );
163             }
164 0         0 return;
165             },
166             );
167 11         64 }
168 11         81  
169              
170 0         0 our $AUTHORITY = 'cpan:TOBYINK';
171             our $VERSION = '0.045';
172 101         715  
173             use Mouse::Role;
174              
175             'Sub::HandlesVia::Toolkit::Mouse',
176             }
177              
178             around add_attribute => sub {
179             my ($next, $self, @args) = (shift, shift, @_);
180 21     21   33281 my ($spec, $attrobj, $attrname);
  21         23352  
  21         134  
181             if (@args == 1) {
182             $spec = $attrobj = $_[0];
183 203     203   1295 $attrname = $attrobj->name;
184             }
185             elsif (@args == 2) {
186             ($attrname, $spec) = @args;
187             }
188             else {
189             my %spec;
190             ($attrname, %spec) = @args;
191             $spec = \%spec;
192             }
193             ( my $real_attrname = $attrname ) =~ s/^[+]//;
194             $spec->{provides}{shv} = $self->_shv_toolkit->clean_spec($self->name, $real_attrname, $spec)
195             unless $spec->{provides}{shv};
196             my $attr = $self->$next($attrobj ? $attrobj : ($attrname, %$spec));
197             if ($spec->{provides}{shv} and $self->isa('Mouse::Meta::Class')) {
198             $self->_shv_toolkit->install_delegations(+{
199             %{ $spec->{provides}{shv} },
200             target => $self->name,
201             });
202             }
203             return $attr;
204             };
205              
206              
207             our $AUTHORITY = 'cpan:TOBYINK';
208             our $VERSION = '0.045';
209              
210             use Mouse::Role;
211             requires '_shv_toolkit';
212              
213             around apply => sub {
214             my ($next, $self, $other, %args) = (shift, shift, @_);
215             $other = $self->_shv_toolkit->meta_hack( $other );
216             $self->$next( $other, %args );
217             };
218              
219 21     21   15256 # This is a horrible hack.
  21         49  
  21         123  
220             do {
221             no warnings 'redefine';
222             require Mouse::Meta::Role;
223             require Scalar::Util;
224             my $next = \&Mouse::Meta::Role::combine;
225             *Mouse::Meta::Role::combine = sub {
226             my ( $class, @roles ) = ( shift, @_ );
227             my $combined = $class->$next( @roles );
228             my ($hack) = map {
229             ( ref $_ and blessed $_->[0] and $_->[0]->can( '_shv_toolkit' ) )
230 21     21   7898 ? $_->[0]->_shv_toolkit
  21         329  
  21         4643  
231             : ();
232             } @roles;
233             if ($hack) {
234             $combined = $hack->meta_hack( $combined );
235 4     4   2342 }
236 4         24 return $combined;
237             };
238 4 50 33     16924 };
  8         137  
239              
240             1;