File Coverage

blib/lib/Mite/Shim.pm
Criterion Covered Total %
statement 224 233 96.1
branch 54 64 84.3
condition 9 19 47.3
subroutine 60 62 96.7
pod 0 18 0.0
total 347 396 87.6


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 224     224   19493 use strict;
  210         1348  
5 210     189   4025 use warnings;
  189         953  
  189         7816  
6 189     203   2560 no strict 'refs';
  203         953  
  203         10878  
7 203     178   3129  
  178         3969  
  178         76107  
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 178     177   1986 require Data::Dumper;
31 177         668 local $Data::Dumper::Terse = 1;
  177         79155  
32 177   0     2633556 local $Data::Dumper::Indent = 0;
33             $message = sprintf $message, map {
34             ref($_) ? Data::Dumper::Dumper($_) : defined($_) ? $_ : '(undef)'
35             } @args;
36             }
37 919     919   2522 my $next = do { require Carp; \&{"Carp::$func"} };
38 919 100       2671 @_ = ( $message );
39 50         11231 goto $next;
40 50         99826 }
41 50         744  
42              
43 50 50       190 # Exportable guard function
  113 50       762  
44             {
45             my $GUARD_PACKAGE = __PACKAGE__ . '::Guard';
46 919         1352 *{"$GUARD_PACKAGE\::DESTROY"} = sub { $_[0][0] or $_[0][1]->() };
  919         4634  
  919         1331  
  919         3317  
47 919         2397 *{"$GUARD_PACKAGE\::restore"} = sub { $_[0]->DESTROY; $_[0][0] = true };
48 919         119461 *{"$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 919     919 0 2685  
  919         3879  
53 0     0 0 0 defined $Mite::COMPILING and $Mite::COMPILING eq __PACKAGE__;
  0         0  
54             }
55              
56             my $me = shift;
57             my %arg = map { lc($_) => true } @_;
58 261 100   261   3469 my ( $caller, $file ) = caller;
59 1     1   4  
  1         4  
60 1     1   4 if( _is_compiling() ) {
61 3     3   24 require Mite::Project;
62 260     260   1888 Mite::Project->default->inject_mite_functions(
63             package => $caller,
64             file => $file,
65             arg => \%arg,
66 1932 100   1932   14333 shim => $me,
67             );
68             }
69             else {
70 294     294   1279 # Changes to this filename must be coordinated with Mite::Compiled
71 294         1169 my $mite_file = $file . ".mite.pm";
  100         575  
72 294         2083 if( !-e $mite_file ) {
73             croak "Compiled Mite file ($mite_file) for $file is missing";
74 294 100       1190 }
75 110         531  
76 110         673 {
77             local @INC = ('.', @INC);
78             require $mite_file;
79             }
80             }
81              
82             warnings->import;
83             strict->import;
84             'namespace::autoclean'->import( -cleanee => $caller )
85 184         952 if _HAS_AUTOCLEAN && !$arg{'-unclean'};
86 184 50       3545 }
87 0         0  
88             {
89             my ( $cb_before, $cb_after );
90             my ( $me, $role, $caller, $args ) = @_;
91 184         542 if ( $INC{'Role/Hooks.pm'} ) {
  184         3338  
92 184         88832 $cb_before ||= \%Role::Hooks::CALLBACKS_BEFORE_APPLY;
93             $cb_after ||= \%Role::Hooks::CALLBACKS_AFTER_APPLY;
94             }
95             if ( $cb_before ) {
96 294         8055 $_->( $role, $caller ) for @{ $cb_before->{$role} || [] };
97 294         1802 }
98             'Role::Tiny'->_check_requires( $caller, $role );
99 294 100       4690 my $info = $Role::Tiny::INFO{$role};
100             for ( @{ $info->{modifiers} || [] } ) {
101             my @args = @$_;
102             my $modification = shift @args;
103             my $handler = "HANDLE_$modification";
104             $me->$handler( $caller, undef, @args );
105 2     2   5 }
106 2 100       6 if ( $cb_after ) {
107 1   50     5 $_->( $role, $caller ) for @{ $cb_after->{$role} || [] };
108 1   50     3 }
109             return;
110 2 100       4 }
111 1 50       2  
  1         3  
