From: Reedy Date: Sun, 14 Apr 2019 15:04:32 +0000 (+0100) Subject: Move ClassCollector to its own file X-Git-Tag: 1.34.0-rc.0~1983^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=14826d1e0c2a42ff88ae3fea7fce416a06e98e94 Move ClassCollector to its own file Change-Id: I881f1ccc4aaf8babc40ad534a2a91f1ccf3baad4 --- diff --git a/.phpcs.xml b/.phpcs.xml index f08ed80a69..93aa226c87 100644 --- a/.phpcs.xml +++ b/.phpcs.xml @@ -214,7 +214,6 @@ */includes/parser/Preprocessor_DOM\.php */includes/parser/Preprocessor_Hash\.php */includes/parser/Preprocessor\.php - */includes/utils/AutoloadGenerator\.php */maintenance/dumpIterator\.php */maintenance/Maintenance\.php */maintenance/findDeprecated\.php diff --git a/autoload.php b/autoload.php index f70dd5cadc..c7075d2cfa 100644 --- a/autoload.php +++ b/autoload.php @@ -262,7 +262,7 @@ $wgAutoloadLocalClasses = [ 'CheckLess' => __DIR__ . '/maintenance/checkLess.php', 'CheckStorage' => __DIR__ . '/maintenance/storage/checkStorage.php', 'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php', - 'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php', + 'ClassCollector' => __DIR__ . '/includes/utils/ClassCollector.php', 'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php', 'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php', 'CleanupCaps' => __DIR__ . '/maintenance/cleanupCaps.php', diff --git a/includes/utils/AutoloadGenerator.php b/includes/utils/AutoloadGenerator.php index 2fc7bc0645..260f66c979 100644 --- a/includes/utils/AutoloadGenerator.php +++ b/includes/utils/AutoloadGenerator.php @@ -1,4 +1,22 @@ namespace = ''; - $this->classes = []; - $this->startToken = null; - $this->alias = null; - $this->tokens = []; - - foreach ( token_get_all( $code ) as $token ) { - if ( $this->startToken === null ) { - $this->tryBeginExpect( $token ); - } else { - $this->tryEndExpect( $token ); - } - } - - return $this->classes; - } - - /** - * Determine if $token begins the next expect sequence. - * - * @param array $token - */ - protected function tryBeginExpect( $token ) { - if ( is_string( $token ) ) { - return; - } - // Note: When changing class name discovery logic, - // AutoLoaderStructureTest.php may also need to be updated. - switch ( $token[0] ) { - case T_NAMESPACE: - case T_CLASS: - case T_INTERFACE: - case T_TRAIT: - case T_DOUBLE_COLON: - case T_NEW: - $this->startToken = $token; - break; - case T_STRING: - if ( $token[1] === 'class_alias' ) { - $this->startToken = $token; - $this->alias = []; - } - } - } - - /** - * Accepts the next token in an expect sequence - * - * @param array $token - */ - protected function tryEndExpect( $token ) { - switch ( $this->startToken[0] ) { - case T_DOUBLE_COLON: - // Skip over T_CLASS after T_DOUBLE_COLON because this is something like - // "self::static" which accesses the class name. It doens't define a new class. - $this->startToken = null; - break; - case T_NEW: - // Skip over T_CLASS after T_NEW because this is a PHP 7 anonymous class. - if ( !is_array( $token ) || $token[0] !== T_WHITESPACE ) { - $this->startToken = null; - } - break; - case T_NAMESPACE: - if ( $token === ';' || $token === '{' ) { - $this->namespace = $this->implodeTokens() . '\\'; - } else { - $this->tokens[] = $token; - } - break; - - case T_STRING: - if ( $this->alias !== null ) { - // Flow 1 - Two string literals: - // - T_STRING class_alias - // - '(' - // - T_CONSTANT_ENCAPSED_STRING 'TargetClass' - // - ',' - // - T_WHITESPACE - // - T_CONSTANT_ENCAPSED_STRING 'AliasName' - // - ')' - // Flow 2 - Use of ::class syntax for first parameter - // - T_STRING class_alias - // - '(' - // - T_STRING TargetClass - // - T_DOUBLE_COLON :: - // - T_CLASS class - // - ',' - // - T_WHITESPACE - // - T_CONSTANT_ENCAPSED_STRING 'AliasName' - // - ')' - if ( $token === '(' ) { - // Start of a function call to class_alias() - $this->alias = [ 'target' => false, 'name' => false ]; - } elseif ( $token === ',' ) { - // Record that we're past the first parameter - if ( $this->alias['target'] === false ) { - $this->alias['target'] = true; - } - } elseif ( is_array( $token ) && $token[0] === T_CONSTANT_ENCAPSED_STRING ) { - if ( $this->alias['target'] === true ) { - // We already saw a first argument, this must be the second. - // Strip quotes from the string literal. - $this->alias['name'] = substr( $token[1], 1, -1 ); - } - } elseif ( $token === ')' ) { - // End of function call - $this->classes[] = $this->alias['name']; - $this->alias = null; - $this->startToken = null; - } elseif ( !is_array( $token ) || ( - $token[0] !== T_STRING && - $token[0] !== T_DOUBLE_COLON && - $token[0] !== T_CLASS && - $token[0] !== T_WHITESPACE - ) ) { - // Ignore this call to class_alias() - compat/Timestamp.php - $this->alias = null; - $this->startToken = null; - } - } - break; - - case T_CLASS: - case T_INTERFACE: - case T_TRAIT: - $this->tokens[] = $token; - if ( is_array( $token ) && $token[0] === T_STRING ) { - $this->classes[] = $this->namespace . $this->implodeTokens(); - } - } - } - - /** - * Returns the string representation of the tokens within the - * current expect sequence and resets the sequence. - * - * @return string - */ - protected function implodeTokens() { - $content = []; - foreach ( $this->tokens as $token ) { - $content[] = is_string( $token ) ? $token : $token[1]; - } - - $this->tokens = []; - $this->startToken = null; - - return trim( implode( '', $content ), " \n\t" ); - } -} diff --git a/includes/utils/ClassCollector.php b/includes/utils/ClassCollector.php new file mode 100644 index 0000000000..c987354d37 --- /dev/null +++ b/includes/utils/ClassCollector.php @@ -0,0 +1,206 @@ +namespace = ''; + $this->classes = []; + $this->startToken = null; + $this->alias = null; + $this->tokens = []; + + foreach ( token_get_all( $code ) as $token ) { + if ( $this->startToken === null ) { + $this->tryBeginExpect( $token ); + } else { + $this->tryEndExpect( $token ); + } + } + + return $this->classes; + } + + /** + * Determine if $token begins the next expect sequence. + * + * @param array $token + */ + protected function tryBeginExpect( $token ) { + if ( is_string( $token ) ) { + return; + } + // Note: When changing class name discovery logic, + // AutoLoaderStructureTest.php may also need to be updated. + switch ( $token[0] ) { + case T_NAMESPACE: + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + case T_DOUBLE_COLON: + case T_NEW: + $this->startToken = $token; + break; + case T_STRING: + if ( $token[1] === 'class_alias' ) { + $this->startToken = $token; + $this->alias = []; + } + } + } + + /** + * Accepts the next token in an expect sequence + * + * @param array $token + */ + protected function tryEndExpect( $token ) { + switch ( $this->startToken[0] ) { + case T_DOUBLE_COLON: + // Skip over T_CLASS after T_DOUBLE_COLON because this is something like + // "self::static" which accesses the class name. It doens't define a new class. + $this->startToken = null; + break; + case T_NEW: + // Skip over T_CLASS after T_NEW because this is a PHP 7 anonymous class. + if ( !is_array( $token ) || $token[0] !== T_WHITESPACE ) { + $this->startToken = null; + } + break; + case T_NAMESPACE: + if ( $token === ';' || $token === '{' ) { + $this->namespace = $this->implodeTokens() . '\\'; + } else { + $this->tokens[] = $token; + } + break; + + case T_STRING: + if ( $this->alias !== null ) { + // Flow 1 - Two string literals: + // - T_STRING class_alias + // - '(' + // - T_CONSTANT_ENCAPSED_STRING 'TargetClass' + // - ',' + // - T_WHITESPACE + // - T_CONSTANT_ENCAPSED_STRING 'AliasName' + // - ')' + // Flow 2 - Use of ::class syntax for first parameter + // - T_STRING class_alias + // - '(' + // - T_STRING TargetClass + // - T_DOUBLE_COLON :: + // - T_CLASS class + // - ',' + // - T_WHITESPACE + // - T_CONSTANT_ENCAPSED_STRING 'AliasName' + // - ')' + if ( $token === '(' ) { + // Start of a function call to class_alias() + $this->alias = [ 'target' => false, 'name' => false ]; + } elseif ( $token === ',' ) { + // Record that we're past the first parameter + if ( $this->alias['target'] === false ) { + $this->alias['target'] = true; + } + } elseif ( is_array( $token ) && $token[0] === T_CONSTANT_ENCAPSED_STRING ) { + if ( $this->alias['target'] === true ) { + // We already saw a first argument, this must be the second. + // Strip quotes from the string literal. + $this->alias['name'] = substr( $token[1], 1, -1 ); + } + } elseif ( $token === ')' ) { + // End of function call + $this->classes[] = $this->alias['name']; + $this->alias = null; + $this->startToken = null; + } elseif ( !is_array( $token ) || ( + $token[0] !== T_STRING && + $token[0] !== T_DOUBLE_COLON && + $token[0] !== T_CLASS && + $token[0] !== T_WHITESPACE + ) ) { + // Ignore this call to class_alias() - compat/Timestamp.php + $this->alias = null; + $this->startToken = null; + } + } + break; + + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + $this->tokens[] = $token; + if ( is_array( $token ) && $token[0] === T_STRING ) { + $this->classes[] = $this->namespace . $this->implodeTokens(); + } + } + } + + /** + * Returns the string representation of the tokens within the + * current expect sequence and resets the sequence. + * + * @return string + */ + protected function implodeTokens() { + $content = []; + foreach ( $this->tokens as $token ) { + $content[] = is_string( $token ) ? $token : $token[1]; + } + + $this->tokens = []; + $this->startToken = null; + + return trim( implode( '', $content ), " \n\t" ); + } +}