File Coverage

blib/lib/PPIx/DocumentName.pm
Criterion Covered Total %
statement 62 79 78.4
branch 25 34 73.5
condition 10 12 83.3
subroutine 14 18 77.7
pod 3 3 100.0
total 114 146 78.0


line stmt bran cond sub pod time code
1 3     3   210222 use 5.006; # our
  3         36  
2 3     3   20 use strict;
  3         5  
  3         69  
3 3     3   24 use warnings;
  3         6  
  3         209  
4              
5             package PPIx::DocumentName;
6              
7             # ABSTRACT: Utility to extract a name from a PPI Document
8             our $VERSION = '1.01'; # VERSION
9              
10 3     3   1435 use PPI::Util qw( _Document );
  3         23615  
  3         669  
11              
12              
13             sub log_info(&@);
14             sub log_debug(&@);
15             sub log_trace(&@);
16              
17             my %callers;
18              
19             BEGIN {
20 3 50   3   19 if ( $INC{'Log/Contextual.pm'} ) {
21             ## Hide from autoprereqs
22 0         0 require 'Log/Contextual/WarnLogger.pm'; ## no critic (Modules::RequireBarewordIncludes)
23 0         0 my $deflogger = Log::Contextual::WarnLogger->new( { env_prefix => 'PPIX_DOCUMENTNAME', } );
24 0         0 Log::Contextual->import( 'log_info', 'log_debug', 'log_trace', '-default_logger' => $deflogger );
25             }
26             else {
27 3         18 require Carp;
28 3     0   22 *log_info = sub (&@) { Carp::carp( $_[0]->() ) };
  0         0  
29 3     26   13 *log_debug = sub (&@) { };
30 3     8   2639 *log_trace = sub (&@) { };
31             }
32             }
33              
34             sub import {
35 4     4   1162 my(undef, %args) = @_;
36 4 100       1488 if(defined $args{'-api'}) {
37 2 100 66     17 if($args{'-api'} != 0 && $args{'-api'} != 1) {
38 1         190 Carp::croak("illegal api level: $args{'-api'}");
39             }
40 1 50       4 if($] < 5.010) {
41 0         0 my($package) = caller;
42 0         0 $callers{$package} = $args{'-api'};
43 0         0 require Carp;
44 0         0 Carp::carp("Because of the age of your Perl, -api $args{'-api'} " .
45             'will be package scoped instead of block scoped. ' .
46             'Please upgrade to 5.10 or better.');
47             } else {
48 1         31 $^H{'PPIx::DocumentName/api'} = $args{'-api'}; ## no critic (Variables::RequireLocalizedPunctuationVars)
49             }
50             }
51             }
52              
53             sub _api {
54 61     61   113 my ( $api ) = @_;
55 61 50       147 if($] < 5.010) {
56 0         0 my($package) = caller 1;
57 0 0       0 $api = $callers{$package} unless defined $api;
58             } else {
59 61         400 my $hh = (caller 1)[10];
60 61 100 66     277 $api = $hh->{'PPIx::DocumentName/api'} if defined $hh && !defined $api;
61             }
62 61 100       142 $api = 0 unless defined $api;
63 61         105 return $api;
64             }
65              
66             sub _result {
67 10     10   25 my($name, $ppi_document, $node) = @_;
68 10         617 require PPIx::DocumentName::Result;
69 10         40 PPIx::DocumentName::Result->_new($name, $ppi_document, $node); ## no critic (Subroutines::ProtectPrivateSubs)
70             }
71              
72             ## OO
73              
74              
75             sub extract {
76 13     13 1 254977 my ( $self, $ppi_document ) = @_;
77 13         40 my $api = _api(undef);
78 13   100     42 my $result = $self->extract_via_comment($ppi_document, $api) || $self->extract_via_statement($ppi_document, $api);
79 13         641 return $result;
80             }
81              
82              
83             sub extract_via_statement {
84 22     22 1 14109 my ( undef, $ppi_document, $api ) = @_;
85              
86 22         48 $api = _api($api);
87              
88             # Keep alive until done
89             # https://github.com/adamkennedy/PPI/issues/112
90 22         62 my $dom = _Document($ppi_document);
91 22         24700 my $pkg_node = $dom->find_first('PPI::Statement::Package');
92 22 100       3981 if ( not $pkg_node ) {
93 8     0   45 log_debug { "No PPI::Statement::Package found in <<$ppi_document>>" };
  0         0  
94             # The old API was inconsistant here, for just this method, returns
95             # empty list on failure. This is unfortunately different from
96             # extract_via_comment.
97 8 100       48 return 1 == $api ? undef : ();
98             }
99 14 50       58 if ( not $pkg_node->namespace ) {
100 0     0   0 log_debug { "PPI::Statement::Package $pkg_node has empty namespace in <<$ppi_document>>" };
  0         0  
101 0 0       0 return 1 == $api ? undef : ();
102             }
103 14         412 my $name = $pkg_node->namespace;
104 14 100       321 return 1 == $api ? _result($name, $dom, $pkg_node) : $name;
105             }
106              
107              
108             sub extract_via_comment {
109 26     26 1 12563 my ( undef, $ppi_document, $api ) = @_;
110              
111 26         71 $api = _api($api);
112 26         47 my $node;
113              
114 26         109 my $regex = qr{ ^ \s* \#+ \s* PODNAME: \s* (.+) $ }x; ## no critic (RegularExpressions)
115 26         58 my $content;
116             my $finder = sub {
117 196     196   1918 my $maybe = $_[1];
118 196 100       623 return 0 unless $maybe->isa('PPI::Token::Comment');
119 8         46 log_trace { "Found comment node $maybe" };
  0         0  
120 8 50       36 if ( $maybe->content =~ $regex ) {
121 8         103 $content = $1;
122 8         14 $node = $maybe;
123 8         19 return 1;
124             }
125 0         0 return 0;
126 26         118 };
127              
128             # Keep alive until done
129             # https://github.com/adamkennedy/PPI/issues/112
130 26         100 my $dom = _Document($ppi_document);
131 26         31144 $dom->find_first($finder);
132              
133 26 100   0   465 log_debug { "<<$ppi_document>> has no PODNAME comment" } if not $content;
  0         0  
134              
135 26 100 100     175 return 1 == $api && defined $content ? _result($content, $dom, $node) : $content;
136             }
137              
138             1;
139              
140             __END__