File Coverage

blib/lib/Perl/Tidy/Sweetened.pm
Criterion Covered Total %
statement 25 25 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod 0 1 0.0
total 35 36 97.2


line stmt bran cond sub pod time code
1             package Perl::Tidy::Sweetened;
2              
3             # ABSTRACT: Tweaks to Perl::Tidy to support some syntactic sugar
4              
5 15     15   1026306 use 5.010;
  15         184  
6 15     15   81 use strict;
  15         39  
  15         476  
7 15     15   81 use warnings;
  15         44  
  15         440  
8 15     15   18299 use Perl::Tidy qw();
  15         5651291  
  15         839  
9              
10             our $VERSION = '1.20';
11              
12 15     15   7303 use Perl::Tidy::Sweetened::Pluggable;
  15         52  
  15         800  
13 15     15   7028 use Perl::Tidy::Sweetened::Keyword::Block;
  15         41  
  15         478  
14 15     15   6773 use Perl::Tidy::Sweetened::Variable::Twigils;
  15         50  
  15         6747  
15              
16             our $plugins = Perl::Tidy::Sweetened::Pluggable->new();
17              
18             # Create a subroutine filter for:
19             # sub foo ($i, $j) {}
20             $plugins->add_filter(
21             Perl::Tidy::Sweetened::Keyword::Block->new(
22             keyword => 'sub',
23             marker => 'SUB',
24             replacement => 'sub',
25             clauses => ['PAREN'],
26             ) );
27              
28             # Create a subroutine filter for:
29             # func foo (Int $i) returns (Bool) {}
30             # where both the parameter list and the returns type are optional
31             $plugins->add_filter(
32             Perl::Tidy::Sweetened::Keyword::Block->new(
33             keyword => 'func',
34             marker => 'FUNC',
35             replacement => 'sub',
36             clauses => [ 'PAREN?', '(returns \s* PAREN)?' ],
37             ) );
38              
39             # Create a subroutine filter for:
40             # fun foo (Int $i) {}
41             # where the parameter list is optional
42             $plugins->add_filter(
43             Perl::Tidy::Sweetened::Keyword::Block->new(
44             keyword => 'fun',
45             marker => 'FUN',
46             replacement => 'sub',
47             clauses => ['PAREN?'],
48             ) );
49              
50             # Create a subroutine filter for:
51             # method foo (Int $i) returns (Bool) {}
52             # method foo(@\@) :prototype(@\@) :Bar (Baz) ($i %args) {}
53             # where all of the parameter list, returns type, signature, and colon-prefixed parameters are optional
54             $plugins->add_filter(
55             Perl::Tidy::Sweetened::Keyword::Block->new(
56             keyword => 'method',
57             marker => 'METHOD',
58             replacement => 'sub',
59             clauses => [
60             'PAREN?',
61             '(:\w+ PAREN?)*',
62             '(returns \s* PAREN)?',
63             '(\b(?:is|but|does) \s+ \w+)?'
64             ],
65             ) );
66              
67             # Create a subroutine filter for:
68             # around foo (Int $i) returns (Bool) {}
69             # before foo (Int $i) returns (Bool) {}
70             # after foo (Int $i) returns (Bool) {}
71             # where both the parameter list and the returns type are optional
72             $plugins->add_filter(
73             Perl::Tidy::Sweetened::Keyword::Block->new(
74             keyword => $_,
75             marker => uc($_),
76             replacement => 'sub',
77             clauses => ['PAREN?'],
78             ) ) for qw(around before after);
79              
80             # Create a subroutine filter for:
81             # classmethod foo (Int $i) {}
82             # where the parameter list is optional
83             $plugins->add_filter(
84             Perl::Tidy::Sweetened::Keyword::Block->new(
85             keyword => 'classmethod',
86             marker => 'CLASSMETHOD',
87             replacement => 'sub',
88             clauses => ['PAREN?'],
89             ) );
90              
91             # Create a subroutine filter for:
92             # objectmethod foo (Int $i) {}
93             # where the parameter list is optional
94             $plugins->add_filter(
95             Perl::Tidy::Sweetened::Keyword::Block->new(
96             keyword => 'objectmethod',
97             marker => 'OBJECTMETHOD',
98             replacement => 'sub',
99             clauses => ['PAREN?'],
100             ) );
101              
102             # Create a subroutine filter for:
103             # class Foo extends Bar {
104             # class Foo with Bar, Baz {
105             # class Foo using Baz {
106             # class Foo :Bar :Baz {
107             # class Foo :does(ROLE) {
108             # where all of the extends, with, using and colon-prefixed parameters are optional
109             $plugins->add_filter(
110             Perl::Tidy::Sweetened::Keyword::Block->new(
111             keyword => 'class',
112             marker => 'CLASS',
113             replacement => 'package',
114             clauses => [
115             '(: \w+ (?=\s) )?',
116             '(:does PAREN)?',
117             '(:repr PAREN)?',
118             '(:strict PAREN)?',
119             '(:isa PAREN)?',
120             '(extends \s+ [\w|:]+ )?',
121             '(does \s+ (\w+,?\s*)+ )?',
122             '(isa \s+ (\w+\s*)+ )?',
123             '(with (\s+\w+)* )?',
124             '(is (\s+\w+)* )?',
125             '(using \s+\w+ )?',
126             'PAREN?',
127             ],
128             ) );
129              
130             # Create a subroutine filter for:
131             # role Foo :Bar :Baz {
132             # where the colon-prefixed parameters is optional
133             $plugins->add_filter(
134             Perl::Tidy::Sweetened::Keyword::Block->new(
135             keyword => 'role',
136             marker => 'ROLE',
137             replacement => 'sub',
138             clauses => [ '( : \w+ )?', ],
139             ) );
140              
141             # Create a subroutine filter for:
142             # field $slot_name :Bar //= 'foo' {
143             # where the colon-prefixed parameters are optional
144             $plugins->add_filter(
145             Perl::Tidy::Sweetened::Keyword::Block->new(
146             keyword => 'field',
147             marker => 'FIELD',
148             replacement => 'my',
149             clauses => [ '( : \w+ )?', ],
150             ) );
151              
152             # Create a twigil filter for:
153             # $!variable_name
154             $plugins->add_filter(
155             Perl::Tidy::Sweetened::Variable::Twigils->new(
156             twigil => '$!',
157             marker => 'TWG_BANG',
158             ) );
159              
160             sub perltidy {
161 109     109 0 220410 my %args = @_;
162 109         606 $plugins->add_args( $args{argv} );
163              
164             return Perl::Tidy::perltidy(
165 109     109   3370846 prefilter => sub { $plugins->prefilter( $_[0] ) },
166 109     109   1427934 postfilter => sub { $plugins->postfilter( $_[0] ) },
167             @_
168 109         990 );
169             }
170              
171             1;
172              
173             __END__
174              
175             =pod
176              
177             =head1 NAME
178              
179             Perl::Tidy::Sweetened - Tweaks to Perl::Tidy to support some syntactic sugar
180              
181             =head1 VERSION
182              
183             version 1.20
184              
185             =head1 STATUS
186              
187             =for html <a href="https://travis-ci.org/mvgrimes/Perl-Tidy-Sweetened"><img src="https://travis-ci.org/mvgrimes/Perl-Tidy-Sweetened.svg?branch=master" alt="Build Status"></a>
188             <a href="https://metacpan.org/pod/Perl::Tidy::Sweetened"><img alt="CPAN version" src="https://badge.fury.io/pl/Perl-Tidy-Sweetened.svg" /></a>
189              
190             =head1 DESCRIPTION
191              
192             There are a number of modules on CPAN that allow users to write their classes
193             with a more "modern" syntax. These tools eliminate the need to shift off
194             C<$self>, can support type checking and offer other improvements.
195             Unfortunately, they can break the support tools that the Perl community has
196             come to rely on. This module attempts to work around those issues.
197              
198             The module uses
199             L<Perl::Tidy>'s C<prefilter> and C<postfilter> hooks to support C<method> and
200             C<func> keywords, including the (possibly multi-line) parameter lists. This is
201             quite an ugly hack, but it is the recommended method of supporting these new
202             keywords (see the 2010-12-17 entry in the Perl::Tidy
203             L<CHANGES|https://metacpan.org/source/SHANCOCK/Perl-Tidy-20120714/CHANGES>
204             file). B<The resulting formatted code will leave the parameter lists untouched.>
205              
206             C<Perl::Tidy::Sweetened> attempts to support the syntax outlined in the
207             following modules, but most of the new syntax styles should work:
208              
209             =over
210              
211             =item * p5-mop
212              
213             =item * Method::Signatures::Simple
214              
215             =item * MooseX::Method::Signatures
216              
217             =item * MooseX::Declare
218              
219             =item * Moops
220              
221             =item * perl 5.20 signatures
222              
223             =item * Kavorka
224              
225             =back
226              
227             =head1 THANKS
228              
229             The idea and much of original code taken from Jonathan Swartz'
230             L<blog|http://www.openswartz.com/2010/12/19/perltidy-and-method-happy-together/>.
231              
232             =head1 SEE ALSO
233              
234             L<Perl::Tidy>
235              
236             =head1 AUTHOR
237              
238             Mark Grimes <mgrimes@cpan.org>
239              
240             =head1 SOURCE
241              
242             Source repository is at L<https://github.com/mvgrimes/Perl-Tidy-Sweetened>.
243              
244             =head1 BUGS
245              
246             Please report any bugs or feature requests on the bugtracker website L<https://github.com/mvgrimes/Perl-Tidy-Sweetened/issues>
247              
248             When submitting a bug or request, please include a test-file or a
249             patch to an existing test-file that illustrates the bug or desired
250             feature.
251              
252             =head1 COPYRIGHT AND LICENSE
253              
254             This software is copyright (c) 2023 by Mark Grimes <mgrimes@cpan.org>.
255              
256             This is free software; you can redistribute it and/or modify it under
257             the same terms as the Perl 5 programming language system itself.
258              
259             =cut