make M:M:TC:Parameterized->equals("Unregistered") work
[gitmo/Moose.git] / lib / Moose / Meta / TypeConstraint / Parameterized.pm
CommitLineData
0fbd4b0a 1package Moose::Meta::TypeConstraint::Parameterized;
d67145ed 2
3use strict;
4use warnings;
5use metaclass;
6
7use Scalar::Util 'blessed';
acb8a5db 8use Moose::Util::TypeConstraints;
83526133 9use Moose::Meta::TypeConstraint::Parameterizable;
d67145ed 10
d67145ed 11use base 'Moose::Meta::TypeConstraint';
12
0fbd4b0a 13__PACKAGE__->meta->add_attribute('type_parameter' => (
14 accessor => 'type_parameter',
15 predicate => 'has_type_parameter',
dc2b7cc8 16 Class::MOP::_definition_context(),
d67145ed 17));
18
7fb4b360 19__PACKAGE__->meta->add_attribute('parameterized_from' => (
20 accessor => 'parameterized_from',
21 predicate => 'has_parameterized_from',
dc2b7cc8 22 Class::MOP::_definition_context(),
7fb4b360 23));
24
dabed765 25sub equals {
26 my ( $self, $type_or_name ) = @_;
27
46f2b34a 28 my $other = Moose::Util::TypeConstraints::find_or_create_type_constraint($type_or_name) or return;
dabed765 29
30 return unless $other->isa(__PACKAGE__);
d03bd989 31
dabed765 32 return (
33 $self->type_parameter->equals( $other->type_parameter )
34 and
35 $self->parent->equals( $other->parent )
36 );
37}
38
d67145ed 39sub compile_type_constraint {
40 my $self = shift;
d03bd989 41
70ea9161 42 unless ( $self->has_type_parameter ) {
43 require Moose;
44 Moose->throw_error("You cannot create a Higher Order type without a type parameter");
45 }
46
0fbd4b0a 47 my $type_parameter = $self->type_parameter;
d03bd989 48
70ea9161 49 unless ( blessed $type_parameter && $type_parameter->isa('Moose::Meta::TypeConstraint') ) {
50 require Moose;
51 Moose->throw_error("The type parameter must be a Moose meta type");
52 }
7e4e1ad4 53
54 foreach my $type (Moose::Util::TypeConstraints::get_all_parameterizable_types()) {
55 if (my $constraint = $type->generate_constraint_for($self)) {
56 $self->_set_constraint($constraint);
d03bd989 57 return $self->SUPER::compile_type_constraint;
7e4e1ad4 58 }
d67145ed 59 }
d03bd989 60
61 # if we get here, then we couldn't
7e4e1ad4 62 # find a way to parameterize this type
70ea9161 63 require Moose;
d03bd989 64 Moose->throw_error("The " . $self->name . " constraint cannot be used, because "
4c0b3599 65 . $self->parent->name . " doesn't subtype or coerce from a parameterizable type.");
d67145ed 66}
67
7c047a36 68sub can_be_inlined {
7fb4b360 69 my $self = shift;
70
b612a613 71 return
72 $self->has_parameterized_from
73 && $self->parameterized_from->has_inline_generator
7c047a36 74 && $self->type_parameter->can_be_inlined;
7fb4b360 75}
76
e750d47f 77sub inline_environment {
78 my $self = shift;
79
80 return {
9bc21383 81 ($self->has_parameterized_from
82 ? (%{ $self->parameterized_from->inline_environment })
83 : ()),
84 ($self->has_type_parameter
85 ? (%{ $self->type_parameter->inline_environment })
86 : ()),
e750d47f 87 };
88}
89
7fb4b360 90sub _inline_check {
91 my $self = shift;
92
7c047a36 93 return unless $self->can_be_inlined;
7fb4b360 94
b612a613 95 return $self->parameterized_from->generate_inline_for( $self->type_parameter, @_ );
7fb4b360 96}
97
85a9908f 98sub create_child_type {
9ceb576e 99 my ($self, %opts) = @_;
83526133 100 return Moose::Meta::TypeConstraint::Parameterizable->new(%opts, parent=>$self);
9ceb576e 101}
102
d67145ed 1031;
104
ad46f524 105# ABSTRACT: Type constraints with a bound parameter (ArrayRef[Int])
106
d67145ed 107__END__
108
109
110=pod
111
d67145ed 112=head1 METHODS
113
f6fdcfe7 114This class is intentionally not documented because the API is
115confusing and needs some work.
d67145ed 116
f6fdcfe7 117=head1 INHERITANCE
d67145ed 118
f6fdcfe7 119C<Moose::Meta::TypeConstraint::Parameterized> is a subclass of
120L<Moose::Meta::TypeConstraint>.
d67145ed 121
122=head1 BUGS
123
d4048ef3 124See L<Moose/BUGS> for details on reporting bugs.
d67145ed 125
d67145ed 126=cut