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   1276 use strict;
  2         2  
  2         45  
3 2     2   6 use warnings;
  2         1  
  2         37  
4 2     2   439 use PPI;
  2         81891  
  2         590  
5              
6             sub new {
7 14     14 0 17045 my ($class) = @_;
8 14         39 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 50 my ($self, @arguments) = @_;
18              
19 2 100       12 die "class and method required" unless @arguments >= 2;
20              
21 1         2 $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 28 my ($self, $target_class_name, $target_method_name) = @_;
32              
33 13         33 $self->{target_class_name} = $target_class_name;
34 13         25 $self->{target_method_name} = $target_method_name;
35             }
36              
37             sub target_class_name {
38 11     11 0 213 my ($self) = @_;
39              
40 11         41 $self->{target_class_name};
41             }
42              
43             sub target_method_name {
44 16     16 0 228 my ($self) = @_;
45              
46 16         61 $self->{target_method_name};
47             }
48              
49             sub deleted_code {
50 7     7 0 3395 my ($self) = @_;
51              
52 7         34 $self->{deleted_code};
53             }
54              
55             # refactor a file
56             # argumensts:
57             # $file: filename for refactoring
58             sub execute {
59 12     12 0 1848 my ($self, $file) = @_;
60              
61 12         49 my $document = PPI::Document->new($file);
62              
63 12 50       62503 return unless $document;
64              
65 12         53 my $package = $document->find_first('PPI::Statement::Package');
66              
67 12 100       5328 return unless $package;
68 9 100       37 return unless $package->namespace eq $self->target_class_name;
69              
70 7         23 my $subs = $document->find('PPI::Statement::Sub');
71              
72 7         13456 my $replaced = 0;
73 7         19 for my $sub (@$subs) {
74 14 100       73 next unless $sub->name eq $self->target_method_name;
75 7         8 my @garbages;
76              
77             # comment before method
78 7         36 my $cursor = $sub->first_token->previous_token;
79 7   66     414 while (defined $cursor && ref $cursor eq 'PPI::Token::Comment') {
80 4         42 unshift @garbages, $cursor;
81 4         24 $cursor = $cursor->previous_token;
82             }
83              
84             # method body
85 7         42 push @garbages, $sub;
86              
87             # whitespace after method
88 7         51 $cursor = $sub->last_token->next_token;
89 7   66     456 while (defined $cursor && ref $cursor eq 'PPI::Token::Whitespace') {
90 14         132 push @garbages, $cursor;
91 14         29 $cursor = $cursor->next_token;
92             }
93              
94 7         175 $self->{deleted_code} = join '', @garbages;
95              
96 7         684 $_->remove for @garbages;
97 7         504 $replaced++;
98             }
99              
100 7 50       67 $document->save($file) if $replaced;
101             }
102              
103             1;