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   107680 use utf8;
  4         13  
  4         19  
7 4     4   109 use strict;
  4         7  
  4         60  
8 4     4   16 use warnings;
  4         5  
  4         113  
9              
10 4     4   18 use List::Util 1.33 qw( none );
  4         76  
  4         229  
11              
12 4     4   247 use Locale::Babelfish::Phrase::Literal ();
  4         7  
  4         54  
13 4     4   244 use Locale::Babelfish::Phrase::Variable ();
  4         7  
  4         67  
14 4     4   266 use Locale::Babelfish::Phrase::PluralForms ();
  4         6  
  4         67  
15              
16 4     4   15 use parent qw( Class::Accessor::Fast );
  4         27  
  4         16  
17              
18             our $VERSION = '2.003'; # VERSION
19              
20             __PACKAGE__->mk_accessors( qw( ast ) );
21              
22             my $sub_index = 0;
23              
24              
25             sub new {
26 4     4 1 1165 my ( $class, $ast ) = @_;
27 4         10 my $parser = bless {}, $class;
28 4 50       11 $parser->init( $ast ) if $ast;
29 4         8 return $parser;
30             }
31              
32              
33             sub init {
34 53     53 1 87 my ( $self, $ast ) = @_;
35 53         778 $self->ast( $ast );
36 53         446 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 53     53 1 180 my ( $self, $ast ) = @_;
49              
50 53 50       165 $self->init( $ast ) if $ast;
51              
52 53 50       746 $self->throw("No AST given") unless $self->ast;
53 53 50       227 $self->throw("Empty AST given") if scalar( @{ $self->ast } ) == 0;
  53         741  
54              
55 53 100 66     245 if ( scalar( @{ $self->ast } ) == 1 && ref($self->ast->[0]) eq 'Locale::Babelfish::Phrase::Literal' ) {
  53         727  
56             # просто строка
57 39         1300 return $self->ast->[0]->text;
58             }
59              
60 14         115 my $text = 'sub { my ( $params ) = @_; return join \'\',';
61 14         25 for my $node ( @{ $self->ast } ) {
  14         211  
62 65 100       253 if ( ref($node) eq 'Locale::Babelfish::Phrase::Literal' ) {
    100          
    50          
63 34         105 $text .= $node->to_perl_escaped_str. ',';
64             }
65             elsif ( ref($node) eq 'Locale::Babelfish::Phrase::Variable' ) {
66 16         55 $text .= "(\$params->{". $node->to_perl_escaped_str. "} // ''),";
67             }
68             elsif ( ref($node) eq 'Locale::Babelfish::Phrase::PluralForms' ) {
69 15         51 my $sub = $node->to_perl_sub();
70 15         40 my $index = ++$sub_index;
71 15         41 my $name = "Locale::Babelfish::Phrase::Compiler::COMPILED_SUB_$index";
72 4     4   1180 no strict 'refs';
  4         7  
  4         130  
73 15         30 *{$name} = $sub;
  15         113  
74 4     4   18 use strict 'refs';
  4         9  
  4         274  
75 15         61 $text .= "$name(\$params),"
76             }
77             }
78 14         30 $text .= '\'\'; }';
79 14         1252 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.003
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             =back
151              
152             =head1 COPYRIGHT AND LICENSE
153              
154             This software is Copyright (c) 2014 by REG.RU LLC.
155              
156             This is free software, licensed under:
157              
158             The MIT (X11) License
159              
160             =cut