File Coverage

blib/lib/App/p5find.pm
Criterion Covered Total %
statement 42 54 77.7
branch 7 14 50.0
condition 5 5 100.0
subroutine 14 15 93.3
pod 0 5 0.0
total 68 93 73.1


line stmt bran cond sub pod time code
1             package App::p5find;
2 4     4   1007456 use v5.18;
  4         38  
3             our $VERSION = "0.04";
4              
5 4     4   2069 use File::Next;
  4         10636  
  4         162  
6 4     4   2013 use PPI::Document::File;
  4         327797  
  4         157  
7 4     4   2216 use PPIx::QuoteLike;
  4         72218  
  4         143  
8              
9 4     4   37 use Exporter 'import';
  4         11  
  4         2570  
10             our @EXPORT_OK = qw( p5_doc_iterator
11             p5_source_file_iterator
12             p5_method_call_iterator
13             print_file_linenum_line );
14              
15             my %EXCLUDED = (
16             '.git' => 1,
17             '.svn' => 1,
18             'CVS' => 1,
19             'node_modules' => 1, # You won't hide your Perl5 code there, right ?
20             );
21              
22             sub p5_doc_iterator {
23 3     3 0 14017 my (@paths) = @_;
24 3         14 my $files = p5_source_file_iterator(@paths);
25             return sub {
26 11     11   17863 my $f = $files->();
27 11 100       34 return undef unless defined($f);
28 10         84 my $dom = PPI::Document::File->new( $f, readonly => 1 );
29 10         461769 $dom->index_locations;
30 10         100757 return $dom;
31 3         18 };
32             }
33              
34             sub p5_source_file_iterator {
35 5     5 0 8441 my (@paths) = @_;
36             my $files = File::Next::files(
37 16     16   2276 +{ descend_filter => sub { ! $EXCLUDED{$_} } },
38             @paths
39 5         45 );
40             return sub {
41 15     15   81 my $f;
42 15   100     35 do { $f = $files->() } while defined($f) && ! is_perl5_source_file($f);
  23         66  
43 15         71 return $f;
44             }
45 5         823 }
46              
47             sub is_perl5_source_file {
48 22     22 0 2317 my ($file) = @_;
49 22 100       184 return 1 if $file =~ / \.(?: t|p[ml]|pod|comp ) $/xi;
50 8 50       39 return 0 if $file =~ / \. /xi;
51 0 0       0 if (open my $fh, '<', $file) {
52 0         0 my $line = <$fh>;
53 0 0       0 return 1 if $line =~ m{^#!.*perl};
54             }
55 0         0 return 0;
56             }
57              
58             sub print_file_linenum_line {
59 0     0 0 0 my ($file, $to_print) = @_;
60              
61 0         0 my $line_number = 0;
62 0         0 open my $fh, "<", $file;
63 0         0 while (my $line = <$fh>) {
64 0         0 $line_number++;
65 0 0       0 if ( $to_print->{$line_number} ) {
66 0         0 print "${file}:${line_number}:${line}";
67             }
68             }
69 0         0 close($fh);
70             }
71              
72             sub p5_method_call_iterator {
73 2     2 0 16625 my ($doc) = @_;
74              
75             my $arrows = $doc->find(
76             sub {
77 41     41   463 my $op = $_[1];
78 41         151 return 0 unless $op->isa("PPI::Token::Operator") && $op->content eq '->';
79 4         44 my $op_next = $op->snext_sibling or return 0;
80 4         136 return 0 if $op_next->isa("PPI::Structure::Subscript") || $op_next->isa("PPI::Structure::List");
81 2         5 return 1;
82             }
83 2   100     18 ) || [];
84              
85             return sub {
86 4 100   4   64 return @$arrows ? shift(@$arrows) : undef;
87 2         38 };
88             }
89              
90             1;
91              
92             __END__