File Coverage

blib/lib/PPIx/Regexp/Util.pm
Criterion Covered Total %
statement 66 78 84.6
branch 19 38 50.0
condition 12 18 66.6
subroutine 17 18 94.4
pod 3 3 100.0
total 117 155 75.4


line stmt bran cond sub pod time code
1             package PPIx::Regexp::Util;
2              
3 9     9   125116 use 5.006;
  9         31  
4              
5 9     9   62 use strict;
  9         23  
  9         213  
6 9     9   43 use warnings;
  9         42  
  9         340  
7              
8 9     9   57 use Carp;
  9         26  
  9         676  
9 9         1449 use PPIx::Regexp::Constant qw{
10             INFINITY
11             MINIMUM_PERL
12             @CARP_NOT
13 9     9   4087 };
  9         178  
14 9     9   68 use Scalar::Util qw{ blessed };
  9         27  
  9         427  
15              
16 9     9   51 use base qw{ Exporter };
  9         38  
  9         6380  
17              
18             our @EXPORT_OK = qw{
19             is_ppi_regexp_element
20             __choose_tokenizer_class
21             __instance
22             __is_ppi_regexp_element
23             __merge_perl_requirements
24             __ns_can
25             __post_rebless_error
26             raw_width
27             __to_ordinal_en
28             width
29             };
30              
31             our %EXPORT_TAGS = (
32             all => \@EXPORT_OK,
33             width_one => [ qw{ raw_width width } ],
34             );
35              
36             our $VERSION = '0.087';
37              
38             sub is_ppi_regexp_element {
39 11     11 1 39 my ( $elem ) = @_;
40 11 50       30 __instance( $elem, 'PPI::Element' )
41             or return;
42 11   66     84 return $elem->isa( 'PPI::Token::Regexp' ) ||
43             $elem->isa( 'PPI::Token::QuoteLike::Regexp' );
44             }
45              
46             sub __is_ppi_regexp_element {
47 0     0   0 Carp::cluck(
48             '__is_ppi_regexp_element is deprecated. Use is_ppi_regexp_element'
49             );
50 0         0 goto &is_ppi_regexp_element;
51             }
52              
53             # TODO ditch this once the deprecation period ends
54             sub __choose_tokenizer_class {
55             # my ( $content, $arg ) = @_;
56 538     538   1657 my ( undef, $arg ) = @_;
57 538 50       1922 if ( defined $arg->{parse} ) {
58 0         0 my $warning = q;
59             { guess => 1, string => 1 }->{$arg->{parse}}
60 0 0       0 and $warning = join ' ', $warning,
61             q;
62 0         0 croak $warning;
63             }
64 538         1652 return 'PPIx::Regexp::Tokenizer';
65             }
66              
67             sub __instance {
68 55876     55876   97903 my ( $object, $class ) = @_;
69 55876 100       169074 blessed( $object ) or return;
70 23759         106539 return $object->isa( $class );
71             }
72              
73             sub __merge_perl_requirements { ## no critic (RequireArgUnpacking)
74             my @work =
75 113 50       219 sort { $a->[0] <=> $b->[0] || $b->[1] <=> $a->[1] }
76 30         118 map { ( [ $_->[0], 1 ], [ $_->[1], 0 ] ) }
77 9 100   9   18 map { [ $_->{introduced}, defined $_->{removed} ? $_->{removed} : INFINITY ] } @_;
  30         81  
78 9         28 my @rslt;
79 9         23 while ( @work ) {
80 11         19 my ( $intro, $rem );
81 11   66     98 $intro = ( shift @work )->[0] while @work && $work[0][1];
82 11 50       30 if ( @work ) {
83 11         18 $rem = $work[0][0];
84 11   100     95 shift @work while @work && ! $work[0][1];
85             }
86 11 50       28 defined $intro
87             or $intro = MINIMUM_PERL;
88 11 50       39 defined $rem
89             or $rem = INFINITY;
90 11 50       51 $intro != $rem
91             and push @rslt, {
92             introduced => $intro,
93             removed => $rem,
94             };
95             }
96             @rslt
97             and $rslt[-1]{removed} == INFINITY
98 9 50 33     41 and delete $rslt[-1]{removed};
99 9         42 return @rslt;
100             }
101              
102             sub __ns_can {
103 252     252   515 my ( $class, $name ) = @_;
104 252   33     871 my $fqn = join '::', ref $class || $class, $name;
105 9     9   132 no strict qw{ refs };
  9         20  
  9         4071  
106 252 50       1548 return defined &$fqn ? \&$fqn : undef;
107             }
108              
109             sub __post_rebless_error {
110 8     8   33 my ( $self, %arg ) = @_;
111 8         22 my $rslt = 0;
112 8 50       58 unless ( defined( $self->{error} = $arg{error} ) ) {
113 0         0 my $class = ref $self;
114 0         0 Carp::cluck( "Making $class with no error message" );
115 0         0 $self->{error} = 'Unspecified error';
116 0         0 $rslt++;
117             }
118             $self->{explanation} = defined $arg{explanation} ?
119             $arg{explanation} :
120 8 50       44 $arg{error};
121 8         28 return $rslt;
122              
123             }
124              
125             # Unquantified number of characters matched.
126             sub raw_width {
127 527     527 1 1195 return ( 1, 1 );
128             }
129              
130             sub __to_ordinal_en {
131 1     1   4 my ( $num ) = @_;
132 1         2 $num += 0;
133 1 50       11 1 == int( ( $num % 100 ) / 10 ) # teens
134             and return "${num}th";
135 1 50       8 1 == $num % 10
136             and return "${num}st";
137 0 0       0 2 == $num % 10
138             and return "${num}nd";
139 0 0       0 3 == $num % 10
140             and return "${num}rd";
141 0         0 return "${num}th";
142             }
143              
144             sub width {
145 727     727 1 1227 my ( $self ) = @_;
146 727         1770 my @raw_width = $self->raw_width();
147 727         1166 my ( $code, $next_sib );
148 727 100 100     1747 $next_sib = $self->snext_sibling()
149             and $code = $next_sib->can( '__quantified_width' )
150             or return @raw_width;
151 91         319 return $code->( $next_sib, @raw_width );
152             }
153              
154             1;
155              
156             __END__