File Coverage

blib/lib/Perl/ToPerl6/Transformer/ModuleSpecific/Exporter.pm
Criterion Covered Total %
statement 23 61 37.7
branch 0 22 0.0
condition 0 9 0.0
subroutine 10 18 55.5
pod 3 7 42.8
total 36 117 30.7


line stmt bran cond sub pod time code
1             package Perl::ToPerl6::Transformer::ModuleSpecific::Exporter;
2              
3 1     1   770 use 5.006001;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         18  
5 1     1   5 use warnings;
  1         2  
  1         21  
6 1     1   9 use Readonly;
  1         1  
  1         41  
7              
8 1     1   4 use Perl::ToPerl6::Utils qw{ :severities };
  1         2  
  1         49  
9 1         48 use Perl::ToPerl6::Utils::PPI qw{
10             ppi_list_elements
11             insert_trailing_whitespace
12 1     1   115 };
  1         2  
13              
14 1     1   5 use base 'Perl::ToPerl6::Transformer';
  1         2  
  1         722  
15              
16             #-----------------------------------------------------------------------------
17              
18             Readonly::Scalar my $DESC => q{Add 'is export' and 'is export(:tag)' declarations to subroutines};
19             Readonly::Scalar my $EXPL => q{Add 'is export' and 'is export(:tag)' declarations to subroutines};
20              
21             #-----------------------------------------------------------------------------
22              
23 1     1 0 4 sub run_before { return 'Operators::FormatOperators' }
24 1     1 0 4 sub supported_parameters { return () }
25 1     1 1 4 sub default_necessity { return $NECESSITY_HIGHEST }
26 0     0 1   sub default_themes { return qw( tweaks ) }
27 0     0 1   sub applies_to { return 'PPI::Document' }
28              
29             #-----------------------------------------------------------------------------
30              
31             sub ppi_rhs_list_values {
32 0     0 0   my ($elem) = @_;
33 0           my @values;
34 0 0 0       if ( $elem->snext_sibling and
      0        
      0        
35             $elem->snext_sibling->isa('PPI::Token::Operator') and
36             $elem->snext_sibling->content eq '=' and
37             $elem->snext_sibling->snext_sibling ) {
38 0           push @values, ppi_list_elements(
39             $elem->snext_sibling->snext_sibling
40             );
41             }
42 0           return @values;
43             }
44              
45             #
46             # All subs in @EXPORT will be marked with 'is export(:MANDATORY)'
47             # All subs in @EXPORT_OK will be marked with just 'is export'
48             # All subs in a tag of %EXPORT_TAGS will be marked with 'is export(:tag)'
49             # (there's a default ':ALL' tag that may be useful)
50             # ( 'is export(:a :b)' works for multiple tag names, I guess)
51              
52             sub transform {
53 0     0 0   my ($self, $elem, $doc) = @_;
54             return unless $doc->find( sub {
55 0 0   0     $_[1]->isa('PPI::Statement::Include') and
56             $_[1]->schild(1)->content =~ m< ^ Exporter >x
57 0 0         } );
58              
59 0           my $subroutine_tags = {};
60              
61             my $export = $doc->find( sub {
62 0 0   0     $_[1]->isa('PPI::Token::Symbol') and
63             $_[1]->content eq '@EXPORT'
64 0           } );
65              
66             my $export_ok = $doc->find( sub {
67 0 0   0     $_[1]->isa('PPI::Token::Symbol') and
68             $_[1]->content eq '@EXPORT_OK'
69 0           } );
70              
71             my $export_tags = $doc->find( sub {
72 0 0   0     $_[1]->isa('PPI::Token::Symbol') and
73             $_[1]->content eq '%EXPORT_TAGS'
74 0           } );
75              
76 0           my $subs = $doc->find('PPI::Statement::Sub');
77              
78 0 0         if ( @$export ) {
79 0           for my $_elem ( @$export ) {
80 0           for ( ppi_rhs_list_values($_elem) ) {
81 0           push @{ $subroutine_tags->{$_} }, 'MANDATORY'
  0            
82             }
83             }
84             }
85             #
86             # XXX The code here assumes that @EXPORT and @EXPORT_OK are disjoint sets.
87             #
88 0 0         if ( @$export_ok ) {
89 0           for my $_elem ( @$export_ok ) {
90 0           for ( ppi_rhs_list_values($_elem) ) {
91 0           $subroutine_tags->{$_} = 1;
92             }
93             }
94             }
95              
96 0           for my $sub ( @$subs ) {
97 0 0         next unless $sub->name;
98 0 0         next unless exists $subroutine_tags->{$sub->name};
99 0           my $export_tags = '';
100 0 0         if ( ref $subroutine_tags->{$sub->name} ) {
101             $export_tags = ' (' .
102 0           join( ', ', map { ":$_" }
103 0           @{ $subroutine_tags->{$sub->name} } ) .
  0            
104             ')';
105             }
106 0           $sub->schild(1)->insert_after(
107             PPI::Token::Attribute->new('is export' . $export_tags)
108             );
109 0           insert_trailing_whitespace($sub->schild(1));
110             }
111              
112 0           return $self->transformation( $DESC, $EXPL, $elem );
113             }
114              
115             1;
116              
117             #-----------------------------------------------------------------------------
118              
119             __END__
120              
121             =pod
122              
123             =head1 NAME
124              
125             Perl::ToPerl6::Transformer::ModuleSpecific::Exporter - Replace EXPORT variables with 'is export' notation
126              
127              
128             =head1 AFFILIATION
129              
130             This Transformer is part of the core L<Perl::ToPerl6|Perl::ToPerl6>
131             distribution.
132              
133              
134             =head1 DESCRIPTION
135              
136             Perl6 now has a built-in 'is export' feature for exporting functions.
137              
138             @EXPORT = qw( foo ); sub foo { } --> sub foo is export(:MANDATORY)
139              
140             Transforms subroutines outside of comments, heredocs, strings and POD.
141              
142             =head1 CONFIGURATION
143              
144             This Transformer is not configurable except for the standard options.
145              
146             =head1 AUTHOR
147              
148             Jeffrey Goff <drforr@pobox.com>
149              
150             =head1 COPYRIGHT
151              
152             Copyright (c) 2015 Jeffrey Goff
153              
154             This program is free software; you can redistribute it and/or modify
155             it under the same terms as Perl itself.
156              
157             =cut
158              
159             ##############################################################################
160             # Local Variables:
161             # mode: cperl
162             # cperl-indent-level: 4
163             # fill-column: 78
164             # indent-tabs-mode: nil
165             # c-indentation-style: bsd
166             # End:
167             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :