diff --git a/.travis.yml b/.travis.yml index 84e37c1..692e892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: php php: - - 5.4 - 5.5 - 5.6 - 7.0 + - 7.1 - hhvm script: make test diff --git a/composer.json b/composer.json index ff553eb..d00508a 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ ], "require": { - "php": ">=5.4.0", - "nikic/php-parser": "^2.0.0", + "php": ">=5.5.0", + "nikic/php-parser": "3.0.*@beta || ^3.0", "symfony/console": "*", "doctrine/annotations": "*", "vektah/common": "*", diff --git a/src/main/bugfree/visitors/NameValidator.php b/src/main/bugfree/visitors/NameValidator.php index 6a0b655..f6a8eb9 100644 --- a/src/main/bugfree/visitors/NameValidator.php +++ b/src/main/bugfree/visitors/NameValidator.php @@ -19,6 +19,7 @@ use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\Stmt\Catch_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; @@ -473,6 +474,12 @@ public function enterNode(Node $node) } } + if ($node instanceof Catch_) { + foreach ($node->types as $type) { + $this->resolveType($node->getLine(), $type); + } + } + // eclipse can only handle inline type hints in a normal comment block if ($node instanceof Variable) { $comments = $node->getAttribute('comments'); diff --git a/src/test/bugfree/BugfreeTest.php b/src/test/bugfree/BugfreeTest.php index 6690f9a..15973af 100644 --- a/src/test/bugfree/BugfreeTest.php +++ b/src/test/bugfree/BugfreeTest.php @@ -8,9 +8,10 @@ class BugfreeTest extends \PHPUnit_Framework_TestCase { + /** @var Resolver */ private $resolver; - /** @var Bugfree */ + /** @var Bugfree */ private $bugfree; public function setUp() @@ -40,7 +41,7 @@ private function assertErrorWithMessage(array $array, $string) public function testNamespaceError() { - $result = $this->bugfree->parse('test', 'resolver); + $result = $this->bugfree->parse('test', 'assertErrorWithMessage($result->getErrors(), 'Every source file should have a namespace'); @@ -50,7 +51,7 @@ public function testNamespaceError() public function testMultiPartUseWarning() { - $result = $this->bugfree->parse('test', 'resolver); + $result = $this->bugfree->parse('test', 'assertErrorWithMessage($result->getErrors(), 'Multiple uses in one statement is discouraged'); } @@ -58,14 +59,14 @@ public function testUnresolvingUseStatement() { Phake::when($this->resolver)->isValid('\asdf')->thenReturn(false); - $result = $this->bugfree->parse('test', 'resolver); + $result = $this->bugfree->parse('test', 'assertErrorWithMessage($result->getErrors(), "Use '\\asdf' could not be resolved"); } public function testUnusedUse() { - $result = $this->bugfree->parse('test', 'resolver); + $result = $this->bugfree->parse('test', 'assertErrorWithMessage($result->getErrors(), "Use 'asdf' is not being used"); } @@ -76,7 +77,7 @@ public function testUseInSameNamespace() use foo\bar\Blah; $blah = new Blah(); '; - $result = $this->bugfree->parse('test', $src, $this->resolver); + $result = $this->bugfree->parse('test', $src); $this->assertErrorWithMessage($result->getErrors(), "Use 'foo\bar\Blah' is automatically included as it is in the same namespace"); } @@ -87,7 +88,7 @@ public function testDuplicateAlias() use asdf; use foo\asdf; '; - $result = $this->bugfree->parse('test', $src, $this->resolver); + $result = $this->bugfree->parse('test', $src); $this->assertErrorWithMessage($result->getErrors(), "Alias 'asdf' is already in use on line 2"); } @@ -101,7 +102,7 @@ public function testEmailsAreIgnored() */ function foo() {} '; - $result = $this->bugfree->parse('test', $src, $this->resolver); + $result = $this->bugfree->parse('test', $src); $this->assertEquals([], $result->getErrors()); @@ -122,7 +123,7 @@ function test(Baz \$f) {} } "; - $result = $this->bugfree->parse('test', $src, $this->resolver); + $result = $this->bugfree->parse('test', $src); $this->assertErrorWithMessage($result->getErrors(), "Type 'foo\\Foo' could not be resolved"); $this->assertErrorWithMessage($result->getErrors(), "Type 'baz\\Baz' could not be resolved"); @@ -193,13 +194,13 @@ public function useProvider() ]; } - private function verifySource($src, $options) + private function verifySource($src, array $options) { foreach ($options['invalid'] as $invalid) { Phake::when($this->resolver)->isValid($invalid)->thenReturn(false); } - $result = $this->bugfree->parse('test', $src, $this->resolver); + $result = $this->bugfree->parse('test', $src); foreach ($options['errors'] as $error) { $this->assertErrorWithMessage($result->getErrors(), $error); @@ -230,7 +231,7 @@ function asdf({$options['type']} \$foo) {}"; /** * @dataProvider useProvider */ - public function testClassImplements($options) + public function testClassImplements(array $options) { $src = "verifySource($src, $options); } + public static function multipleCatchProvider() { + return [ + [[ + 'invalid' => ['Thing'], + 'types' => ['\Thing', 'Thing'], + 'errors' => ["Type 'Thing' could not be resolved"], + ]], + [[ + 'invalid' => [], + 'types' => ['\Thing', 'Thing'], + 'errors' => [], + ]], + ]; + } + + /** + * @dataProvider multipleCatchProvider + */ + public function testMultipleCatch(array $options) + { + $types = join(' | ', $options['types']); + $src = "verifySource($src, $options); + } + public function builtinTypeProvider() { return [