Merge "Add PHPUnit tests for methods in ViewAction::class"
[lhc/web/wiklou.git] / includes / utils / AutoloadGenerator.php
index 511b673..2fc7bc0 100644 (file)
@@ -49,6 +49,13 @@ class AutoloadGenerator {
         */
        protected $excludePaths = [];
 
+       /**
+        * Configured PSR4 namespaces
+        *
+        * @var string[] namespace => path
+        */
+       protected $psr4Namespaces = [];
+
        /**
         * @param string $basepath Root path of the project being scanned for classes
         * @param array|string $flags
@@ -79,6 +86,22 @@ class AutoloadGenerator {
                }
        }
 
+       /**
+        * Set PSR4 namespaces
+        *
+        * Unlike self::setExcludePaths(), this will only skip outputting the
+        * autoloader entry when the namespace matches the path.
+        *
+        * @since 1.32
+        * @param string[] $namespaces Associative array mapping namespace to path
+        */
+       public function setPsr4Namespaces( array $namespaces ) {
+               foreach ( $namespaces as $ns => $path ) {
+                       $ns = rtrim( $ns, '\\' ) . '\\';
+                       $this->psr4Namespaces[$ns] = rtrim( self::normalizePathSeparator( $path ), '/' );
+               }
+       }
+
        /**
         * Whether the file should be excluded
         *
@@ -135,6 +158,25 @@ class AutoloadGenerator {
                $result = $this->collector->getClasses(
                        file_get_contents( $inputPath )
                );
+
+               // Filter out classes that will be found by PSR4
+               $result = array_filter( $result, function ( $class ) use ( $inputPath ) {
+                       $parts = explode( '\\', $class );
+                       for ( $i = count( $parts ) - 1; $i > 0; $i-- ) {
+                               $ns = implode( '\\', array_slice( $parts, 0, $i ) ) . '\\';
+                               if ( isset( $this->psr4Namespaces[$ns] ) ) {
+                                       $expectedPath = $this->psr4Namespaces[$ns] . '/'
+                                               . implode( '/', array_slice( $parts, $i ) )
+                                               . '.php';
+                                       if ( $inputPath === $expectedPath ) {
+                                               return false;
+                                       }
+                               }
+                       }
+
+                       return true;
+               } );
+
                if ( $result ) {
                        $shortpath = substr( $inputPath, $len );
                        $this->classes[$shortpath] = $result;