File Coverage

blib/lib/Mite/Package.pm
Criterion Covered Total %
statement 107 111 96.4
branch 27 38 71.0
condition 1 2 50.0
subroutine 24 25 96.0
pod 0 7 0.0
total 159 183 86.8


line stmt bran cond sub pod time code
1 109     109   2355 use 5.010001;
  109         407  
2 109     109   669 use strict;
  109         275  
  109         16197  
3 109     109   599 use warnings;
  109         292  
  109         30269  
4              
5             package Mite::Package;
6 109     109   756 use Mite::Miteception -all;
  109         306  
  109         15402  
7              
8             our $AUTHORITY = 'cpan:TOBYINK';
9             our $VERSION = '0.012000';
10              
11             has name =>
12             is => ro,
13             isa => ValidClassName,
14             required => true;
15              
16             has shim_name =>
17             is => rw,
18             isa => ValidClassName,
19             lazy => true,
20             builder => sub {
21 6     6   23 my $self = shift;
22 6   50     13 eval { $self->project->config->data->{shim} } // 'Mite::Shim'
  6         19  
23             };
24              
25             has source =>
26             is => rw,
27             isa => MiteSource,
28             # avoid a circular dep with Mite::Source
29             weak_ref => true;
30              
31             has imported_functions =>
32             is => ro,
33             isa => Map[ MethodName, Str ],
34 155     155   2072 builder => sub { {} };
35              
36             has imported_keywords =>
37             is => ro,
38             isa => Map[ MethodName, Str ],
39 155     155   578 builder => sub { {} };
40              
41             has arg =>
42             is => rw,
43             default => {};
44              
45 0     0 0 0 sub kind { 'package' }
46              
47             sub BUILD {
48 155     155 0 635 my $self = shift;
49              
50 155         52016 require Type::Registry;
51 155         1843087 my $reg = 'Type::Registry'->for_class( $self->name );
52 155         2906 $reg->add_types( 'Types::Standard' );
53 155         1324028 $reg->add_types( 'Types::Common::Numeric' );
54 155         2849143 $reg->add_types( 'Types::Common::String' );
55              
56 155         451892 my $library = eval { $self->project->config->data->{types} };
  155         1890  
57 155 50       5957 $reg->add_types( $library ) if $library;
58             }
59              
60             sub project {
61 1112     1112 0 2070 my $self = shift;
62              
63 1112         3418 return $self->source->project;
64             }
65              
66             sub inject_mite_functions {
67 117     117 0 478 my ( $self, $file, $arg ) = ( shift, @_ );
68              
69 117 100   1989   772 my $requested = sub { $arg->{$_[0]} ? 1 : $arg->{'!'.$_[0]} ? 0 : $arg->{'-all'} ? 1 : $_[1]; };
  1989 50       8015  
    100          
70 117         520 my $shim = $self->shim_name;
71 117         579 my $package = $self->name;
72 117         856 my $ctxt = $shim->can( '_definition_context' );
73              
74 109     109   976 no strict 'refs';
  109         307  
  109         66032  
75 117         411 ${ $package .'::USES_MITE' } = ref( $self );
  117         702  
76 117         298 ${ $package .'::MITE_SHIM' } = $shim;
  117         501  
77              
78 117         456 my $want_bool = $requested->( '-bool', 0 );
79 117         426 my $want_is = $requested->( '-is', 0 );
80 117         459 for my $f ( qw/ true false / ) {
81 234 100       603 next unless $requested->( $f, $want_bool );
82 24         52 *{"$package\::$f"} = \&{"$shim\::$f"};
  24         101  
  24         96  
83 24         171 $self->imported_functions->{$f} = "$shim\::$f";
84             }
85 117         547 for my $f ( qw/ ro rw rwp lazy bare / ) {
86 585 100       1015 next unless $requested->( $f, $want_is );
87 55         89 *{"$package\::$f"} = \&{"$shim\::$f"};
  55         230  
  55         173  
88 55         206 $self->imported_functions->{$f} = "$shim\::$f";
89             }
90 117         542 for my $f ( qw/ carp croak confess guard STRICT lock unlock / ) {
91 819 100       1543 next unless $requested->( $f, false );
92 71         119 *{"$package\::$f"} = \&{"$shim\::$f"};
  71         213  
  71         191  
93 71         260 $self->imported_functions->{$f} = "$shim\::$f";
94             }
95 117 100       576 if ( $requested->( blessed => false ) ) {
96 10         71 require Scalar::Util;
97 10         37 *{"$package\::blessed"} = \&Scalar::Util::blessed;
  10         42  
98 10         145 $self->imported_functions->{blessed} = "Scalar::Util::blessed";
99             }
100             }
101              
102             sub autolax {
103 210     210 0 498 my $self = shift;
104              
105             return undef
106 210 50       447 if not eval { $self->project->config->data->{autolax} };
  210         791  
107              
108             return $self->imported_functions->{STRICT}
109             ? 'STRICT'
110 0 0       0 : sprintf( '%s::STRICT', $self->project->config->data->{shim} );
111             }
112              
113             for my $function ( qw/ carp croak confess / ) {
114 109     109   1002 no strict 'refs';
  109         317  
  109         136887  
115             *{"_function_for_$function"} = sub {
116 295     295   649 my $self = shift;
117             return $function
118 295 100       1622 if $self->imported_functions->{$function};
119 233 50       876 return sprintf '%s::%s', $self->shim_name, $function
120             if $self->shim_name;
121 0 0       0 $function eq 'carp' ? 'warn sprintf' : 'die sprintf';
122             };
123             }
124              
125             sub compile {
126 123     123 0 430 my $self = shift;
127              
128 123         3842 my $code = join "\n",
129             '{',
130             map( $self->$_, $self->compilation_stages ),
131             '1;',
132             '}';
133              
134             #::diag $code if main->can('diag');
135 123         2527 return $code;
136             }
137              
138             sub _compile_meta {
139 284     284   1101 my ( $self, $classvar, $selfvar, $argvar, $metavar ) = @_;
140 284         2659 return sprintf '( $Mite::META{%s} ||= %s->__META__ )',
141             $classvar, $classvar;
142             }
143              
144             sub compilation_stages {
145 123     123 0 756 return qw(
146             _compile_package
147             _compile_pragmas
148             _compile_uses_mite
149             _compile_imported_keywords
150             _compile_imported_functions
151             _compile_meta_method
152             );
153             }
154              
155             sub _compile_package {
156 123     123   333 my $self = shift;
157              
158 123         313 return "package @{[ $self->name ]};";
  123         3884  
159             }
160              
161             sub _compile_pragmas {
162 123     123   364 my $self = shift;
163              
164 123         382 return <<'CODE';
165             use strict;
166             use warnings;
167             no warnings qw( once void );
168             CODE
169             }
170              
171             sub _compile_uses_mite {
172 123     123   362 my $self = shift;
173              
174 123         1163 my @code = sprintf 'our $USES_MITE = %s;', B::perlstring( ref($self) );
175 123 50       817 if ( $self->shim_name ) {
176 123         583 push @code, sprintf 'our $MITE_SHIM = %s;', B::perlstring( $self->shim_name );
177             }
178 123         2300 push @code, sprintf 'our $MITE_VERSION = %s;', B::perlstring( $self->VERSION );
179 123         1694 join "\n", @code;
180             }
181              
182             sub _compile_imported_keywords {
183 123     123   394 my $self = shift;
184              
185 123 50       296 my %func = %{ $self->imported_keywords or {} } or return;
  123 100       2082  
186 117         1100 my @keywords = sort keys %func;
187 117         1140 my $keyword_slots = join q{, }, map "*$_", @keywords;
188 117         1432 my $coderefs = join "\n", map " $func{$_},", @keywords;
189              
190 117         665 return sprintf <<'CODE', B::perlstring( $self->shim_name ), B::perlstring( $self->name ), $keyword_slots, $self->shim_name, $coderefs;
191             # Mite keywords
192             BEGIN {
193             my ( $SHIM, $CALLER ) = ( %s, %s );
194             ( %s ) = do {
195             package %s;
196             no warnings 'redefine';
197             (
198             %s
199             );
200             };
201             };
202             CODE
203             }
204              
205             sub _compile_imported_functions {
206 123     123   402 my $self = shift;
207 123 100       295 my %func = %{ $self->imported_functions } or return;
  123         4031  
208              
209             return join "\n",
210             '# Mite imports',
211             'BEGIN {',
212             ( $func{blessed} ? ' require Scalar::Util;' : () ),
213             map(
214 13 100       789 sprintf( ' *%s = \&%s;', $_, $func{$_} ),
215             sort keys %func
216             ),
217             '};',
218             '';
219             }
220              
221             sub _compile_meta_method {
222 100     100   291 my $self = shift;
223              
224 100         328 my $code = <<'CODE';
225             # Gather metadata for constructor and destructor
226             sub __META__ {
227             no strict 'refs';
228             my $class = shift; $class = ref($class) || $class;
229             my $linear_isa = mro::get_linear_isa( $class );
230             return {
231             BUILD => [
232             map { ( *{$_}{CODE} ) ? ( *{$_}{CODE} ) : () }
233             map { "$_\::BUILD" } reverse @$linear_isa
234             ],
235             DEMOLISH => [
236             map { ( *{$_}{CODE} ) ? ( *{$_}{CODE} ) : () }
237             map { "$_\::DEMOLISH" } @$linear_isa
238             ],
239             HAS_BUILDARGS => $class->can('BUILDARGS'),
240             HAS_FOREIGNBUILDARGS => $class->can('FOREIGNBUILDARGS'),
241             };
242             }
243             CODE
244              
245 100 50       313 if ( eval { $self->project->config->data->{mop} } ) {
  100         450  
246 0         0 $code .= sprintf <<'CODE', $self->project->config->data->{mop};
247              
248             # Moose-compatibility method
249             sub meta {
250             require %s;
251             Moose::Util::find_meta( ref $_[0] or $_[0] );
252             }
253             CODE
254             }
255              
256 100         3927 return $code;
257             }
258              
259             1;