'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
'MediaWiki\\OutputHandler' => __DIR__ . '/includes/OutputHandler.php',
- 'MediaWiki\\Preferences\\DefaultPreferencesFactory' => __DIR__ . '/includes/preferences/DefaultPreferencesFactory.php',
- 'MediaWiki\\Preferences\\PreferencesFactory' => __DIR__ . '/includes/preferences/PreferencesFactory.php',
'MediaWiki\\ProcOpenError' => __DIR__ . '/includes/exception/ProcOpenError.php',
'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
- 'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/services/CannotReplaceActiveServiceException.php',
- 'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/services/ContainerDisabledException.php',
- 'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/services/DestructibleService.php',
- 'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/services/NoSuchServiceException.php',
- 'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/services/SalvageableService.php',
- 'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/services/ServiceAlreadyDefinedException.php',
- 'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/services/ServiceContainer.php',
- 'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/services/ServiceDisabledException.php',
- 'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php',
- 'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php',
- 'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php',
- 'MediaWiki\\Session\\MetadataMergeException' => __DIR__ . '/includes/session/MetadataMergeException.php',
- 'MediaWiki\\Session\\PHPSessionHandler' => __DIR__ . '/includes/session/PHPSessionHandler.php',
- 'MediaWiki\\Session\\Session' => __DIR__ . '/includes/session/Session.php',
- 'MediaWiki\\Session\\SessionBackend' => __DIR__ . '/includes/session/SessionBackend.php',
- 'MediaWiki\\Session\\SessionId' => __DIR__ . '/includes/session/SessionId.php',
- 'MediaWiki\\Session\\SessionInfo' => __DIR__ . '/includes/session/SessionInfo.php',
- 'MediaWiki\\Session\\SessionManager' => __DIR__ . '/includes/session/SessionManager.php',
- 'MediaWiki\\Session\\SessionManagerInterface' => __DIR__ . '/includes/session/SessionManagerInterface.php',
- 'MediaWiki\\Session\\SessionProvider' => __DIR__ . '/includes/session/SessionProvider.php',
- 'MediaWiki\\Session\\SessionProviderInterface' => __DIR__ . '/includes/session/SessionProviderInterface.php',
- 'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
- 'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
- 'MediaWiki\\Shell\\Command' => __DIR__ . '/includes/shell/Command.php',
- 'MediaWiki\\Shell\\CommandFactory' => __DIR__ . '/includes/shell/CommandFactory.php',
- 'MediaWiki\\Shell\\FirejailCommand' => __DIR__ . '/includes/shell/FirejailCommand.php',
- 'MediaWiki\\Shell\\Result' => __DIR__ . '/includes/shell/Result.php',
- 'MediaWiki\\Shell\\Shell' => __DIR__ . '/includes/shell/Shell.php',
'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
- 'MediaWiki\\Sparql\\SparqlClient' => __DIR__ . '/includes/sparql/SparqlClient.php',
- 'MediaWiki\\Sparql\\SparqlException' => __DIR__ . '/includes/sparql/SparqlException.php',
- 'MediaWiki\\Storage\\BlobAccessException' => __DIR__ . '/includes/Storage/BlobAccessException.php',
- 'MediaWiki\\Storage\\BlobStore' => __DIR__ . '/includes/Storage/BlobStore.php',
- 'MediaWiki\\Storage\\BlobStoreFactory' => __DIR__ . '/includes/Storage/BlobStoreFactory.php',
- 'MediaWiki\\Storage\\IncompleteRevisionException' => __DIR__ . '/includes/Storage/IncompleteRevisionException.php',
- 'MediaWiki\\Storage\\MutableRevisionRecord' => __DIR__ . '/includes/Storage/MutableRevisionRecord.php',
- 'MediaWiki\\Storage\\MutableRevisionSlots' => __DIR__ . '/includes/Storage/MutableRevisionSlots.php',
- 'MediaWiki\\Storage\\NameTableAccessException' => __DIR__ . '/includes/Storage/NameTableAccessException.php',
- 'MediaWiki\\Storage\\NameTableStore' => __DIR__ . '/includes/Storage/NameTableStore.php',
- 'MediaWiki\\Storage\\RevisionAccessException' => __DIR__ . '/includes/Storage/RevisionAccessException.php',
- 'MediaWiki\\Storage\\RevisionArchiveRecord' => __DIR__ . '/includes/Storage/RevisionArchiveRecord.php',
- 'MediaWiki\\Storage\\RevisionFactory' => __DIR__ . '/includes/Storage/RevisionFactory.php',
- 'MediaWiki\\Storage\\RevisionLookup' => __DIR__ . '/includes/Storage/RevisionLookup.php',
- 'MediaWiki\\Storage\\RevisionRecord' => __DIR__ . '/includes/Storage/RevisionRecord.php',
- 'MediaWiki\\Storage\\RevisionSlots' => __DIR__ . '/includes/Storage/RevisionSlots.php',
- 'MediaWiki\\Storage\\RevisionSlotsUpdate' => __DIR__ . '/includes/Storage/RevisionSlotsUpdate.php',
- 'MediaWiki\\Storage\\RevisionStore' => __DIR__ . '/includes/Storage/RevisionStore.php',
- 'MediaWiki\\Storage\\RevisionStoreRecord' => __DIR__ . '/includes/Storage/RevisionStoreRecord.php',
- 'MediaWiki\\Storage\\SlotRecord' => __DIR__ . '/includes/Storage/SlotRecord.php',
- 'MediaWiki\\Storage\\SqlBlobStore' => __DIR__ . '/includes/Storage/SqlBlobStore.php',
- 'MediaWiki\\Storage\\SuppressedDataException' => __DIR__ . '/includes/Storage/SuppressedDataException.php',
- 'MediaWiki\\Tidy\\RaggettBase' => __DIR__ . '/includes/tidy/RaggettBase.php',
- 'MediaWiki\\Tidy\\RaggettExternal' => __DIR__ . '/includes/tidy/RaggettExternal.php',
- 'MediaWiki\\Tidy\\RaggettInternalHHVM' => __DIR__ . '/includes/tidy/RaggettInternalHHVM.php',
- 'MediaWiki\\Tidy\\RaggettInternalPHP' => __DIR__ . '/includes/tidy/RaggettInternalPHP.php',
- 'MediaWiki\\Tidy\\RaggettWrapper' => __DIR__ . '/includes/tidy/RaggettWrapper.php',
- 'MediaWiki\\Tidy\\RemexCompatFormatter' => __DIR__ . '/includes/tidy/RemexCompatFormatter.php',
- 'MediaWiki\\Tidy\\RemexCompatMunger' => __DIR__ . '/includes/tidy/RemexCompatMunger.php',
- 'MediaWiki\\Tidy\\RemexDriver' => __DIR__ . '/includes/tidy/RemexDriver.php',
- 'MediaWiki\\Tidy\\RemexMungerData' => __DIR__ . '/includes/tidy/RemexMungerData.php',
- 'MediaWiki\\Tidy\\TidyDriverBase' => __DIR__ . '/includes/tidy/TidyDriverBase.php',
'MediaWiki\\User\\UserIdentity' => __DIR__ . '/includes/user/UserIdentity.php',
'MediaWiki\\User\\UserIdentityValue' => __DIR__ . '/includes/user/UserIdentityValue.php',
'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
);
}
+ public function providePSR4Completeness() {
+ foreach ( AutoLoader::$psr4Namespaces as $prefix => $dir ) {
+ foreach ( $this->recurseFiles( $dir ) as $file ) {
+ yield [ $prefix, $file ];
+ }
+ }
+ }
+
+ private function recurseFiles( $dir ) {
+ return ( new File_Iterator_Facade() )->getFilesAsArray( $dir, [ '.php' ] );
+ }
+
+ /**
+ * @coversNothing
+ * @dataProvider providePSR4Completeness
+ */
+ public function testPSR4Completeness( $prefix, $file ) {
+ global $wgAutoloadLocalClasses, $wgAutoloadClasses;
+ $contents = file_get_contents( $file );
+ list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+ $classes = array_keys( $classesInFile );
+ $this->assertCount( 1, $classes,
+ "Only one class per file in PSR-4 autoloaded classes ($file)" );
+
+ $this->assertStringStartsWith( $prefix, $classes[0] );
+ $this->assertTrue(
+ class_exists( $classes[0] ) || interface_exists( $classes[0] ) || trait_exists( $classes[0] ),
+ "Class {$classes[0]} not autoloaded properly"
+ );
+
+ $otherClasses = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+ foreach ( $aliasesInFile as $alias => $class ) {
+ $this->assertArrayHasKey( $alias, $otherClasses,
+ 'Alias must be in the classmap autoloader'
+ );
+ }
+ }
+
+ private static function parseFile( $contents ) {
+ // We could use token_get_all() here, but this is faster
+ // Note: Keep in sync with ClassCollector
+ $matches = [];
+ preg_match_all( '/
+ ^ [\t ]* (?:
+ (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
+ (?P<class> [a-zA-Z0-9_]+)
+ |
+ class_alias \s* \( \s*
+ ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
+ ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
+ \) \s* ;
+ |
+ class_alias \s* \( \s*
+ (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
+ ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
+ \) \s* ;
+ )
+ /imx', $contents, $matches, PREG_SET_ORDER );
+
+ $namespaceMatch = [];
+ preg_match( '/
+ ^ [\t ]*
+ namespace \s+
+ ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
+ \s* ;
+ /imx', $contents, $namespaceMatch );
+ $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
+
+ $classesInFile = [];
+ $aliasesInFile = [];
+
+ foreach ( $matches as $match ) {
+ if ( !empty( $match['class'] ) ) {
+ // 'class Foo {}'
+ $class = $fileNamespace . $match['class'];
+ $classesInFile[$class] = true;
+ } else {
+ if ( !empty( $match['original'] ) ) {
+ // 'class_alias( "Foo", "Bar" );'
+ $aliasesInFile[$match['alias']] = $match['original'];
+ } else {
+ // 'class_alias( Foo::class, "Bar" );'
+ $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
+ }
+ }
+ }
+
+ return [ $classesInFile, $aliasesInFile ];
+ }
+
protected static function checkAutoLoadConf() {
global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
continue;
}
- // We could use token_get_all() here, but this is faster
- // Note: Keep in sync with ClassCollector
- $matches = [];
- preg_match_all( '/
- ^ [\t ]* (?:
- (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
- (?P<class> [a-zA-Z0-9_]+)
- |
- class_alias \s* \( \s*
- ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
- ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
- \) \s* ;
- |
- class_alias \s* \( \s*
- (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
- ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
- \) \s* ;
- )
- /imx', $contents, $matches, PREG_SET_ORDER );
-
- $namespaceMatch = [];
- preg_match( '/
- ^ [\t ]*
- namespace \s+
- ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
- \s* ;
- /imx', $contents, $namespaceMatch );
- $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
-
- $classesInFile = [];
- $aliasesInFile = [];
+ list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
- foreach ( $matches as $match ) {
- if ( !empty( $match['class'] ) ) {
- // 'class Foo {}'
- $class = $fileNamespace . $match['class'];
- $actual[$class] = $file;
- $classesInFile[$class] = true;
- } else {
- if ( !empty( $match['original'] ) ) {
- // 'class_alias( "Foo", "Bar" );'
- $aliasesInFile[$match['alias']] = $match['original'];
- } else {
- // 'class_alias( Foo::class, "Bar" );'
- $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
- }
- }
+ foreach ( $classesInFile as $className => $ignore ) {
+ $actual[$className] = $file;
}
// Only accept aliases for classes in the same file, because for correct