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   2695 use strict;
  2         4  
  2         58  
3 2     2   9 use warnings;
  2         4  
  2         47  
4 2     2   580 use PPI;
  2         106403  
  2         862  
5              
6             sub new {
7 14     14 0 30793 my ($class) = @_;
8 14         51 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 94 my ($self, @arguments) = @_;
18              
19 2 100       19 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 51 my ($self, $target_class_name, $target_method_name) = @_;
32              
33 13         51 $self->{target_class_name} = $target_class_name;
34 13         80 $self->{target_method_name} = $target_method_name;
35             }
36              
37             sub target_class_name {
38 11     11 0 286 my ($self) = @_;
39              
40 11         51 $self->{target_class_name};
41             }
42              
43             sub target_method_name {
44 16     16 0 383 my ($self) = @_;
45              
46 16         67 $self->{target_method_name};
47             }
48              
49             sub deleted_code {
50 7     7 0 6045 my ($self) = @_;
51              
52 7         59 $self->{deleted_code};
53             }
54              
55             # refactor a file
56             # argumensts:
57             # $file: filename for refactoring
58             sub execute {
59 12     12 0 4256 my ($self, $file) = @_;
60              
61 12         51 my $document = PPI::Document->new($file);
62              
63 12 50       130382 return unless $document;
64              
65 12         73 my $package = $document->find_first('PPI::Statement::Package');
66              
67 12 100       8106 return unless $package;
68 9 100       51 return unless $package->namespace eq $self->target_class_name;
69              
70 7         35 my $subs = $document->find('PPI::Statement::Sub');
71              
72 7         20006 my $replaced = 0;
73 7         25 for my $sub (@$subs) {
74 14 100       109 next unless $sub->name eq $self->target_method_name;
75 7         18 my @garbages;
76              
77             # comment before method
78 7         45 my $cursor = $sub->first_token->previous_token;
79 7   66     737 while (defined $cursor && ref $cursor eq 'PPI::Token::Comment') {
80 4         84 unshift @garbages, $cursor;
81 4         34 $cursor = $cursor->previous_token;
82             }
83              
84             # method body
85 7         76 push @garbages, $sub;
86              
87             # whitespace after method
88 7         32 $cursor = $sub->last_token->next_token;
89 7   66     805 while (defined $cursor && ref $cursor eq 'PPI::Token::Whitespace') {
90 14         259 push @garbages, $cursor;
91 14         33 $cursor = $cursor->next_token;
92             }
93              
94 7         330 $self->{deleted_code} = join '', @garbages;
95              
96 7         1107 $_->remove for @garbages;
97 7         1076 $replaced++;
98             }
99              
100 7 50       47 $document->save($file) if $replaced;
101             }
102              
103             1;