File Coverage

lib/PPIx/Element/Package.pm
Criterion Covered Total %
statement 33 33 100.0
branch 16 18 88.8
condition 5 9 55.5
subroutine 8 8 100.0
pod 3 3 100.0
total 65 71 91.5


line stmt bran cond sub pod time code
1 7     7   180118 use 5.006; # our
  7         25  
2 7     7   32 use strict;
  7         13  
  7         140  
3 7     7   44 use warnings;
  7         17  
  7         527  
4              
5             package PPIx::Element::Package;
6              
7             our $VERSION = '0.001000'; # TRIAL
8              
9             # ABSTRACT: Derive the package an element is defined in
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 7     7   40 use Scalar::Util qw( refaddr );
  7         13  
  7         419  
14 7     7   34 use Exporter 5.57 qw( import );
  7         90  
  7         2256  
15             our @EXPORT_OK = qw( identify_package identify_package_namespace identify_package_in_previous_siblings );
16              
17              
18              
19              
20              
21              
22              
23              
24              
25              
26             sub identify_package {
27 221     221 1 268 my ($element) = @_;
28              
29             # Packages are their own owners
30 221 100       889 return $element if $element->isa('PPI::Statement::Package');
31              
32             # Elements without parents have no Package
33 216 100 66     1136 return unless $element->can('parent') and my $parent = $element->parent;
34              
35             # Any element which is directly a child of a Package is also the Package
36             # ( These are the package tokens themselves )
37 192 100       1882 return $parent if $parent->isa('PPI::Statement::Package');
38              
39             # Check any sibling nodes previous to the current one
40             # and return the nearest Package, if present.
41 172         284 my $package = identify_package_in_previous_siblings($element);
42 172 100       416 return $package if defined $package;
43              
44             # Otherwise, recursively assume the Package of whatever your
45             # parent is.
46 132         234 return identify_package($parent);
47             }
48              
49              
50              
51              
52              
53              
54              
55              
56              
57              
58              
59              
60              
61             sub identify_package_namespace {
62 89     89 1 912182 my ($element) = @_;
63 89         173 my $package = identify_package($element);
64              
65 89 100 66     516 return ( defined $package and defined $package->namespace ) ? $package->namespace : 'main';
66             }
67              
68              
69              
70              
71              
72              
73              
74              
75              
76              
77              
78              
79              
80             sub identify_package_in_previous_siblings {
81 172     172 1 202 my ($element) = @_;
82              
83             # elements without parents or children can't hold siblings
84 172 50 33     726 return unless $element->can('parent') and my $parent = $element->parent;
85 172 50       1444 return unless $parent->can('children');
86              
87 172         346 my $self_addr = refaddr($element);
88 172         171 my $last_package;
89              
90 172         390 for my $sibling ( $parent->children ) {
91              
92             # Record most recently found Package
93 648 100       2729 $last_package = $sibling if $sibling->isa('PPI::Statement::Package');
94              
95             # Return whatever package was found as soon as we find ourselves
96             # ( Because we don't care about Packages after ourselves.
97 648 100       1823 return $last_package if $self_addr eq refaddr($sibling);
98             }
99 8         15 return;
100             }
101              
102             1;
103              
104             __END__