File Coverage

blib/lib/Perl/PrereqScanner/Scanner/Moose.pm
Criterion Covered Total %
statement 60 62 96.7
branch 31 34 91.1
condition 18 21 85.7
subroutine 4 4 100.0
pod 0 1 0.0
total 113 122 92.6


line stmt bran cond sub pod time code
1 2     2   12 use strict;
  2         4  
  2         57  
2 2     2   9 use warnings;
  2         4  
  2         69  
3              
4             package Perl::PrereqScanner::Scanner::Moose 1.025;
5             # ABSTRACT: scan for Moose sugar indicators of required modules
6              
7 2     2   11 use Moose;
  2         3  
  2         19  
8             with 'Perl::PrereqScanner::Scanner';
9              
10             #pod =head1 DESCRIPTION
11             #pod
12             #pod This scanner will look for the following indicators:
13             #pod
14             #pod =begin :list
15             #pod
16             #pod * L<Moose> inheritance declared with the C<extends> keyword
17             #pod
18             #pod * L<Moose> roles included with the C<with> keyword
19             #pod
20             #pod =end :list
21             #pod
22             #pod =cut
23              
24             sub scan_for_prereqs {
25 265     265 0 523 my ($self, $ppi_doc, $req) = @_;
26              
27             # Moose-based roles / inheritance
28             my @chunks =
29             # This is what we get when someone does: with('Foo');
30             # The target to get at is the PPI::Token::Quote::Single.
31             # -- rjbs, 2010-09-05
32             #
33             # PPI::Statement
34             # PPI::Token::Word
35             # PPI::Structure::List
36             # PPI::Statement::Expression
37             # PPI::Token::Quote::Single
38             # PPI::Token::Structure
39              
40 132         2020 map { [ $_->schildren ] }
41 486         5121 grep { $_->child(0)->literal =~ m{\A(?:with|extends)\z} }
42 612         133631 grep { $_->child(0)->isa('PPI::Token::Word') }
43 265 100       407 @{ $ppi_doc->find('PPI::Statement') || [] };
  265         579  
44              
45 265         4251 foreach my $hunk ( @chunks ) {
46             # roles/inheritance *WITH* version declaration ( added in Moose 1.03 )
47 132 100       384 if ( grep { $_->isa('PPI::Structure::Constructor') || $_->isa('PPI::Structure::List') } @$hunk ) {
  528 100       2851  
48             # hack for List
49 96         208 my @hunkdata = @$hunk;
50 96         350 while ( $hunkdata[0]->isa('PPI::Token::Whitespace') ) { shift @hunkdata }
  0         0  
51 96 100       573 if ( $hunkdata[1]->isa('PPI::Structure::List') ) {
52 60         373 @hunkdata = $hunkdata[1]->children;
53 60 50       374 next unless @hunkdata;
54 60         222 while ( $hunkdata[0]->isa('PPI::Token::Whitespace') ) { shift @hunkdata }
  42         129  
55             }
56 96 100       303 if ( $hunkdata[0]->isa('PPI::Statement::Expression') ) {
57 60         123 @hunkdata = $hunkdata[0]->children;
58 60 50       299 next unless @hunkdata;
59             }
60              
61             # possibly contains a version declaration!
62 96         190 my( $pkg, $done );
63 96         185 foreach my $elem ( @hunkdata ) {
64             # Scan for the first quote-like word, which is the package name
65 672 100 66     2405 if ( $elem->isa('PPI::Token::Quote') || $elem->isa('PPI::Token::QuoteLike') ) {
66             # found a new package and the previous one didn't have a version?
67 180 100       318 if ( defined $pkg ) {
68 36         122 $req->add_minimum( $pkg => 0 );
69             }
70 180         1746 $pkg = ( $self->_q_contents( $elem ) )[0];
71 180         266 undef $done;
72 180         317 next;
73             }
74              
75             # skip over the fluff and look for the version block
76 492 100 100     1332 if ( $pkg and $elem->isa('PPI::Structure::Constructor') ) {
77 87         223 foreach my $subelem ( $elem->children ) {
78             # skip over the fluff and look for the real version code
79 234 100       927 if ( $subelem->isa('PPI::Statement') ) {
80 87         134 my $found_ver;
81 87         163 foreach my $code ( $subelem->children ) {
82             # skip over the fluff until we're sure we saw the version declaration
83 468 100 100     1441 if ( $code->isa('PPI::Token::Word') and $code->literal eq '-version' ) {
84 81         779 $found_ver++;
85 81         144 next;
86             }
87              
88 387 100 100     1826 if ( $found_ver and ( $code->isa('PPI::Token::Quote') || $code->isa('PPI::Token::QuoteLike') || $code->isa('PPI::Token::Number') ) ) {
      100        
89 81         202 $req->add_minimum( $pkg => ( $self->_q_contents( $code ) )[0] );
90 81         6809 $done++;
91 81         133 undef $pkg;
92 81         127 last;
93             }
94             }
95              
96             # Did we fail to find the ver?
97 87 50 66     357 if ( $found_ver and ! $done ) {
98 0         0 die "Possible internal error!";
99             }
100             }
101             }
102              
103             # Failed to find version-specific stuff
104 87 100       224 if ( ! $done ) {
105 6         19 $req->add_minimum( $pkg => 0 );
106 6         172 undef $pkg;
107 6         9 next;
108             }
109             }
110             }
111              
112             # If we found a pkg but no done, this must be the "last" pkg to be declared and it has no version
113 96 100 66     352 if ( $pkg and ! $done ) {
114 57         132 $req->add_minimum( $pkg => 0 );
115             }
116             } else {
117             # no version or funky blocks in code, yay!
118 36         70 $req->add_minimum( $_ => 0 ) for
119 42         171 grep { Params::Util::_CLASS($_) }
120 36         106 map { $self->_q_contents( $_ ) }
121 114 100       484 grep { $_->isa('PPI::Token::Quote') || $_->isa('PPI::Token::QuoteLike') }
122             @$hunk;
123             }
124             }
125             }
126              
127             1;
128              
129             __END__
130              
131             =pod
132              
133             =encoding UTF-8
134              
135             =head1 NAME
136              
137             Perl::PrereqScanner::Scanner::Moose - scan for Moose sugar indicators of required modules
138              
139             =head1 VERSION
140              
141             version 1.025
142              
143             =head1 DESCRIPTION
144              
145             This scanner will look for the following indicators:
146              
147             =over 4
148              
149             =item *
150              
151             L<Moose> inheritance declared with the C<extends> keyword
152              
153             =item *
154              
155             L<Moose> roles included with the C<with> keyword
156              
157             =back
158              
159             =head1 PERL VERSION
160              
161             This library should run on perls released even a long time ago. It should work
162             on any version of perl released in the last five years.
163              
164             Although it may work on older versions of perl, no guarantee is made that the
165             minimum required version will not be increased. The version may be increased
166             for any reason, and there is no promise that patches will be accepted to lower
167             the minimum required perl.
168              
169             =head1 AUTHORS
170              
171             =over 4
172              
173             =item *
174              
175             Jerome Quelin
176              
177             =item *
178              
179             Ricardo Signes <cpan@semiotic.systems>
180              
181             =back
182              
183             =head1 COPYRIGHT AND LICENSE
184              
185             This software is copyright (c) 2009 by Jerome Quelin.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut