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