File Coverage

blib/lib/Method/Signatures/Utils.pm
Criterion Covered Total %
statement 35 39 89.7
branch 6 10 60.0
condition 5 6 83.3
subroutine 8 8 100.0
pod 0 4 0.0
total 54 67 80.6


line stmt bran cond sub pod time code
1             package Method::Signatures::Utils;
2              
3 62     62   226 use strict;
  62         69  
  62         1428  
4 62     62   183 use warnings;
  62         70  
  62         1111  
5 62     62   192 use Carp;
  62         68  
  62         2754  
6              
7 62     62   213 use base qw(Exporter);
  62         69  
  62         25011  
8             our @EXPORT = qw(new_ppi_doc sig_parsing_error carp_location_for DEBUG);
9              
10             sub DEBUG {
11 1448 50   1448 0 10887 return unless $Method::Signatures::DEBUG;
12              
13 0         0 require Data::Dumper;
14 0         0 local $Data::Dumper::Sortkeys = 1;
15 0 0       0 print STDERR "DEBUG: ", map { ref $_ ? Data::Dumper::Dumper($_) : $_ } @_;
  0         0  
16             }
17              
18              
19             sub new_ppi_doc {
20 324     324 0 321 my $code = shift;
21              
22 324         28494 require PPI;
23 324 50       5137213 my $ppi = PPI::Document->new($code) or
24             sig_parsing_error(
25             "source '$$code' cannot be parsed by PPI: " . PPI::Document->errstr
26             );
27              
28 324         320009 return $ppi;
29             };
30              
31              
32             # Generate cleaner error messages...
33             sub carp_location_for {
34 85     85 0 104 my ($class, $target) = @_;
35 85 100       358 $target = qr{(?!)} if !$target;
36              
37             # using @CARP_NOT here even though we're not using Carp
38             # who knows? maybe someday Carp will be capable of doing what we want
39             # until then, we're rolling our own, but @CARP_NOT is still serving roughly the same purpose
40 85         84 our @CARP_NOT;
41 85         113 local @CARP_NOT;
42 85         117 push @CARP_NOT, 'Method::Signatures';
43 85 100       130 push @CARP_NOT, $class unless $class =~ /^${\__PACKAGE__}(::|$)/;
  85         673  
44 85         161 push @CARP_NOT, qw< Class::MOP Moose Mouse Devel::Declare >;
45              
46             # Skip any package in the @CARP_NOT list or their sub packages.
47 85         262 my $carp_not_list_re = join '|', @CARP_NOT;
48 85         1056 my $skip = qr/^ $carp_not_list_re (?: :: | $ ) /x;
49              
50 85         107 my $level = 0;
51 85         79 my ($pack, $file, $line, $method);
52 85   100     79 do {
      66        
53 327         8495 ($pack, $file, $line, $method) = caller(++$level);
54             } while $method !~ $target and $method =~ /$skip/ or $pack =~ /$skip/;
55              
56 85         3049 return ($file, $line, $method);
57             }
58              
59             sub sig_parsing_error {
60 17     17 0 59 my ($file, $line) = carp_location_for(__PACKAGE__, 'Devel::Declare::linestr_callback');
61 17         66 my $msg = join('', @_, " in declaration at $file line $line.\n");
62 17         467 die($msg);
63             }
64              
65             1;