diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dba8dbc1a8..bf79544f54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - name: "Install dependencies" run: | composer require php-coveralls/php-coveralls:^2.2 --dev --no-update - composer update --no-progress --prefer-dist + COMPOSER_ROOT_VERSION=dev-master composer update --no-progress --prefer-dist - name: "Tests" run: "php vendor/bin/phpunit --coverage-clover build/logs/clover.xml" - name: Coveralls @@ -49,7 +49,7 @@ jobs: ini-file: "development" tools: composer:v2 - name: "Install dependencies" - run: "composer update --no-progress --prefer-dist ${{ matrix.flags }}" + run: "COMPOSER_ROOT_VERSION=dev-master composer update --no-progress --prefer-dist ${{ matrix.flags }}" - name: "PHPUnit" run: "php vendor/bin/phpunit" test_old_73_80: @@ -66,7 +66,7 @@ jobs: ini-file: "development" tools: composer:v2 - name: "Install PHP 8 dependencies" - run: "composer update --no-progress --prefer-dist" + run: "COMPOSER_ROOT_VERSION=dev-master composer update --no-progress --prefer-dist" - name: "Tests" run: "test_old/run-php-src.sh 7.4.33" test_old_80_70: @@ -83,7 +83,7 @@ jobs: ini-file: "development" tools: composer:v2 - name: "Install PHP 8 dependencies" - run: "composer update --no-progress --prefer-dist" + run: "COMPOSER_ROOT_VERSION=dev-master composer update --no-progress --prefer-dist" - name: "Tests" run: "test_old/run-php-src.sh 8.3.0RC2" phpstan: diff --git a/lib/PhpParser/Node.php b/lib/PhpParser/Node.php index 843e2ea66c..fd2a9b7247 100644 --- a/lib/PhpParser/Node.php +++ b/lib/PhpParser/Node.php @@ -6,6 +6,7 @@ interface Node { /** * Gets the type of the node. * + * @psalm-return non-empty-string * @return string Type of the node */ public function getType(): string; diff --git a/lib/PhpParser/Node/Identifier.php b/lib/PhpParser/Node/Identifier.php index 266166cbb6..01eebe5ca4 100644 --- a/lib/PhpParser/Node/Identifier.php +++ b/lib/PhpParser/Node/Identifier.php @@ -8,7 +8,10 @@ * Represents a non-namespaced name. Namespaced names are represented using Name nodes. */ class Identifier extends NodeAbstract { - /** @var string Identifier as string */ + /** + * @psalm-var non-empty-string + * @var string Identifier as string + */ public string $name; /** @var array */ @@ -25,6 +28,10 @@ class Identifier extends NodeAbstract { * @param array $attributes Additional attributes */ public function __construct(string $name, array $attributes = []) { + if ($name === '') { + throw new \InvalidArgumentException('Identifier name cannot be empty'); + } + $this->attributes = $attributes; $this->name = $name; } @@ -36,6 +43,7 @@ public function getSubNodeNames(): array { /** * Get identifier as string. * + * @psalm-return non-empty-string * @return string Identifier as string. */ public function toString(): string { @@ -45,6 +53,7 @@ public function toString(): string { /** * Get lowercased identifier as string. * + * @psalm-return non-empty-string * @return string Lowercased identifier as string */ public function toLowerString(): string { @@ -63,6 +72,7 @@ public function isSpecialClassName(): bool { /** * Get identifier as string. * + * @psalm-return non-empty-string * @return string Identifier as string */ public function __toString(): string { diff --git a/lib/PhpParser/Node/Name.php b/lib/PhpParser/Node/Name.php index 26b863e40b..aa2b90eb22 100644 --- a/lib/PhpParser/Node/Name.php +++ b/lib/PhpParser/Node/Name.php @@ -5,7 +5,10 @@ use PhpParser\NodeAbstract; class Name extends NodeAbstract { - /** @var string Name as string */ + /** + * @psalm-var non-empty-string + * @var string Name as string + */ public string $name; /** @var array */ @@ -33,6 +36,7 @@ public function getSubNodeNames(): array { /** * Get parts of name (split by the namespace separator). * + * @psalm-return non-empty-list * @return string[] Parts of name */ public function getParts(): array { @@ -103,6 +107,7 @@ public function isRelative(): bool { * Returns a string representation of the name itself, without taking the name type into * account (e.g., not including a leading backslash for fully qualified names). * + * @psalm-return non-empty-string * @return string String representation */ public function toString(): string { @@ -113,6 +118,7 @@ public function toString(): string { * Returns a string representation of the name as it would occur in code (e.g., including * leading backslash for fully qualified names. * + * @psalm-return non-empty-string * @return string String representation */ public function toCodeString(): string { @@ -123,6 +129,7 @@ public function toCodeString(): string { * Returns lowercased string representation of the name, without taking the name type into * account (e.g., no leading backslash for fully qualified names). * + * @psalm-return non-empty-string * @return string Lowercased string representation */ public function toLowerString(): string { @@ -142,6 +149,7 @@ public function isSpecialClassName(): bool { * Returns a string representation of the name by imploding the namespace parts with the * namespace separator. * + * @psalm-return non-empty-string * @return string String representation */ public function __toString(): string { @@ -237,6 +245,7 @@ public static function concat($name1, $name2, array $attributes = []) { * * @param string|string[]|self $name Name to prepare * + * @psalm-return non-empty-string * @return string Prepared name */ private static function prepareName($name): string { diff --git a/test/PhpParser/Node/IdentifierTest.php b/test/PhpParser/Node/IdentifierTest.php index 74e7de54ac..3b52806b9c 100644 --- a/test/PhpParser/Node/IdentifierTest.php +++ b/test/PhpParser/Node/IdentifierTest.php @@ -3,6 +3,11 @@ namespace PhpParser\Node; class IdentifierTest extends \PHPUnit\Framework\TestCase { + public function testConstructorThrows() { + self::expectException(\InvalidArgumentException::class); + new Identifier(''); + } + public function testToString() { $identifier = new Identifier('Foo');