Remove all uses of CMOP::{load_class, is_class_loaded, load_first_existing_class...
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints / Builtins.pm
index 9904669..7ea867c 100644 (file)
@@ -3,110 +3,152 @@ package Moose::Util::TypeConstraints::Builtins;
 use strict;
 use warnings;
 
-use Scalar::Util qw( blessed reftype );
+use Class::Load qw( is_class_loaded );
+use List::MoreUtils ();
+use Scalar::Util qw( blessed looks_like_number reftype );
 
 sub type { goto &Moose::Util::TypeConstraints::type }
 sub subtype { goto &Moose::Util::TypeConstraints::subtype }
 sub as { goto &Moose::Util::TypeConstraints::as }
 sub where (&) { goto &Moose::Util::TypeConstraints::where }
 sub optimize_as (&) { goto &Moose::Util::TypeConstraints::optimize_as }
+sub inline_as (&) { goto &Moose::Util::TypeConstraints::inline_as }
 
 sub define_builtins {
     my $registry = shift;
 
-    type 'Any'  => where {1};    # meta-type including all
-    subtype 'Item' => as 'Any';  # base-type
+    type 'Any'    # meta-type including all
+        => where {1}
+        => inline_as { '1' };
 
-    subtype 'Undef'   => as 'Item' => where { !defined($_) };
-    subtype 'Defined' => as 'Item' => where { defined($_) };
+    subtype 'Item'  # base type
+        => as 'Any'
+        => inline_as { '1' };
+
+    subtype 'Undef'
+        => as 'Item'
+        => where { !defined($_) }
+        => inline_as {
+            '!defined(' . $_[1] . ')'
+        };
+
+    subtype 'Defined'
+        => as 'Item'
+        => where { defined($_) }
+        => inline_as {
+            'defined(' . $_[1] . ')'
+        };
 
     subtype 'Bool'
         => as 'Item'
-        => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
+        => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
+        => inline_as {
+            '('
+                . '!defined(' . $_[1] . ') '
+                . '|| ' . $_[1] . ' eq "" '
+                . '|| (' . $_[1] . '."") eq "1" '
+                . '|| (' . $_[1] . '."") eq "0"'
+            . ')'
+        };
 
     subtype 'Value'
         => as 'Defined'
         => where { !ref($_) }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
+        => inline_as {
+            $_[0]->parent()->_inline_check($_[1])
+            . ' && !ref(' . $_[1] . ')'
+        };
 
     subtype 'Ref'
         => as 'Defined'
         => where { ref($_) }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
+            # no need to call parent - ref also checks for definedness
+        => inline_as { 'ref(' . $_[1] . ')' };
 
     subtype 'Str'
         => as 'Value'
-        => where { ref(\$_) eq 'SCALAR' }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
+        => where { ref(\$_) eq 'SCALAR' || ref(\(my $val = $_)) eq 'SCALAR' }
+        => inline_as {
+            $_[0]->parent()->_inline_check($_[1])
+            . ' && ('
+                . 'ref(\\' . $_[1] . ') eq "SCALAR"'
+                . ' || ref(\\(my $val = ' . $_[1] . ')) eq "SCALAR"'
+            . ')'
+        };
 
+    my $value_type = Moose::Util::TypeConstraints::find_type_constraint('Value');
     subtype 'Num'
         => as 'Str'
         => where { Scalar::Util::looks_like_number($_) }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
+        => inline_as {
+            # the long Str tests are redundant here
+            $value_type->_inline_check($_[1])
+            . ' && Scalar::Util::looks_like_number(' . $_[1] . ')'
+        };
 
     subtype 'Int'
         => as 'Num'
-        => where { "$_" =~ /^-?[0-9]+$/ }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
+        => where { (my $val = $_) =~ /\A-?[0-9]+\z/ }
+        => inline_as {
+            $value_type->_inline_check($_[1])
+            . ' && (my $val = ' . $_[1] . ') =~ /\A-?[0-9]+\z/'
+        };
 
     subtype 'CodeRef'
         => as 'Ref'
         => where { ref($_) eq 'CODE' }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
+        => inline_as { 'ref(' . $_[1] . ') eq "CODE"' };
 
     subtype 'RegexpRef'
         => as 'Ref'
-        => where( \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef )
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
+        => where( \&_RegexpRef )
+        => inline_as {
+            'Moose::Util::TypeConstraints::Builtins::_RegexpRef(' . $_[1] . ')'
+        };
 
     subtype 'GlobRef'
         => as 'Ref'
         => where { ref($_) eq 'GLOB' }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
+        => inline_as { 'ref(' . $_[1] . ') eq "GLOB"' };
 
     # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
     # filehandle
     subtype 'FileHandle'
-        => as 'GlobRef'
+        => as 'Ref'
         => where {
-            Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
+            (ref($_) eq "GLOB" && Scalar::Util::openhandle($_))
+         || (blessed($_) && $_->isa("IO::Handle"));
         }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
+        => inline_as {
+            '(ref(' . $_[1] . ') eq "GLOB" '
+            . '&& Scalar::Util::openhandle(' . $_[1] . ')) '
+            . '|| (Scalar::Util::blessed(' . $_[1] . ') '
+            . '&& ' . $_[1] . '->isa("IO::Handle"))'
+        };
 
     subtype 'Object'
         => as 'Ref'
         => where { blessed($_) }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
-
-    # This type is deprecated.
-    subtype 'Role'
-        => as 'Object'
-        => where { $_->can('does') }
-        => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
+        => inline_as { 'Scalar::Util::blessed(' . $_[1] . ')' };
 
     subtype 'ClassName'
         => as 'Str'
-        => where { Class::MOP::is_class_loaded($_) }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
+        => where { is_class_loaded($_) }
+            # the long Str tests are redundant here
+        => inline_as { 'Class::Load::is_class_loaded(' . $_[1] . ')' };
 
     subtype 'RoleName'
         => as 'ClassName'
         => where {
             (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
         }
-        => optimize_as
-            \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
+        => inline_as {
+            $_[0]->parent()->_inline_check($_[1])
+            . ' && do {'
+                . 'my $meta = Class::MOP::class_of(' . $_[1] . ');'
+                . '$meta && $meta->isa("Moose::Meta::Role");'
+            . '}'
+        };
 
     $registry->add_type_constraint(
         Moose::Meta::TypeConstraint::Parameterizable->new(
@@ -115,15 +157,24 @@ sub define_builtins {
             parent =>
                 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
             constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
-            optimized =>
-                \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
             constraint_generator => sub {
                 my $type_parameter = shift;
                 my $check = $type_parameter->_compiled_type_constraint;
                 return sub {
                     return $check->( ${$_} );
                 };
-            }
+            },
+            inlined => sub {
+                'ref(' . $_[1] . ') eq "SCALAR" '
+                  . '|| ref(' . $_[1] . ') eq "REF"'
+            },
+            inline_generator => sub {
+                my $self           = shift;
+                my $type_parameter = shift;
+                my $val            = shift;
+                '(ref(' . $val . ') eq "SCALAR" || ref(' . $val . ') eq "REF") '
+                  . '&& ' . $type_parameter->_inline_check('${(' . $val . ')}')
+            },
         )
     );
 
@@ -134,8 +185,6 @@ sub define_builtins {
             parent =>
                 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
             constraint => sub { ref($_) eq 'ARRAY' },
-            optimized =>
-                \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
             constraint_generator => sub {
                 my $type_parameter = shift;
                 my $check = $type_parameter->_compiled_type_constraint;
@@ -145,7 +194,22 @@ sub define_builtins {
                     }
                     1;
                     }
-            }
+            },
+            inlined          => sub { 'ref(' . $_[1] . ') eq "ARRAY"' },
+            inline_generator => sub {
+                my $self           = shift;
+                my $type_parameter = shift;
+                my $val            = shift;
+
+                'do {'
+                    . 'my $check = ' . $val . ';'
+                    . 'ref($check) eq "ARRAY" '
+                        . '&& &List::MoreUtils::all('
+                            . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
+                            . '@{$check}'
+                        . ')'
+                . '}';
+            },
         )
     );
 
