File Coverage

blib/lib/Perl/Tidy/Sweetened/Variable/Twigils.pm
Criterion Covered Total %
statement 36 37 97.3
branch 3 6 50.0
condition n/a
subroutine 11 11 100.0
pod 2 7 28.5
total 52 61 85.2


line stmt bran cond sub pod time code
1             package Perl::Tidy::Sweetened::Variable::Twigils;
2              
3             # ABSTRACT: Perl::Tidy::Sweetened filter plugin to handle twigls
4              
5 15     15   257 use 5.010; # Needed for balanced parens matching with qr/(?-1)/
  15         55  
6 15     15   96 use strict;
  15         31  
  15         491  
7 15     15   95 use warnings;
  15         118  
  15         543  
8 15     15   123 use Carp;
  15         63  
  15         7776  
9             $|++;
10              
11             our $VERSION = '1.20';
12              
13             sub new {
14 15     15 0 57 my ( $class, %args ) = @_;
15 15 50       108 croak 'twigil not specified' if not exists $args{twigil};
16 15 50       82 croak 'marker not specified' if not exists $args{marker};
17 15 50       143 $args{clauses} = [] unless exists $args{clauses};
18 15         154 return bless {%args}, $class;
19             }
20              
21 117     117 1 472 sub twigil { return $_[0]->{twigil} }
22 117     117 1 339 sub marker { return $_[0]->{marker} }
23              
24             sub emit_placeholder {
25 8     8 0 44 my ( $self, $varname ) = @_;
26              
27             # Store the signature and returns() for later use
28 8         27 my $id = $self->{counter}++;
29 8         27 $self->{store}->{$id} = $varname;
30              
31 8         23 return sprintf '$__%s_%s', $self->marker, $id;
32             }
33              
34             sub emit_twigil {
35 8     8 0 46 my ( $self, $id ) = @_;
36              
37             # Get the signature and returns() from store
38 8         24 my $varname = $self->{store}->{$id};
39              
40 8         22 return sprintf '%s%s', $self->twigil, $varname;
41             }
42              
43             sub prefilter {
44 109     109 0 349 my ( $self, $code ) = @_;
45 109         401 my $twigil = '\\' . $self->twigil;
46              
47 109         761 $code =~ s{
48             (?: ^|\s)\K # needs to be sperated by a space
49             $twigil # the twigil (ie, $!)
50             (?<varname> \w+) # the variable name
51             }{
52             $self->emit_placeholder( $+{varname} )
53 8         50 }egmx;
54              
55 109         405 return $code;
56             }
57              
58             sub postfilter {
59 109     109 0 350 my ( $self, $code ) = @_;
60 109         369 my $marker = $self->marker;
61              
62             # Convert back to method
63 109         880 $code =~ s{
64             (?: ^|\s)\K # needs to be sperated by a space
65             \$ __ $marker # keyword was convert to package
66             _ (?<id> \d+ ) \b # the method name and a word break
67             }{
68 8         46 $self->emit_twigil( $+{id} );
69             }egmx;
70              
71             # Check to see if tidy turned it into "sub name\n{ #..."
72 109         919 $code =~ s{
73             ^\s*\K # preserve leading whitespace
74             package \s+ # method was converted to sub
75             (?<subname> \w+)\n \s* # the method name and a newline
76             (?<brace> \{ .*?) [ ]* # opening brace on newline followed orig comments
77             \#__$marker \s+ # our magic token
78             (?<id> \d+) # our sub identifier
79             [ ]* # trailing spaces (not all whitespace)
80             }{
81 0         0 $self->emit_keyword( $+{subname}, $+{brace}, $+{id} );
82             }egmx;
83              
84 109         452 return $code;
85             }
86              
87             1;
88              
89             __END__
90              
91             =pod
92              
93             =head1 NAME
94              
95             Perl::Tidy::Sweetened::Variable::Twigils - Perl::Tidy::Sweetened filter plugin to handle twigls
96              
97             =head1 VERSION
98              
99             version 1.20
100              
101             =head1 SYNOPSIS
102              
103             our $plugins = Perl::Tidy::Sweetened::Pluggable->new();
104              
105             $plugins->add_filter(
106             Perl::Tidy::Sweetened::Variable::Twigils->new(
107             twigil => '$!',
108             marker => 'TWG_BANG',
109             ) );
110              
111             =head1 DESCRIPTION
112              
113             This is a Perl::Tidy::Sweetened filter which enables the use of twigils as
114             defined by the L<Twigils> module. New accepts:
115              
116             =over 4
117              
118             =item twigil
119              
120             twigil => '$!'
121              
122             Declares a new twigil. In this case to be used as C<$!variable>.
123              
124             =item marker
125              
126             marker => 'TWG_BANG'
127              
128             Provides a text marker to be used to flag the new keywords during
129             C<prefilter>. The source code will be filtered prior to formatting by
130             Perl::Tidy such that:
131              
132             $!class_attribute
133              
134             is turned into:
135              
136             $__TWG_BANK_1
137              
138             Then back into the original twigiled variable in the C<postfilter>.
139              
140             =back
141              
142             =head1 AUTHOR
143              
144             Mark Grimes <mgrimes@cpan.org>
145              
146             =head1 SOURCE
147              
148             Source repository is at L<https://github.com/mvgrimes/Perl-Tidy-Sweetened>.
149              
150             =head1 BUGS
151              
152             Please report any bugs or feature requests on the bugtracker website L<https://github.com/mvgrimes/Perl-Tidy-Sweetened/issues>
153              
154             When submitting a bug or request, please include a test-file or a
155             patch to an existing test-file that illustrates the bug or desired
156             feature.
157              
158             =head1 COPYRIGHT AND LICENSE
159              
160             This software is copyright (c) 2023 by Mark Grimes <mgrimes@cpan.org>.
161              
162             This is free software; you can redistribute it and/or modify it under
163             the same terms as the Perl 5 programming language system itself.
164              
165             =cut