File Coverage

blib/lib/Syntax/Collector.pm
Criterion Covered Total %
statement 65 69 94.2
branch 18 30 60.0
condition 2 6 33.3
subroutine 13 13 100.0
pod n/a
total 98 118 83.0


line stmt bran cond sub pod time code
1 3     3   112786 use 5.006001;
  3         13  
  3         153  
2 3     3   16 use strict;
  3         3  
  3         104  
3 3     3   15 use warnings;
  3         10  
  3         111  
4              
5 3     3   8136 use Exporter::Tiny qw//;
  3         19114  
  3         80  
6 3     3   19544 use Module::Runtime qw//;
  3         9284  
  3         178  
7              
8             {
9             package Syntax::Collector;
10            
11             BEGIN {
12 3     3   8 $Syntax::Collector::AUTHORITY = 'cpan:TOBYINK';
13 3         1244 $Syntax::Collector::VERSION = '0.006';
14             }
15            
16             sub import
17             {
18 3     3   33 my $class = shift;
19            
20 3         7 my %opts;
21 3         4 my $opt = 'collect';
22 3         18 while (my $arg = shift @_)
23             {
24 3         18 ($arg =~ /^-(.+)$/)
25             ? ($opt = $1)
26 4 100       30 : push(@{$opts{$opt}}, $arg)
27             }
28            
29 3 50       13 Exporter::Tiny::_croak("Need to provide a list of use lines to collect")
30             unless $opts{collect};
31 3 50       16 $opts{collect} = [$opts{collect}] unless ref $opts{collect};
32            
33 7 100       332 my @features =
    50          
34             map {
35 7         17 m{^
36             (use|no) \s+ # "use" or "no"
37             (\S+) \s+ # module name
38             ([\d\._v]+) # module version
39             (?: # everything else
40             \s* (.+)
41             )? # ... perhaps
42             [;] \s* # semicolon
43             $}x
44             ? [$1, $2, $3, [ defined($4) ? eval "($4)" : ()] ]
45             : Exporter::Tiny::_croak("Line q{$_} doesn't conform to 'use MODULE VERSION [ARGS];'")
46             }
47 19         47 grep { ! m/^#/ } # not a comment
48 19         59 grep { m/[A-Z0-9]/i } # at least one alphanum
49 19         38 map { s/(^\s+)|(\s+$)//; $_ } # trim
  3         78  
50 3         10 map { split /(\r?\n|\r)/ } # split lines
51 3         6 @{ $opts{collect} };
52            
53 3     3   33 no strict 'refs';
  3         8  
  3         136  
54 3     3   18 no warnings 'closure';
  3         6  
  3         1057  
55 3         10889 my $caller = caller;
56 3         14 unshift @{"$caller\::ISA"}, 'Syntax::Collector::Collection';
  3         73  
57 3 50   4   309 eval "package $caller; sub _syntax_collector_features { \@features }; 1"
  4         21  
58             or Exporter::Tiny::_croak("$@");
59 3   33     24 $INC{Module::Runtime::module_notional_filename($caller)} ||= (caller(0))[1];
60             }
61             }
62              
63             {
64             package Syntax::Collector::Collection;
65            
66             BEGIN {
67 3     3   12 $Syntax::Collector::Collection::AUTHORITY = 'cpan:TOBYINK';
68 3         1495 $Syntax::Collector::Collection::VERSION = '0.006';
69             }
70            
71             our @ISA = 'Exporter::Tiny';
72            
73             sub _exporter_validate_opts
74             {
75 2     2   293 my $class = shift;
76 2         6 my ($opt) = @_;
77            
78 2         5 my $caller = $opt->{into};
79 2 50 33     22 defined($caller) && !ref($caller)
80             or Exporter::Tiny::_croak("Expected to be installing into a package!");
81            
82 2         23 $class->SUPER::_exporter_validate_opts(@_);
83            
84 2         674 my ($coderef_use, $coderef_no) = eval qq[
85             package $caller;
86             (
87             sub { shift->import(\@_) },
88             sub { shift->unimport(\@_) },
89             )
90             ];
91            
92 2         73 foreach my $f ($class->_syntax_collector_features)
93             {
94 6         20 my ($use, $module, $version, $everything) = @$f;
95 6         22 Module::Runtime::require_module($module);
96 6 50       153 $module->VERSION($version) if $version;
97            
98 6 50       40 if (ref $opt->{$module} eq 'ARRAY')
    50          
    50          
99 0         0 { $everything = $opt->{$module} }
100             elsif (ref $opt->{$module} eq 'HASH')
101 0         0 { $everything = [ %{$opt->{$module}} ] }
  0         0  
102             elsif ($opt->{$module})
103 0         0 { next; }
104            
105 6 50       196 ($module =~ /^Syntax::Feature::/)
    50          
106             ? $module->install(into => $caller, @$everything)
107             : ($use eq 'no' ? $coderef_no : $coderef_use)->($module, @$everything)
108             }
109            
110 2 100       48 if (my $afterlife = $class->can('IMPORT'))
111             {
112 1         83 eval qq[package $caller; \$afterlife->(\$opt)];
113             }
114             }
115            
116             sub modules
117             {
118 2     2   5 my $class = shift;
119            
120 2         85 my %modules = map { $_->[1] => $_->[2] } $class->_syntax_collector_features;
  6         30  
121 2 50       38 return (wantarray ? keys(%modules) : \%modules);
122             }
123             }
124              
125             __FILE__
126             __END__