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 55     55   2018 use 5.008001;
  55         219  
4 55     55   372 use strict;
  55         133  
  55         1101  
5 55     55   327 use warnings;
  55         132  
  55         2365  
6              
7             BEGIN {
8 55 50   55   2175 if ( $] < 5.010 ) { require Devel::TypeTiny::Perl58Compat }
  0         0  
9             }
10              
11             BEGIN {
12 55     55   265 $Eval::TypeTiny::CodeAccumulator::AUTHORITY = 'cpan:TOBYINK';
13 55         54136 $Eval::TypeTiny::CodeAccumulator::VERSION = '2.002001';
14             }
15              
16             $Eval::TypeTiny::CodeAccumulator::VERSION =~ tr/_//d;
17              
18             sub new {
19 317     317 1 725 my $class = shift;
20              
21 317 50       1388 my %self = @_ == 1 ? %{$_[0]} : @_;
  0         0  
22 317   50     1855 $self{env} ||= {};
23 317   50     1626 $self{code} ||= [];
24 317   50     1644 $self{placeholders} ||= {};
25 317   50     1935 $self{indent} ||= '';
26              
27 317         1094 bless \%self, $class;
28             }
29              
30 364     364 1 705 sub code { join( "\n", @{ $_[0]{code} } ) }
  364         3948  
31 293     293 1 1425 sub description { $_[0]{description} }
32 293     293 1 1278 sub env { $_[0]{env} }
33              
34             sub add_line {
35 5290     5290 1 9260 my $self = shift;
36 5290         8976 my $indent = $self->{indent};
37              
38 5290         7355 push @{ $self->{code} }, map { $indent . $_ } map { split /\n/ } @_;
  5290         10675  
  7124         19692  
  5290         15303  
39              
40 5290         12200 $self;
41             }
42              
43             sub increase_indent {
44 56     56 1 114 $_[0]{indent} .= "\t";
45 56         98 $_[0];
46             }
47              
48             sub decrease_indent {
49 56     56 1 241 $_[0]{indent} =~ s/\t$//;
50 56         109 $_[0];
51             }
52              
53             sub add_gap {
54 1834     1834 1 2653 push @{ $_[0]{code} }, '';
  1834         4965  
55             }
56              
57             sub add_placeholder {
58 4     4 1 13 my ( $self, $for ) = ( shift, @_ );
59 4   50     14 my $indent = $self->{indent} || '';
60              
61             $self->{placeholders}{$for} = [
62 4         12 scalar( @{ $self->{code} } ),
63             $self->{indent},
64 4         7 ];
65 4         8 push @{ $self->{code} }, "$indent# placeholder [ $for ]";
  4         11  
66              
67 4 100       14 if ( defined wantarray ) {
68 2     1   12 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       4 my ( $line_number, $indent ) = @{ delete $self->{placeholders}{$for} or die };
  2         8  
76 2         6 my @indented_lines = map { $indent . $_ } map { split /\n/ } @lines;
  2         6  
  2         6  
77 2         4 splice( @{ $self->{code} }, $line_number, 1, @indented_lines );
  2         19  
78              
79 2         7 $self;
80             }
81              
82             sub add_variable {
83 234     234 1 2015 my ( $self, $suggested_name, $reference ) = ( shift, @_ );
84            
85 234         552 my $actual_name = $suggested_name;
86 234         405 my $i = 1;
87 234         793 while ( exists $self->{env}{$actual_name} ) {
88 61         206 $actual_name = sprintf '%s_%d', $suggested_name, ++$i;
89             }
90              
91 234         627 $self->{env}{$actual_name} = $reference;
92              
93 234         610 $actual_name;
94             }
95              
96             sub finalize {
97 293     293 1 560 my $self = shift;
98              
99 293         518 for my $p ( values %{ $self->{placeholders} } ) {
  293         1114  
100 2         3 splice( @{ $self->{code} }, $p->[0], 1 );
  2         6  
101             }
102              
103 293         648 $self;
104             }
105              
106             sub compile {
107 293     293 1 841 my ( $self, %opts ) = ( shift, @_ );
108              
109 293 50       1775 $self->{finalized}++ or $self->finalize();
110              
111 293         2615 require Eval::TypeTiny;
112 293         986 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__