File Coverage

blib/lib/KiokuDB/TypeMap/Resolver.pm
Criterion Covered Total %
statement 46 46 100.0
branch 4 4 100.0
condition 3 3 100.0
subroutine 18 18 100.0
pod 0 13 0.0
total 71 84 84.5


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package KiokuDB::TypeMap::Resolver;
4 22     22   11428 use Moose;
  22         46  
  22         142  
5              
6 22     22   88557 use Carp qw(croak);
  22         40  
  22         1280  
7              
8 22     22   2420 use KiokuDB::TypeMap;
  22         43  
  22         574  
9 22     22   9357 use KiokuDB::TypeMap::Entry::MOP;
  22         61  
  22         967  
10              
11 22     22   179 use namespace::clean -except => 'meta';
  22         41  
  22         201  
12              
13             has typemap => (
14             does => "KiokuDB::Role::TypeMap",
15             is => "ro",
16             );
17              
18             has _compiled => (
19             isa => "HashRef",
20             is => "ro",
21             default => sub { return {} },
22             );
23              
24             has fallback_entry => (
25             does => "KiokuDB::TypeMap::Entry",
26             is => "ro",
27             default => sub { KiokuDB::TypeMap::Entry::MOP->new },
28             );
29              
30             sub clear_compiled {
31 24     24 0 40 my $self = shift;
32              
33 24         38 %{ $self->_compiled } = ();
  24         699  
34             }
35              
36             sub resolved {
37 37     37 0 921 my ( $self, $class ) = @_;
38              
39 37         1369 exists $self->_compiled->{$class};
40             }
41              
42             sub collapse_method {
43 13109     13109 0 167481 my ( $self, $class ) = @_;
44              
45 13109         28872 return $self->find_or_resolve($class)->collapse_method;
46             }
47              
48             sub expand_method {
49 5518     5518 0 77876 my ( $self, $class ) = @_;
50              
51 5518         12846 return $self->find_or_resolve($class)->expand_method;
52             }
53              
54             sub refresh_method {
55 35     35 0 522 my ( $self, $class ) = @_;
56              
57 35         117 return $self->find_or_resolve($class)->refresh_method;
58             }
59              
60             sub id_method {
61 2181     2181 0 24671 my ( $self, $class ) = @_;
62              
63 2181         4679 return $self->find_or_resolve($class)->id_method;
64             }
65              
66             sub compile_entry {
67 681     681 0 1252 my ( $self, $class, $entry ) = @_;
68              
69 681         2765 return $self->register_compiled( $class, $entry->compile($class, $self) );
70             }
71              
72             sub register_compiled {
73 681     681 0 1196 my ( $self, $class, $compiled ) = @_;
74              
75 681         20840 return ( $self->_compiled->{$class} = $compiled );
76             }
77              
78             sub find_or_resolve {
79 20843     20843 0 24589 my ( $self, $class ) = @_;
80              
81 20843   100     568224 return ( $self->_compiled->{$class} || $self->resolve($class) );
82             }
83              
84             sub resolve {
85 699     699 0 1156 my ( $self, $class ) = @_;
86              
87 699 100       19061 if ( my $entry = $self->typemap->resolve($class) ) {
88 411         1062 return $self->compile_entry( $class, $entry );
89             } else {
90 288         942 return $self->resolve_fallback($class);
91             }
92             }
93              
94             sub resolve_fallback {
95 288     288 0 486 my ( $self, $class ) = @_;
96              
97 288 100       864 if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
98 270         1642 return $self->resolve_fallback_with_meta($class, $meta);
99             } else {
100 18         104 return $self->resolve_fallback_without_meta($class);
101             }
102             }
103              
104             sub resolve_fallback_with_meta {
105 270     270 0 484 my ( $self, $class, $meta ) = @_;
106              
107             # FIXME only allow with Storage?
108 270         8854 return $self->compile_entry( $class => $self->fallback_entry );
109             }
110              
111             sub resolve_fallback_without_meta {
112 18     18 0 33 my ( $self, $class ) = @_;
113              
114 18         393 croak "$class has no metaclass, please provide a typemap entry or add to the allowed classes";
115             }
116              
117             __PACKAGE__->meta->make_immutable;
118              
119             __PACKAGE__
120              
121             __END__
122              
123             =pod
124              
125             =head1 NAME
126              
127             KiokuDB::TypeMap::Resolver - Caching resolver for L<KiokuDB::TypeMap>
128              
129             =head1 SYNOPSIS
130              
131             This object is used by L<KiokuDB::Linker> and L<KiokuDB::Collapser> to map
132             class names to collapsing/expanding method bodies.
133              
134             Since L<KiokuDB::TypeMap>s are fairly complex, and L<KiokuDB::TypeMap::Entry>
135             objects can benefit from specializing to a class by precomputing some things,
136             resolution is performed once per class, and the results are cached in the
137             resolver.
138              
139             =cut