File Coverage

blib/lib/Mite/Shim.pm
Criterion Covered Total %
statement 235 250 94.0
branch 55 68 80.8
condition 9 19 47.3
subroutine 64 66 96.9
pod 0 20 0.0
total 363 423 85.8


line stmt bran cond sub pod time code
1             # NOTE: Since the intention is to ship this file with a project, this file
2             # cannot have any non-core dependencies.
3             use 5.008001;
4 238     238   33061 use strict;
  218         5663  
5 212     197   4334 use warnings;
  191         1032  
  191         5974  
6 191     204   2874 no strict 'refs';
  204         1120  
  204         10073  
7 204     179   3497  
  179         3921  
  179         78811  
8             if ( $] < 5.009005 ) { require MRO::Compat; }
9             else { require mro; }
10              
11             defined ${^GLOBAL_PHASE}
12             or eval { require Devel::GlobalDestruction; 1 }
13             or do {
14             carp( "WARNING: Devel::GlobalDestruction recommended!" );
15             *Devel::GlobalDestruction::in_global_destruction = sub { undef; };
16             };
17              
18             # Constants
19              
20             # More complicated constants
21             BEGIN {
22             my @bool = ( \&false, \&true );
23             *_HAS_AUTOCLEAN = $bool[ 0+!! eval { require namespace::autoclean } ];
24             *STRICT = $bool[ 0+!! ( $ENV{PERL_STRICT} || $ENV{EXTENDED_TESTING} || $ENV{AUTHOR_TESTING} || $ENV{RELEASE_TESTING} ) ];
25             };
26              
27             # Exportable error handlers
28             my ( $func, $message, @args ) = @_;
29             if ( @args ) {
30 179     179   1959 require Data::Dumper;
31 179         767 local $Data::Dumper::Terse = 1;
  179         80459  
32 179   0     2942235 local $Data::Dumper::Indent = 0;
33             $message = sprintf $message, map {
34             ref($_) ? Data::Dumper::Dumper($_) : defined($_) ? $_ : '(undef)'
35             } @args;
36             }
37 880     880   2773 my $next = do { require Carp; \&{"Carp::$func"} };
38 880 100       3112 @_ = ( $message );
39 43         9387 goto $next;
40 43         94105 }
41 43         251  
42              
43 43 50       138 # Exportable guard function
  98 50       1225  
44             {
45             my $GUARD_PACKAGE = __PACKAGE__ . '::Guard';
46 880         2178 *{"$GUARD_PACKAGE\::DESTROY"} = sub { $_[0][0] or $_[0][1]->() };
  880         5136  
  880         1510  
  880         3608  
47 880         2382 *{"$GUARD_PACKAGE\::restore"} = sub { $_[0]->DESTROY; $_[0][0] = true };
48 880         132037 *{"$GUARD_PACKAGE\::dismiss"} = sub { $_[0][0] = true };
49             *{"$GUARD_PACKAGE\::peek"} = sub { $_[0][2] };
50             *guard = sub (&) { bless [ 0, @_ ] => $GUARD_PACKAGE };
51 0     0 0 0 }
  0         0  
52 880     880 0 2715  
  880         3902  
53 0     0 0 0 # Exportable lock and unlock
  0         0  
54             my ( $lul, $ref ) = @_;
55             if ( ref $ref eq 'ARRAY' ) {
56             &Internals::SvREADONLY( $ref, $lul );
57             &Internals::SvREADONLY( \$_, $lul ) for @$ref;
58 261 100   261   3974 return;
59 1     1   4 }
  1         3  
