Skip to content

Commit 0446267

Browse files
authored
Throw more informative error when file has PHP syntax error (#18)
* Throw more informative error when file has PHP syntax error * Fix warning, passing generator to count
1 parent 8d1a597 commit 0446267

File tree

7 files changed

+64
-4
lines changed

7 files changed

+64
-4
lines changed

fixture_src/BadPhpFileFixture.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Cspray\AnnotatedTargetFixture;
4+
5+
class BadPhpFileFixture implements Fixture {
6+
7+
public function getPath() : string {
8+
return __DIR__ . '/InvalidPhpSyntax';
9+
}
10+
11+
}

fixture_src/Fixtures.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,8 @@ public static function classOnlyAttributeSingleInterface() : ClassOnlyAttributeS
8585
public static function targetAttributeInterface() : TargetAttributeInterfaceFixture {
8686
return new TargetAttributeInterfaceFixture();
8787
}
88+
89+
public static function invalidSyntax() : BadPhpFileFixture {
90+
return new BadPhpFileFixture();
91+
}
8892
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Cspray\AnnotatedTargetFixture\InvalidPhpSyntax;
4+
5+
class BadPhpFile {
6+
7+
public function method() : string {
8+
return '':
9+
}
10+
11+
}

src/Exception/InvalidPhpSyntax.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Cspray\AnnotatedTarget\Exception;
4+
5+
final class InvalidPhpSyntax extends Exception {
6+
7+
}

src/PhpParserAnnotatedTargetParser.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace Cspray\AnnotatedTarget;
44

5+
use Cspray\AnnotatedTarget\Exception\InvalidPhpSyntax;
56
use FilesystemIterator;
67
use Generator;
78
use Iterator;
9+
use PhpParser\Error;
810
use PhpParser\Node;
911
use PhpParser\NodeTraverser;
1012
use PhpParser\NodeVisitor;
@@ -42,9 +44,17 @@ public function parse(AnnotatedTargetParserOptions $options) : Generator {
4244
));
4345

4446
foreach ($this->getSourceIterator($options) as $sourceFile) {
45-
$nodes = $this->parser->parse(file_get_contents($sourceFile->getPathname()));
46-
$nodeTraverser->traverse($nodes);
47-
unset($nodes);
47+
try {
48+
$nodes = $this->parser->parse(file_get_contents($sourceFile->getPathname()));
49+
$nodeTraverser->traverse($nodes);
50+
} catch (Error $error) {
51+
throw new InvalidPhpSyntax(
52+
message: sprintf('Encountered error parsing %s. Message: %s', $sourceFile, $error->getMessage()),
53+
previous: $error
54+
);
55+
} finally {
56+
unset($nodes);
57+
}
4858
}
4959

5060
yield from $data->targets;

tests/Unit/InvalidPhpSyntaxTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Cspray\AnnotatedTarget\Unit;
4+
5+
use Cspray\AnnotatedTarget\Exception\InvalidPhpSyntax;
6+
use Cspray\AnnotatedTargetFixture\Fixtures;
7+
8+
uses(AnnotatedTargetParserTestCase::class);
9+
10+
beforeEach()->withFixtures(Fixtures::invalidSyntax());
11+
12+
13+
it('throws an exception if invalid PHP syntax is encountered', fn() => $this->getTargets())
14+
->throws(
15+
InvalidPhpSyntax::class,
16+
'Encountered error parsing ' . Fixtures::invalidSyntax()->getPath() . '/BadPhpFile.php. Message: Syntax error, unexpected \':\', expecting \';\' on line 8'
17+
);

tests/Unit/ParseAttributesMultipleDirectoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use function Cspray\AnnotatedTarget\parseAttributes;
99
use function Cspray\Typiphy\objectType;
1010

11-
$targets = fn() => parseAttributes([Fixtures::classOnlyAttributeSingleClass()->getPath(), Fixtures::propertyOnlyAttributeSingleClass()->getPath()]);
11+
$targets = fn() => iterator_to_array(parseAttributes([Fixtures::classOnlyAttributeSingleClass()->getPath(), Fixtures::propertyOnlyAttributeSingleClass()->getPath()]));
1212

1313
it('counts targets for single class')
1414
->expect($targets)

0 commit comments

Comments
 (0)