File Coverage

blib/lib/YAML/Perl/Composer.pm
Criterion Covered Total %
statement 86 91 94.5
branch 21 30 70.0
condition 6 9 66.6
subroutine 13 14 92.8
pod 0 9 0.0
total 126 153 82.3


line stmt bran cond sub pod time code
1             # pyyaml/lib/yaml/composer.py
2             package YAML::Perl::Composer;
3 7     7   2150 use strict;
  7         16  
  7         276  
4 7     7   40 use warnings;
  7         13  
  7         303  
5              
6             package YAML::Perl::Composer;
7 7     7   1029 use YAML::Perl::Processor -base;
  7         15  
  7         85  
8 7     7   4204 use YAML::Perl::Events;
  7         24  
  7         249  
9 7     7   4293 use YAML::Perl::Nodes;
  7         22  
  7         9051  
10              
11             field 'next_layer' => 'parser';
12              
13             field 'parser_class', 'YAML::Perl::Parser';
14             field 'parser', -init => '$self->create("parser")';
15              
16             field 'resolver_class', 'YAML::Perl::Resolver';
17             field 'resolver', -init => '$self->create("resolver")';
18              
19             field 'anchors' => {};
20              
21             sub compose {
22 1     1 0 2 my $self = shift;
23 1 50       4 if (wantarray) {
24 1         2 my @nodes = ();
25 1         5 while ($self->check_node()) {
26 1         7 push @nodes, $self->get_node();
27             }
28 1         18 return @nodes;
29             }
30             else {
31 0 0       0 return $self->check_node() ? $self->get_node() : ();
32             }
33             }
34              
35             sub check_node {
36 56     56 0 268 my $self = shift;
37 56 100       2010 $self->parser->get_event()
38             if $self->parser->check_event('YAML::Perl::Event::StreamStart');
39 56         1429 return not($self->parser->check_event('YAML::Perl::Event::StreamEnd'));
40             }
41              
42             sub get_node {
43 19     19 0 35 my $self = shift;
44 19 50       471 return $self->parser->check_event('YAML::Perl::Event::StreamEnd')
45             ? ()
46             : $self->compose_document();
47             }
48              
49 0     0 0 0 sub get_single_node {
50             # We won't implement this.
51             # The PyYaml version throws an error when composing a single node but
52             # multiple nodes exist. In Perl we will allow this for iteration.
53             }
54              
55             sub compose_document {
56 19     19 0 33 my $self = shift;
57             # Drop the DOCUMENT-START event.
58 19         503 $self->parser->get_event;
59              
60 19         91 my $node = $self->compose_node(undef, undef);
61              
62             # Drop the DOCUMENT-END event.
63 19         478 $self->parser->get_event();
64              
65 19         510 $self->anchors({});
66 19         160 return $node;
67             }
68              
69             sub compose_node {
70 76     76 0 168 my $self = shift;
71 76         119 my $parent = shift;
72 76         118 my $index = shift;
73              
74 76         106 my $node;
75 76 100       2051 if ($self->parser->check_event('YAML::Perl::Event::Alias')) {
76 2         67 my $event = $self->parser->get_event();
77 2         56 my $anchor = $event->anchor;
78 2 50       61 if (not $self->anchors->{$anchor}) {
79 0         0 throw YAML::Perl::Error::Composer(
80             "found undefined alias $anchor ", $event->start_mark
81             );
82             }
83 2         52 return $self->anchors->{$anchor};
84             }
85 74         2037 my $event = $self->parser->peek_event();
86 74         2035 my $anchor = $event->anchor;
87 74 50 66     316 if ( defined $anchor && $self->anchors()->{ $anchor } ) {
88 0         0 throw "found duplicate anchor $anchor"
89             . " first occurance " . $self->anchors()->{ $anchor }
90             . " second occurance " . $event->start_mark();
91             }
92             # $self->resolver->descend_resolver( $parent, $node );
93 74 50       1814 $node = $self->parser->check_event( 'YAML::Perl::Event::Scalar' ) ?
    100          
    100          
94             $self->compose_scalar_node( $anchor ) :
95             $self->parser->check_event( 'YAML::Perl::Event::SequenceStart' ) ?
96             $self->compose_sequence_node( $anchor ) :
97             $self->parser->check_event( 'YAML::Perl::Event::MappingStart' ) ?
98             $self->compose_mapping_node( $anchor ) : undef;
99             # $self->resolver->ascend_resolver();
100 74         641 return $node;
101             }
102              
103             sub compose_scalar_node {
104 49     49 0 89 my $self = shift;
105 49         75 my $anchor = shift;
106 49         1412 my $event = $self->parser->get_event();
107 49         1401 my $tag = $event->tag;
108             # $tag = $self->resolver->resolve(
109             # 'YAML::Perl::Node::Scalar',
110             # $event->value,
111             # $event->implicit,
112             # ) if not defined $tag or $tag == '!';
113 49         1232 my $node = YAML::Perl::Node::Scalar->new(
114             tag => $tag,
115             value => $event->value,
116             start_mark => $event->start_mark,
117             end_mark => $event->end_mark,
118             style => $event->style,
119             );
120 49 50       183 $self->anchors->{$anchor} = $node
121             if defined $anchor;
122 49         181 return $node;
123             }
124              
125             sub compose_sequence_node {
126 11     11 0 22 my $self = shift;
127 11         28 my $anchor = shift;
128 11         331 my $start_event = $self->parser->get_event();
129 11         275 my $tag = $start_event->tag;
130 11 100 66     54 if (not $tag or $tag eq '!') {
131 9         237 $tag = $self->resolver->resolve(
132             'YAML::Perl::Node::Sequence', undef, $start_event->implicit
133             );
134             }
135 11         309 my $node = YAML::Perl::Node::Sequence-> new(
136             tag => $tag,
137             value => [],
138             start_mark => $start_event->start_mark,
139             end_mark => undef,
140             flow_style => $start_event->flow_style
141             );
142 11 50       40 if ($anchor) {
143 0         0 $self->anchors->{$anchor} = $node;
144             }
145 11         19 my $index = 0;
146 11         356 while (not $self->parser->check_event('YAML::Perl::Event::SequenceEnd')) {
147 25         59 push @{$node->value}, $self->compose_node($node, $index);
  25         750  
148 25         661 $index += 1;
149             }
150 11         282 my $end_event = $self->parser->get_event();
151 11         262 $node->end_mark($end_event->end_mark);
152 11         89 return $node;
153             }
154              
155             sub compose_mapping_node {
156 14     14 0 33 my $self = shift;
157 14         24 my $anchor = shift;
158 14         329 my $start_event = $self->parser->get_event();
159 14         347 my $tag = $start_event->tag;
160 14 100 66     72 if (not defined $tag or $tag eq '!') {
161 12         308 $tag = $self->resolver->resolve(
162             'YAML::Perl::Node::Mapping',
163             undef,
164             $start_event->implicit,
165             );
166             }
167 14         364 my $node = YAML::Perl::Node::Mapping->new(
168             tag => $tag,
169             value => [],
170             start_mark => $start_event->start_mark,
171             end_mark => undef,
172             flow_style => $start_event->flow_style,
173             );
174 14 100       48 if ($anchor) {
175 2         48 $self->anchors->{$anchor} = $node;
176             }
177 14         366 while (not $self->parser->check_event('YAML::Perl::Event::MappingEnd')) {
178             #key_event = self.peek_event()
179 16         98 my $item_key = $self->compose_node($node, undef);
180             #if item_key in node.value:
181             # raise ComposerError("while composing a mapping", start_event.start_mark,
182             # "found duplicate key", key_event.start_mark)
183 16         52 my $item_value = $self->compose_node($node, $item_key);
184             #node.value[item_key] = item_value
185 16         62 push @{$node->value}, $item_key, $item_value;
  16         534  
186             }
187 14         374 my $end_event = $self->parser->get_event();
188 14         409 $node->end_mark($end_event->end_mark);
189 14         85 return $node;
190             }
191              
192             1;