112             # Usage: $me, $caller, @with_args
113 2         9 my ( $me, $caller ) = ( shift, shift );
114 2         19 while ( @_ ) {
115 2 100       2 my $role = shift;
  2         10  
116 2         5 my $args = ref($_[0]) ? shift : undef;
117 2         4 if ( $INC{'Role/Tiny.pm'} and 'Role::Tiny'->is_role( $role ) ) {
118 2         4 $me->_finalize_application_roletiny( $role, $caller, $args );
119 2         6 }
120             else {
121 2 100       6 $role->__FINALIZE_APPLICATION__( $caller, $args );
122 1 50       2 }
  1         4  
123             }
124 2         20 return;
125             }
126             }
127              
128             # Usage: $me, $caller, $keyword, @has_args
129 139     139 0 515 my ( $me, $caller, $keyword, $names ) = ( shift, shift, shift, shift );
130 139         592 if ( @_ % 2 ) {
131 847         1546 my $default = shift;
132 847 100       1813 unshift @_, ( 'CODE' eq ref( $default ) )
133 847 100 100     2509 ? ( is => lazy, builder => $default )
134 2         19 : ( is => ro, default => $default );
135             }
136             my %spec = @_;
137 845         5829 my $code;
138             for my $name ( ref($names) ? @$names : $names ) {
139             $name =~ s/^\+//;
140 137         430 'CODE' eq ref( $code = $spec{default} )
141             and ${"$caller\::__$name\_DEFAULT__"} = $code;
142             'CODE' eq ref( $code = $spec{builder} )
143             and *{"$caller\::_build_$name"} = $code;
144             'CODE' eq ref( $code = $spec{trigger} )
145             and *{"$caller\::_trigger_$name"} = $code;
146 5683     5683 0 16240 'CODE' eq ref( $code = $spec{clone} )
147 5683 100       14063 and *{"$caller\::_clone_$name"} = $code;
148 4         7 }
149 4 100       24 return;
150             }
151              
152             {
153 5683         20415 my $_kind = sub { ${ shift() . '::USES_MITE' } =~ /Role/ ? 'role' : 'class' };
154 5683         7603  
155 5683 100       12926 my ( $caller, $name ) = @_;
156 6466         10039 my $orig = $caller->can( $name );
157             return $orig if $orig;
158 6466 100       15036 croak "Cannot modify method $name in $caller: no such method";
  1441         6158  
159             }
160 6466 100       25607  
  1118         7714  
161             my $coderef = pop;
162 6466 100       21471 my $names = [ map { ref($_) ? @$_ : $_ } @_ ];
  108         681  
163             ( $names, $coderef );
164 6466 100       12399 }
  3         21  
165              
166 5683         14213 # Usage: $me, $caller, $caller_kind, @before_args
167             my ( $me, $caller, $kind ) = ( shift, shift, shift );
168             my ( $names, $coderef ) = &_parse_mm_args;
169             $kind ||= $caller->$_kind;
170             if ( $kind eq 'role' ) {
171             push @{"$caller\::METHOD_MODIFIERS"},
172             [ before => $names, $coderef ];
173 2642     2642   4083 return;
174 2642         11530 }
175 2642 50       6237 for my $name ( @$names ) {
176 0         0 my $orig = _get_orig_method( $caller, $name );
177             local $@;
178             eval <<"BEFORE" or die $@;
179             package $caller;
180 4404     4404   5623 no warnings 'redefine';
181 4404 100       6948 sub $name {
  4404         24531  
182 4404         9718 \$coderef->( \@_ );
183             \$orig->( \@_ );
184             }
185             1;
186             BEFORE
187 940     940 0 2521 }
188 940         1837 return;
189 940   33     2320 }
190 940 100       2354  
191 447         670 # Usage: $me, $caller, $caller_kind, @after_args
  447         2164  
192             my ( $me, $caller, $kind ) = ( shift, shift, shift );
193 447         1216 my ( $names, $coderef ) = &_parse_mm_args;
194             $kind ||= $caller->$_kind;
195 493         1096 if ( $kind eq 'role' ) {
196 493         1092 push @{"$caller\::METHOD_MODIFIERS"},
197 493         785 [ after => $names, $coderef ];
198 124 50   124 0 867 return;
  124     108   334  
  124     108   7089  
  108     108   676  
  108     105   260  
  108         4884  
  108         655  
  108         208  
  108         5282  
  108         610  
  108         271  
  108         5003  
  493         33652  
  105         766  
  105         1883  
199             }
200             for my $name ( @$names ) {
201             my $orig = _get_orig_method( $caller, $name );
202             local $@;
203             eval <<"AFTER" or die $@;
204             package $caller;
205             no warnings 'redefine';
206             sub $name {
207             my \@r;
208 493         1817 if ( wantarray ) {
209             \@r = \$orig->( \@_ );
210             }
211             elsif ( defined wantarray ) {
212             \@r = scalar \$orig->( \@_ );
213 12     12 0 89 }
214 12         209 else {
215 1   33     3 \$orig->( \@_ );
216 1 50       3 1;
217 0         0 }
  0         0  
218             \$coderef->( \@_ );
219 0         0 wantarray ? \@r : \$r[0];
220             }
221 1         2 1;
222 1         2 AFTER
223 1         1 }
224 1 50       73 return;
    50          
225             }
226              
227             # Usage: $me, $caller, $caller_kind, @around_args
228             my ( $me, $caller, $kind ) = ( shift, shift, shift );
229             my ( $names, $coderef ) = &_parse_mm_args;
230             $kind ||= $caller->$_kind;
231             if ( $kind eq 'role' ) {
232             push @{"$caller\::METHOD_MODIFIERS"},
233             [ around => $names, $coderef ];
234             return;
235             }
236             for my $name ( @$names ) {
237             my $orig = _get_orig_method( $caller, $name );
238             local $@;
239             eval <<"AROUND" or die $@;
240             package $caller;
241             no warnings 'redefine';
242             sub $name {
243             \$coderef->( \$orig, \@_ );
244             }
245 1         3 1;
246             AROUND
247             }
248             return;
249             }
250 3460     3460 0 7343 }
251 3460         16331  
252 3459   66     18414 # Usage: $me, $caller, $caller_kind, @signature_for_args
253 3460 100       37914 my ( $me, $caller, $kind, $name ) = @_;
254 1313         1766 $name =~ s/^\+//;
  1313         5280  
255             $me->HANDLE_around( $caller, $kind, $name, ${"$caller\::SIGNATURE_FOR"}{$name} );
256 1314         2853 return;
257             }
258 2147         3688  
259 2148         14051 1;