| 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; |