Have ClassCollector ignore PHP 7 anonymous classes
authorBrad Jorsch <bjorsch@wikimedia.org>
Tue, 1 May 2018 17:13:37 +0000 (13:13 -0400)
committerBrad Jorsch <bjorsch@wikimedia.org>
Tue, 1 May 2018 17:13:37 +0000 (13:13 -0400)
PHP 7 introduces anonymous classes with a syntax like

 $instance = new class() extends Foo { ... };

ClassCollector is incorrectly detecting this as a class named
"() extends Foo". This patch fixes that by having it ignore "new class"
in much the same way it currently ignores "::class".

Change-Id: I4d1985a9c04be71f7bea6cb7b61dcea74f44a6e2

includes/utils/AutoloadGenerator.php
tests/phpunit/includes/utils/ClassCollectorTest.php

index 0e2ef85..98d2c0e 100644 (file)
@@ -396,6 +396,7 @@ class ClassCollector {
                        case T_INTERFACE:
                        case T_TRAIT:
                        case T_DOUBLE_COLON:
+                       case T_NEW:
                                $this->startToken = $token;
                                break;
                        case T_STRING:
@@ -418,6 +419,12 @@ class ClassCollector {
                                // "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() . '\\';
index 9e5163f..9c7c50f 100644 (file)
@@ -43,6 +43,10 @@ class ClassCollectorTest extends PHPUnit\Framework\TestCase {
                                "namespace Example;\nclass Foo {}\nclass_alias( Foo::class, 'Bar' );",
                                [ 'Example\Foo', 'Bar' ],
                        ],
+                       [
+                               "new class() extends Foo {}",
+                               []
+                       ]
                ];
        }