Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 11e6785

Browse files
committed
Merge branch 'feature/41-fix-method-names-reserved' into develop
Close #41
2 parents e50e9f7 + b974f63 commit 11e6785

File tree

5 files changed

+104
-12
lines changed

5 files changed

+104
-12
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ All notable changes to this project will be documented in this file, in reverse
2424

2525
### Fixed
2626

27-
- Nothing.
27+
- [#41](https://github.com/zendframework/zend-file/pull/41) fixes an issue in PHP 7.1 and up with false-positive detection of classes,
28+
interfaces, and traits when class methods are named after these keywords.
2829

2930
## 2.7.1 - 2017-01-11
3031

src/ClassFileLocator.php

+27-1
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,22 @@ public function accept()
8080
$contents = file_get_contents($file->getRealPath());
8181
$tokens = token_get_all($contents);
8282
$count = count($tokens);
83+
$inFunctionDeclaration = false;
8384
for ($i = 0; $i < $count; $i++) {
8485
$token = $tokens[$i];
86+
87+
// single character token found; skip
8588
if (! is_array($token)) {
86-
// single character token found; skip
89+
// If we were in a function declaration, and we encounter an
90+
// opening paren, reset the $inFunctionDeclaration flag.
91+
if ('(' === $token) {
92+
$inFunctionDeclaration = false;
93+
}
94+
8795
$i++;
8896
continue;
8997
}
98+
9099
switch ($token[0]) {
91100
case T_NAMESPACE:
92101
// Namespace found; grab it for later
@@ -116,13 +125,23 @@ public function accept()
116125
$savedNamespace = $namespace;
117126
}
118127
break;
128+
case T_FUNCTION:
129+
$inFunctionDeclaration = true;
130+
break;
119131
case T_TRAIT:
120132
case T_CLASS:
121133
// ignore T_CLASS after T_DOUBLE_COLON to allow PHP >=5.5 FQCN scalar resolution
122134
if ($i > 0 && is_array($tokens[$i - 1]) && $tokens[$i - 1][0] === T_DOUBLE_COLON) {
123135
break;
124136
}
125137

138+
// Ignore if we are within a function declaration;
139+
// functions are allowed to be named after keywords
140+
// such as class, interface, and trait.
141+
if ($inFunctionDeclaration) {
142+
break;
143+
}
144+
126145
// ignore anonymous classes on PHP 7.1 and greater
127146
if ($i >= 2
128147
&& \is_array($tokens[$i - 1])
@@ -137,6 +156,13 @@ public function accept()
137156
case T_INTERFACE:
138157
// Abstract class, class, interface or trait found
139158

159+
// Ignore if we are within a function declaration;
160+
// functions are allowed to be named after keywords
161+
// such as class, interface, and trait.
162+
if ($inFunctionDeclaration) {
163+
break;
164+
}
165+
140166
// Get the classname
141167
for ($i++; $i < $count; $i++) {
142168
$token = $tokens[$i];

test/ClassFileLocatorTest.php

+29-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
<?php
22
/**
3-
* Zend Framework (http://framework.zend.com/)
4-
*
5-
* @link http://github.com/zendframework/zf2 for the canonical source repository
6-
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
7-
* @license http://framework.zend.com/license/new-bsd New BSD License
3+
* @see https://github.com/zendframework/zend-file for the canonical source repository
4+
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-file/blob/master/LICENSE.md New BSD License
86
*/
97

108
namespace ZendTest\File;
@@ -14,11 +12,6 @@
1412
use Zend\File\Exception;
1513
use Zend\File\PhpClassFile;
1614

17-
/**
18-
* Test class for Zend\File\ClassFileLocator
19-
*
20-
* @group Zend_File
21-
*/
2215
class ClassFileLocatorTest extends TestCase
2316
{
2417
public function testConstructorThrowsInvalidArgumentExceptionForInvalidStringDirectory()
@@ -177,4 +170,30 @@ public function testIgnoresAnonymousClasses()
177170

178171
$this->assertEquals($expected, $classNames);
179172
}
173+
174+
/**
175+
* @requires PHP 7.1
176+
*/
177+
public function testIgnoresMethodsNamedAfterKeywords()
178+
{
179+
$classFileLocator = new ClassFileLocator(__DIR__ . '/TestAsset/WithMethodsNamedAfterKeywords');
180+
181+
$classFiles = \iterator_to_array($classFileLocator);
182+
183+
$this->assertCount(2, $classFiles);
184+
185+
$classNames = \array_reduce($classFiles, function (array $classNames, PhpClassFile $classFile) {
186+
return \array_merge(
187+
$classNames,
188+
$classFile->getClasses()
189+
);
190+
}, []);
191+
192+
$expected = [
193+
TestAsset\WithMethodsNamedAfterKeywords\WithoutReturnTypeDeclaration::class,
194+
TestAsset\WithMethodsNamedAfterKeywords\WithReturnTypeDeclaration::class,
195+
];
196+
197+
$this->assertEquals($expected, $classNames, '', 0.0, 10, true);
198+
}
180199
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* @see https://github.com/zendframework/zend-file for the canonical source repository
4+
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-file/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
namespace ZendTest\File\TestAsset\WithMethodsNamedAfterKeywords;
9+
10+
final class WithReturnTypeDeclaration
11+
{
12+
public function class() : string
13+
{
14+
}
15+
16+
public function interface() : string
17+
{
18+
}
19+
20+
public function trait() : string
21+
{
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* @see https://github.com/zendframework/zend-file for the canonical source repository
4+
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-file/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
namespace ZendTest\File\TestAsset\WithMethodsNamedAfterKeywords;
9+
10+
final class WithoutReturnTypeDeclaration
11+
{
12+
public function class()
13+
{
14+
}
15+
16+
public function interface()
17+
{
18+
}
19+
20+
public function trait()
21+
{
22+
}
23+
}

0 commit comments

Comments
 (0)