File Coverage

blib/lib/Locale/Babelfish/Phrase/Compiler.pm
Criterion Covered Total %
statement 59 61 96.7
branch 11 16 68.7
condition 2 3 66.6
subroutine 13 14 92.8
pod 4 4 100.0
total 89 98 90.8


line stmt bran cond sub pod time code
1             package Locale::Babelfish::Phrase::Compiler;
2              
3             # ABSTRACT: Babelfish AST Compiler
4              
5              
6 4     4   155188 use utf8;
  4         23  
  4         27  
7 4     4   130 use strict;
  4         8  
  4         72  
8 4     4   18 use warnings;
  4         7  
  4         156  
9              
10 4     4   23 use List::Util 1.33 qw( none );
  4         115  
  4         311  
11              
12 4     4   453 use Locale::Babelfish::Phrase::Literal ();
  4         8  
  4         88  
13 4     4   415 use Locale::Babelfish::Phrase::Variable ();
  4         15  
  4         84  
14 4     4   439 use Locale::Babelfish::Phrase::PluralForms ();
  4         39  
  4         117  
15              
16 4     4   25 use parent qw( Class::Accessor::Fast );
  4         17  
  4         23  
17              
18             our $VERSION = '2.10'; # VERSION
19              
20             __PACKAGE__->mk_accessors( qw( ast ) );
21              
22             my $sub_index = 0;
23              
24              
25             sub new {
26 4     4 1 1576 my ( $class, $ast ) = @_;
27 4         10 my $parser = bless {}, $class;
28 4 50       11 $parser->init( $ast ) if $ast;
29 4         9 return $parser;
30             }
31              
32              
33             sub init {
34 69     69 1 128 my ( $self, $ast ) = @_;
35 69         1235 $self->ast( $ast );
36 69         607 return $self;
37             }
38              
39              
40             sub throw {
41 0     0 1 0 my ( $self, $message ) = @_;
42 0         0 die "Cannot compile: $message";
43             }
44              
45              
46              
47             sub compile {
48 69     69 1 314 my ( $self, $ast ) = @_;
49              
50 69 50       232 $self->init( $ast ) if $ast;
51              
52 69 50       1188 $self->throw("No AST given") unless $self->ast;
53 69 50       353 $self->throw("Empty AST given") if scalar( @{ $self->ast } ) == 0;
  69         1148  
54              
55 69 100 66     341 if ( scalar( @{ $self->ast } ) == 1 && ref($self->ast->[0]) eq 'Locale::Babelfish::Phrase::Literal' ) {
  69         1102  
56             # просто строка
57 47         1821 return $self->ast->[0]->text;
58             }
59              
60 22         143 my $text = 'sub { my ( $params ) = @_; return join \'\',';
61 22         35 for my $node ( @{ $self->ast } ) {
  22         361  
62 81 100       366 if ( ref($node) eq 'Locale::Babelfish::Phrase::Literal' ) {
    100          
    50          
63 42         132 $text .= $node->to_perl_escaped_str. ',';
64             }
65             elsif ( ref($node) eq 'Locale::Babelfish::Phrase::Variable' ) {
66 24         72 $text .= "(\$params->{". $node->to_perl_escaped_str. "} // ''),";
67             }
68             elsif ( ref($node) eq 'Locale::Babelfish::Phrase::PluralForms' ) {
69 15         47 my $sub = $node->to_perl_sub();
70 15         39 my $index = ++$sub_index;
71 15         50 my $name = "Locale::Babelfish::Phrase::Compiler::COMPILED_SUB_$index";
72 4     4   1741 no strict 'refs';
  4         9  
  4         195  
73 15         24 *{$name} = $sub;
  15         156  
74 4     4   25 use strict 'refs';
  4         13  
  4         417  
75 15         66 $text .= "$name(\$params),"
76             }
77             }
78 22         43 $text .= '\'\'; }';
79 22         2636 return eval $text;
80             }
81              
82             1;
83              
84             __END__
85              
86             =pod
87              
88             =encoding UTF-8
89              
90             =head1 NAME
91              
92             Locale::Babelfish::Phrase::Compiler - Babelfish AST Compiler
93              
94             =head1 VERSION
95              
96             version 2.10
97              
98             =head1 DESCRIPTION
99              
100             Compiles AST to string or to coderef.
101              
102             =head1 METHODS
103              
104             =head2 new
105              
106             $class->new()
107             $class->new( $ast )
108              
109             Instantiates AST compiler.
110              
111             =head2 init
112              
113             Initializes compiler. Should not be called directly.
114              
115             =head2 throw
116              
117             $self->throw( $message )
118              
119             Throws given message in compiler context.
120              
121             =head2 compile
122              
123             $self->compile()
124             $self->compile( $ast )
125              
126             Compiles AST.
127              
128             Result is string when possible; coderef otherwise.
129              
130             =head1 AUTHORS
131              
132             =over 4
133              
134             =item *
135              
136             Akzhan Abdulin <akzhan@cpan.org>
137              
138             =item *
139              
140             Igor Mironov <grif@cpan.org>
141              
142             =item *
143              
144             Victor Efimov <efimov@reg.ru>
145              
146             =item *
147              
148             REG.RU LLC
149              
150             =item *
151              
152             Kirill Sysoev <k.sysoev@me.com>
153              
154             =item *
155              
156             Alexandr Tkach <tkach@reg.ru>
157              
158             =back
159              
160             =head1 COPYRIGHT AND LICENSE
161              
162             This software is Copyright (c) 2014 by REG.RU LLC.
163              
164             This is free software, licensed under:
165              
166             The MIT (X11) License
167              
168             =cut