Remove code forgotten in 085dbdd69
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / _Util.pm
index 35d11df..f6e04fe 100644 (file)
@@ -71,40 +71,53 @@ BEGIN {
           ( $mro_recursor_stack->{cache} || {} )->{$_}{methlist} ||= do {
 
             my $class = $_;
-
             no strict 'refs';
-            my %methlist =
+
+            # RV to be hashed up and turned into a number
+            join "\0", (
+              $class,
               map
-                # this is essentially a uniq_by step
-                # it is crucial on OLD_MRO
-                {( Scalar::Util::refaddr($_) => $_ )}
+                {(
+                  # stringification should be sufficient, ignore names/refaddr entirely
+                  $_,
+                  attributes::get( $_ ),
+                )}
                 map
-                  {
+                  {(
+                    # skip dummy C::C3 helper crefs
+                    ! ( ( $Class::C3::MRO{$class} || {} )->{methods}{$_} )
+                      and
                     (
                       ref(\ "${class}::"->{$_} ) ne 'GLOB'
                         or
                       defined( *{ "${class}::"->{$_} }{CODE} )
                     )
+                  )
                     ? ( \&{"${class}::$_"} )
                     : ()
                   }
                   keys %{ "${class}::" }
-            ;
-
-            # RV to be hashed up and turned into a number
-            join "\0", (
-              $class,
-              map {(
-                $_, # refaddr is sufficient, ignore names entirely
-                attributes::get( $methlist{$_} )
-              )} sort keys %methlist
-            ),
+            );
           }
-        } ( 'UNIVERSAL', @{
-          ( $mro_recursor_stack->{cache} || {} )->{$_[0]}{linear_isa}
-            ||=
-           mro::get_linear_isa($_[0])
-        } ) ) ) )
+        } (
+
+          @{
+            ( $mro_recursor_stack->{cache} || {} )->{$_[0]}{linear_isa}
+              ||=
+            mro::get_linear_isa($_[0])
+          },
+
+          ((
+            ( $mro_recursor_stack->{cache} || {} )->{$_[0]}{is_universal}
+              ||=
+            mro::is_universal($_[0])
+          ) ? () : @{
+            ( $mro_recursor_stack->{cache} || {} )->{UNIVERSAL}{linear_isa}
+              ||=
+            mro::get_linear_isa("UNIVERSAL")
+          } ),
+
+        ) ) ) )
       );
     };
   }