60 1     1   4 if ( ref $ref eq 'HASH' ) {
61 3     3   22 &Internals::hv_clear_placeholders( $ref );
62 260     260   2174 &Internals::SvREADONLY( $ref, $lul );
63             &Internals::SvREADONLY( \$_, $lul ) for values %$ref;
64             return;
65             }
66             return;
67 6     6   12 }
68 6 50       19  
69 6         16 unshift @_, true;
70 6         25 goto \&_lul;
71 6         19 }
72              
73 0 0       0 my $ref = shift;
74 0         0 _lul( 0 , $ref );
75 0         0 &guard( sub { _lul( 1, $ref ) } );
76 0         0 }
77 0         0  
78             defined $Mite::COMPILING and $Mite::COMPILING eq __PACKAGE__;
79 0         0 }
80              
81             my $me = shift;
82             my %arg = map { lc($_) => true } @_;
83 2     2 0 7 my ( $caller, $file ) = caller;
84 2         8  
85             if( _is_compiling() ) {
86             require Mite::Project;
87             Mite::Project->default->inject_mite_functions(
88 2     2 0 3 package => $caller,
89 2         16 file => $file,
90 2     2   9 arg => \%arg,
  2         7  
91             shim => $me,
92             );
93             }
94 1947 100   1947   16923 else {
95             # Changes to this filename must be coordinated with Mite::Compiled
96             my $mite_file = $file . ".mite.pm";
97             if( !-e $mite_file ) {
98 294     294   1541 croak "Compiled Mite file ($mite_file) for $file is missing";
99 294         1542 }
  90         585  
100 294         2391  
101             {
102 294 100       1446 local @INC = ('.', @INC);
103 111         601 require $mite_file;
104 111         968 }
105             }
106              
107             warnings->import;
108             strict->import;
109             'namespace::autoclean'->import( -cleanee => $caller )
110             if _HAS_AUTOCLEAN && !$arg{'-unclean'};
111             }
112              
113 183         995 {
114 183 50       3480 my ( $cb_before, $cb_after );
115 0         0 my ( $me, $role, $caller, $args ) = @_;
116             if ( $INC{'Role/Hooks.pm'} ) {
117             $cb_before ||= \%Role::Hooks::CALLBACKS_BEFORE_APPLY;
118             $cb_after ||= \%Role::Hooks::CALLBACKS_AFTER_APPLY;
119 183         580 }
  183         3154  
120 183         69844 if ( $cb_before ) {
121             $_->( $role, $caller ) for @{ $cb_before->{$role} || [] };
122             }
123             'Role::Tiny'->_check_requires( $caller, $role );
124 294         8593 my $info = $Role::Tiny::INFO{$role};
125 294         2314 for ( @{ $info->{modifiers} || [] } ) {
126             my @args = @$_;
127 294 100       5234 my $modification = shift @args;
128             my $handler = "HANDLE_$modification";
129             $me->$handler( $caller, undef, @args );
130             }
131             if ( $cb_after ) {
132             $_->( $role, $caller ) for @{ $cb_after->{$role} || [] };
133 2     2   8 }
134 2 100       6 return;
135 1   50     6 }
136 1   50     3  
137             # Usage: $me, $caller, @with_args
138 2 100       8 my ( $me, $caller ) = ( shift, shift );
139 1 50       2 while ( @_ ) {
  1         36  
140             my $role = shift;
141 2         12 my $args = ref($_[0]) ? shift : undef;
142 2         24 if ( $INC{'Role/Tiny.pm'} and 'Role::Tiny'->is_role( $role ) ) {
143 2 100       5 $me->_finalize_application_roletiny( $role, $caller, $args );
  2         12  
144 2         5 }
145 2         4 else {
146 2         5 $role->__FINALIZE_APPLICATION__( $caller, $args );
147 2         7 }
148             }
149 2 100       7 return;
150 1 50       3 }
  1         5  
151             }
152 2         22  
153             # Usage: $me, $caller, $keyword, @has_args
154             my ( $me, $caller, $keyword, $names ) = ( shift, shift, shift, shift );
155             if ( @_ % 2 ) {
156             my $default = shift;
157 139     139 0 619 unshift @_, ( 'CODE' eq ref( $default ) )
158 139         657 ? ( is => lazy, builder => $default )
159 853         1764 : ( is => ro, default => $default );
160 853 100       2191 }
161 853 100 100     2979 my %spec = @_;
162 2         27 my $code;
163             for my $name ( ref($names) ? @$names : $names ) {
164             $name =~ s/^\+//;
165 851         7515 'CODE' eq ref( $code = $spec{default} )
166             and ${"$caller\::__$name\_DEFAULT__"} = $code;
167             'CODE' eq ref( $code = $spec{builder} )
168 136         476 and *{"$caller\::_build_$name"} = $code;
169             'CODE' eq ref( $code = $spec{trigger} )
170             and *{"$caller\::_trigger_$name"} = $code;
171             'CODE' eq ref( $code = $spec{clone} )
172             and *{"$caller\::_clone_$name"} = $code;
173             }
174 5817     5817 0 25157 return;
175 5817 100       16727 }
176 4         6  
177 4 100       16 {
178             my $_kind = sub { ${ shift() . '::USES_MITE' } =~ /Role/ ? 'role' : 'class' };
179              
180             my ( $caller, $name ) = @_;
181 5817         35171 my $orig = $caller->can( $name );
182 5817         9317 return $orig if $orig;
183 5817 100       16265 croak "Cannot modify method $name in $caller: no such method";
184 6612         12256 }
185              
186 6612 100       18532 my $coderef = pop;
  1455         7307  
