Skip to content

Commit

Permalink
Merge pull request #15 from guymers/php71
Browse files Browse the repository at this point in the history
Support parsing PHP 7.1
  • Loading branch information
vektah committed Nov 14, 2016
2 parents fee58e0 + fc32bd2 commit 1f14206
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- hhvm
script: make test
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "*",
Expand Down
7 changes: 7 additions & 0 deletions src/main/bugfree/visitors/NameValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down Expand Up @@ -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');
Expand Down
93 changes: 64 additions & 29 deletions src/test/bugfree/BugfreeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

class BugfreeTest extends \PHPUnit_Framework_TestCase
{
/** @var Resolver */
private $resolver;

/** @var Bugfree */
/** @var Bugfree */
private $bugfree;

public function setUp()
Expand Down Expand Up @@ -40,7 +41,7 @@ private function assertErrorWithMessage(array $array, $string)

public function testNamespaceError()
{
$result = $this->bugfree->parse('test', '<?php use asdf,hjkl;', $this->resolver);
$result = $this->bugfree->parse('test', '<?php use asdf,hjkl;');
// Make sure no namespace raises an error
$this->assertErrorWithMessage($result->getErrors(), 'Every source file should have a namespace');

Expand All @@ -50,22 +51,22 @@ public function testNamespaceError()

public function testMultiPartUseWarning()
{
$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf, hjkl;', $this->resolver);
$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf, hjkl;');
$this->assertErrorWithMessage($result->getErrors(), 'Multiple uses in one statement is discouraged');
}

public function testUnresolvingUseStatement()
{
Phake::when($this->resolver)->isValid('\asdf')->thenReturn(false);

$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf, hjkl;', $this->resolver);
$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf, hjkl;');

$this->assertErrorWithMessage($result->getErrors(), "Use '\\asdf' could not be resolved");
}

public function testUnusedUse()
{
$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf;', $this->resolver);
$result = $this->bugfree->parse('test', '<?php namespace foo; use asdf;');

$this->assertErrorWithMessage($result->getErrors(), "Use 'asdf' is not being used");
}
Expand All @@ -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");
}
Expand All @@ -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");
}
Expand All @@ -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());

Expand All @@ -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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -230,7 +231,7 @@ function asdf({$options['type']} \$foo) {}";
/**
* @dataProvider useProvider
*/
public function testClassImplements($options)
public function testClassImplements(array $options)
{

$src = "<?php namespace testns;
Expand All @@ -247,7 +248,7 @@ class far implements {$options['type']} {}
/**
* @dataProvider useProvider
*/
public function testClassExtends($options)
public function testClassExtends(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -264,7 +265,7 @@ class far extends {$options['type']} {}
/**
* @dataProvider useProvider
*/
public function testMethod($options)
public function testMethod(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -282,7 +283,7 @@ public function boo({$options['type']} \$foo) {}
/**
* @dataProvider useProvider
*/
public function testCatch($options)
public function testCatch(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -300,7 +301,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testThrow($options)
public function testThrow(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -316,7 +317,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testThrowStatic($options)
public function testThrowStatic(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -337,7 +338,7 @@ protected function bar() {
/**
* @dataProvider useProvider
*/
public function testNew($options)
public function testNew(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -353,7 +354,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testConstant($options)
public function testConstant(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -369,7 +370,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testConstantInFunctionCall($options)
public function testConstantInFunctionCall(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -385,7 +386,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testConstantInStaticMethodCall($options)
public function testConstantInStaticMethodCall(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -401,7 +402,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testConstantInInstanceMethodCall($options)
public function testConstantInInstanceMethodCall(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -418,7 +419,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testUseResolutionInFunctionDocBlockTypeHint($options)
public function testUseResolutionInFunctionDocBlockTypeHint(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -437,7 +438,7 @@ function foo(\$a) {}
/**
* @dataProvider useProvider
*/
public function testUseResolutionInFunctionDocBlockReturnTypeHint($options)
public function testUseResolutionInFunctionDocBlockReturnTypeHint(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -456,7 +457,7 @@ function foo(\$a) {}
/**
* @dataProvider useProvider
*/
public function testUseResolutionInFunctionDocBlockTypeHintArraySyntax($options)
public function testUseResolutionInFunctionDocBlockTypeHintArraySyntax(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -475,7 +476,7 @@ function foo(\$a) {}
/**
* @dataProvider useProvider
*/
public function testUseResolutionInAtVarAnnotationSyntax($options)
public function testUseResolutionInAtVarAnnotationSyntax(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -494,7 +495,7 @@ function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
/**
* @dataProvider useProvider
*/
public function testUseResolutionInAtVarAnnotationSyntaxOnClassPrivates($options)
public function testUseResolutionInAtVarAnnotationSyntaxOnClassPrivates(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -515,7 +516,7 @@ class Faz {
/**
* @dataProvider useProvider
*/
public function testUseResolutionInTraitUse($options)
public function testUseResolutionInTraitUse(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -533,7 +534,7 @@ class Faz {
/**
* @dataProvider useProvider
*/
public function testEclipseInlineTypeHint($options)
public function testEclipseInlineTypeHint(array $options)
{
$src = "<?php namespace testns;
use foo\\bar\\baz;
Expand All @@ -554,6 +555,40 @@ public function foo(array \$blahs) {
$this->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 = "<?php namespace testns;
use foo\\bar\\baz;
use foo\\Thing;
function doNotWarnAboutUnused(baz \$a, Thing \$b) {}
try {
} catch({$types} \$e) {}
";
$this->verifySource($src, $options);
}

public function builtinTypeProvider()
{
return [
Expand Down

0 comments on commit 1f14206

Please sign in to comment.