File Coverage

blib/lib/self.pm
Criterion Covered Total %
statement 53 59 89.8
branch 16 22 72.7
condition 3 3 100.0
subroutine 12 12 100.0
pod 2 2 100.0
total 86 98 87.7


line stmt bran cond sub pod time code
1 17     17   166873 use strict;
  17         23  
  17         391  
2 17     17   53 use warnings;
  17         17  
  17         447  
3              
4             package self;
5 17     17   269 use 5.006;
  17         35  
6              
7             our $VERSION = '0.35';
8 17     17   8034 use Sub::Exporter;
  17         148569  
  17         69  
9              
10 17     17   9378 use Devel::Declare ();
  17         65017  
  17         405  
11 17     17   6432 use B::Hooks::Parser;
  17         7849  
  17         8035  
12              
13             my $NO_SELF;
14              
15             sub import {
16 18     18   114 my ($class) = @_;
17 18         31 my $caller = caller;
18              
19 18         208 B::Hooks::Parser::setup();
20              
21 18         65 my $linestr = B::Hooks::Parser::get_linestr();
22 18         42 my $offset = B::Hooks::Parser::get_linestr_offset();
23 18         41 substr($linestr, $offset, 0) = 'use B::OPCheck const => check => \&self::_check;';
24 18         153 B::Hooks::Parser::set_linestr($linestr);
25              
26 18         120 my $exporter = Sub::Exporter::build_exporter({
27             into_level => 1,
28             exports => [qw(self args)],
29             groups => { default => [ -all ] }
30             });
31 18         2363 $exporter->(@_);
32             }
33              
34             sub unimport {
35 1     1   6 my ($class) = @_;
36 1         1 my $caller = caller;
37 1         7 $NO_SELF = 1;
38             }
39              
40             sub _check {
41 351     351   111555 my $op = shift;
42 351         325 my $caller = caller;
43 351 100       1529 return if $NO_SELF;
44 337 100       1323 return unless ref($op->gv) eq 'B::PV';
45              
46 303         633 my $linestr = B::Hooks::Parser::get_linestr;
47 303         333 my $offset = B::Hooks::Parser::get_linestr_offset;
48 303         291 my $line = substr($linestr, $offset);
49              
50 303         186 my $code = 'my($self,@args)=@_;';
51              
52             # This cover cases like:
53             # sub foo { ... }
54             # Offset is at the first '{' because subroutine name is also a "const"
55 303 100       1736 if (substr($linestr, $offset, 1) eq '{') {
    50          
    100          
56 88 100       823 if (substr($linestr, 0, $offset) =~ m/sub\s\S+\s*\z/x ) {
57 57 100       231 if (index($line, "{$code") < 0) {
58 49         78 substr($linestr, $offset + 1, 0) = $code;
59 49         901 B::Hooks::Parser::set_linestr($linestr);
60             }
61             }
62             }
63             elsif (substr($linestr, $offset, 3) eq 'sub') {
64 0 0       0 if ($line =~ m/^sub\s.*{ /x ) {
65 0 0       0 if (index($line, "{$code") < 0) {
66 0         0 substr($linestr, $offset + index($line, '{') + 1, 0) = $code;
67 0         0 B::Hooks::Parser::set_linestr($linestr);
68             }
69             }
70             }
71              
72             # This elsif block handles:
73             # sub foo
74             # {
75             # ...
76             # }
77             elsif (index($linestr, 'sub') >= 0) {
78 57         99 $offset += Devel::Declare::toke_skipspace($offset);
79 57 100       789 if ($linestr =~ /(sub.*?\n\s*{)/) {
80 2         5 my $pos = index($linestr, $1);
81 2 50       54 if ($pos + length($1) - 1 == $offset) {
82 0         0 substr($linestr, $offset + 1, 0) = $code;
83 0         0 B::Hooks::Parser::set_linestr($linestr);
84             }
85             }
86             }
87             }
88              
89             sub _args {
90 77     77   54 my $level = 2;
91 77         65 my @c = ();
92             package DB;
93 77   100     706 @c = caller($level++)
94             while !defined($c[3]) || $c[3] eq '(eval)';
95 77         252 return @DB::args;
96             }
97              
98             sub self {
99 66     66 1 3040 (_args)[0];
100             }
101              
102             sub args {
103 11     11 1 50 my @a = _args;
104 11         27 return @a[1..$#a];
105             }
106              
107             1;
108              
109             __END__