File Coverage

blib/lib/App/PerlNitpick/Rule/QuoteSimpleStringWithSingleQuote.pm
Criterion Covered Total %
statement 23 32 71.8
branch 6 14 42.8
condition 0 6 0.0
subroutine 6 6 100.0
pod 0 1 0.0
total 35 59 59.3


line stmt bran cond sub pod time code
1             package App::PerlNitpick::Rule::QuoteSimpleStringWithSingleQuote;
2             # ABSTRACT: Re-quote strings with single quotes ('') if they look "simple"
3              
4             =encoding UTF-8
5              
6             =head1 DESCRIPTION
7              
8             This nitpicking rule re-quote simple strings with single-quote.
9             For example, C<"coffee"> becomes C<'coffee'>.
10              
11             =head2 Simple strings ?
12              
13             Simple strings is a subset of strings that satisfies all of these
14             constraints:
15              
16             - is a string literal (not variable)
17             - is quoted with: q, qq, double-quote ("), or single-quote (')
18             - is a single-line string
19             - has no interpolations inside
20             - has no quote characters inside
21             - has no sigil characters inside
22             - has no metachar
23              
24             For example, here's a short list of simple strings:
25              
26             - q<肆拾貳>
27             - qq{Latte Art}
28             - "Spring"
29             - "Error: insufficient vespene gas"
30              
31             While here are some counter examples:
32              
33             - "john.smith@example.com"
34             - "'s-Gravenhage"
35             - 'Look at this @{[ longmess() ]}'
36             - q<The symbol $ is also known as dollor sign.>
37              
38             Roughly speaking, given a string, if you can re-quote it with single-quote (')
39             without changing its value -- then it is a simple string.
40              
41             =cut
42              
43 1     1   243819 use Moose;
  1         475604  
  1         5  
44 1     1   8194 use PPI::Document;
  1         117713  
  1         477  
45              
46             sub rewrite {
47 2     2 0 11881 my ($self, $doc) = @_;
48              
49 2 50   10   6 for my $tok (@{$doc->find(sub { $_[1]->isa('PPI::Token::Quote::Double') }) || []}) {
  2         18  
  10         210  
50 2 50       40 next if $tok->interpolations;
51 2         30 my $value = $tok->string;
52 2 100       25 next if index($value, "\n") > 0;
53 1         4 $tok->simplify;
54             }
55              
56 2         60 my @todo;
57 2 50   10   5 for my $tok (@{ $doc->find(sub { $_[1]->isa('PPI::Token::Quote::Interpolate') }) || []}) {
  2         21  
  10         159  
58 0         0 my $value = $tok->string;
59 0 0 0     0 next if $value =~ /[\\\$@%\'\"]/ || index($value, "\n") > 0;
60 0         0 push @todo, $tok;
61             }
62              
63 2 50   10   42 for my $tok (@{ $doc->find(sub { $_[1]->isa('PPI::Token::Quote::Literal') }) || []}) {
  2         10  
  10         132  
64 0         0 my $value = $tok->string;
65 0 0 0     0 next if $value =~ /\'/ || index($value, "\n") > 0;
66 0         0 push @todo, $tok;
67             }
68              
69 2         43 for my $tok (@todo) {
70 0         0 my $value = $tok->string;
71             # I probably know what I am doing.
72 0         0 $tok->{content} = "'" . $tok->string . "'";
73 0         0 bless $tok, 'PPI::Token::Quote::Single';
74             }
75              
76 2         8 return $doc;
77             }
78              
79             1;