@@ -640,11 +653,22 @@ sub modver_gt_or_eq_and_lt ($$$) {
   our $describe_class_query_cache;
 
   sub describe_class_methods {
-    my ($class) = @_;
+    my ($class, $requested_mro) = @_;
 
     croak "Expecting a class name"
       if not defined $class or $class !~ $module_name_rx;
 
+    $requested_mro ||= mro::get_mro($class);
+
+    # mro::set_mro() does not bump pkg_gen - WHAT THE FUCK?!
+    my $query_cache_key = "$class|$requested_mro";
+
+    my $stack_cache_key =
+      ( mro::get_mro($class) eq $requested_mro )
+        ? $class
+        : $query_cache_key
+    ;
+
     # use a cache on old MRO, since while we are recursing in this function
     # nothing can possibly change (the speedup is immense)
     # (yes, people could be tie()ing the stash and adding methods on access
@@ -658,47 +682,57 @@ sub modver_gt_or_eq_and_lt ($$$) {
 
     my $my_gen = 0;
 
-    $my_gen += get_real_pkg_gen($_) for (
-      'UNIVERSAL',
-      ( $class, my @my_ISA ) = @{
-        $mro_recursor_stack->{cache}{$class}{linear_isa}
+    $my_gen += get_real_pkg_gen($_) for ( my @full_ISA = (
+
+      @{
+        $mro_recursor_stack->{cache}{$stack_cache_key}{linear_isa}
           ||=
-        mro::get_linear_isa($class)
-      }
-    );
+        mro::get_linear_isa($class, $requested_mro)
+      },
 
-    my $slot = $describe_class_query_cache->{$class} ||= {};
+      ((
+        $mro_recursor_stack->{cache}{$class}{is_universal}
+          ||=
+        mro::is_universal($class)
+      ) ? () : @{
+        $mro_recursor_stack->{cache}{UNIVERSAL}{linear_isa}
+          ||=
+        mro::get_linear_isa("UNIVERSAL")
+      }),
+
+    ));
+
+    my $slot = $describe_class_query_cache->{$query_cache_key} ||= {};
 
     unless ( ($slot->{cumulative_gen}||0) == $my_gen ) {
 
+      # remove ourselves from ISA
+      shift @full_ISA;
+
       # reset
       %$slot = (
         class => $class,
-        isa => [ @my_ISA ], # copy before we shove UNIVERSAL into it
+        isa => [
+          @{ $mro_recursor_stack->{cache}{$stack_cache_key}{linear_isa} }
+            [ 1 .. $#{$mro_recursor_stack->{cache}{$stack_cache_key}{linear_isa}} ]
+        ],
         mro => {
-          type => mro::get_mro($class),
+          type => $requested_mro,
+          is_c3 => ( ($requested_mro eq 'c3') ? 1 : 0 ),
         },
         cumulative_gen => $my_gen,
       );
-      $slot->{mro}{is_c3} = ($slot->{mro}{type} eq 'c3') ? 1 : 0;
-
-      push @my_ISA, 'UNIVERSAL';
 
       # ensure the cache is populated for the parents, code below can then
       # efficiently operate over the query_cache directly
-      describe_class_methods($_) for reverse @my_ISA;
+      describe_class_methods($_) for reverse @full_ISA;
 
-      my ($methods_seen_via_ISA_on_old_mro, $current_node_refaddr);
       no strict 'refs';
 
       # combine full ISA-order inherited and local method list into a
       # "shadowing stack"
 
       (
-        $current_node_refaddr = refaddr($_)
-
-          and
-
         unshift @{ $slot->{methods}{$_->{name}} }, $_
 
           and
@@ -719,41 +753,26 @@ sub modver_gt_or_eq_and_lt ($$$) {
 
       ) for (
 
-        # what describe_class_methods for @my_ISA produced above
+        # what describe_class_methods for @full_ISA produced above
         ( map { values %{
           $describe_class_query_cache->{$_}{methods_defined_in_class} || {}
-        } } reverse @my_ISA ),
+        } } map { "$_|" . mro::get_mro($_) } reverse @full_ISA ),
 
         # our own non-cleaned subs + their attributes
         ( map {
           (
-            # these 2 OR-ed checks are sufficient for 5.10+
+            # need to account for dummy helper crefs under OLD_MRO
             (
-              ref(\ "${class}::"->{$_} ) ne 'GLOB'
+              ! DBIx::Class::_ENV_::OLD_MRO
                 or
-              defined( *{ "${class}::"->{$_} }{CODE} )
+              ! ( ( $Class::C3::MRO{$class} || {} )->{methods}{$_} )
             )
               and
-            # need to account for dummy helper crefs under OLD_MRO
+            # these 2 OR-ed checks are sufficient for 5.10+
             (
-              ! DBIx::Class::_ENV_::OLD_MRO
+              ref(\ "${class}::"->{$_} ) ne 'GLOB'
                 or
-              (
-                $methods_seen_via_ISA_on_old_mro ||= do {
-                  my $rv = {};
-                  $rv->{$_->{name}}->{ refaddr( \&{ "$_->{via_class}::$_->{name}"} ) } = 1 for
-                    map { @$_ } map
-                      { values %{ $describe_class_query_cache->{$_}{methods} } }
-                      @my_ISA;
-                  $rv;
-                }
-                  and
-                (
-                  ! $methods_seen_via_ISA_on_old_mro->{$_}
-                    or
-                  ! $methods_seen_via_ISA_on_old_mro->{$_}{ refaddr( \&{"${class}::${_}"} ) }
-                )
-              )
+              defined( *{ "${class}::"->{$_} }{CODE} )
             )
           ) ? {
               via_class => $class,
@@ -779,7 +798,7 @@ sub modver_gt_or_eq_and_lt ($$$) {
 
         $slot->{cumulative_gen} = 0;
         $slot->{cumulative_gen} += get_real_pkg_gen($_)
-          for $class, @my_ISA;
+          for $class, @full_ISA;
       }
     }