File Coverage

lib/App/PRT/Command/DeleteMethod.pm
Criterion Covered Total %
statement 48 48 100.0
branch 10 12 83.3
condition 4 6 66.6
subroutine 10 10 100.0
pod 0 7 0.0
total 72 83 86.7


line stmt bran cond sub pod time code
1             package App::PRT::Command::DeleteMethod;
2 2     2   2218 use strict;
  2         4  
  2         69  
3 2     2   11 use warnings;
  2         5  
  2         54  
4 2     2   919 use PPI;
  2         143729  
  2         1109  
5              
6             sub new {
7 14     14 0 31080 my ($class) = @_;
8 14         78 bless {}, $class;
9             }
10              
11             # parse arguments from CLI
12             # arguments:
13             # @arguments
14             # returns:
15             # @rest_arguments
16             sub parse_arguments {
17 2     2 0 71 my ($self, @arguments) = @_;
18              
19 2 100       20 die "class and method required" unless @arguments >= 2;
20              
21 1         6 $self->register(shift @arguments => shift @arguments);
22              
23 1         3 @arguments;
24             }
25              
26             # register a replacing rule
27             # arguments:
28             # $target_class_name: Target Class Name
29             # $target_method_name: Target Method Name
30             sub register {
31 13     13 0 44 my ($self, $target_class_name, $target_method_name) = @_;
32              
33 13         52 $self->{target_class_name} = $target_class_name;
34 13         45 $self->{target_method_name} = $target_method_name;
35             }
36              
37             sub target_class_name {
38 11     11 0 295 my ($self) = @_;
39              
40 11         78 $self->{target_class_name};
41             }
42              
43             sub target_method_name {
44 16     16 0 441 my ($self) = @_;
45              
46 16         82 $self->{target_method_name};
47             }
48              
49             sub deleted_code {
50 7     7 0 6241 my ($self) = @_;
51              
52 7         82 $self->{deleted_code};
53             }
54              
55             # refactor a file
56             # argumensts:
57             # $file: filename for refactoring
58             sub execute {
59 12     12 0 3040 my ($self, $file) = @_;
60              
61 12         77 my $document = PPI::Document->new($file);
62              
63 12 50       132211 return unless $document;
64              
65 12         92 my $package = $document->find_first('PPI::Statement::Package');
66              
67 12 100       9201 return unless $package;
68 9 100       62 return unless $package->namespace eq $self->target_class_name;
69              
70 7         41 my $subs = $document->find('PPI::Statement::Sub');
71              
72 7         28691 my $replaced = 0;
73 7         28 for my $sub (@$subs) {
74 14 100       121 next unless $sub->name eq $self->target_method_name;
75 7         17 my @garbages;
76              
77             # comment before method
78 7         73 my $cursor = $sub->first_token->previous_token;
79 7   66     1698 while (defined $cursor && ref $cursor eq 'PPI::Token::Comment') {
80 4         73 unshift @garbages, $cursor;
81 4         28 $cursor = $cursor->previous_token;
82             }
83              
84             # method body
85 7         71 push @garbages, $sub;
86              
87             # whitespace after method
88 7         49 $cursor = $sub->last_token->next_token;
89 7   66     1585 while (defined $cursor && ref $cursor eq 'PPI::Token::Whitespace') {
90 14         249 push @garbages, $cursor;
91 14         59 $cursor = $cursor->next_token;
92             }
93              
94 7         483 $self->{deleted_code} = join '', @garbages;
95              
96 7         1434 $_->remove for @garbages;
97 7         948 $replaced++;
98             }
99              
100 7 50       127 $document->save($file) if $replaced;
101             }
102              
103             1;