File Coverage

blib/lib/Eval/TypeTiny/CodeAccumulator.pm
Criterion Covered Total %
statement 70 72 97.2
branch 6 10 60.0
condition 5 10 50.0
subroutine 19 19 100.0
pod 13 13 100.0
total 113 124 91.1


line stmt bran cond sub pod time code
1             package Eval::TypeTiny::CodeAccumulator;
2              
3 56     56   2006 use 5.008001;
  56         236  
4 56     56   301 use strict;
  56         122  
  56         1143  
5 56     56   272 use warnings;
  56         120  
  56         2433  
6              
7             BEGIN {
8 56 50   56   2092 if ( $] < 5.010 ) { require Devel::TypeTiny::Perl58Compat }
  0         0  
9             }
10              
11             BEGIN {
12 56     56   179 $Eval::TypeTiny::CodeAccumulator::AUTHORITY = 'cpan:TOBYINK';
13 56         49911 $Eval::TypeTiny::CodeAccumulator::VERSION = '2.004000';
14             }
15              
16             $Eval::TypeTiny::CodeAccumulator::VERSION =~ tr/_//d;
17              
18             sub new {
19 321     321 1 744 my $class = shift;
20              
21 321 50       2256 my %self = @_ == 1 ? %{$_[0]} : @_;
  0         0  
22 321   50     1902 $self{env} ||= {};
23 321   50     1891 $self{code} ||= [];
24 321   50     1972 $self{placeholders} ||= {};
25 321   50     1525 $self{indent} ||= '';
26              
27 321         1360 bless \%self, $class;
28             }
29              
30 371     371 1 691 sub code { join( "\n", @{ $_[0]{code} } ) }
  371         4106  
31 297     297 1 1109 sub description { $_[0]{description} }
32 297     297 1 1423 sub env { $_[0]{env} }
33              
34             sub add_line {
35 5364     5364 1 9056 my $self = shift;
36 5364         9017 my $indent = $self->{indent};
37              
38 5364         7457 push @{ $self->{code} }, map { $indent . $_ } map { split /\n/ } @_;
  5364         11230  
  7293         20089  
  5364         15337  
39              
40 5364         12515 $self;
41             }
42              
43             sub increase_indent {
44 56     56 1 104 $_[0]{indent} .= "\t";
45 56         89 $_[0];
46             }
47              
48             sub decrease_indent {
49 56     56 1 216 $_[0]{indent} =~ s/\t$//;
50 56         115 $_[0];
51             }
52              
53             sub add_gap {
54 1867     1867 1 2886 push @{ $_[0]{code} }, '';
  1867         5020  
55             }
56              
57             sub add_placeholder {
58 4     4 1 17 my ( $self, $for ) = ( shift, @_ );
59 4   50     15 my $indent = $self->{indent} || '';
60              
61             $self->{placeholders}{$for} = [
62 4         14 scalar( @{ $self->{code} } ),
63             $self->{indent},
64 4         6 ];
65 4         7 push @{ $self->{code} }, "$indent# placeholder [ $for ]";
  4         11  
66              
67 4 100       13 if ( defined wantarray ) {
68 2     1   9 return sub { $self->fill_placeholder( $for, @_ ) };
  1         5  
69             }
70             }
71              
72             sub fill_placeholder {
73 2     2 1 6 my ( $self, $for, @lines ) = ( shift, @_ );
74              
75 2 50       3 my ( $line_number, $indent ) = @{ delete $self->{placeholders}{$for} or die };
  2         9  
76 2         6 my @indented_lines = map { $indent . $_ } map { split /\n/ } @lines;
  2         22  
  2         5  
77 2         4 splice( @{ $self->{code} }, $line_number, 1, @indented_lines );
  2         28  
78              
79 2         9 $self;
80             }
81              
82             sub add_variable {
83 237     237 1 1986 my ( $self, $suggested_name, $reference ) = ( shift, @_ );
84            
85 237         430 my $actual_name = $suggested_name;
86 237         410 my $i = 1;
87 237         769 while ( exists $self->{env}{$actual_name} ) {
88 61         232 $actual_name = sprintf '%s_%d', $suggested_name, ++$i;
89             }
90              
91 237         634 $self->{env}{$actual_name} = $reference;
92              
93 237         620 $actual_name;
94             }
95              
96             sub finalize {
97 297     297 1 589 my $self = shift;
98              
99 297         560 for my $p ( values %{ $self->{placeholders} } ) {
  297         1120  
100 2         3 splice( @{ $self->{code} }, $p->[0], 1 );
  2         8  
101             }
102              
103 297         585 $self;
104             }
105              
106             sub compile {
107 297     297 1 884 my ( $self, %opts ) = ( shift, @_ );
108              
109 297 50       3449 $self->{finalized}++ or $self->finalize();
110              
111 297         2556 require Eval::TypeTiny;
112 297         1041 return Eval::TypeTiny::eval_closure(
113             description => $self->description,
114             %opts,
115             source => $self->code,
116             environment => $self->env,
117             );
118             }
119              
120             1;
121              
122             __END__