187             my $names = [ map { ref($_) ? @$_ : $_ } @_ ];
188 6612 100       16645 ( $names, $coderef );
  1132         8162  
189             }
190 6612 100       14565  
  109         784  
191             # Usage: $me, $caller, $caller_kind, @before_args
192 6612 100       15520 my ( $me, $caller, $kind ) = ( shift, shift, shift );
  1         8  
193             my ( $names, $coderef ) = &_parse_mm_args;
194 5817         17355 $kind ||= $caller->$_kind;
195             if ( $kind eq 'role' ) {
196             push @{"$caller\::METHOD_MODIFIERS"},
197             [ before => $names, $coderef ];
198             return;
199             }
200             for my $name ( @$names ) {
201 2662     2662   4933 my $orig = _get_orig_method( $caller, $name );
202 2662         12890 local $@;
203 2662 50       7571 eval <<"BEFORE" or die $@;
204 0         0 package $caller;
205             no warnings 'redefine';
206             sub $name {
207             \$coderef->( \@_ );
208 4440     4440   6875 \$orig->( \@_ );
209 4440 100       8190 }
  4440         17784  
210 4440         11500 1;
211             BEFORE
212             }
213             return;
214             }
215 948     948 0 2983  
216 948         2314 # Usage: $me, $caller, $caller_kind, @after_args
217 948   33     2725 my ( $me, $caller, $kind ) = ( shift, shift, shift );
218 948 100       2788 my ( $names, $coderef ) = &_parse_mm_args;
219 451         868 $kind ||= $caller->$_kind;
  451         2576  
220             if ( $kind eq 'role' ) {
221 451         1477 push @{"$caller\::METHOD_MODIFIERS"},
222             [ after => $names, $coderef ];
223 497         1574 return;
224 497         1263 }
225 497         912 for my $name ( @$names ) {
226 125 50   125 0 989 my $orig = _get_orig_method( $caller, $name );
  125     109   378  
  125     109   8210  
  109     109   751  
  109     102   264  
  109         5711  
  109         801  
  109         280  
  109         6340  
  109         756  
  109         270  
  109         5836  
  497         37896  
  102         859  
  102         2289  
227             local $@;
228             eval <<"AFTER" or die $@;
229             package $caller;
230             no warnings 'redefine';
231             sub $name {
232             my \@r;
233             if ( wantarray ) {
234             \@r = \$orig->( \@_ );
235             }
236 497         2316 elsif ( defined wantarray ) {
237             \@r = scalar \$orig->( \@_ );
238             }
239             else {
240             \$orig->( \@_ );
241 16     16 0 133 1;
242 16         326 }
243 1   33     3 \$coderef->( \@_ );
244 1 50       22 wantarray ? \@r : \$r[0];
245 0         0 }
  0         0  
246             1;
247 0         0 AFTER
248             }
249 1         4 return;
250 1         2 }
251 1         2  
252 1 50       93 # Usage: $me, $caller, $caller_kind, @around_args
    50          
253             my ( $me, $caller, $kind ) = ( shift, shift, shift );
254             my ( $names, $coderef ) = &_parse_mm_args;
255             $kind ||= $caller->$_kind;
256             if ( $kind eq 'role' ) {
257             push @{"$caller\::METHOD_MODIFIERS"},
258             [ around => $names, $coderef ];
259             return;
260             }
261             for my $name ( @$names ) {
262             my $orig = _get_orig_method( $caller, $name );
263             local $@;
264             eval <<"AROUND" or die $@;
265             package $caller;
266             no warnings 'redefine';
267             sub $name {
268             \$coderef->( \$orig, \@_ );
269             }
270             1;
271             AROUND
272             }
273 1         4 return;
274             }
275             }
276              
277             # Usage: $me, $caller, $caller_kind, @signature_for_args
278 3488     3488 0 8913 my ( $me, $caller, $kind, $name ) = @_;
279 3488         6792 $name =~ s/^\+//;
280 3487   66     20297 $me->HANDLE_around( $caller, $kind, $name, ${"$caller\::SIGNATURE_FOR"}{$name} );
281 3488 100       21684 return;
282 1325         2007 }
  1325         5670  
283              
284 1326         3274 1;