@@ -156,8 +220,6 @@ sub define_builtins {
             parent =>
                 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
             constraint => sub { ref($_) eq 'HASH' },
-            optimized =>
-                \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
             constraint_generator => sub {
                 my $type_parameter = shift;
                 my $check = $type_parameter->_compiled_type_constraint;
@@ -167,7 +229,22 @@ sub define_builtins {
                     }
                     1;
                     }
-            }
+            },
+            inlined          => sub { 'ref(' . $_[1] . ') eq "HASH"' },
+            inline_generator => sub {
+                my $self           = shift;
+                my $type_parameter = shift;
+                my $val            = shift;
+
+                'do {'
+                    . 'my $check = ' . $val . ';'
+                    . 'ref($check) eq "HASH" '
+                        . '&& &List::MoreUtils::all('
+                            . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
+                            . 'values %{$check}'
+                        . ')'
+                . '}';
+            },
         )
     );
 
@@ -185,9 +262,26 @@ sub define_builtins {
                     return 1 if not( defined($_) ) || $check->($_);
                     return;
                     }
-            }
+            },
+            inlined          => sub {'1'},
+            inline_generator => sub {
+                my $self           = shift;
+                my $type_parameter = shift;
+                my $val            = shift;
+                '!defined(' . $val . ') '
+                  . '|| (' . $type_parameter->_inline_check($val) . ')'
+            },
         )
     );
 }
 
 1;
+
+__END__
+
+=pod
+
+=for pod_coverage_needs_some_pod
+
+=cut
+