| Current File : /home/jvzmxxx/wiki1/extensions/Flow/scripts/one-class-per-file.php |
<?php
// NOTE: you must clone https://github.com/nikic/PHP-Parser into
// vendor manually
require __DIR__ . '/../vendor/PHP-Parser/lib/bootstrap.php';
$wgAutoloadClasses = array();
require __DIR__ . '/../autoload.php';
class OneClassPerFile {
public function __construct( PhpParser\Parser $parser) {
$this->parser = $parser;
}
public function splitCode( $code ) {
$stmts = $this->parser->parse( $code );
// expect single top level namespace
if ( count( $stmts ) !== 1 || !$stmts[0] instanceof PhpParser\Node\Stmt\Namespace_ ) {
throw new RuntimeException( 'no toplevel namespace' );
}
$lines = explode( "\n", $code );
$namespaceName = $stmts[0]->name->toString();
$classes = $this->getClasses( $stmts[0] );
$common = $this->getCommonHeader( $lines, $classes );
foreach ( $classes as $stmt ) {
$fqcn = $namespaceName . '\\' . $stmt->name;
$result[$fqcn] = $common . $this->getCodeForStatement( $lines, $stmt );
}
return $result;
}
protected function getClasses( $stmt ) {
$classes = array();
foreach ( $stmt->stmts as $stmt ) {
if (
$stmt instanceof PhpParser\Node\Stmt\Interface_
|| $stmt instanceof PhpParser\Node\Stmt\Class_
) {
$classes[] = $stmt;
}
}
return $classes;
}
protected function getStartingLine( PhpParser\Node\Stmt $stmt ) {
if ( $stmt->hasAttribute( 'comments' ) ) {
$comments = $stmt->getAttribute( 'comments' );
return $comments[0]->getLine() - 1;
} else {
return $stmt->getAttribute( 'startLine' ) - 1;
}
}
protected function getEndingLine( $stmt ) {
return $stmt->getAttribute( 'endLine' );
}
protected function getCommonHeader( array $lines, array $classes ) {
$lastCommonLine = $this->getStartingLine( $classes[0] );
return implode( "\n", array_slice( $lines, 0, $lastCommonLine ) ) . "\n";
}
protected function getCodeForStatement( array $lines, PhpParser\Node\Stmt $stmt ) {
$start = $this->getStartingLine( $stmt );
$end = $this->getEndingLine( $stmt );
return implode( "\n", array_slice( $lines, $start, $end - $start ) ) . "\n";
}
}
$files = array();
foreach ( $wgAutoloadClasses as $class => $file ) {
$files[$file][] = $class;
}
$files = array_filter( $files, function( $classes ) {
return count( $classes ) > 1;
} );
$ocpf = new OneClassPerFile( new PhpParser\Parser( new PhpParser\Lexer ) );
foreach ( array_keys( $files ) as $file ) {
$classes = $ocpf->splitCode( file_get_contents( $file ) );
echo "Clearing out $file\n";
unlink( $file );
foreach ( $classes as $fqcn => $code ) {
if ( false === strpos( $fqcn, '\\Tests\\' ) ) {
// normal class
$dest = 'includes/' . strtr( substr( $fqcn, 5 ), '\\', '/' ) . '.php';
} else {
// test class
$dest = 'tests/phpunit/' . strtr( substr( $fqcn, 11 ), '\\', '/' ) . '.php';
}
echo "Writing $fqcn to $dest\n";
file_put_contents( __DIR__ . '/../' . $dest, $code );
}
}