File Coverage

blib/lib/MooX/TypeTiny/Role/GenerateAccessor.pm
Criterion Covered Total %
statement 11 11 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 15 15 100.0


line stmt bran cond sub pod time code
1             package MooX::TypeTiny::Role::GenerateAccessor;
2 6     6   4472 use Moo::Role;
  6         15  
  6         43  
3 6     6   3222 use Sub::Quote qw(quotify sanitize_identifier);
  6         18  
  6         408  
4 6     6   41 use Scalar::Util qw(blessed);
  6         14  
  6         4364  
5              
6             around _generate_isa_check => sub {
7             $Error::TypeTiny::CarpInternal{$_} = 1
8             for grep /\A(?:MooX?|Method::Generate)::/, keys %Carp::CarpInternal;
9              
10             my $orig = shift;
11             my $self = shift;
12             my ($name, $value, $check, $init_arg) = @_;
13             return $self->$orig(@_)
14             unless blessed $check && $check->isa('Type::Tiny');
15              
16             my $var = '$isa_check_for_'.sanitize_identifier($name);
17             $self->{captures}->{$var} = \$check;
18              
19             my $varname = defined $init_arg
20             ? sprintf('$args->{%s}', quotify($init_arg))
21             : sprintf('$self->{%s}', quotify($name));
22              
23             my $assertion = $check->inline_assert(
24             $value,
25             $var,
26             mgaca => 0,
27             attribute_name => $name,
28             attribute_step => 'isa check',
29             varname => $varname,
30             );
31             $assertion =~ s/;\z//;
32             return $assertion;
33             };
34              
35             around _generate_coerce => sub {
36             $Error::TypeTiny::CarpInternal{$_} = 1
37             for grep /\A(?:MooX?|Method::Generate)::/, keys %Carp::Internal;
38              
39             my $orig = shift;
40             my $self = shift;
41             my ($name, $value, $coerce, $init_arg) = @_;
42             return $self->$orig(@_)
43             unless blessed $coerce && $coerce->isa('Type::Coercion');
44              
45             my $var = '$coercion_for_'.sanitize_identifier($name);
46             $self->{captures}->{$var} = \$coerce;
47              
48             my $need_temp = !$self->_is_simple_value($value);
49             my $inline_value = $value;
50             if ($need_temp) {
51             $inline_value = $value;
52             $value = '$tmp';
53             }
54              
55             my $code = $coerce->can_be_inlined ? $coerce->inline_coercion($value) : "${var}->coerce(${value})";
56              
57             if ($need_temp) {
58             return "do { my \$tmp = $inline_value; $code }";
59             }
60             else {
61             return $code;
62             }
63             };
64              
65             # this doesn't need to be perfect. false negatives are fine.
66             sub _is_simple_value {
67 10     10   25 my ($self, $value) = @_;
68 10         80 return $value =~ /\A(?:
69             \$\w+(?:(?:->)?(?:\[[0-9]+\]|\{\w+\}))?
70             |
71             [-0-9_.ex]+
72             |
73             "[^\$\@"]*"
74             |
75             '[^']*'
76             |
77             undef\(\)
78             |
79             \(!1\)
80             )\z/x;
81             }
82              
83             1;